Merge tag 'drm-next-5.5-2019-11-01' of git://people.freedesktop.org/~agd5f/linux into drm-next
drm-next-5.5-2019-11-01: amdgpu: - Add EEPROM support for Arcturus - Enable VCN encode support for Arcturus - Misc PSP fixes - Misc DC fixes - swSMU cleanup amdkfd: - Misc cleanups - Fix typo in cu bitmap parsing Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20191101190607.3763-1-alexander.deucher@amd.com
This commit is contained in:
commit
8a86b00a43
@ -107,7 +107,7 @@ struct amdgpu_mgpu_info
|
|||||||
uint32_t num_apu;
|
uint32_t num_apu;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AMDGPU_MAX_TIMEOUT_PARAM_LENTH 256
|
#define AMDGPU_MAX_TIMEOUT_PARAM_LENGTH 256
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Modules parameters.
|
* Modules parameters.
|
||||||
@ -125,7 +125,7 @@ extern int amdgpu_disp_priority;
|
|||||||
extern int amdgpu_hw_i2c;
|
extern int amdgpu_hw_i2c;
|
||||||
extern int amdgpu_pcie_gen2;
|
extern int amdgpu_pcie_gen2;
|
||||||
extern int amdgpu_msi;
|
extern int amdgpu_msi;
|
||||||
extern char amdgpu_lockup_timeout[AMDGPU_MAX_TIMEOUT_PARAM_LENTH];
|
extern char amdgpu_lockup_timeout[AMDGPU_MAX_TIMEOUT_PARAM_LENGTH];
|
||||||
extern int amdgpu_dpm;
|
extern int amdgpu_dpm;
|
||||||
extern int amdgpu_fw_load_type;
|
extern int amdgpu_fw_load_type;
|
||||||
extern int amdgpu_aspm;
|
extern int amdgpu_aspm;
|
||||||
@ -139,6 +139,7 @@ extern int amdgpu_vm_fragment_size;
|
|||||||
extern int amdgpu_vm_fault_stop;
|
extern int amdgpu_vm_fault_stop;
|
||||||
extern int amdgpu_vm_debug;
|
extern int amdgpu_vm_debug;
|
||||||
extern int amdgpu_vm_update_mode;
|
extern int amdgpu_vm_update_mode;
|
||||||
|
extern int amdgpu_exp_hw_support;
|
||||||
extern int amdgpu_dc;
|
extern int amdgpu_dc;
|
||||||
extern int amdgpu_sched_jobs;
|
extern int amdgpu_sched_jobs;
|
||||||
extern int amdgpu_sched_hw_submission;
|
extern int amdgpu_sched_hw_submission;
|
||||||
|
@ -130,14 +130,6 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
|||||||
adev->gfx.mec.queue_bitmap,
|
adev->gfx.mec.queue_bitmap,
|
||||||
KGD_MAX_QUEUES);
|
KGD_MAX_QUEUES);
|
||||||
|
|
||||||
/* remove the KIQ bit as well */
|
|
||||||
if (adev->gfx.kiq.ring.sched.ready)
|
|
||||||
clear_bit(amdgpu_gfx_mec_queue_to_bit(adev,
|
|
||||||
adev->gfx.kiq.ring.me - 1,
|
|
||||||
adev->gfx.kiq.ring.pipe,
|
|
||||||
adev->gfx.kiq.ring.queue),
|
|
||||||
gpu_resources.queue_bitmap);
|
|
||||||
|
|
||||||
/* According to linux/bitmap.h we shouldn't use bitmap_clear if
|
/* According to linux/bitmap.h we shouldn't use bitmap_clear if
|
||||||
* nbits is not compile time constant
|
* nbits is not compile time constant
|
||||||
*/
|
*/
|
||||||
|
@ -19,10 +19,6 @@
|
|||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#undef pr_fmt
|
|
||||||
#define pr_fmt(fmt) "kfd2kgd: " fmt
|
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/fdtable.h>
|
#include <linux/fdtable.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
@ -19,9 +19,6 @@
|
|||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#undef pr_fmt
|
|
||||||
#define pr_fmt(fmt) "kfd2kgd: " fmt
|
|
||||||
|
|
||||||
#include <linux/mmu_context.h>
|
#include <linux/mmu_context.h>
|
||||||
#include "amdgpu.h"
|
#include "amdgpu.h"
|
||||||
#include "amdgpu_amdkfd.h"
|
#include "amdgpu_amdkfd.h"
|
||||||
|
@ -19,9 +19,6 @@
|
|||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) "kfd2kgd: " fmt
|
|
||||||
|
|
||||||
#include <linux/mmu_context.h>
|
#include <linux/mmu_context.h>
|
||||||
|
|
||||||
#include "amdgpu.h"
|
#include "amdgpu.h"
|
||||||
|
@ -19,9 +19,6 @@
|
|||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) "kfd2kgd: " fmt
|
|
||||||
|
|
||||||
#include <linux/dma-buf.h>
|
#include <linux/dma-buf.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
|
@ -1089,8 +1089,8 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
|
|||||||
{
|
{
|
||||||
adev->debugfs_preempt =
|
adev->debugfs_preempt =
|
||||||
debugfs_create_file("amdgpu_preempt_ib", 0600,
|
debugfs_create_file("amdgpu_preempt_ib", 0600,
|
||||||
adev->ddev->primary->debugfs_root,
|
adev->ddev->primary->debugfs_root, adev,
|
||||||
(void *)adev, &fops_ib_preempt);
|
&fops_ib_preempt);
|
||||||
if (!(adev->debugfs_preempt)) {
|
if (!(adev->debugfs_preempt)) {
|
||||||
DRM_ERROR("unable to create amdgpu_preempt_ib debugsfs file\n");
|
DRM_ERROR("unable to create amdgpu_preempt_ib debugsfs file\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -1877,6 +1877,19 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
|||||||
if (r)
|
if (r)
|
||||||
goto init_failed;
|
goto init_failed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* retired pages will be loaded from eeprom and reserved here,
|
||||||
|
* it should be called after amdgpu_device_ip_hw_init_phase2 since
|
||||||
|
* for some ASICs the RAS EEPROM code relies on SMU fully functioning
|
||||||
|
* for I2C communication which only true at this point.
|
||||||
|
* recovery_init may fail, but it can free all resources allocated by
|
||||||
|
* itself and its failure should not stop amdgpu init process.
|
||||||
|
*
|
||||||
|
* Note: theoretically, this should be called before all vram allocations
|
||||||
|
* to protect retired page from abusing
|
||||||
|
*/
|
||||||
|
amdgpu_ras_recovery_init(adev);
|
||||||
|
|
||||||
if (adev->gmc.xgmi.num_physical_nodes > 1)
|
if (adev->gmc.xgmi.num_physical_nodes > 1)
|
||||||
amdgpu_xgmi_add_device(adev);
|
amdgpu_xgmi_add_device(adev);
|
||||||
amdgpu_amdkfd_device_init(adev);
|
amdgpu_amdkfd_device_init(adev);
|
||||||
@ -2258,6 +2271,12 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
|
|||||||
/* displays are handled in phase1 */
|
/* displays are handled in phase1 */
|
||||||
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE)
|
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE)
|
||||||
continue;
|
continue;
|
||||||
|
/* PSP lost connection when err_event_athub occurs */
|
||||||
|
if (amdgpu_ras_intr_triggered() &&
|
||||||
|
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP) {
|
||||||
|
adev->ip_blocks[i].status.hw = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
/* XXX handle errors */
|
/* XXX handle errors */
|
||||||
r = adev->ip_blocks[i].version->funcs->suspend(adev);
|
r = adev->ip_blocks[i].version->funcs->suspend(adev);
|
||||||
/* XXX handle errors */
|
/* XXX handle errors */
|
||||||
@ -2615,9 +2634,9 @@ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev)
|
|||||||
else
|
else
|
||||||
adev->compute_timeout = MAX_SCHEDULE_TIMEOUT;
|
adev->compute_timeout = MAX_SCHEDULE_TIMEOUT;
|
||||||
|
|
||||||
if (strnlen(input, AMDGPU_MAX_TIMEOUT_PARAM_LENTH)) {
|
if (strnlen(input, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH)) {
|
||||||
while ((timeout_setting = strsep(&input, ",")) &&
|
while ((timeout_setting = strsep(&input, ",")) &&
|
||||||
strnlen(timeout_setting, AMDGPU_MAX_TIMEOUT_PARAM_LENTH)) {
|
strnlen(timeout_setting, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH)) {
|
||||||
ret = kstrtol(timeout_setting, 0, &timeout);
|
ret = kstrtol(timeout_setting, 0, &timeout);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -911,7 +911,8 @@ int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low)
|
|||||||
if (is_support_sw_smu(adev)) {
|
if (is_support_sw_smu(adev)) {
|
||||||
ret = smu_get_dpm_freq_range(&adev->smu, SMU_GFXCLK,
|
ret = smu_get_dpm_freq_range(&adev->smu, SMU_GFXCLK,
|
||||||
low ? &clk_freq : NULL,
|
low ? &clk_freq : NULL,
|
||||||
!low ? &clk_freq : NULL);
|
!low ? &clk_freq : NULL,
|
||||||
|
true);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 0;
|
return 0;
|
||||||
return clk_freq * 100;
|
return clk_freq * 100;
|
||||||
@ -928,7 +929,8 @@ int amdgpu_dpm_get_mclk(struct amdgpu_device *adev, bool low)
|
|||||||
if (is_support_sw_smu(adev)) {
|
if (is_support_sw_smu(adev)) {
|
||||||
ret = smu_get_dpm_freq_range(&adev->smu, SMU_UCLK,
|
ret = smu_get_dpm_freq_range(&adev->smu, SMU_UCLK,
|
||||||
low ? &clk_freq : NULL,
|
low ? &clk_freq : NULL,
|
||||||
!low ? &clk_freq : NULL);
|
!low ? &clk_freq : NULL,
|
||||||
|
true);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 0;
|
return 0;
|
||||||
return clk_freq * 100;
|
return clk_freq * 100;
|
||||||
|
@ -298,12 +298,6 @@ enum amdgpu_pcie_gen {
|
|||||||
#define amdgpu_dpm_get_current_power_state(adev) \
|
#define amdgpu_dpm_get_current_power_state(adev) \
|
||||||
((adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle))
|
((adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle))
|
||||||
|
|
||||||
#define amdgpu_smu_get_current_power_state(adev) \
|
|
||||||
((adev)->smu.ppt_funcs->get_current_power_state(&((adev)->smu)))
|
|
||||||
|
|
||||||
#define amdgpu_smu_set_power_state(adev) \
|
|
||||||
((adev)->smu.ppt_funcs->set_power_state(&((adev)->smu)))
|
|
||||||
|
|
||||||
#define amdgpu_dpm_get_pp_num_states(adev, data) \
|
#define amdgpu_dpm_get_pp_num_states(adev, data) \
|
||||||
((adev)->powerplay.pp_funcs->get_pp_num_states((adev)->powerplay.pp_handle, data))
|
((adev)->powerplay.pp_funcs->get_pp_num_states((adev)->powerplay.pp_handle, data))
|
||||||
|
|
||||||
|
@ -84,9 +84,10 @@
|
|||||||
* - 3.33.0 - Fixes for GDS ENOMEM failures in AMDGPU_CS.
|
* - 3.33.0 - Fixes for GDS ENOMEM failures in AMDGPU_CS.
|
||||||
* - 3.34.0 - Non-DC can flip correctly between buffers with different pitches
|
* - 3.34.0 - Non-DC can flip correctly between buffers with different pitches
|
||||||
* - 3.35.0 - Add drm_amdgpu_info_device::tcc_disabled_mask
|
* - 3.35.0 - Add drm_amdgpu_info_device::tcc_disabled_mask
|
||||||
|
* - 3.36.0 - Allow reading more status registers on si/cik
|
||||||
*/
|
*/
|
||||||
#define KMS_DRIVER_MAJOR 3
|
#define KMS_DRIVER_MAJOR 3
|
||||||
#define KMS_DRIVER_MINOR 35
|
#define KMS_DRIVER_MINOR 36
|
||||||
#define KMS_DRIVER_PATCHLEVEL 0
|
#define KMS_DRIVER_PATCHLEVEL 0
|
||||||
|
|
||||||
int amdgpu_vram_limit = 0;
|
int amdgpu_vram_limit = 0;
|
||||||
@ -101,7 +102,7 @@ int amdgpu_disp_priority = 0;
|
|||||||
int amdgpu_hw_i2c = 0;
|
int amdgpu_hw_i2c = 0;
|
||||||
int amdgpu_pcie_gen2 = -1;
|
int amdgpu_pcie_gen2 = -1;
|
||||||
int amdgpu_msi = -1;
|
int amdgpu_msi = -1;
|
||||||
char amdgpu_lockup_timeout[AMDGPU_MAX_TIMEOUT_PARAM_LENTH];
|
char amdgpu_lockup_timeout[AMDGPU_MAX_TIMEOUT_PARAM_LENGTH];
|
||||||
int amdgpu_dpm = -1;
|
int amdgpu_dpm = -1;
|
||||||
int amdgpu_fw_load_type = -1;
|
int amdgpu_fw_load_type = -1;
|
||||||
int amdgpu_aspm = -1;
|
int amdgpu_aspm = -1;
|
||||||
|
@ -319,8 +319,7 @@ int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void amdgpu_gfx_kiq_free_ring(struct amdgpu_ring *ring,
|
void amdgpu_gfx_kiq_free_ring(struct amdgpu_ring *ring)
|
||||||
struct amdgpu_irq_src *irq)
|
|
||||||
{
|
{
|
||||||
amdgpu_device_wb_free(ring->adev, ring->adev->virt.reg_val_offs);
|
amdgpu_device_wb_free(ring->adev, ring->adev->virt.reg_val_offs);
|
||||||
amdgpu_ring_fini(ring);
|
amdgpu_ring_fini(ring);
|
||||||
|
@ -330,8 +330,7 @@ int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev,
|
|||||||
struct amdgpu_ring *ring,
|
struct amdgpu_ring *ring,
|
||||||
struct amdgpu_irq_src *irq);
|
struct amdgpu_irq_src *irq);
|
||||||
|
|
||||||
void amdgpu_gfx_kiq_free_ring(struct amdgpu_ring *ring,
|
void amdgpu_gfx_kiq_free_ring(struct amdgpu_ring *ring);
|
||||||
struct amdgpu_irq_src *irq);
|
|
||||||
|
|
||||||
void amdgpu_gfx_kiq_fini(struct amdgpu_device *adev);
|
void amdgpu_gfx_kiq_fini(struct amdgpu_device *adev);
|
||||||
int amdgpu_gfx_kiq_init(struct amdgpu_device *adev,
|
int amdgpu_gfx_kiq_init(struct amdgpu_device *adev,
|
||||||
|
@ -218,7 +218,7 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
|
|||||||
struct amdgpu_ring *ring = to_amdgpu_ring(sched_job->sched);
|
struct amdgpu_ring *ring = to_amdgpu_ring(sched_job->sched);
|
||||||
struct dma_fence *fence = NULL, *finished;
|
struct dma_fence *fence = NULL, *finished;
|
||||||
struct amdgpu_job *job;
|
struct amdgpu_job *job;
|
||||||
int r;
|
int r = 0;
|
||||||
|
|
||||||
job = to_amdgpu_job(sched_job);
|
job = to_amdgpu_job(sched_job);
|
||||||
finished = &job->base.s_fence->finished;
|
finished = &job->base.s_fence->finished;
|
||||||
@ -243,6 +243,8 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
|
|||||||
job->fence = dma_fence_get(fence);
|
job->fence = dma_fence_get(fence);
|
||||||
|
|
||||||
amdgpu_job_free_resources(job);
|
amdgpu_job_free_resources(job);
|
||||||
|
|
||||||
|
fence = r ? ERR_PTR(r) : fence;
|
||||||
return fence;
|
return fence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev,
|
|||||||
|
|
||||||
if (is_support_sw_smu(adev)) {
|
if (is_support_sw_smu(adev)) {
|
||||||
if (adev->smu.ppt_funcs->get_current_power_state)
|
if (adev->smu.ppt_funcs->get_current_power_state)
|
||||||
pm = amdgpu_smu_get_current_power_state(adev);
|
pm = smu_get_current_power_state(&adev->smu);
|
||||||
else
|
else
|
||||||
pm = adev->pm.dpm.user_state;
|
pm = adev->pm.dpm.user_state;
|
||||||
} else if (adev->powerplay.pp_funcs->get_current_power_state) {
|
} else if (adev->powerplay.pp_funcs->get_current_power_state) {
|
||||||
@ -907,7 +907,7 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (is_support_sw_smu(adev))
|
if (is_support_sw_smu(adev))
|
||||||
ret = smu_force_clk_levels(&adev->smu, SMU_SCLK, mask);
|
ret = smu_force_clk_levels(&adev->smu, SMU_SCLK, mask, true);
|
||||||
else if (adev->powerplay.pp_funcs->force_clock_level)
|
else if (adev->powerplay.pp_funcs->force_clock_level)
|
||||||
ret = amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask);
|
ret = amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask);
|
||||||
|
|
||||||
@ -954,7 +954,7 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (is_support_sw_smu(adev))
|
if (is_support_sw_smu(adev))
|
||||||
ret = smu_force_clk_levels(&adev->smu, SMU_MCLK, mask);
|
ret = smu_force_clk_levels(&adev->smu, SMU_MCLK, mask, true);
|
||||||
else if (adev->powerplay.pp_funcs->force_clock_level)
|
else if (adev->powerplay.pp_funcs->force_clock_level)
|
||||||
ret = amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask);
|
ret = amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask);
|
||||||
|
|
||||||
@ -994,7 +994,7 @@ static ssize_t amdgpu_set_pp_dpm_socclk(struct device *dev,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (is_support_sw_smu(adev))
|
if (is_support_sw_smu(adev))
|
||||||
ret = smu_force_clk_levels(&adev->smu, SMU_SOCCLK, mask);
|
ret = smu_force_clk_levels(&adev->smu, SMU_SOCCLK, mask, true);
|
||||||
else if (adev->powerplay.pp_funcs->force_clock_level)
|
else if (adev->powerplay.pp_funcs->force_clock_level)
|
||||||
ret = amdgpu_dpm_force_clock_level(adev, PP_SOCCLK, mask);
|
ret = amdgpu_dpm_force_clock_level(adev, PP_SOCCLK, mask);
|
||||||
|
|
||||||
@ -1034,7 +1034,7 @@ static ssize_t amdgpu_set_pp_dpm_fclk(struct device *dev,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (is_support_sw_smu(adev))
|
if (is_support_sw_smu(adev))
|
||||||
ret = smu_force_clk_levels(&adev->smu, SMU_FCLK, mask);
|
ret = smu_force_clk_levels(&adev->smu, SMU_FCLK, mask, true);
|
||||||
else if (adev->powerplay.pp_funcs->force_clock_level)
|
else if (adev->powerplay.pp_funcs->force_clock_level)
|
||||||
ret = amdgpu_dpm_force_clock_level(adev, PP_FCLK, mask);
|
ret = amdgpu_dpm_force_clock_level(adev, PP_FCLK, mask);
|
||||||
|
|
||||||
@ -1074,7 +1074,7 @@ static ssize_t amdgpu_set_pp_dpm_dcefclk(struct device *dev,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (is_support_sw_smu(adev))
|
if (is_support_sw_smu(adev))
|
||||||
ret = smu_force_clk_levels(&adev->smu, SMU_DCEFCLK, mask);
|
ret = smu_force_clk_levels(&adev->smu, SMU_DCEFCLK, mask, true);
|
||||||
else if (adev->powerplay.pp_funcs->force_clock_level)
|
else if (adev->powerplay.pp_funcs->force_clock_level)
|
||||||
ret = amdgpu_dpm_force_clock_level(adev, PP_DCEFCLK, mask);
|
ret = amdgpu_dpm_force_clock_level(adev, PP_DCEFCLK, mask);
|
||||||
|
|
||||||
@ -1114,7 +1114,7 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (is_support_sw_smu(adev))
|
if (is_support_sw_smu(adev))
|
||||||
ret = smu_force_clk_levels(&adev->smu, SMU_PCIE, mask);
|
ret = smu_force_clk_levels(&adev->smu, SMU_PCIE, mask, true);
|
||||||
else if (adev->powerplay.pp_funcs->force_clock_level)
|
else if (adev->powerplay.pp_funcs->force_clock_level)
|
||||||
ret = amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask);
|
ret = amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask);
|
||||||
|
|
||||||
@ -1306,7 +1306,7 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
|
|||||||
}
|
}
|
||||||
parameter[parameter_size] = profile_mode;
|
parameter[parameter_size] = profile_mode;
|
||||||
if (is_support_sw_smu(adev))
|
if (is_support_sw_smu(adev))
|
||||||
ret = smu_set_power_profile_mode(&adev->smu, parameter, parameter_size);
|
ret = smu_set_power_profile_mode(&adev->smu, parameter, parameter_size, true);
|
||||||
else if (adev->powerplay.pp_funcs->set_power_profile_mode)
|
else if (adev->powerplay.pp_funcs->set_power_profile_mode)
|
||||||
ret = amdgpu_dpm_set_power_profile_mode(adev, parameter, parameter_size);
|
ret = amdgpu_dpm_set_power_profile_mode(adev, parameter, parameter_size);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
@ -2015,7 +2015,7 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev,
|
|||||||
uint32_t limit = 0;
|
uint32_t limit = 0;
|
||||||
|
|
||||||
if (is_support_sw_smu(adev)) {
|
if (is_support_sw_smu(adev)) {
|
||||||
smu_get_power_limit(&adev->smu, &limit, true);
|
smu_get_power_limit(&adev->smu, &limit, true, true);
|
||||||
return snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
|
return snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
|
||||||
} else if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_power_limit) {
|
} else if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_power_limit) {
|
||||||
adev->powerplay.pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, true);
|
adev->powerplay.pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, true);
|
||||||
@ -2033,7 +2033,7 @@ static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev,
|
|||||||
uint32_t limit = 0;
|
uint32_t limit = 0;
|
||||||
|
|
||||||
if (is_support_sw_smu(adev)) {
|
if (is_support_sw_smu(adev)) {
|
||||||
smu_get_power_limit(&adev->smu, &limit, false);
|
smu_get_power_limit(&adev->smu, &limit, false, true);
|
||||||
return snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
|
return snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);
|
||||||
} else if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_power_limit) {
|
} else if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_power_limit) {
|
||||||
adev->powerplay.pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, false);
|
adev->powerplay.pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, false);
|
||||||
@ -2830,6 +2830,19 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
|
|||||||
DRM_ERROR("failed to create device file pp_dpm_sclk\n");
|
DRM_ERROR("failed to create device file pp_dpm_sclk\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Arcturus does not support standalone mclk/socclk/fclk level setting */
|
||||||
|
if (adev->asic_type == CHIP_ARCTURUS) {
|
||||||
|
dev_attr_pp_dpm_mclk.attr.mode &= ~S_IWUGO;
|
||||||
|
dev_attr_pp_dpm_mclk.store = NULL;
|
||||||
|
|
||||||
|
dev_attr_pp_dpm_socclk.attr.mode &= ~S_IWUGO;
|
||||||
|
dev_attr_pp_dpm_socclk.store = NULL;
|
||||||
|
|
||||||
|
dev_attr_pp_dpm_fclk.attr.mode &= ~S_IWUGO;
|
||||||
|
dev_attr_pp_dpm_fclk.store = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ret = device_create_file(adev->dev, &dev_attr_pp_dpm_mclk);
|
ret = device_create_file(adev->dev, &dev_attr_pp_dpm_mclk);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DRM_ERROR("failed to create device file pp_dpm_mclk\n");
|
DRM_ERROR("failed to create device file pp_dpm_mclk\n");
|
||||||
@ -3013,7 +3026,8 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
|
|||||||
struct smu_dpm_context *smu_dpm = &adev->smu.smu_dpm;
|
struct smu_dpm_context *smu_dpm = &adev->smu.smu_dpm;
|
||||||
smu_handle_task(&adev->smu,
|
smu_handle_task(&adev->smu,
|
||||||
smu_dpm->dpm_level,
|
smu_dpm->dpm_level,
|
||||||
AMD_PP_TASK_DISPLAY_CONFIG_CHANGE);
|
AMD_PP_TASK_DISPLAY_CONFIG_CHANGE,
|
||||||
|
true);
|
||||||
} else {
|
} else {
|
||||||
if (adev->powerplay.pp_funcs->dispatch_tasks) {
|
if (adev->powerplay.pp_funcs->dispatch_tasks) {
|
||||||
if (!amdgpu_device_has_dc_support(adev)) {
|
if (!amdgpu_device_has_dc_support(adev)) {
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
#include "psp_v11_0.h"
|
#include "psp_v11_0.h"
|
||||||
#include "psp_v12_0.h"
|
#include "psp_v12_0.h"
|
||||||
|
|
||||||
|
#include "amdgpu_ras.h"
|
||||||
|
|
||||||
static void psp_set_funcs(struct amdgpu_device *adev);
|
static void psp_set_funcs(struct amdgpu_device *adev);
|
||||||
|
|
||||||
static int psp_early_init(void *handle)
|
static int psp_early_init(void *handle)
|
||||||
@ -90,7 +92,7 @@ static int psp_sw_init(void *handle)
|
|||||||
|
|
||||||
ret = psp_mem_training_init(psp);
|
ret = psp_mem_training_init(psp);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DRM_ERROR("Failed to initliaze memory training!\n");
|
DRM_ERROR("Failed to initialize memory training!\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = psp_mem_training(psp, PSP_MEM_TRAIN_COLD_BOOT);
|
ret = psp_mem_training(psp, PSP_MEM_TRAIN_COLD_BOOT);
|
||||||
@ -167,6 +169,13 @@ psp_cmd_submit_buf(struct psp_context *psp,
|
|||||||
while (*((unsigned int *)psp->fence_buf) != index) {
|
while (*((unsigned int *)psp->fence_buf) != index) {
|
||||||
if (--timeout == 0)
|
if (--timeout == 0)
|
||||||
break;
|
break;
|
||||||
|
/*
|
||||||
|
* Shouldn't wait for timeout when err_event_athub occurs,
|
||||||
|
* because gpu reset thread triggered and lock resource should
|
||||||
|
* be released for psp resume sequence.
|
||||||
|
*/
|
||||||
|
if (amdgpu_ras_intr_triggered())
|
||||||
|
break;
|
||||||
msleep(1);
|
msleep(1);
|
||||||
amdgpu_asic_invalidate_hdp(psp->adev, NULL);
|
amdgpu_asic_invalidate_hdp(psp->adev, NULL);
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,11 @@ const char *ras_block_string[] = {
|
|||||||
/* inject address is 52 bits */
|
/* inject address is 52 bits */
|
||||||
#define RAS_UMC_INJECT_ADDR_LIMIT (0x1ULL << 52)
|
#define RAS_UMC_INJECT_ADDR_LIMIT (0x1ULL << 52)
|
||||||
|
|
||||||
|
enum amdgpu_ras_retire_page_reservation {
|
||||||
|
AMDGPU_RAS_RETIRE_PAGE_RESERVED,
|
||||||
|
AMDGPU_RAS_RETIRE_PAGE_PENDING,
|
||||||
|
AMDGPU_RAS_RETIRE_PAGE_FAULT,
|
||||||
|
};
|
||||||
|
|
||||||
atomic_t amdgpu_ras_in_intr = ATOMIC_INIT(0);
|
atomic_t amdgpu_ras_in_intr = ATOMIC_INIT(0);
|
||||||
|
|
||||||
@ -153,8 +158,6 @@ static int amdgpu_ras_debugfs_ctrl_parse_data(struct file *f,
|
|||||||
op = 1;
|
op = 1;
|
||||||
else if (sscanf(str, "inject %32s %8s", block_name, err) == 2)
|
else if (sscanf(str, "inject %32s %8s", block_name, err) == 2)
|
||||||
op = 2;
|
op = 2;
|
||||||
else if (sscanf(str, "reboot %32s", block_name) == 1)
|
|
||||||
op = 3;
|
|
||||||
else if (str[0] && str[1] && str[2] && str[3])
|
else if (str[0] && str[1] && str[2] && str[3])
|
||||||
/* ascii string, but commands are not matched. */
|
/* ascii string, but commands are not matched. */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -218,12 +221,11 @@ static struct ras_manager *amdgpu_ras_find_obj(struct amdgpu_device *adev,
|
|||||||
* value to the address.
|
* value to the address.
|
||||||
*
|
*
|
||||||
* Second member: struct ras_debug_if::op.
|
* Second member: struct ras_debug_if::op.
|
||||||
* It has four kinds of operations.
|
* It has three kinds of operations.
|
||||||
*
|
*
|
||||||
* - 0: disable RAS on the block. Take ::head as its data.
|
* - 0: disable RAS on the block. Take ::head as its data.
|
||||||
* - 1: enable RAS on the block. Take ::head as its data.
|
* - 1: enable RAS on the block. Take ::head as its data.
|
||||||
* - 2: inject errors on the block. Take ::inject as its data.
|
* - 2: inject errors on the block. Take ::inject as its data.
|
||||||
* - 3: reboot on unrecoverable error
|
|
||||||
*
|
*
|
||||||
* How to use the interface?
|
* How to use the interface?
|
||||||
* programs:
|
* programs:
|
||||||
@ -305,9 +307,6 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user *
|
|||||||
/* data.inject.address is offset instead of absolute gpu address */
|
/* data.inject.address is offset instead of absolute gpu address */
|
||||||
ret = amdgpu_ras_error_inject(adev, &data.inject);
|
ret = amdgpu_ras_error_inject(adev, &data.inject);
|
||||||
break;
|
break;
|
||||||
case 3:
|
|
||||||
amdgpu_ras_get_context(adev)->reboot = true;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
@ -559,15 +558,17 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
|
|||||||
if (!(!!enable ^ !!amdgpu_ras_is_feature_enabled(adev, head)))
|
if (!(!!enable ^ !!amdgpu_ras_is_feature_enabled(adev, head)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = psp_ras_enable_features(&adev->psp, &info, enable);
|
if (!amdgpu_ras_intr_triggered()) {
|
||||||
if (ret) {
|
ret = psp_ras_enable_features(&adev->psp, &info, enable);
|
||||||
DRM_ERROR("RAS ERROR: %s %s feature failed ret %d\n",
|
if (ret) {
|
||||||
enable ? "enable":"disable",
|
DRM_ERROR("RAS ERROR: %s %s feature failed ret %d\n",
|
||||||
ras_block_str(head->block),
|
enable ? "enable":"disable",
|
||||||
ret);
|
ras_block_str(head->block),
|
||||||
if (ret == TA_RAS_STATUS__RESET_NEEDED)
|
ret);
|
||||||
return -EAGAIN;
|
if (ret == TA_RAS_STATUS__RESET_NEEDED)
|
||||||
return -EINVAL;
|
return -EAGAIN;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup the obj */
|
/* setup the obj */
|
||||||
@ -815,11 +816,11 @@ static int amdgpu_ras_badpages_read(struct amdgpu_device *adev,
|
|||||||
static char *amdgpu_ras_badpage_flags_str(unsigned int flags)
|
static char *amdgpu_ras_badpage_flags_str(unsigned int flags)
|
||||||
{
|
{
|
||||||
switch (flags) {
|
switch (flags) {
|
||||||
case 0:
|
case AMDGPU_RAS_RETIRE_PAGE_RESERVED:
|
||||||
return "R";
|
return "R";
|
||||||
case 1:
|
case AMDGPU_RAS_RETIRE_PAGE_PENDING:
|
||||||
return "P";
|
return "P";
|
||||||
case 2:
|
case AMDGPU_RAS_RETIRE_PAGE_FAULT:
|
||||||
default:
|
default:
|
||||||
return "F";
|
return "F";
|
||||||
};
|
};
|
||||||
@ -1037,6 +1038,17 @@ static void amdgpu_ras_debugfs_create_ctrl_node(struct amdgpu_device *adev)
|
|||||||
adev, &amdgpu_ras_debugfs_ctrl_ops);
|
adev, &amdgpu_ras_debugfs_ctrl_ops);
|
||||||
debugfs_create_file("ras_eeprom_reset", S_IWUGO | S_IRUGO, con->dir,
|
debugfs_create_file("ras_eeprom_reset", S_IWUGO | S_IRUGO, con->dir,
|
||||||
adev, &amdgpu_ras_debugfs_eeprom_ops);
|
adev, &amdgpu_ras_debugfs_eeprom_ops);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* After one uncorrectable error happens, usually GPU recovery will
|
||||||
|
* be scheduled. But due to the known problem in GPU recovery failing
|
||||||
|
* to bring GPU back, below interface provides one direct way to
|
||||||
|
* user to reboot system automatically in such case within
|
||||||
|
* ERREVENT_ATHUB_INTERRUPT generated. Normal GPU recovery routine
|
||||||
|
* will never be called.
|
||||||
|
*/
|
||||||
|
debugfs_create_bool("auto_reboot", S_IWUGO | S_IRUGO, con->dir,
|
||||||
|
&con->reboot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void amdgpu_ras_debugfs_create(struct amdgpu_device *adev,
|
void amdgpu_ras_debugfs_create(struct amdgpu_device *adev,
|
||||||
@ -1289,13 +1301,13 @@ static int amdgpu_ras_badpages_read(struct amdgpu_device *adev,
|
|||||||
(*bps)[i] = (struct ras_badpage){
|
(*bps)[i] = (struct ras_badpage){
|
||||||
.bp = data->bps[i].retired_page,
|
.bp = data->bps[i].retired_page,
|
||||||
.size = AMDGPU_GPU_PAGE_SIZE,
|
.size = AMDGPU_GPU_PAGE_SIZE,
|
||||||
.flags = 0,
|
.flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (data->last_reserved <= i)
|
if (data->last_reserved <= i)
|
||||||
(*bps)[i].flags = 1;
|
(*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_PENDING;
|
||||||
else if (data->bps_bo[i] == NULL)
|
else if (data->bps_bo[i] == NULL)
|
||||||
(*bps)[i].flags = 2;
|
(*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_FAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
*count = data->count;
|
*count = data->count;
|
||||||
|
@ -216,6 +216,10 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control)
|
|||||||
ret = smu_v11_0_i2c_eeprom_control_init(&control->eeprom_accessor);
|
ret = smu_v11_0_i2c_eeprom_control_init(&control->eeprom_accessor);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CHIP_ARCTURUS:
|
||||||
|
ret = smu_i2c_eeprom_init(&adev->smu, &control->eeprom_accessor);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -260,6 +264,9 @@ void amdgpu_ras_eeprom_fini(struct amdgpu_ras_eeprom_control *control)
|
|||||||
case CHIP_VEGA20:
|
case CHIP_VEGA20:
|
||||||
smu_v11_0_i2c_eeprom_control_fini(&control->eeprom_accessor);
|
smu_v11_0_i2c_eeprom_control_fini(&control->eeprom_accessor);
|
||||||
break;
|
break;
|
||||||
|
case CHIP_ARCTURUS:
|
||||||
|
smu_i2c_eeprom_fini(&adev->smu, &control->eeprom_accessor);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
@ -364,7 +371,7 @@ int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control,
|
|||||||
struct eeprom_table_record *record;
|
struct eeprom_table_record *record;
|
||||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||||
|
|
||||||
if (adev->asic_type != CHIP_VEGA20)
|
if (adev->asic_type != CHIP_VEGA20 && adev->asic_type != CHIP_ARCTURUS)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
buffs = kcalloc(num, EEPROM_ADDRESS_SIZE + EEPROM_TABLE_RECORD_SIZE,
|
buffs = kcalloc(num, EEPROM_ADDRESS_SIZE + EEPROM_TABLE_RECORD_SIZE,
|
||||||
|
@ -486,15 +486,12 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict,
|
|||||||
struct ttm_operation_ctx *ctx,
|
struct ttm_operation_ctx *ctx,
|
||||||
struct ttm_mem_reg *new_mem)
|
struct ttm_mem_reg *new_mem)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev;
|
|
||||||
struct ttm_mem_reg *old_mem = &bo->mem;
|
struct ttm_mem_reg *old_mem = &bo->mem;
|
||||||
struct ttm_mem_reg tmp_mem;
|
struct ttm_mem_reg tmp_mem;
|
||||||
struct ttm_place placements;
|
struct ttm_place placements;
|
||||||
struct ttm_placement placement;
|
struct ttm_placement placement;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
adev = amdgpu_ttm_adev(bo->bdev);
|
|
||||||
|
|
||||||
/* create space/pages for new_mem in GTT space */
|
/* create space/pages for new_mem in GTT space */
|
||||||
tmp_mem = *new_mem;
|
tmp_mem = *new_mem;
|
||||||
tmp_mem.mm_node = NULL;
|
tmp_mem.mm_node = NULL;
|
||||||
@ -545,15 +542,12 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict,
|
|||||||
struct ttm_operation_ctx *ctx,
|
struct ttm_operation_ctx *ctx,
|
||||||
struct ttm_mem_reg *new_mem)
|
struct ttm_mem_reg *new_mem)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev;
|
|
||||||
struct ttm_mem_reg *old_mem = &bo->mem;
|
struct ttm_mem_reg *old_mem = &bo->mem;
|
||||||
struct ttm_mem_reg tmp_mem;
|
struct ttm_mem_reg tmp_mem;
|
||||||
struct ttm_placement placement;
|
struct ttm_placement placement;
|
||||||
struct ttm_place placements;
|
struct ttm_place placements;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
adev = amdgpu_ttm_adev(bo->bdev);
|
|
||||||
|
|
||||||
/* make space in GTT for old_mem buffer */
|
/* make space in GTT for old_mem buffer */
|
||||||
tmp_mem = *new_mem;
|
tmp_mem = *new_mem;
|
||||||
tmp_mem.mm_node = NULL;
|
tmp_mem.mm_node = NULL;
|
||||||
@ -1220,11 +1214,8 @@ static struct ttm_backend_func amdgpu_backend_func = {
|
|||||||
static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo,
|
static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo,
|
||||||
uint32_t page_flags)
|
uint32_t page_flags)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev;
|
|
||||||
struct amdgpu_ttm_tt *gtt;
|
struct amdgpu_ttm_tt *gtt;
|
||||||
|
|
||||||
adev = amdgpu_ttm_adev(bo->bdev);
|
|
||||||
|
|
||||||
gtt = kzalloc(sizeof(struct amdgpu_ttm_tt), GFP_KERNEL);
|
gtt = kzalloc(sizeof(struct amdgpu_ttm_tt), GFP_KERNEL);
|
||||||
if (gtt == NULL) {
|
if (gtt == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1810,17 +1801,6 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
|||||||
adev->gmc.visible_vram_size);
|
adev->gmc.visible_vram_size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* retired pages will be loaded from eeprom and reserved here,
|
|
||||||
* it should be called after ttm init since new bo may be created,
|
|
||||||
* recovery_init may fail, but it can free all resources allocated by
|
|
||||||
* itself and its failure should not stop amdgpu init process.
|
|
||||||
*
|
|
||||||
* Note: theoretically, this should be called before all vram allocations
|
|
||||||
* to protect retired page from abusing
|
|
||||||
*/
|
|
||||||
amdgpu_ras_recovery_init(adev);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*The reserved vram for firmware must be pinned to the specified
|
*The reserved vram for firmware must be pinned to the specified
|
||||||
*place on the VRAM, so reserve it early.
|
*place on the VRAM, so reserve it early.
|
||||||
|
@ -39,6 +39,8 @@
|
|||||||
#include "cikd.h"
|
#include "cikd.h"
|
||||||
#include "uvd/uvd_4_2_d.h"
|
#include "uvd/uvd_4_2_d.h"
|
||||||
|
|
||||||
|
#include "amdgpu_ras.h"
|
||||||
|
|
||||||
/* 1 second timeout */
|
/* 1 second timeout */
|
||||||
#define UVD_IDLE_TIMEOUT msecs_to_jiffies(1000)
|
#define UVD_IDLE_TIMEOUT msecs_to_jiffies(1000)
|
||||||
|
|
||||||
@ -372,7 +374,13 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
|
|||||||
if (!adev->uvd.inst[j].saved_bo)
|
if (!adev->uvd.inst[j].saved_bo)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size);
|
/* re-write 0 since err_event_athub will corrupt VCPU buffer */
|
||||||
|
if (amdgpu_ras_intr_triggered()) {
|
||||||
|
DRM_WARN("UVD VCPU state may lost due to RAS ERREVENT_ATHUB_INTERRUPT\n");
|
||||||
|
memset(adev->uvd.inst[j].saved_bo, 0, size);
|
||||||
|
} else {
|
||||||
|
memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -966,6 +966,25 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev,
|
|||||||
|
|
||||||
static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = {
|
static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = {
|
||||||
{mmGRBM_STATUS},
|
{mmGRBM_STATUS},
|
||||||
|
{mmGRBM_STATUS2},
|
||||||
|
{mmGRBM_STATUS_SE0},
|
||||||
|
{mmGRBM_STATUS_SE1},
|
||||||
|
{mmGRBM_STATUS_SE2},
|
||||||
|
{mmGRBM_STATUS_SE3},
|
||||||
|
{mmSRBM_STATUS},
|
||||||
|
{mmSRBM_STATUS2},
|
||||||
|
{mmSDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET},
|
||||||
|
{mmSDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET},
|
||||||
|
{mmCP_STAT},
|
||||||
|
{mmCP_STALLED_STAT1},
|
||||||
|
{mmCP_STALLED_STAT2},
|
||||||
|
{mmCP_STALLED_STAT3},
|
||||||
|
{mmCP_CPF_BUSY_STAT},
|
||||||
|
{mmCP_CPF_STALLED_STAT1},
|
||||||
|
{mmCP_CPF_STATUS},
|
||||||
|
{mmCP_CPC_BUSY_STAT},
|
||||||
|
{mmCP_CPC_STALLED_STAT1},
|
||||||
|
{mmCP_CPC_STATUS},
|
||||||
{mmGB_ADDR_CONFIG},
|
{mmGB_ADDR_CONFIG},
|
||||||
{mmMC_ARB_RAMCFG},
|
{mmMC_ARB_RAMCFG},
|
||||||
{mmGB_TILE_MODE0},
|
{mmGB_TILE_MODE0},
|
||||||
|
@ -93,7 +93,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_1[] =
|
|||||||
{
|
{
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x00400014),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x00400014),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_CPF_CLK_CTRL, 0xfcff8fff, 0xf8000100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_CPF_CLK_CTRL, 0xfcff8fff, 0xf8000100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xc0000000, 0xc0000100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xcd000000, 0x0d000100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQ_CLK_CTRL, 0x60000ff0, 0x60000100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQ_CLK_CTRL, 0x60000ff0, 0x60000100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQG_CLK_CTRL, 0x40000000, 0x40000100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQG_CLK_CTRL, 0x40000000, 0x40000100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_VGT_CLK_CTRL, 0xffff8fff, 0xffff8100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_VGT_CLK_CTRL, 0xffff8fff, 0xffff8100),
|
||||||
@ -140,7 +140,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_1_1[] =
|
|||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x003c0014),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x003c0014),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_GS_NGG_CLK_CTRL, 0xffff8fff, 0xffff8100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_GS_NGG_CLK_CTRL, 0xffff8fff, 0xffff8100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_IA_CLK_CTRL, 0xffff0fff, 0xffff0100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_IA_CLK_CTRL, 0xffff0fff, 0xffff0100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xc0000000, 0xc0000100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xcd000000, 0x0d000100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQ_CLK_CTRL, 0xf8ff0fff, 0x60000100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQ_CLK_CTRL, 0xf8ff0fff, 0x60000100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQG_CLK_CTRL, 0x40000ff0, 0x40000100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQG_CLK_CTRL, 0x40000ff0, 0x40000100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_VGT_CLK_CTRL, 0xffff8fff, 0xffff8100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_VGT_CLK_CTRL, 0xffff8fff, 0xffff8100),
|
||||||
@ -179,7 +179,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_1_2[] =
|
|||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0x003e001f, 0x003c0014),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0x003e001f, 0x003c0014),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_GS_NGG_CLK_CTRL, 0xffff8fff, 0xffff8100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_GS_NGG_CLK_CTRL, 0xffff8fff, 0xffff8100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_IA_CLK_CTRL, 0xffff0fff, 0xffff0100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_IA_CLK_CTRL, 0xffff0fff, 0xffff0100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xff7f0fff, 0xc0000100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xff7f0fff, 0x0d000100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQ_CLK_CTRL, 0xffffcfff, 0x60000100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQ_CLK_CTRL, 0xffffcfff, 0x60000100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQG_CLK_CTRL, 0xffff0fff, 0x40000100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQG_CLK_CTRL, 0xffff0fff, 0x40000100),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_VGT_CLK_CTRL, 0xffff8fff, 0xffff8100),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_VGT_CLK_CTRL, 0xffff8fff, 0xffff8100),
|
||||||
@ -1442,7 +1442,7 @@ static int gfx_v10_0_sw_fini(void *handle)
|
|||||||
amdgpu_ring_fini(&adev->gfx.compute_ring[i]);
|
amdgpu_ring_fini(&adev->gfx.compute_ring[i]);
|
||||||
|
|
||||||
amdgpu_gfx_mqd_sw_fini(adev);
|
amdgpu_gfx_mqd_sw_fini(adev);
|
||||||
amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq.ring, &adev->gfx.kiq.irq);
|
amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq.ring);
|
||||||
amdgpu_gfx_kiq_fini(adev);
|
amdgpu_gfx_kiq_fini(adev);
|
||||||
|
|
||||||
gfx_v10_0_pfp_fini(adev);
|
gfx_v10_0_pfp_fini(adev);
|
||||||
@ -3106,6 +3106,7 @@ static int gfx_v10_0_gfx_init_queue(struct amdgpu_ring *ring)
|
|||||||
memcpy(mqd, adev->gfx.me.mqd_backup[AMDGPU_MAX_GFX_RINGS], sizeof(*mqd));
|
memcpy(mqd, adev->gfx.me.mqd_backup[AMDGPU_MAX_GFX_RINGS], sizeof(*mqd));
|
||||||
/* reset the ring */
|
/* reset the ring */
|
||||||
ring->wptr = 0;
|
ring->wptr = 0;
|
||||||
|
adev->wb.wb[ring->wptr_offs] = 0;
|
||||||
amdgpu_ring_clear_ring(ring);
|
amdgpu_ring_clear_ring(ring);
|
||||||
#ifdef BRING_UP_DEBUG
|
#ifdef BRING_UP_DEBUG
|
||||||
mutex_lock(&adev->srbm_mutex);
|
mutex_lock(&adev->srbm_mutex);
|
||||||
|
@ -2103,7 +2103,7 @@ static int gfx_v8_0_sw_fini(void *handle)
|
|||||||
amdgpu_ring_fini(&adev->gfx.compute_ring[i]);
|
amdgpu_ring_fini(&adev->gfx.compute_ring[i]);
|
||||||
|
|
||||||
amdgpu_gfx_mqd_sw_fini(adev);
|
amdgpu_gfx_mqd_sw_fini(adev);
|
||||||
amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq.ring, &adev->gfx.kiq.irq);
|
amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq.ring);
|
||||||
amdgpu_gfx_kiq_fini(adev);
|
amdgpu_gfx_kiq_fini(adev);
|
||||||
|
|
||||||
gfx_v8_0_mec_fini(adev);
|
gfx_v8_0_mec_fini(adev);
|
||||||
|
@ -703,6 +703,7 @@ static const struct soc15_reg_golden golden_settings_gc_9_4_1_arct[] =
|
|||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_3_ARCT, 0x3fffffff, 0x2ebd9fe3),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_3_ARCT, 0x3fffffff, 0x2ebd9fe3),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_4_ARCT, 0x3fffffff, 0xb90f5b1),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_4_ARCT, 0x3fffffff, 0xb90f5b1),
|
||||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_5_ARCT, 0x3ff, 0x135),
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_5_ARCT, 0x3ff, 0x135),
|
||||||
|
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_CONFIG, 0xffffffff, 0x011A0000),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u32 GFX_RLC_SRM_INDEX_CNTL_ADDR_OFFSETS[] =
|
static const u32 GFX_RLC_SRM_INDEX_CNTL_ADDR_OFFSETS[] =
|
||||||
@ -2153,7 +2154,7 @@ static int gfx_v9_0_sw_fini(void *handle)
|
|||||||
amdgpu_ring_fini(&adev->gfx.compute_ring[i]);
|
amdgpu_ring_fini(&adev->gfx.compute_ring[i]);
|
||||||
|
|
||||||
amdgpu_gfx_mqd_sw_fini(adev);
|
amdgpu_gfx_mqd_sw_fini(adev);
|
||||||
amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq.ring, &adev->gfx.kiq.irq);
|
amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq.ring);
|
||||||
amdgpu_gfx_kiq_fini(adev);
|
amdgpu_gfx_kiq_fini(adev);
|
||||||
|
|
||||||
gfx_v9_0_mec_fini(adev);
|
gfx_v9_0_mec_fini(adev);
|
||||||
@ -3736,8 +3737,10 @@ static int gfx_v9_0_hw_fini(void *handle)
|
|||||||
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
|
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
|
||||||
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
|
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
|
||||||
|
|
||||||
/* disable KCQ to avoid CPC touch memory not valid anymore */
|
/* DF freeze and kcq disable will fail */
|
||||||
gfx_v9_0_kcq_disable(adev);
|
if (!amdgpu_ras_intr_triggered())
|
||||||
|
/* disable KCQ to avoid CPC touch memory not valid anymore */
|
||||||
|
gfx_v9_0_kcq_disable(adev);
|
||||||
|
|
||||||
if (amdgpu_sriov_vf(adev)) {
|
if (amdgpu_sriov_vf(adev)) {
|
||||||
gfx_v9_0_cp_gfx_enable(adev, false);
|
gfx_v9_0_cp_gfx_enable(adev, false);
|
||||||
|
@ -155,6 +155,15 @@ static void gfxhub_v2_0_init_cache_regs(struct amdgpu_device *adev)
|
|||||||
WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL2, tmp);
|
WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL2, tmp);
|
||||||
|
|
||||||
tmp = mmGCVM_L2_CNTL3_DEFAULT;
|
tmp = mmGCVM_L2_CNTL3_DEFAULT;
|
||||||
|
if (adev->gmc.translate_further) {
|
||||||
|
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 12);
|
||||||
|
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3,
|
||||||
|
L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
|
||||||
|
} else {
|
||||||
|
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 9);
|
||||||
|
tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3,
|
||||||
|
L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
|
||||||
|
}
|
||||||
WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL3, tmp);
|
WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL3, tmp);
|
||||||
|
|
||||||
tmp = mmGCVM_L2_CNTL4_DEFAULT;
|
tmp = mmGCVM_L2_CNTL4_DEFAULT;
|
||||||
|
@ -309,6 +309,7 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
|||||||
|
|
||||||
job->vm_pd_addr = amdgpu_gmc_pd_addr(adev->gart.bo);
|
job->vm_pd_addr = amdgpu_gmc_pd_addr(adev->gart.bo);
|
||||||
job->vm_needs_flush = true;
|
job->vm_needs_flush = true;
|
||||||
|
job->ibs->ptr[job->ibs->length_dw++] = ring->funcs->nop;
|
||||||
amdgpu_ring_pad_ib(ring, &job->ibs[0]);
|
amdgpu_ring_pad_ib(ring, &job->ibs[0]);
|
||||||
r = amdgpu_job_submit(job, &adev->mman.entity,
|
r = amdgpu_job_submit(job, &adev->mman.entity,
|
||||||
AMDGPU_FENCE_OWNER_UNDEFINED, &fence);
|
AMDGPU_FENCE_OWNER_UNDEFINED, &fence);
|
||||||
|
@ -142,6 +142,15 @@ static void mmhub_v2_0_init_cache_regs(struct amdgpu_device *adev)
|
|||||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL2, tmp);
|
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL2, tmp);
|
||||||
|
|
||||||
tmp = mmMMVM_L2_CNTL3_DEFAULT;
|
tmp = mmMMVM_L2_CNTL3_DEFAULT;
|
||||||
|
if (adev->gmc.translate_further) {
|
||||||
|
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 12);
|
||||||
|
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3,
|
||||||
|
L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
|
||||||
|
} else {
|
||||||
|
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 9);
|
||||||
|
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3,
|
||||||
|
L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
|
||||||
|
}
|
||||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL3, tmp);
|
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL3, tmp);
|
||||||
|
|
||||||
tmp = mmMMVM_L2_CNTL4_DEFAULT;
|
tmp = mmMMVM_L2_CNTL4_DEFAULT;
|
||||||
|
@ -178,6 +178,7 @@ static struct soc15_allowed_register_entry nv_allowed_read_registers[] = {
|
|||||||
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_BUSY_STAT)},
|
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_BUSY_STAT)},
|
||||||
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STALLED_STAT1)},
|
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STALLED_STAT1)},
|
||||||
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STATUS)},
|
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STATUS)},
|
||||||
|
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_BUSY_STAT)},
|
||||||
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STALLED_STAT1)},
|
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STALLED_STAT1)},
|
||||||
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STATUS)},
|
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STATUS)},
|
||||||
{ SOC15_REG_ENTRY(GC, 0, mmGB_ADDR_CONFIG)},
|
{ SOC15_REG_ENTRY(GC, 0, mmGB_ADDR_CONFIG)},
|
||||||
@ -298,7 +299,7 @@ nv_asic_reset_method(struct amdgpu_device *adev)
|
|||||||
{
|
{
|
||||||
struct smu_context *smu = &adev->smu;
|
struct smu_context *smu = &adev->smu;
|
||||||
|
|
||||||
if (smu_baco_is_support(smu))
|
if (!amdgpu_sriov_vf(adev) && smu_baco_is_support(smu))
|
||||||
return AMD_RESET_METHOD_BACO;
|
return AMD_RESET_METHOD_BACO;
|
||||||
else
|
else
|
||||||
return AMD_RESET_METHOD_MODE1;
|
return AMD_RESET_METHOD_MODE1;
|
||||||
|
@ -244,7 +244,7 @@ static int psp_v11_0_bootloader_load_kdb(struct psp_context *psp)
|
|||||||
/* Copy PSP KDB binary to memory */
|
/* Copy PSP KDB binary to memory */
|
||||||
memcpy(psp->fw_pri_buf, psp->kdb_start_addr, psp->kdb_bin_size);
|
memcpy(psp->fw_pri_buf, psp->kdb_start_addr, psp->kdb_bin_size);
|
||||||
|
|
||||||
/* Provide the sys driver to bootloader */
|
/* Provide the PSP KDB to bootloader */
|
||||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
|
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
|
||||||
(uint32_t)(psp->fw_pri_mc_addr >> 20));
|
(uint32_t)(psp->fw_pri_mc_addr >> 20));
|
||||||
psp_gfxdrv_command_reg = PSP_BL__LOAD_KEY_DATABASE;
|
psp_gfxdrv_command_reg = PSP_BL__LOAD_KEY_DATABASE;
|
||||||
@ -467,6 +467,14 @@ static int psp_v11_0_ring_create(struct psp_context *psp,
|
|||||||
0x80000000, 0x8000FFFF, false);
|
0x80000000, 0x8000FFFF, false);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
/* Wait for sOS ready for ring creation */
|
||||||
|
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
|
||||||
|
0x80000000, 0x80000000, false);
|
||||||
|
if (ret) {
|
||||||
|
DRM_ERROR("Failed to wait for sOS ready for ring creation\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write low address of the ring to C2PMSG_69 */
|
/* Write low address of the ring to C2PMSG_69 */
|
||||||
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
|
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
|
||||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_69, psp_ring_reg);
|
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_69, psp_ring_reg);
|
||||||
|
@ -254,6 +254,7 @@ static const struct soc15_reg_golden golden_settings_sdma_4_3[] = {
|
|||||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
||||||
|
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x00000000)
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 sdma_v4_0_get_reg_offset(struct amdgpu_device *adev,
|
static u32 sdma_v4_0_get_reg_offset(struct amdgpu_device *adev,
|
||||||
|
@ -975,6 +975,17 @@ static void si_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
|
|||||||
|
|
||||||
static struct amdgpu_allowed_register_entry si_allowed_read_registers[] = {
|
static struct amdgpu_allowed_register_entry si_allowed_read_registers[] = {
|
||||||
{GRBM_STATUS},
|
{GRBM_STATUS},
|
||||||
|
{mmGRBM_STATUS2},
|
||||||
|
{mmGRBM_STATUS_SE0},
|
||||||
|
{mmGRBM_STATUS_SE1},
|
||||||
|
{mmSRBM_STATUS},
|
||||||
|
{mmSRBM_STATUS2},
|
||||||
|
{DMA_STATUS_REG + DMA0_REGISTER_OFFSET},
|
||||||
|
{DMA_STATUS_REG + DMA1_REGISTER_OFFSET},
|
||||||
|
{mmCP_STAT},
|
||||||
|
{mmCP_STALLED_STAT1},
|
||||||
|
{mmCP_STALLED_STAT2},
|
||||||
|
{mmCP_STALLED_STAT3},
|
||||||
{GB_ADDR_CONFIG},
|
{GB_ADDR_CONFIG},
|
||||||
{MC_ARB_RAMCFG},
|
{MC_ARB_RAMCFG},
|
||||||
{GB_TILE_MODE0},
|
{GB_TILE_MODE0},
|
||||||
|
@ -339,6 +339,7 @@ static struct soc15_allowed_register_entry soc15_allowed_read_registers[] = {
|
|||||||
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_BUSY_STAT)},
|
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_BUSY_STAT)},
|
||||||
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STALLED_STAT1)},
|
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STALLED_STAT1)},
|
||||||
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STATUS)},
|
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STATUS)},
|
||||||
|
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_BUSY_STAT)},
|
||||||
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STALLED_STAT1)},
|
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STALLED_STAT1)},
|
||||||
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STATUS)},
|
{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STATUS)},
|
||||||
{ SOC15_REG_ENTRY(GC, 0, mmGB_ADDR_CONFIG)},
|
{ SOC15_REG_ENTRY(GC, 0, mmGB_ADDR_CONFIG)},
|
||||||
|
@ -265,9 +265,6 @@ static int vcn_v2_5_hw_init(void *handle)
|
|||||||
|
|
||||||
for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
|
for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
|
||||||
ring = &adev->vcn.inst[j].ring_enc[i];
|
ring = &adev->vcn.inst[j].ring_enc[i];
|
||||||
/* disable encode rings till the robustness of the FW */
|
|
||||||
ring->sched.ready = false;
|
|
||||||
continue;
|
|
||||||
r = amdgpu_ring_test_helper(ring);
|
r = amdgpu_ring_test_helper(ring);
|
||||||
if (r)
|
if (r)
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -710,7 +710,7 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
|
|||||||
pcache_info,
|
pcache_info,
|
||||||
cu_info,
|
cu_info,
|
||||||
mem_available,
|
mem_available,
|
||||||
cu_info->cu_bitmap[i][j],
|
cu_info->cu_bitmap[i % 4][j + i / 4],
|
||||||
ct,
|
ct,
|
||||||
cu_processor_id,
|
cu_processor_id,
|
||||||
k);
|
k);
|
||||||
|
@ -730,9 +730,6 @@ int kgd2kfd_pre_reset(struct kfd_dev *kfd)
|
|||||||
return 0;
|
return 0;
|
||||||
kgd2kfd_suspend(kfd);
|
kgd2kfd_suspend(kfd);
|
||||||
|
|
||||||
/* hold dqm->lock to prevent further execution*/
|
|
||||||
dqm_lock(kfd->dqm);
|
|
||||||
|
|
||||||
kfd_signal_reset_event(kfd);
|
kfd_signal_reset_event(kfd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -750,8 +747,6 @@ int kgd2kfd_post_reset(struct kfd_dev *kfd)
|
|||||||
if (!kfd->init_complete)
|
if (!kfd->init_complete)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dqm_unlock(kfd->dqm);
|
|
||||||
|
|
||||||
ret = kfd_resume(kfd);
|
ret = kfd_resume(kfd);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -340,6 +340,10 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
|
|||||||
mqd_mgr->init_mqd(mqd_mgr, &q->mqd, q->mqd_mem_obj,
|
mqd_mgr->init_mqd(mqd_mgr, &q->mqd, q->mqd_mem_obj,
|
||||||
&q->gart_mqd_addr, &q->properties);
|
&q->gart_mqd_addr, &q->properties);
|
||||||
if (q->properties.is_active) {
|
if (q->properties.is_active) {
|
||||||
|
if (!dqm->sched_running) {
|
||||||
|
WARN_ONCE(1, "Load non-HWS mqd while stopped\n");
|
||||||
|
goto add_queue_to_list;
|
||||||
|
}
|
||||||
|
|
||||||
if (WARN(q->process->mm != current->mm,
|
if (WARN(q->process->mm != current->mm,
|
||||||
"should only run in user thread"))
|
"should only run in user thread"))
|
||||||
@ -351,6 +355,7 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
|
|||||||
goto out_free_mqd;
|
goto out_free_mqd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add_queue_to_list:
|
||||||
list_add(&q->list, &qpd->queues_list);
|
list_add(&q->list, &qpd->queues_list);
|
||||||
qpd->queue_count++;
|
qpd->queue_count++;
|
||||||
if (q->properties.is_active)
|
if (q->properties.is_active)
|
||||||
@ -458,6 +463,11 @@ static int destroy_queue_nocpsch_locked(struct device_queue_manager *dqm,
|
|||||||
|
|
||||||
deallocate_doorbell(qpd, q);
|
deallocate_doorbell(qpd, q);
|
||||||
|
|
||||||
|
if (!dqm->sched_running) {
|
||||||
|
WARN_ONCE(1, "Destroy non-HWS queue while stopped\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
retval = mqd_mgr->destroy_mqd(mqd_mgr, q->mqd,
|
retval = mqd_mgr->destroy_mqd(mqd_mgr, q->mqd,
|
||||||
KFD_PREEMPT_TYPE_WAVEFRONT_RESET,
|
KFD_PREEMPT_TYPE_WAVEFRONT_RESET,
|
||||||
KFD_UNMAP_LATENCY_MS,
|
KFD_UNMAP_LATENCY_MS,
|
||||||
@ -533,6 +543,12 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
|
|||||||
(q->properties.type == KFD_QUEUE_TYPE_COMPUTE ||
|
(q->properties.type == KFD_QUEUE_TYPE_COMPUTE ||
|
||||||
q->properties.type == KFD_QUEUE_TYPE_SDMA ||
|
q->properties.type == KFD_QUEUE_TYPE_SDMA ||
|
||||||
q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)) {
|
q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)) {
|
||||||
|
|
||||||
|
if (!dqm->sched_running) {
|
||||||
|
WARN_ONCE(1, "Update non-HWS queue while stopped\n");
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
retval = mqd_mgr->destroy_mqd(mqd_mgr, q->mqd,
|
retval = mqd_mgr->destroy_mqd(mqd_mgr, q->mqd,
|
||||||
KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN,
|
KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN,
|
||||||
KFD_UNMAP_LATENCY_MS, q->pipe, q->queue);
|
KFD_UNMAP_LATENCY_MS, q->pipe, q->queue);
|
||||||
@ -602,6 +618,11 @@ static int evict_process_queues_nocpsch(struct device_queue_manager *dqm,
|
|||||||
mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(
|
mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(
|
||||||
q->properties.type)];
|
q->properties.type)];
|
||||||
q->properties.is_active = false;
|
q->properties.is_active = false;
|
||||||
|
dqm->queue_count--;
|
||||||
|
|
||||||
|
if (WARN_ONCE(!dqm->sched_running, "Evict when stopped\n"))
|
||||||
|
continue;
|
||||||
|
|
||||||
retval = mqd_mgr->destroy_mqd(mqd_mgr, q->mqd,
|
retval = mqd_mgr->destroy_mqd(mqd_mgr, q->mqd,
|
||||||
KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN,
|
KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN,
|
||||||
KFD_UNMAP_LATENCY_MS, q->pipe, q->queue);
|
KFD_UNMAP_LATENCY_MS, q->pipe, q->queue);
|
||||||
@ -610,7 +631,6 @@ static int evict_process_queues_nocpsch(struct device_queue_manager *dqm,
|
|||||||
* maintain a consistent eviction state
|
* maintain a consistent eviction state
|
||||||
*/
|
*/
|
||||||
ret = retval;
|
ret = retval;
|
||||||
dqm->queue_count--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -711,6 +731,11 @@ static int restore_process_queues_nocpsch(struct device_queue_manager *dqm,
|
|||||||
mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(
|
mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(
|
||||||
q->properties.type)];
|
q->properties.type)];
|
||||||
q->properties.is_active = true;
|
q->properties.is_active = true;
|
||||||
|
dqm->queue_count++;
|
||||||
|
|
||||||
|
if (WARN_ONCE(!dqm->sched_running, "Restore when stopped\n"))
|
||||||
|
continue;
|
||||||
|
|
||||||
retval = mqd_mgr->load_mqd(mqd_mgr, q->mqd, q->pipe,
|
retval = mqd_mgr->load_mqd(mqd_mgr, q->mqd, q->pipe,
|
||||||
q->queue, &q->properties, mm);
|
q->queue, &q->properties, mm);
|
||||||
if (retval && !ret)
|
if (retval && !ret)
|
||||||
@ -718,7 +743,6 @@ static int restore_process_queues_nocpsch(struct device_queue_manager *dqm,
|
|||||||
* maintain a consistent eviction state
|
* maintain a consistent eviction state
|
||||||
*/
|
*/
|
||||||
ret = retval;
|
ret = retval;
|
||||||
dqm->queue_count++;
|
|
||||||
}
|
}
|
||||||
qpd->evicted = 0;
|
qpd->evicted = 0;
|
||||||
out:
|
out:
|
||||||
@ -915,7 +939,8 @@ static int start_nocpsch(struct device_queue_manager *dqm)
|
|||||||
|
|
||||||
if (dqm->dev->device_info->asic_family == CHIP_HAWAII)
|
if (dqm->dev->device_info->asic_family == CHIP_HAWAII)
|
||||||
return pm_init(&dqm->packets, dqm);
|
return pm_init(&dqm->packets, dqm);
|
||||||
|
dqm->sched_running = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -923,7 +948,8 @@ static int stop_nocpsch(struct device_queue_manager *dqm)
|
|||||||
{
|
{
|
||||||
if (dqm->dev->device_info->asic_family == CHIP_HAWAII)
|
if (dqm->dev->device_info->asic_family == CHIP_HAWAII)
|
||||||
pm_uninit(&dqm->packets);
|
pm_uninit(&dqm->packets);
|
||||||
|
dqm->sched_running = false;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1074,6 +1100,7 @@ static int start_cpsch(struct device_queue_manager *dqm)
|
|||||||
dqm_lock(dqm);
|
dqm_lock(dqm);
|
||||||
/* clear hang status when driver try to start the hw scheduler */
|
/* clear hang status when driver try to start the hw scheduler */
|
||||||
dqm->is_hws_hang = false;
|
dqm->is_hws_hang = false;
|
||||||
|
dqm->sched_running = true;
|
||||||
execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
|
execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
|
||||||
dqm_unlock(dqm);
|
dqm_unlock(dqm);
|
||||||
|
|
||||||
@ -1089,6 +1116,7 @@ static int stop_cpsch(struct device_queue_manager *dqm)
|
|||||||
{
|
{
|
||||||
dqm_lock(dqm);
|
dqm_lock(dqm);
|
||||||
unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0);
|
unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0);
|
||||||
|
dqm->sched_running = false;
|
||||||
dqm_unlock(dqm);
|
dqm_unlock(dqm);
|
||||||
|
|
||||||
kfd_gtt_sa_free(dqm->dev, dqm->fence_mem);
|
kfd_gtt_sa_free(dqm->dev, dqm->fence_mem);
|
||||||
@ -1275,9 +1303,10 @@ static int map_queues_cpsch(struct device_queue_manager *dqm)
|
|||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
if (!dqm->sched_running)
|
||||||
|
return 0;
|
||||||
if (dqm->queue_count <= 0 || dqm->processes_count <= 0)
|
if (dqm->queue_count <= 0 || dqm->processes_count <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (dqm->active_runlist)
|
if (dqm->active_runlist)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1299,6 +1328,8 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm,
|
|||||||
{
|
{
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
|
if (!dqm->sched_running)
|
||||||
|
return 0;
|
||||||
if (dqm->is_hws_hang)
|
if (dqm->is_hws_hang)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
if (!dqm->active_runlist)
|
if (!dqm->active_runlist)
|
||||||
@ -1903,6 +1934,12 @@ int dqm_debugfs_hqds(struct seq_file *m, void *data)
|
|||||||
int pipe, queue;
|
int pipe, queue;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
|
if (!dqm->sched_running) {
|
||||||
|
seq_printf(m, " Device is stopped\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
r = dqm->dev->kfd2kgd->hqd_dump(dqm->dev->kgd,
|
r = dqm->dev->kfd2kgd->hqd_dump(dqm->dev->kgd,
|
||||||
KFD_CIK_HIQ_PIPE, KFD_CIK_HIQ_QUEUE,
|
KFD_CIK_HIQ_PIPE, KFD_CIK_HIQ_QUEUE,
|
||||||
&dump, &n_regs);
|
&dump, &n_regs);
|
||||||
|
@ -201,6 +201,7 @@ struct device_queue_manager {
|
|||||||
bool is_hws_hang;
|
bool is_hws_hang;
|
||||||
struct work_struct hw_exception_work;
|
struct work_struct hw_exception_work;
|
||||||
struct kfd_mem_obj hiq_sdma_mqd;
|
struct kfd_mem_obj hiq_sdma_mqd;
|
||||||
|
bool sched_running;
|
||||||
};
|
};
|
||||||
|
|
||||||
void device_queue_manager_init_cik(
|
void device_queue_manager_init_cik(
|
||||||
|
@ -147,6 +147,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||||||
static void handle_cursor_update(struct drm_plane *plane,
|
static void handle_cursor_update(struct drm_plane *plane,
|
||||||
struct drm_plane_state *old_plane_state);
|
struct drm_plane_state *old_plane_state);
|
||||||
|
|
||||||
|
static void amdgpu_dm_set_psr_caps(struct dc_link *link);
|
||||||
|
static bool amdgpu_dm_psr_enable(struct dc_stream_state *stream);
|
||||||
|
static bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream);
|
||||||
|
static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dm_vblank_get_counter
|
* dm_vblank_get_counter
|
||||||
*
|
*
|
||||||
@ -722,6 +728,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
|||||||
if (amdgpu_dc_feature_mask & DC_MULTI_MON_PP_MCLK_SWITCH_MASK)
|
if (amdgpu_dc_feature_mask & DC_MULTI_MON_PP_MCLK_SWITCH_MASK)
|
||||||
init_data.flags.multi_mon_pp_mclk_switch = true;
|
init_data.flags.multi_mon_pp_mclk_switch = true;
|
||||||
|
|
||||||
|
if (amdgpu_dc_feature_mask & DC_DISABLE_FRACTIONAL_PWM_MASK)
|
||||||
|
init_data.flags.disable_fractional_pwm = true;
|
||||||
|
|
||||||
init_data.flags.power_down_display_on_boot = true;
|
init_data.flags.power_down_display_on_boot = true;
|
||||||
|
|
||||||
#ifdef CONFIG_DRM_AMD_DC_DCN2_0
|
#ifdef CONFIG_DRM_AMD_DC_DCN2_0
|
||||||
@ -2418,6 +2427,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
|||||||
} else if (dc_link_detect(link, DETECT_REASON_BOOT)) {
|
} else if (dc_link_detect(link, DETECT_REASON_BOOT)) {
|
||||||
amdgpu_dm_update_connector_after_detect(aconnector);
|
amdgpu_dm_update_connector_after_detect(aconnector);
|
||||||
register_backlight_device(dm, link);
|
register_backlight_device(dm, link);
|
||||||
|
if (amdgpu_dc_feature_mask & DC_PSR_MASK)
|
||||||
|
amdgpu_dm_set_psr_caps(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3399,6 +3410,9 @@ static void fill_stream_properties_from_drm_display_mode(
|
|||||||
struct hdmi_vendor_infoframe hv_frame;
|
struct hdmi_vendor_infoframe hv_frame;
|
||||||
struct hdmi_avi_infoframe avi_frame;
|
struct hdmi_avi_infoframe avi_frame;
|
||||||
|
|
||||||
|
memset(&hv_frame, 0, sizeof(hv_frame));
|
||||||
|
memset(&avi_frame, 0, sizeof(avi_frame));
|
||||||
|
|
||||||
timing_out->h_border_left = 0;
|
timing_out->h_border_left = 0;
|
||||||
timing_out->h_border_right = 0;
|
timing_out->h_border_right = 0;
|
||||||
timing_out->v_border_top = 0;
|
timing_out->v_border_top = 0;
|
||||||
@ -3740,7 +3754,16 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||||||
|
|
||||||
if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
|
if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
|
||||||
mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket, false, false);
|
mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket, false, false);
|
||||||
|
if (stream->link->psr_feature_enabled) {
|
||||||
|
struct dc *core_dc = stream->link->ctx->dc;
|
||||||
|
|
||||||
|
if (dc_is_dmcu_initialized(core_dc)) {
|
||||||
|
struct dmcu *dmcu = core_dc->res_pool->dmcu;
|
||||||
|
|
||||||
|
stream->psr_version = dmcu->dmcu_version.psr_version;
|
||||||
|
mod_build_vsc_infopacket(stream, &stream->vsc_infopacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
finish:
|
finish:
|
||||||
dc_sink_release(sink);
|
dc_sink_release(sink);
|
||||||
|
|
||||||
@ -5824,6 +5847,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||||||
uint32_t target_vblank, last_flip_vblank;
|
uint32_t target_vblank, last_flip_vblank;
|
||||||
bool vrr_active = amdgpu_dm_vrr_active(acrtc_state);
|
bool vrr_active = amdgpu_dm_vrr_active(acrtc_state);
|
||||||
bool pflip_present = false;
|
bool pflip_present = false;
|
||||||
|
bool swizzle = true;
|
||||||
struct {
|
struct {
|
||||||
struct dc_surface_update surface_updates[MAX_SURFACES];
|
struct dc_surface_update surface_updates[MAX_SURFACES];
|
||||||
struct dc_plane_info plane_infos[MAX_SURFACES];
|
struct dc_plane_info plane_infos[MAX_SURFACES];
|
||||||
@ -5869,6 +5893,9 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||||||
|
|
||||||
dc_plane = dm_new_plane_state->dc_state;
|
dc_plane = dm_new_plane_state->dc_state;
|
||||||
|
|
||||||
|
if (dc_plane && !dc_plane->tiling_info.gfx9.swizzle)
|
||||||
|
swizzle = false;
|
||||||
|
|
||||||
bundle->surface_updates[planes_count].surface = dc_plane;
|
bundle->surface_updates[planes_count].surface = dc_plane;
|
||||||
if (new_pcrtc_state->color_mgmt_changed) {
|
if (new_pcrtc_state->color_mgmt_changed) {
|
||||||
bundle->surface_updates[planes_count].gamma = dc_plane->gamma_correction;
|
bundle->surface_updates[planes_count].gamma = dc_plane->gamma_correction;
|
||||||
@ -6059,14 +6086,29 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||||||
&acrtc_state->vrr_params.adjust);
|
&acrtc_state->vrr_params.adjust);
|
||||||
spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
|
spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&dm->dc_lock);
|
mutex_lock(&dm->dc_lock);
|
||||||
|
if ((acrtc_state->update_type > UPDATE_TYPE_FAST) &&
|
||||||
|
acrtc_state->stream->link->psr_allow_active)
|
||||||
|
amdgpu_dm_psr_disable(acrtc_state->stream);
|
||||||
|
|
||||||
dc_commit_updates_for_stream(dm->dc,
|
dc_commit_updates_for_stream(dm->dc,
|
||||||
bundle->surface_updates,
|
bundle->surface_updates,
|
||||||
planes_count,
|
planes_count,
|
||||||
acrtc_state->stream,
|
acrtc_state->stream,
|
||||||
&bundle->stream_update,
|
&bundle->stream_update,
|
||||||
dc_state);
|
dc_state);
|
||||||
|
|
||||||
|
if ((acrtc_state->update_type > UPDATE_TYPE_FAST) &&
|
||||||
|
acrtc_state->stream->psr_version &&
|
||||||
|
!acrtc_state->stream->link->psr_feature_enabled)
|
||||||
|
amdgpu_dm_link_setup_psr(acrtc_state->stream);
|
||||||
|
else if ((acrtc_state->update_type == UPDATE_TYPE_FAST) &&
|
||||||
|
acrtc_state->stream->link->psr_feature_enabled &&
|
||||||
|
!acrtc_state->stream->link->psr_allow_active &&
|
||||||
|
swizzle) {
|
||||||
|
amdgpu_dm_psr_enable(acrtc_state->stream);
|
||||||
|
}
|
||||||
|
|
||||||
mutex_unlock(&dm->dc_lock);
|
mutex_unlock(&dm->dc_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6375,10 +6417,13 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||||||
crtc->hwmode = new_crtc_state->mode;
|
crtc->hwmode = new_crtc_state->mode;
|
||||||
} else if (modereset_required(new_crtc_state)) {
|
} else if (modereset_required(new_crtc_state)) {
|
||||||
DRM_DEBUG_DRIVER("Atomic commit: RESET. crtc id %d:[%p]\n", acrtc->crtc_id, acrtc);
|
DRM_DEBUG_DRIVER("Atomic commit: RESET. crtc id %d:[%p]\n", acrtc->crtc_id, acrtc);
|
||||||
|
|
||||||
/* i.e. reset mode */
|
/* i.e. reset mode */
|
||||||
if (dm_old_crtc_state->stream)
|
if (dm_old_crtc_state->stream) {
|
||||||
|
if (dm_old_crtc_state->stream->link->psr_allow_active)
|
||||||
|
amdgpu_dm_psr_disable(dm_old_crtc_state->stream);
|
||||||
|
|
||||||
remove_stream(adev, acrtc, dm_old_crtc_state->stream);
|
remove_stream(adev, acrtc, dm_old_crtc_state->stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} /* for_each_crtc_in_state() */
|
} /* for_each_crtc_in_state() */
|
||||||
|
|
||||||
@ -7754,3 +7799,92 @@ update:
|
|||||||
freesync_capable);
|
freesync_capable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void amdgpu_dm_set_psr_caps(struct dc_link *link)
|
||||||
|
{
|
||||||
|
uint8_t dpcd_data[EDP_PSR_RECEIVER_CAP_SIZE];
|
||||||
|
|
||||||
|
if (!(link->connector_signal & SIGNAL_TYPE_EDP))
|
||||||
|
return;
|
||||||
|
if (link->type == dc_connection_none)
|
||||||
|
return;
|
||||||
|
if (dm_helpers_dp_read_dpcd(NULL, link, DP_PSR_SUPPORT,
|
||||||
|
dpcd_data, sizeof(dpcd_data))) {
|
||||||
|
link->psr_feature_enabled = dpcd_data[0] ? true:false;
|
||||||
|
DRM_INFO("PSR support:%d\n", link->psr_feature_enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* amdgpu_dm_link_setup_psr() - configure psr link
|
||||||
|
* @stream: stream state
|
||||||
|
*
|
||||||
|
* Return: true if success
|
||||||
|
*/
|
||||||
|
static bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream)
|
||||||
|
{
|
||||||
|
struct dc_link *link = NULL;
|
||||||
|
struct psr_config psr_config = {0};
|
||||||
|
struct psr_context psr_context = {0};
|
||||||
|
struct dc *dc = NULL;
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
if (stream == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
link = stream->link;
|
||||||
|
dc = link->ctx->dc;
|
||||||
|
|
||||||
|
psr_config.psr_version = dc->res_pool->dmcu->dmcu_version.psr_version;
|
||||||
|
|
||||||
|
if (psr_config.psr_version > 0) {
|
||||||
|
psr_config.psr_exit_link_training_required = 0x1;
|
||||||
|
psr_config.psr_frame_capture_indication_req = 0;
|
||||||
|
psr_config.psr_rfb_setup_time = 0x37;
|
||||||
|
psr_config.psr_sdp_transmit_line_num_deadline = 0x20;
|
||||||
|
psr_config.allow_smu_optimizations = 0x0;
|
||||||
|
|
||||||
|
ret = dc_link_setup_psr(link, stream, &psr_config, &psr_context);
|
||||||
|
|
||||||
|
}
|
||||||
|
DRM_DEBUG_DRIVER("PSR link: %d\n", link->psr_feature_enabled);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* amdgpu_dm_psr_enable() - enable psr f/w
|
||||||
|
* @stream: stream state
|
||||||
|
*
|
||||||
|
* Return: true if success
|
||||||
|
*/
|
||||||
|
bool amdgpu_dm_psr_enable(struct dc_stream_state *stream)
|
||||||
|
{
|
||||||
|
struct dc_link *link = stream->link;
|
||||||
|
struct dc_static_screen_events triggers = {0};
|
||||||
|
|
||||||
|
DRM_DEBUG_DRIVER("Enabling psr...\n");
|
||||||
|
|
||||||
|
triggers.cursor_update = true;
|
||||||
|
triggers.overlay_update = true;
|
||||||
|
triggers.surface_update = true;
|
||||||
|
|
||||||
|
dc_stream_set_static_screen_events(link->ctx->dc,
|
||||||
|
&stream, 1,
|
||||||
|
&triggers);
|
||||||
|
|
||||||
|
return dc_link_set_psr_allow_active(link, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* amdgpu_dm_psr_disable() - disable psr f/w
|
||||||
|
* @stream: stream state
|
||||||
|
*
|
||||||
|
* Return: true if success
|
||||||
|
*/
|
||||||
|
static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream)
|
||||||
|
{
|
||||||
|
|
||||||
|
DRM_DEBUG_DRIVER("Disabling psr...\n");
|
||||||
|
|
||||||
|
return dc_link_set_psr_allow_active(stream->link, false, true);
|
||||||
|
}
|
||||||
|
@ -210,6 +210,8 @@ static int __set_legacy_tf(struct dc_transfer_func *func,
|
|||||||
res = mod_color_calculate_regamma_params(func, gamma, true, has_rom,
|
res = mod_color_calculate_regamma_params(func, gamma, true, has_rom,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
dc_gamma_release(&gamma);
|
||||||
|
|
||||||
return res ? 0 : -ENOMEM;
|
return res ? 0 : -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -969,6 +969,25 @@ static int force_yuv420_output_get(void *data, u64 *val)
|
|||||||
DEFINE_DEBUGFS_ATTRIBUTE(force_yuv420_output_fops, force_yuv420_output_get,
|
DEFINE_DEBUGFS_ATTRIBUTE(force_yuv420_output_fops, force_yuv420_output_get,
|
||||||
force_yuv420_output_set, "%llu\n");
|
force_yuv420_output_set, "%llu\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read PSR state
|
||||||
|
*/
|
||||||
|
static int psr_get(void *data, u64 *val)
|
||||||
|
{
|
||||||
|
struct amdgpu_dm_connector *connector = data;
|
||||||
|
struct dc_link *link = connector->dc_link;
|
||||||
|
uint32_t psr_state = 0;
|
||||||
|
|
||||||
|
dc_link_get_psr_state(link, &psr_state);
|
||||||
|
|
||||||
|
*val = psr_state;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n");
|
||||||
|
|
||||||
void connector_debugfs_init(struct amdgpu_dm_connector *connector)
|
void connector_debugfs_init(struct amdgpu_dm_connector *connector)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -982,6 +1001,8 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector)
|
|||||||
dp_debugfs_entries[i].fops);
|
dp_debugfs_entries[i].fops);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
|
||||||
|
debugfs_create_file_unsafe("psr_state", 0444, dir, connector, &psr_fops);
|
||||||
|
|
||||||
debugfs_create_file_unsafe("force_yuv420_output", 0644, dir, connector,
|
debugfs_create_file_unsafe("force_yuv420_output", 0644, dir, connector,
|
||||||
&force_yuv420_output_fops);
|
&force_yuv420_output_fops);
|
||||||
|
@ -113,6 +113,7 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
|
|||||||
result = -EIO;
|
result = -EIO;
|
||||||
break;
|
break;
|
||||||
case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY:
|
case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY:
|
||||||
|
case AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE:
|
||||||
result = -EBUSY;
|
result = -EBUSY;
|
||||||
break;
|
break;
|
||||||
case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT:
|
case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT:
|
||||||
|
@ -345,7 +345,7 @@ bool dm_pp_get_clock_levels_by_type(
|
|||||||
/* Error in pplib. Provide default values. */
|
/* Error in pplib. Provide default values. */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (adev->smu.funcs && adev->smu.funcs->get_clock_by_type) {
|
} else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_clock_by_type) {
|
||||||
if (smu_get_clock_by_type(&adev->smu,
|
if (smu_get_clock_by_type(&adev->smu,
|
||||||
dc_to_pp_clock_type(clk_type),
|
dc_to_pp_clock_type(clk_type),
|
||||||
&pp_clks)) {
|
&pp_clks)) {
|
||||||
@ -365,7 +365,7 @@ bool dm_pp_get_clock_levels_by_type(
|
|||||||
validation_clks.memory_max_clock = 80000;
|
validation_clks.memory_max_clock = 80000;
|
||||||
validation_clks.level = 0;
|
validation_clks.level = 0;
|
||||||
}
|
}
|
||||||
} else if (adev->smu.funcs && adev->smu.funcs->get_max_high_clocks) {
|
} else if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->get_max_high_clocks) {
|
||||||
if (smu_get_max_high_clocks(&adev->smu, &validation_clks)) {
|
if (smu_get_max_high_clocks(&adev->smu, &validation_clks)) {
|
||||||
DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
|
DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
|
||||||
validation_clks.engine_max_clock = 72000;
|
validation_clks.engine_max_clock = 72000;
|
||||||
@ -506,8 +506,8 @@ bool dm_pp_apply_clock_for_voltage_request(
|
|||||||
ret = adev->powerplay.pp_funcs->display_clock_voltage_request(
|
ret = adev->powerplay.pp_funcs->display_clock_voltage_request(
|
||||||
adev->powerplay.pp_handle,
|
adev->powerplay.pp_handle,
|
||||||
&pp_clock_request);
|
&pp_clock_request);
|
||||||
else if (adev->smu.funcs &&
|
else if (adev->smu.ppt_funcs &&
|
||||||
adev->smu.funcs->display_clock_voltage_request)
|
adev->smu.ppt_funcs->display_clock_voltage_request)
|
||||||
ret = smu_display_clock_voltage_request(&adev->smu,
|
ret = smu_display_clock_voltage_request(&adev->smu,
|
||||||
&pp_clock_request);
|
&pp_clock_request);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -527,7 +527,7 @@ bool dm_pp_get_static_clocks(
|
|||||||
ret = adev->powerplay.pp_funcs->get_current_clocks(
|
ret = adev->powerplay.pp_funcs->get_current_clocks(
|
||||||
adev->powerplay.pp_handle,
|
adev->powerplay.pp_handle,
|
||||||
&pp_clk_info);
|
&pp_clk_info);
|
||||||
else if (adev->smu.funcs)
|
else if (adev->smu.ppt_funcs)
|
||||||
ret = smu_get_current_clocks(&adev->smu, &pp_clk_info);
|
ret = smu_get_current_clocks(&adev->smu, &pp_clk_info);
|
||||||
if (ret)
|
if (ret)
|
||||||
return false;
|
return false;
|
||||||
@ -603,7 +603,7 @@ void pp_rv_set_pme_wa_enable(struct pp_smu *pp)
|
|||||||
|
|
||||||
if (pp_funcs && pp_funcs->notify_smu_enable_pwe)
|
if (pp_funcs && pp_funcs->notify_smu_enable_pwe)
|
||||||
pp_funcs->notify_smu_enable_pwe(pp_handle);
|
pp_funcs->notify_smu_enable_pwe(pp_handle);
|
||||||
else if (adev->smu.funcs)
|
else if (adev->smu.ppt_funcs)
|
||||||
smu_notify_smu_enable_pwe(&adev->smu);
|
smu_notify_smu_enable_pwe(&adev->smu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,10 +717,10 @@ enum pp_smu_status pp_nv_set_pme_wa_enable(struct pp_smu *pp)
|
|||||||
struct amdgpu_device *adev = ctx->driver_context;
|
struct amdgpu_device *adev = ctx->driver_context;
|
||||||
struct smu_context *smu = &adev->smu;
|
struct smu_context *smu = &adev->smu;
|
||||||
|
|
||||||
if (!smu->funcs)
|
if (!smu->ppt_funcs)
|
||||||
return PP_SMU_RESULT_UNSUPPORTED;
|
return PP_SMU_RESULT_UNSUPPORTED;
|
||||||
|
|
||||||
/* 0: successful or smu.funcs->set_azalia_d3_pme = NULL; 1: fail */
|
/* 0: successful or smu.ppt_funcs->set_azalia_d3_pme = NULL; 1: fail */
|
||||||
if (smu_set_azalia_d3_pme(smu))
|
if (smu_set_azalia_d3_pme(smu))
|
||||||
return PP_SMU_RESULT_FAIL;
|
return PP_SMU_RESULT_FAIL;
|
||||||
|
|
||||||
@ -733,10 +733,10 @@ enum pp_smu_status pp_nv_set_display_count(struct pp_smu *pp, int count)
|
|||||||
struct amdgpu_device *adev = ctx->driver_context;
|
struct amdgpu_device *adev = ctx->driver_context;
|
||||||
struct smu_context *smu = &adev->smu;
|
struct smu_context *smu = &adev->smu;
|
||||||
|
|
||||||
if (!smu->funcs)
|
if (!smu->ppt_funcs)
|
||||||
return PP_SMU_RESULT_UNSUPPORTED;
|
return PP_SMU_RESULT_UNSUPPORTED;
|
||||||
|
|
||||||
/* 0: successful or smu.funcs->set_display_count = NULL; 1: fail */
|
/* 0: successful or smu.ppt_funcs->set_display_count = NULL; 1: fail */
|
||||||
if (smu_set_display_count(smu, count))
|
if (smu_set_display_count(smu, count))
|
||||||
return PP_SMU_RESULT_FAIL;
|
return PP_SMU_RESULT_FAIL;
|
||||||
|
|
||||||
@ -749,10 +749,10 @@ enum pp_smu_status pp_nv_set_min_deep_sleep_dcfclk(struct pp_smu *pp, int mhz)
|
|||||||
struct amdgpu_device *adev = ctx->driver_context;
|
struct amdgpu_device *adev = ctx->driver_context;
|
||||||
struct smu_context *smu = &adev->smu;
|
struct smu_context *smu = &adev->smu;
|
||||||
|
|
||||||
if (!smu->funcs)
|
if (!smu->ppt_funcs)
|
||||||
return PP_SMU_RESULT_UNSUPPORTED;
|
return PP_SMU_RESULT_UNSUPPORTED;
|
||||||
|
|
||||||
/* 0: successful or smu.funcs->set_deep_sleep_dcefclk = NULL;1: fail */
|
/* 0: successful or smu.ppt_funcs->set_deep_sleep_dcefclk = NULL;1: fail */
|
||||||
if (smu_set_deep_sleep_dcefclk(smu, mhz))
|
if (smu_set_deep_sleep_dcefclk(smu, mhz))
|
||||||
return PP_SMU_RESULT_FAIL;
|
return PP_SMU_RESULT_FAIL;
|
||||||
|
|
||||||
@ -767,13 +767,13 @@ enum pp_smu_status pp_nv_set_hard_min_dcefclk_by_freq(
|
|||||||
struct smu_context *smu = &adev->smu;
|
struct smu_context *smu = &adev->smu;
|
||||||
struct pp_display_clock_request clock_req;
|
struct pp_display_clock_request clock_req;
|
||||||
|
|
||||||
if (!smu->funcs)
|
if (!smu->ppt_funcs)
|
||||||
return PP_SMU_RESULT_UNSUPPORTED;
|
return PP_SMU_RESULT_UNSUPPORTED;
|
||||||
|
|
||||||
clock_req.clock_type = amd_pp_dcef_clock;
|
clock_req.clock_type = amd_pp_dcef_clock;
|
||||||
clock_req.clock_freq_in_khz = mhz * 1000;
|
clock_req.clock_freq_in_khz = mhz * 1000;
|
||||||
|
|
||||||
/* 0: successful or smu.funcs->display_clock_voltage_request = NULL
|
/* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL
|
||||||
* 1: fail
|
* 1: fail
|
||||||
*/
|
*/
|
||||||
if (smu_display_clock_voltage_request(smu, &clock_req))
|
if (smu_display_clock_voltage_request(smu, &clock_req))
|
||||||
@ -789,13 +789,13 @@ enum pp_smu_status pp_nv_set_hard_min_uclk_by_freq(struct pp_smu *pp, int mhz)
|
|||||||
struct smu_context *smu = &adev->smu;
|
struct smu_context *smu = &adev->smu;
|
||||||
struct pp_display_clock_request clock_req;
|
struct pp_display_clock_request clock_req;
|
||||||
|
|
||||||
if (!smu->funcs)
|
if (!smu->ppt_funcs)
|
||||||
return PP_SMU_RESULT_UNSUPPORTED;
|
return PP_SMU_RESULT_UNSUPPORTED;
|
||||||
|
|
||||||
clock_req.clock_type = amd_pp_mem_clock;
|
clock_req.clock_type = amd_pp_mem_clock;
|
||||||
clock_req.clock_freq_in_khz = mhz * 1000;
|
clock_req.clock_freq_in_khz = mhz * 1000;
|
||||||
|
|
||||||
/* 0: successful or smu.funcs->display_clock_voltage_request = NULL
|
/* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL
|
||||||
* 1: fail
|
* 1: fail
|
||||||
*/
|
*/
|
||||||
if (smu_display_clock_voltage_request(smu, &clock_req))
|
if (smu_display_clock_voltage_request(smu, &clock_req))
|
||||||
@ -825,7 +825,7 @@ enum pp_smu_status pp_nv_set_voltage_by_freq(struct pp_smu *pp,
|
|||||||
struct smu_context *smu = &adev->smu;
|
struct smu_context *smu = &adev->smu;
|
||||||
struct pp_display_clock_request clock_req;
|
struct pp_display_clock_request clock_req;
|
||||||
|
|
||||||
if (!smu->funcs)
|
if (!smu->ppt_funcs)
|
||||||
return PP_SMU_RESULT_UNSUPPORTED;
|
return PP_SMU_RESULT_UNSUPPORTED;
|
||||||
|
|
||||||
switch (clock_id) {
|
switch (clock_id) {
|
||||||
@ -843,7 +843,7 @@ enum pp_smu_status pp_nv_set_voltage_by_freq(struct pp_smu *pp,
|
|||||||
}
|
}
|
||||||
clock_req.clock_freq_in_khz = mhz * 1000;
|
clock_req.clock_freq_in_khz = mhz * 1000;
|
||||||
|
|
||||||
/* 0: successful or smu.funcs->display_clock_voltage_request = NULL
|
/* 0: successful or smu.ppt_funcs->display_clock_voltage_request = NULL
|
||||||
* 1: fail
|
* 1: fail
|
||||||
*/
|
*/
|
||||||
if (smu_display_clock_voltage_request(smu, &clock_req))
|
if (smu_display_clock_voltage_request(smu, &clock_req))
|
||||||
@ -859,13 +859,13 @@ enum pp_smu_status pp_nv_get_maximum_sustainable_clocks(
|
|||||||
struct amdgpu_device *adev = ctx->driver_context;
|
struct amdgpu_device *adev = ctx->driver_context;
|
||||||
struct smu_context *smu = &adev->smu;
|
struct smu_context *smu = &adev->smu;
|
||||||
|
|
||||||
if (!smu->funcs)
|
if (!smu->ppt_funcs)
|
||||||
return PP_SMU_RESULT_UNSUPPORTED;
|
return PP_SMU_RESULT_UNSUPPORTED;
|
||||||
|
|
||||||
if (!smu->funcs->get_max_sustainable_clocks_by_dc)
|
if (!smu->ppt_funcs->get_max_sustainable_clocks_by_dc)
|
||||||
return PP_SMU_RESULT_UNSUPPORTED;
|
return PP_SMU_RESULT_UNSUPPORTED;
|
||||||
|
|
||||||
if (!smu->funcs->get_max_sustainable_clocks_by_dc(smu, max_clocks))
|
if (!smu_get_max_sustainable_clocks_by_dc(smu, max_clocks))
|
||||||
return PP_SMU_RESULT_OK;
|
return PP_SMU_RESULT_OK;
|
||||||
|
|
||||||
return PP_SMU_RESULT_FAIL;
|
return PP_SMU_RESULT_FAIL;
|
||||||
@ -884,7 +884,7 @@ enum pp_smu_status pp_nv_get_uclk_dpm_states(struct pp_smu *pp,
|
|||||||
if (!smu->ppt_funcs->get_uclk_dpm_states)
|
if (!smu->ppt_funcs->get_uclk_dpm_states)
|
||||||
return PP_SMU_RESULT_UNSUPPORTED;
|
return PP_SMU_RESULT_UNSUPPORTED;
|
||||||
|
|
||||||
if (!smu->ppt_funcs->get_uclk_dpm_states(smu,
|
if (!smu_get_uclk_dpm_states(smu,
|
||||||
clock_values_in_khz, num_states))
|
clock_values_in_khz, num_states))
|
||||||
return PP_SMU_RESULT_OK;
|
return PP_SMU_RESULT_OK;
|
||||||
|
|
||||||
@ -905,7 +905,7 @@ enum pp_smu_status pp_rn_get_dpm_clock_table(
|
|||||||
if (!smu->ppt_funcs->get_dpm_clock_table)
|
if (!smu->ppt_funcs->get_dpm_clock_table)
|
||||||
return PP_SMU_RESULT_UNSUPPORTED;
|
return PP_SMU_RESULT_UNSUPPORTED;
|
||||||
|
|
||||||
if (!smu->ppt_funcs->get_dpm_clock_table(smu, clock_table))
|
if (!smu_get_dpm_clock_table(smu, clock_table))
|
||||||
return PP_SMU_RESULT_OK;
|
return PP_SMU_RESULT_OK;
|
||||||
|
|
||||||
return PP_SMU_RESULT_FAIL;
|
return PP_SMU_RESULT_FAIL;
|
||||||
@ -924,7 +924,7 @@ enum pp_smu_status pp_rn_set_wm_ranges(struct pp_smu *pp,
|
|||||||
wm_with_clock_ranges.wm_mcif_clocks_ranges;
|
wm_with_clock_ranges.wm_mcif_clocks_ranges;
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
|
||||||
if (!smu->funcs)
|
if (!smu->ppt_funcs)
|
||||||
return PP_SMU_RESULT_UNSUPPORTED;
|
return PP_SMU_RESULT_UNSUPPORTED;
|
||||||
|
|
||||||
wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets;
|
wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets;
|
||||||
|
@ -147,7 +147,7 @@ int dce_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
|
|||||||
|
|
||||||
/* Calculate the current DFS clock, in kHz.*/
|
/* 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_mgr->dentist_vco_freq_khz) / target_div;
|
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
|
||||||
|
|
||||||
return dce_adjust_dp_ref_freq_for_ss(clk_mgr, dp_ref_clk_khz);
|
return dce_adjust_dp_ref_freq_for_ss(clk_mgr, dp_ref_clk_khz);
|
||||||
}
|
}
|
||||||
@ -239,7 +239,7 @@ int dce_set_clock(
|
|||||||
/* Make sure requested clock isn't lower than minimum threshold*/
|
/* Make sure requested clock isn't lower than minimum threshold*/
|
||||||
if (requested_clk_khz > 0)
|
if (requested_clk_khz > 0)
|
||||||
requested_clk_khz = max(requested_clk_khz,
|
requested_clk_khz = max(requested_clk_khz,
|
||||||
clk_mgr_dce->dentist_vco_freq_khz / 64);
|
clk_mgr_dce->base.dentist_vco_freq_khz / 64);
|
||||||
|
|
||||||
/* Prepare to program display clock*/
|
/* Prepare to program display clock*/
|
||||||
pxl_clk_params.target_pixel_clock_100hz = requested_clk_khz * 10;
|
pxl_clk_params.target_pixel_clock_100hz = requested_clk_khz * 10;
|
||||||
@ -276,11 +276,11 @@ static void dce_clock_read_integrated_info(struct clk_mgr_internal *clk_mgr_dce)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (bp->integrated_info)
|
if (bp->integrated_info)
|
||||||
clk_mgr_dce->dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq;
|
clk_mgr_dce->base.dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq;
|
||||||
if (clk_mgr_dce->dentist_vco_freq_khz == 0) {
|
if (clk_mgr_dce->base.dentist_vco_freq_khz == 0) {
|
||||||
clk_mgr_dce->dentist_vco_freq_khz = bp->fw_info.smu_gpu_pll_output_freq;
|
clk_mgr_dce->base.dentist_vco_freq_khz = bp->fw_info.smu_gpu_pll_output_freq;
|
||||||
if (clk_mgr_dce->dentist_vco_freq_khz == 0)
|
if (clk_mgr_dce->base.dentist_vco_freq_khz == 0)
|
||||||
clk_mgr_dce->dentist_vco_freq_khz = 3600000;
|
clk_mgr_dce->base.dentist_vco_freq_khz = 3600000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*update the maximum display clock for each power state*/
|
/*update the maximum display clock for each power state*/
|
||||||
|
@ -81,7 +81,7 @@ int dce112_set_clock(struct clk_mgr *clk_mgr_base, int requested_clk_khz)
|
|||||||
/* Make sure requested clock isn't lower than minimum threshold*/
|
/* Make sure requested clock isn't lower than minimum threshold*/
|
||||||
if (requested_clk_khz > 0)
|
if (requested_clk_khz > 0)
|
||||||
requested_clk_khz = max(requested_clk_khz,
|
requested_clk_khz = max(requested_clk_khz,
|
||||||
clk_mgr_dce->dentist_vco_freq_khz / 62);
|
clk_mgr_dce->base.dentist_vco_freq_khz / 62);
|
||||||
|
|
||||||
dce_clk_params.target_clock_frequency = requested_clk_khz;
|
dce_clk_params.target_clock_frequency = requested_clk_khz;
|
||||||
dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS;
|
dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS;
|
||||||
@ -135,7 +135,7 @@ int dce112_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_clk_khz)
|
|||||||
/* Make sure requested clock isn't lower than minimum threshold*/
|
/* Make sure requested clock isn't lower than minimum threshold*/
|
||||||
if (requested_clk_khz > 0)
|
if (requested_clk_khz > 0)
|
||||||
requested_clk_khz = max(requested_clk_khz,
|
requested_clk_khz = max(requested_clk_khz,
|
||||||
clk_mgr->dentist_vco_freq_khz / 62);
|
clk_mgr->base.dentist_vco_freq_khz / 62);
|
||||||
|
|
||||||
dce_clk_params.target_clock_frequency = requested_clk_khz;
|
dce_clk_params.target_clock_frequency = requested_clk_khz;
|
||||||
dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS;
|
dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS;
|
||||||
|
@ -269,11 +269,11 @@ void rv1_clk_mgr_construct(struct dc_context *ctx, struct clk_mgr_internal *clk_
|
|||||||
clk_mgr->base.dprefclk_khz = 600000;
|
clk_mgr->base.dprefclk_khz = 600000;
|
||||||
|
|
||||||
if (bp->integrated_info)
|
if (bp->integrated_info)
|
||||||
clk_mgr->dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq;
|
clk_mgr->base.dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq;
|
||||||
if (bp->fw_info_valid && clk_mgr->dentist_vco_freq_khz == 0) {
|
if (bp->fw_info_valid && clk_mgr->base.dentist_vco_freq_khz == 0) {
|
||||||
clk_mgr->dentist_vco_freq_khz = bp->fw_info.smu_gpu_pll_output_freq;
|
clk_mgr->base.dentist_vco_freq_khz = bp->fw_info.smu_gpu_pll_output_freq;
|
||||||
if (clk_mgr->dentist_vco_freq_khz == 0)
|
if (clk_mgr->base.dentist_vco_freq_khz == 0)
|
||||||
clk_mgr->dentist_vco_freq_khz = 3600000;
|
clk_mgr->base.dentist_vco_freq_khz = 3600000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!debug->disable_dfs_bypass && bp->integrated_info)
|
if (!debug->disable_dfs_bypass && bp->integrated_info)
|
||||||
|
@ -108,11 +108,12 @@ void dcn20_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
|
|||||||
for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
|
for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
|
||||||
int dpp_inst, dppclk_khz;
|
int dpp_inst, dppclk_khz;
|
||||||
|
|
||||||
if (!context->res_ctx.pipe_ctx[i].plane_state)
|
/* Loop index will match dpp->inst if resource exists,
|
||||||
continue;
|
* and we want to avoid dependency on dpp object
|
||||||
|
*/
|
||||||
dpp_inst = context->res_ctx.pipe_ctx[i].plane_res.dpp->inst;
|
dpp_inst = i;
|
||||||
dppclk_khz = context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz;
|
dppclk_khz = context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz;
|
||||||
|
|
||||||
clk_mgr->dccg->funcs->update_dpp_dto(
|
clk_mgr->dccg->funcs->update_dpp_dto(
|
||||||
clk_mgr->dccg, dpp_inst, dppclk_khz);
|
clk_mgr->dccg, dpp_inst, dppclk_khz);
|
||||||
}
|
}
|
||||||
@ -121,9 +122,9 @@ void dcn20_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
|
|||||||
void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr)
|
void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr)
|
||||||
{
|
{
|
||||||
int dpp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
|
int dpp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
|
||||||
* clk_mgr->dentist_vco_freq_khz / clk_mgr->base.clks.dppclk_khz;
|
* clk_mgr->base.dentist_vco_freq_khz / clk_mgr->base.clks.dppclk_khz;
|
||||||
int disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
|
int disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
|
||||||
* clk_mgr->dentist_vco_freq_khz / clk_mgr->base.clks.dispclk_khz;
|
* clk_mgr->base.dentist_vco_freq_khz / clk_mgr->base.clks.dispclk_khz;
|
||||||
|
|
||||||
uint32_t dppclk_wdivider = dentist_get_did_from_divider(dpp_divider);
|
uint32_t dppclk_wdivider = dentist_get_did_from_divider(dpp_divider);
|
||||||
uint32_t dispclk_wdivider = dentist_get_did_from_divider(disp_divider);
|
uint32_t dispclk_wdivider = dentist_get_did_from_divider(disp_divider);
|
||||||
@ -235,6 +236,7 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||||||
|
|
||||||
update_dispclk = true;
|
update_dispclk = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dc->config.forced_clocks == false || (force_reset && safe_to_lower)) {
|
if (dc->config.forced_clocks == false || (force_reset && safe_to_lower)) {
|
||||||
if (dpp_clock_lowered) {
|
if (dpp_clock_lowered) {
|
||||||
// if clock is being lowered, increase DTO before lowering refclk
|
// if clock is being lowered, increase DTO before lowering refclk
|
||||||
@ -244,10 +246,12 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||||||
// if clock is being raised, increase refclk before lowering DTO
|
// if clock is being raised, increase refclk before lowering DTO
|
||||||
if (update_dppclk || update_dispclk)
|
if (update_dppclk || update_dispclk)
|
||||||
dcn20_update_clocks_update_dentist(clk_mgr);
|
dcn20_update_clocks_update_dentist(clk_mgr);
|
||||||
if (update_dppclk)
|
// always update dtos unless clock is lowered and not safe to lower
|
||||||
|
if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz)
|
||||||
dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
|
dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update_dispclk &&
|
if (update_dispclk &&
|
||||||
dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) {
|
dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) {
|
||||||
/*update dmcu for wait_loop count*/
|
/*update dmcu for wait_loop count*/
|
||||||
@ -260,6 +264,8 @@ void dcn2_update_clocks_fpga(struct clk_mgr *clk_mgr,
|
|||||||
struct dc_state *context,
|
struct dc_state *context,
|
||||||
bool safe_to_lower)
|
bool safe_to_lower)
|
||||||
{
|
{
|
||||||
|
struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr);
|
||||||
|
|
||||||
struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
|
struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
|
||||||
/* Min fclk = 1.2GHz since all the extra scemi logic seems to run off of it */
|
/* Min fclk = 1.2GHz since all the extra scemi logic seems to run off of it */
|
||||||
int fclk_adj = new_clocks->fclk_khz > 1200000 ? new_clocks->fclk_khz : 1200000;
|
int fclk_adj = new_clocks->fclk_khz > 1200000 ? new_clocks->fclk_khz : 1200000;
|
||||||
@ -297,14 +303,18 @@ void dcn2_update_clocks_fpga(struct clk_mgr *clk_mgr,
|
|||||||
clk_mgr->clks.dispclk_khz = new_clocks->dispclk_khz;
|
clk_mgr->clks.dispclk_khz = new_clocks->dispclk_khz;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Both fclk and dppclk ref are run on the same scemi clock so we
|
/* Both fclk and ref_dppclk run on the same scemi clock.
|
||||||
* need to keep the same value for both
|
* So take the higher value since the DPP DTO is typically programmed
|
||||||
|
* such that max dppclk is 1:1 with ref_dppclk.
|
||||||
*/
|
*/
|
||||||
if (clk_mgr->clks.fclk_khz > clk_mgr->clks.dppclk_khz)
|
if (clk_mgr->clks.fclk_khz > clk_mgr->clks.dppclk_khz)
|
||||||
clk_mgr->clks.dppclk_khz = clk_mgr->clks.fclk_khz;
|
clk_mgr->clks.dppclk_khz = clk_mgr->clks.fclk_khz;
|
||||||
if (clk_mgr->clks.dppclk_khz > clk_mgr->clks.fclk_khz)
|
if (clk_mgr->clks.dppclk_khz > clk_mgr->clks.fclk_khz)
|
||||||
clk_mgr->clks.fclk_khz = clk_mgr->clks.dppclk_khz;
|
clk_mgr->clks.fclk_khz = clk_mgr->clks.dppclk_khz;
|
||||||
|
|
||||||
|
// Both fclk and ref_dppclk run on the same scemi clock.
|
||||||
|
clk_mgr_int->dccg->ref_dppclk = clk_mgr->clks.fclk_khz;
|
||||||
|
|
||||||
dm_set_dcn_clocks(clk_mgr->ctx, &clk_mgr->clks);
|
dm_set_dcn_clocks(clk_mgr->ctx, &clk_mgr->clks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,7 +416,7 @@ void dcn20_clk_mgr_construct(
|
|||||||
|
|
||||||
if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
|
if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
|
||||||
dcn2_funcs.update_clocks = dcn2_update_clocks_fpga;
|
dcn2_funcs.update_clocks = dcn2_update_clocks_fpga;
|
||||||
clk_mgr->dentist_vco_freq_khz = 3850000;
|
clk_mgr->base.dentist_vco_freq_khz = 3850000;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* DFS Slice 2 should be used for DPREFCLK */
|
/* DFS Slice 2 should be used for DPREFCLK */
|
||||||
@ -430,15 +440,15 @@ void dcn20_clk_mgr_construct(
|
|||||||
pll_req = dc_fixpt_mul_int(pll_req, 100000);
|
pll_req = dc_fixpt_mul_int(pll_req, 100000);
|
||||||
|
|
||||||
/* integer part is now VCO frequency in kHz */
|
/* integer part is now VCO frequency in kHz */
|
||||||
clk_mgr->dentist_vco_freq_khz = dc_fixpt_floor(pll_req);
|
clk_mgr->base.dentist_vco_freq_khz = dc_fixpt_floor(pll_req);
|
||||||
|
|
||||||
/* in case we don't get a value from the register, use default */
|
/* in case we don't get a value from the register, use default */
|
||||||
if (clk_mgr->dentist_vco_freq_khz == 0)
|
if (clk_mgr->base.dentist_vco_freq_khz == 0)
|
||||||
clk_mgr->dentist_vco_freq_khz = 3850000;
|
clk_mgr->base.dentist_vco_freq_khz = 3850000;
|
||||||
|
|
||||||
/* Calculate the DPREFCLK in kHz.*/
|
/* Calculate the DPREFCLK in kHz.*/
|
||||||
clk_mgr->base.dprefclk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
|
clk_mgr->base.dprefclk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
|
||||||
* clk_mgr->dentist_vco_freq_khz) / target_div;
|
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
|
||||||
}
|
}
|
||||||
//Integrated_info table does not exist on dGPU projects so should not be referenced
|
//Integrated_info table does not exist on dGPU projects so should not be referenced
|
||||||
//anywhere in code for dGPUs.
|
//anywhere in code for dGPUs.
|
||||||
|
@ -114,22 +114,22 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||||||
*/
|
*/
|
||||||
if (safe_to_lower) {
|
if (safe_to_lower) {
|
||||||
/* check that we're not already in lower */
|
/* check that we're not already in lower */
|
||||||
if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_OPTIMIZED) {
|
if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) {
|
||||||
|
|
||||||
display_count = rn_get_active_display_cnt_wa(dc, context);
|
display_count = rn_get_active_display_cnt_wa(dc, context);
|
||||||
/* if we can go lower, go lower */
|
/* if we can go lower, go lower */
|
||||||
if (display_count == 0) {
|
if (display_count == 0) {
|
||||||
rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_OPTIMIZED);
|
rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_LOW_POWER);
|
||||||
/* update power state */
|
/* update power state */
|
||||||
clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_OPTIMIZED;
|
clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* check that we're not already in the normal state */
|
/* check that we're not already in D0 */
|
||||||
if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_NORMAL) {
|
if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_MISSION_MODE) {
|
||||||
rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_NORMAL);
|
rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_MISSION_MODE);
|
||||||
/* update power state */
|
/* update power state */
|
||||||
clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_NORMAL;
|
clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_MISSION_MODE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +171,8 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||||||
// if clock is being raised, increase refclk before lowering DTO
|
// if clock is being raised, increase refclk before lowering DTO
|
||||||
if (update_dppclk || update_dispclk)
|
if (update_dppclk || update_dispclk)
|
||||||
rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
|
rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
|
||||||
if (update_dppclk)
|
// always update dtos unless clock is lowered and not safe to lower
|
||||||
|
if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz)
|
||||||
dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
|
dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,7 +394,81 @@ void rn_init_clocks(struct clk_mgr *clk_mgr)
|
|||||||
// Assumption is that boot state always supports pstate
|
// Assumption is that boot state always supports pstate
|
||||||
clk_mgr->clks.p_state_change_support = true;
|
clk_mgr->clks.p_state_change_support = true;
|
||||||
clk_mgr->clks.prev_p_state_change_support = true;
|
clk_mgr->clks.prev_p_state_change_support = true;
|
||||||
clk_mgr->clks.pwr_state = DCN_PWR_STATE_NORMAL;
|
clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_smu_wm_range_sets *ranges)
|
||||||
|
{
|
||||||
|
int i, num_valid_sets;
|
||||||
|
|
||||||
|
num_valid_sets = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < WM_SET_COUNT; i++) {
|
||||||
|
/* skip empty entries, the smu array has no holes*/
|
||||||
|
if (!bw_params->wm_table.entries[i].valid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ranges->reader_wm_sets[num_valid_sets].wm_inst = bw_params->wm_table.entries[i].wm_inst;
|
||||||
|
ranges->reader_wm_sets[num_valid_sets].wm_type = bw_params->wm_table.entries[i].wm_type;;
|
||||||
|
/* We will not select WM based on dcfclk, so leave it as unconstrained */
|
||||||
|
ranges->reader_wm_sets[num_valid_sets].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
||||||
|
ranges->reader_wm_sets[num_valid_sets].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||||
|
/* fclk wil be used to select WM*/
|
||||||
|
|
||||||
|
if (ranges->reader_wm_sets[num_valid_sets].wm_type == WM_TYPE_PSTATE_CHG) {
|
||||||
|
if (i == 0)
|
||||||
|
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = 0;
|
||||||
|
else {
|
||||||
|
/* add 1 to make it non-overlapping with next lvl */
|
||||||
|
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = bw_params->clk_table.entries[i - 1].fclk_mhz + 1;
|
||||||
|
}
|
||||||
|
ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = bw_params->clk_table.entries[i].fclk_mhz;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* unconstrained for memory retraining */
|
||||||
|
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
||||||
|
ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||||
|
|
||||||
|
/* Modify previous watermark range to cover up to max */
|
||||||
|
ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||||
|
}
|
||||||
|
num_valid_sets++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(num_valid_sets != 0); /* Must have at least one set of valid watermarks */
|
||||||
|
ranges->num_reader_wm_sets = num_valid_sets;
|
||||||
|
|
||||||
|
/* modify the min and max to make sure we cover the whole range*/
|
||||||
|
ranges->reader_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
||||||
|
ranges->reader_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
||||||
|
ranges->reader_wm_sets[ranges->num_reader_wm_sets - 1].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||||
|
ranges->reader_wm_sets[ranges->num_reader_wm_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||||
|
|
||||||
|
/* This is for writeback only, does not matter currently as no writeback support*/
|
||||||
|
ranges->num_writer_wm_sets = 1;
|
||||||
|
ranges->writer_wm_sets[0].wm_inst = WM_A;
|
||||||
|
ranges->writer_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
||||||
|
ranges->writer_wm_sets[0].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||||
|
ranges->writer_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
||||||
|
ranges->writer_wm_sets[0].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rn_notify_wm_ranges(struct clk_mgr *clk_mgr_base)
|
||||||
|
{
|
||||||
|
struct dc_debug_options *debug = &clk_mgr_base->ctx->dc->debug;
|
||||||
|
struct pp_smu_wm_range_sets ranges = {0};
|
||||||
|
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
|
||||||
|
struct pp_smu_funcs *pp_smu = clk_mgr->pp_smu;
|
||||||
|
|
||||||
|
if (!debug->disable_pplib_wm_range) {
|
||||||
|
build_watermark_ranges(clk_mgr_base->bw_params, &ranges);
|
||||||
|
|
||||||
|
/* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
|
||||||
|
if (pp_smu && pp_smu->rn_funcs.set_wm_ranges)
|
||||||
|
pp_smu->rn_funcs.set_wm_ranges(&pp_smu->rn_funcs.pp_smu, &ranges);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct clk_mgr_funcs dcn21_funcs = {
|
static struct clk_mgr_funcs dcn21_funcs = {
|
||||||
@ -401,7 +476,8 @@ static struct clk_mgr_funcs dcn21_funcs = {
|
|||||||
.update_clocks = rn_update_clocks,
|
.update_clocks = rn_update_clocks,
|
||||||
.init_clocks = rn_init_clocks,
|
.init_clocks = rn_init_clocks,
|
||||||
.enable_pme_wa = rn_enable_pme_wa,
|
.enable_pme_wa = rn_enable_pme_wa,
|
||||||
/* .dump_clk_registers = rn_dump_clk_registers */
|
/* .dump_clk_registers = rn_dump_clk_registers, */
|
||||||
|
.notify_wm_ranges = rn_notify_wm_ranges
|
||||||
};
|
};
|
||||||
|
|
||||||
struct clk_bw_params rn_bw_params = {
|
struct clk_bw_params rn_bw_params = {
|
||||||
@ -472,63 +548,6 @@ struct clk_bw_params rn_bw_params = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void rn_build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_smu_wm_range_sets *ranges)
|
|
||||||
{
|
|
||||||
int i, num_valid_sets;
|
|
||||||
|
|
||||||
num_valid_sets = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < WM_SET_COUNT; i++) {
|
|
||||||
/* skip empty entries, the smu array has no holes*/
|
|
||||||
if (!bw_params->wm_table.entries[i].valid)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ranges->reader_wm_sets[num_valid_sets].wm_inst = bw_params->wm_table.entries[i].wm_inst;
|
|
||||||
ranges->reader_wm_sets[num_valid_sets].wm_type = bw_params->wm_table.entries[i].wm_type;;
|
|
||||||
/* We will not select WM based on dcfclk, so leave it as unconstrained */
|
|
||||||
ranges->reader_wm_sets[num_valid_sets].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
|
||||||
ranges->reader_wm_sets[num_valid_sets].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
|
||||||
/* fclk wil be used to select WM*/
|
|
||||||
|
|
||||||
if (ranges->reader_wm_sets[num_valid_sets].wm_type == WM_TYPE_PSTATE_CHG) {
|
|
||||||
if (i == 0)
|
|
||||||
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = 0;
|
|
||||||
else {
|
|
||||||
/* add 1 to make it non-overlapping with next lvl */
|
|
||||||
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = bw_params->clk_table.entries[i - 1].fclk_mhz + 1;
|
|
||||||
}
|
|
||||||
ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = bw_params->clk_table.entries[i].fclk_mhz;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* unconstrained for memory retraining */
|
|
||||||
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
|
||||||
ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
|
||||||
|
|
||||||
/* Modify previous watermark range to cover up to max */
|
|
||||||
ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
|
||||||
}
|
|
||||||
num_valid_sets++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(num_valid_sets != 0); /* Must have at least one set of valid watermarks */
|
|
||||||
ranges->num_reader_wm_sets = num_valid_sets;
|
|
||||||
|
|
||||||
/* modify the min and max to make sure we cover the whole range*/
|
|
||||||
ranges->reader_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
|
||||||
ranges->reader_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
|
||||||
ranges->reader_wm_sets[ranges->num_reader_wm_sets - 1].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
|
||||||
ranges->reader_wm_sets[ranges->num_reader_wm_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
|
||||||
|
|
||||||
/* This is for writeback only, does not matter currently as no writeback support*/
|
|
||||||
ranges->num_writer_wm_sets = 1;
|
|
||||||
ranges->writer_wm_sets[0].wm_inst = WM_A;
|
|
||||||
ranges->writer_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
|
||||||
ranges->writer_wm_sets[0].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
|
||||||
ranges->writer_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
|
|
||||||
ranges->writer_wm_sets[0].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage)
|
static unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -542,7 +561,7 @@ static unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsi
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rn_clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct hw_asic_id *asic_id)
|
static void rn_clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct hw_asic_id *asic_id)
|
||||||
{
|
{
|
||||||
int i, j = 0;
|
int i, j = 0;
|
||||||
|
|
||||||
@ -628,17 +647,17 @@ void rn_clk_mgr_construct(
|
|||||||
|
|
||||||
if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
|
if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
|
||||||
dcn21_funcs.update_clocks = dcn2_update_clocks_fpga;
|
dcn21_funcs.update_clocks = dcn2_update_clocks_fpga;
|
||||||
clk_mgr->dentist_vco_freq_khz = 3600000;
|
clk_mgr->base.dentist_vco_freq_khz = 3600000;
|
||||||
clk_mgr->base.dprefclk_khz = 600000;
|
clk_mgr->base.dprefclk_khz = 600000;
|
||||||
} else {
|
} else {
|
||||||
struct clk_log_info log_info = {0};
|
struct clk_log_info log_info = {0};
|
||||||
|
|
||||||
/* TODO: Check we get what we expect during bringup */
|
/* TODO: Check we get what we expect during bringup */
|
||||||
clk_mgr->dentist_vco_freq_khz = get_vco_frequency_from_reg(clk_mgr);
|
clk_mgr->base.dentist_vco_freq_khz = get_vco_frequency_from_reg(clk_mgr);
|
||||||
|
|
||||||
/* in case we don't get a value from the register, use default */
|
/* in case we don't get a value from the register, use default */
|
||||||
if (clk_mgr->dentist_vco_freq_khz == 0)
|
if (clk_mgr->base.dentist_vco_freq_khz == 0)
|
||||||
clk_mgr->dentist_vco_freq_khz = 3600000;
|
clk_mgr->base.dentist_vco_freq_khz = 3600000;
|
||||||
|
|
||||||
rn_dump_clk_registers(&s, &clk_mgr->base, &log_info);
|
rn_dump_clk_registers(&s, &clk_mgr->base, &log_info);
|
||||||
/* Convert dprefclk units from MHz to KHz */
|
/* Convert dprefclk units from MHz to KHz */
|
||||||
@ -661,21 +680,6 @@ void rn_clk_mgr_construct(
|
|||||||
rn_clk_mgr_helper_populate_bw_params(clk_mgr->base.bw_params, &clock_table, &ctx->asic_id);
|
rn_clk_mgr_helper_populate_bw_params(clk_mgr->base.bw_params, &clock_table, &ctx->asic_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Notify SMU which set of WM should be selected for different ranges of fclk
|
|
||||||
* On Renoir there is a maximumum of 4 DF pstates supported, could be less
|
|
||||||
* depending on DDR speed and fused maximum fclk.
|
|
||||||
*/
|
|
||||||
if (!debug->disable_pplib_wm_range) {
|
|
||||||
struct pp_smu_wm_range_sets ranges = {0};
|
|
||||||
|
|
||||||
rn_build_watermark_ranges(clk_mgr->base.bw_params, &ranges);
|
|
||||||
|
|
||||||
/* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
|
|
||||||
if (pp_smu && pp_smu->rn_funcs.set_wm_ranges)
|
|
||||||
pp_smu->rn_funcs.set_wm_ranges(&pp_smu->rn_funcs.pp_smu, &ranges);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && clk_mgr->smu_ver >= 0x00371500) {
|
if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && clk_mgr->smu_ver >= 0x00371500) {
|
||||||
/* enable powerfeatures when displaycount goes to 0 */
|
/* enable powerfeatures when displaycount goes to 0 */
|
||||||
rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(clk_mgr, !debug->disable_48mhz_pwrdwn);
|
rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(clk_mgr, !debug->disable_48mhz_pwrdwn);
|
||||||
|
@ -33,13 +33,6 @@ struct rn_clk_registers {
|
|||||||
uint32_t CLK1_CLK0_CURRENT_CNT; /* DPREFCLK */
|
uint32_t CLK1_CLK0_CURRENT_CNT; /* DPREFCLK */
|
||||||
};
|
};
|
||||||
|
|
||||||
void rn_build_watermark_ranges(
|
|
||||||
struct clk_bw_params *bw_params,
|
|
||||||
struct pp_smu_wm_range_sets *ranges);
|
|
||||||
void rn_clk_mgr_helper_populate_bw_params(
|
|
||||||
struct clk_bw_params *bw_params,
|
|
||||||
struct dpm_clocks *clock_table,
|
|
||||||
struct hw_asic_id *asic_id);
|
|
||||||
void rn_clk_mgr_construct(struct dc_context *ctx,
|
void rn_clk_mgr_construct(struct dc_context *ctx,
|
||||||
struct clk_mgr_internal *clk_mgr,
|
struct clk_mgr_internal *clk_mgr,
|
||||||
struct pp_smu_funcs *pp_smu,
|
struct pp_smu_funcs *pp_smu,
|
||||||
|
@ -170,7 +170,7 @@ void rn_vbios_smu_set_dcn_low_power_state(struct clk_mgr_internal *clk_mgr, enum
|
|||||||
{
|
{
|
||||||
int disp_count;
|
int disp_count;
|
||||||
|
|
||||||
if (state == DCN_PWR_STATE_OPTIMIZED)
|
if (state == DCN_PWR_STATE_LOW_POWER)
|
||||||
disp_count = 0;
|
disp_count = 0;
|
||||||
else
|
else
|
||||||
disp_count = 1;
|
disp_count = 1;
|
||||||
|
@ -194,7 +194,7 @@ static bool create_links(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!should_destory_link) {
|
if (dc->config.force_enum_edp || !should_destory_link) {
|
||||||
dc->links[dc->link_count] = link;
|
dc->links[dc->link_count] = link;
|
||||||
link->dc = dc;
|
link->dc = dc;
|
||||||
++dc->link_count;
|
++dc->link_count;
|
||||||
@ -601,6 +601,10 @@ static bool construct(struct dc *dc,
|
|||||||
#ifdef CONFIG_DRM_AMD_DC_DCN2_0
|
#ifdef CONFIG_DRM_AMD_DC_DCN2_0
|
||||||
// Allocate memory for the vm_helper
|
// Allocate memory for the vm_helper
|
||||||
dc->vm_helper = kzalloc(sizeof(struct vm_helper), GFP_KERNEL);
|
dc->vm_helper = kzalloc(sizeof(struct vm_helper), GFP_KERNEL);
|
||||||
|
if (!dc->vm_helper) {
|
||||||
|
dm_error("%s: failed to create dc->vm_helper\n", __func__);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
memcpy(&dc->bb_overrides, &init_params->bb_overrides, sizeof(dc->bb_overrides));
|
memcpy(&dc->bb_overrides, &init_params->bb_overrides, sizeof(dc->bb_overrides));
|
||||||
@ -1241,15 +1245,9 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
|
|||||||
|
|
||||||
dc_enable_stereo(dc, context, dc_streams, context->stream_count);
|
dc_enable_stereo(dc, context, dc_streams, context->stream_count);
|
||||||
|
|
||||||
if (!dc->optimize_seamless_boot)
|
|
||||||
/* pplib is notified if disp_num changed */
|
|
||||||
dc->hwss.optimize_bandwidth(dc, context);
|
|
||||||
|
|
||||||
for (i = 0; i < context->stream_count; i++)
|
for (i = 0; i < context->stream_count; i++)
|
||||||
context->streams[i]->mode_changed = false;
|
context->streams[i]->mode_changed = false;
|
||||||
|
|
||||||
memset(&context->commit_hints, 0, sizeof(context->commit_hints));
|
|
||||||
|
|
||||||
dc_release_state(dc->current_state);
|
dc_release_state(dc->current_state);
|
||||||
|
|
||||||
dc->current_state = context;
|
dc->current_state = context;
|
||||||
|
@ -2436,6 +2436,191 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dc_link_get_psr_state(const struct dc_link *link, uint32_t *psr_state)
|
||||||
|
{
|
||||||
|
struct dc *core_dc = link->ctx->dc;
|
||||||
|
struct dmcu *dmcu = core_dc->res_pool->dmcu;
|
||||||
|
|
||||||
|
if (dmcu != NULL && link->psr_feature_enabled)
|
||||||
|
dmcu->funcs->get_psr_state(dmcu, psr_state);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline enum physical_phy_id
|
||||||
|
transmitter_to_phy_id(enum transmitter transmitter_value)
|
||||||
|
{
|
||||||
|
switch (transmitter_value) {
|
||||||
|
case TRANSMITTER_UNIPHY_A:
|
||||||
|
return PHYLD_0;
|
||||||
|
case TRANSMITTER_UNIPHY_B:
|
||||||
|
return PHYLD_1;
|
||||||
|
case TRANSMITTER_UNIPHY_C:
|
||||||
|
return PHYLD_2;
|
||||||
|
case TRANSMITTER_UNIPHY_D:
|
||||||
|
return PHYLD_3;
|
||||||
|
case TRANSMITTER_UNIPHY_E:
|
||||||
|
return PHYLD_4;
|
||||||
|
case TRANSMITTER_UNIPHY_F:
|
||||||
|
return PHYLD_5;
|
||||||
|
case TRANSMITTER_NUTMEG_CRT:
|
||||||
|
return PHYLD_6;
|
||||||
|
case TRANSMITTER_TRAVIS_CRT:
|
||||||
|
return PHYLD_7;
|
||||||
|
case TRANSMITTER_TRAVIS_LCD:
|
||||||
|
return PHYLD_8;
|
||||||
|
case TRANSMITTER_UNIPHY_G:
|
||||||
|
return PHYLD_9;
|
||||||
|
case TRANSMITTER_COUNT:
|
||||||
|
return PHYLD_COUNT;
|
||||||
|
case TRANSMITTER_UNKNOWN:
|
||||||
|
return PHYLD_UNKNOWN;
|
||||||
|
default:
|
||||||
|
WARN_ONCE(1, "Unknown transmitter value %d\n",
|
||||||
|
transmitter_value);
|
||||||
|
return PHYLD_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dc_link_setup_psr(struct dc_link *link,
|
||||||
|
const struct dc_stream_state *stream, struct psr_config *psr_config,
|
||||||
|
struct psr_context *psr_context)
|
||||||
|
{
|
||||||
|
struct dc *core_dc;
|
||||||
|
struct dmcu *dmcu;
|
||||||
|
int i;
|
||||||
|
/* updateSinkPsrDpcdConfig*/
|
||||||
|
union dpcd_psr_configuration psr_configuration;
|
||||||
|
|
||||||
|
psr_context->controllerId = CONTROLLER_ID_UNDEFINED;
|
||||||
|
|
||||||
|
if (!link)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
core_dc = link->ctx->dc;
|
||||||
|
dmcu = core_dc->res_pool->dmcu;
|
||||||
|
|
||||||
|
if (!dmcu)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
memset(&psr_configuration, 0, sizeof(psr_configuration));
|
||||||
|
|
||||||
|
psr_configuration.bits.ENABLE = 1;
|
||||||
|
psr_configuration.bits.CRC_VERIFICATION = 1;
|
||||||
|
psr_configuration.bits.FRAME_CAPTURE_INDICATION =
|
||||||
|
psr_config->psr_frame_capture_indication_req;
|
||||||
|
|
||||||
|
/* Check for PSR v2*/
|
||||||
|
if (psr_config->psr_version == 0x2) {
|
||||||
|
/* For PSR v2 selective update.
|
||||||
|
* Indicates whether sink should start capturing
|
||||||
|
* immediately following active scan line,
|
||||||
|
* or starting with the 2nd active scan line.
|
||||||
|
*/
|
||||||
|
psr_configuration.bits.LINE_CAPTURE_INDICATION = 0;
|
||||||
|
/*For PSR v2, determines whether Sink should generate
|
||||||
|
* IRQ_HPD when CRC mismatch is detected.
|
||||||
|
*/
|
||||||
|
psr_configuration.bits.IRQ_HPD_WITH_CRC_ERROR = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dm_helpers_dp_write_dpcd(
|
||||||
|
link->ctx,
|
||||||
|
link,
|
||||||
|
368,
|
||||||
|
&psr_configuration.raw,
|
||||||
|
sizeof(psr_configuration.raw));
|
||||||
|
|
||||||
|
psr_context->channel = link->ddc->ddc_pin->hw_info.ddc_channel;
|
||||||
|
psr_context->transmitterId = link->link_enc->transmitter;
|
||||||
|
psr_context->engineId = link->link_enc->preferred_engine;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_PIPES; i++) {
|
||||||
|
if (core_dc->current_state->res_ctx.pipe_ctx[i].stream
|
||||||
|
== stream) {
|
||||||
|
/* dmcu -1 for all controller id values,
|
||||||
|
* therefore +1 here
|
||||||
|
*/
|
||||||
|
psr_context->controllerId =
|
||||||
|
core_dc->current_state->res_ctx.
|
||||||
|
pipe_ctx[i].stream_res.tg->inst + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hardcoded for now. Can be Pcie or Uniphy (or Unknown)*/
|
||||||
|
psr_context->phyType = PHY_TYPE_UNIPHY;
|
||||||
|
/*PhyId is associated with the transmitter id*/
|
||||||
|
psr_context->smuPhyId =
|
||||||
|
transmitter_to_phy_id(link->link_enc->transmitter);
|
||||||
|
|
||||||
|
psr_context->crtcTimingVerticalTotal = stream->timing.v_total;
|
||||||
|
psr_context->vsyncRateHz = div64_u64(div64_u64((stream->
|
||||||
|
timing.pix_clk_100hz * 100),
|
||||||
|
stream->timing.v_total),
|
||||||
|
stream->timing.h_total);
|
||||||
|
|
||||||
|
psr_context->psrSupportedDisplayConfig = true;
|
||||||
|
psr_context->psrExitLinkTrainingRequired =
|
||||||
|
psr_config->psr_exit_link_training_required;
|
||||||
|
psr_context->sdpTransmitLineNumDeadline =
|
||||||
|
psr_config->psr_sdp_transmit_line_num_deadline;
|
||||||
|
psr_context->psrFrameCaptureIndicationReq =
|
||||||
|
psr_config->psr_frame_capture_indication_req;
|
||||||
|
|
||||||
|
psr_context->skipPsrWaitForPllLock = 0; /* only = 1 in KV */
|
||||||
|
|
||||||
|
psr_context->numberOfControllers =
|
||||||
|
link->dc->res_pool->timing_generator_count;
|
||||||
|
|
||||||
|
psr_context->rfb_update_auto_en = true;
|
||||||
|
|
||||||
|
/* 2 frames before enter PSR. */
|
||||||
|
psr_context->timehyst_frames = 2;
|
||||||
|
/* half a frame
|
||||||
|
* (units in 100 lines, i.e. a value of 1 represents 100 lines)
|
||||||
|
*/
|
||||||
|
psr_context->hyst_lines = stream->timing.v_total / 2 / 100;
|
||||||
|
psr_context->aux_repeats = 10;
|
||||||
|
|
||||||
|
psr_context->psr_level.u32all = 0;
|
||||||
|
|
||||||
|
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
|
||||||
|
/*skip power down the single pipe since it blocks the cstate*/
|
||||||
|
if (ASICREV_IS_RAVEN(link->ctx->asic_id.hw_internal_rev))
|
||||||
|
psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* SMU will perform additional powerdown sequence.
|
||||||
|
* For unsupported ASICs, set psr_level flag to skip PSR
|
||||||
|
* static screen notification to SMU.
|
||||||
|
* (Always set for DAL2, did not check ASIC)
|
||||||
|
*/
|
||||||
|
psr_context->allow_smu_optimizations = psr_config->allow_smu_optimizations;
|
||||||
|
|
||||||
|
/* Complete PSR entry before aborting to prevent intermittent
|
||||||
|
* freezes on certain eDPs
|
||||||
|
*/
|
||||||
|
psr_context->psr_level.bits.DISABLE_PSR_ENTRY_ABORT = 1;
|
||||||
|
|
||||||
|
/* Controls additional delay after remote frame capture before
|
||||||
|
* continuing power down, default = 0
|
||||||
|
*/
|
||||||
|
psr_context->frame_delay = 0;
|
||||||
|
|
||||||
|
link->psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, psr_context);
|
||||||
|
|
||||||
|
/* psr_enabled == 0 indicates setup_psr did not succeed, but this
|
||||||
|
* should not happen since firmware should be running at this point
|
||||||
|
*/
|
||||||
|
if (link->psr_feature_enabled == 0)
|
||||||
|
ASSERT(0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
|
const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
|
||||||
{
|
{
|
||||||
return &link->link_status;
|
return &link->link_status;
|
||||||
@ -2842,6 +3027,15 @@ void core_link_enable_stream(
|
|||||||
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
|
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
|
||||||
COLOR_DEPTH_UNDEFINED);
|
COLOR_DEPTH_UNDEFINED);
|
||||||
|
|
||||||
|
/* This second call is needed to reconfigure the DIG
|
||||||
|
* as a workaround for the incorrect value being applied
|
||||||
|
* from transmitter control.
|
||||||
|
*/
|
||||||
|
if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
|
||||||
|
stream->link->link_enc->funcs->setup(
|
||||||
|
stream->link->link_enc,
|
||||||
|
pipe_ctx->stream->signal);
|
||||||
|
|
||||||
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
||||||
if (pipe_ctx->stream->timing.flags.DSC) {
|
if (pipe_ctx->stream->timing.flags.DSC) {
|
||||||
if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
|
if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
|
||||||
|
@ -374,6 +374,7 @@ void dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
|
|||||||
enum display_dongle_type *dongle = &sink_cap->dongle_type;
|
enum display_dongle_type *dongle = &sink_cap->dongle_type;
|
||||||
uint8_t type2_dongle_buf[DP_ADAPTOR_TYPE2_SIZE];
|
uint8_t type2_dongle_buf[DP_ADAPTOR_TYPE2_SIZE];
|
||||||
bool is_type2_dongle = false;
|
bool is_type2_dongle = false;
|
||||||
|
int retry_count = 2;
|
||||||
struct dp_hdmi_dongle_signature_data *dongle_signature;
|
struct dp_hdmi_dongle_signature_data *dongle_signature;
|
||||||
|
|
||||||
/* Assume we have no valid DP passive dongle connected */
|
/* Assume we have no valid DP passive dongle connected */
|
||||||
@ -386,13 +387,24 @@ void dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
|
|||||||
DP_HDMI_DONGLE_ADDRESS,
|
DP_HDMI_DONGLE_ADDRESS,
|
||||||
type2_dongle_buf,
|
type2_dongle_buf,
|
||||||
sizeof(type2_dongle_buf))) {
|
sizeof(type2_dongle_buf))) {
|
||||||
*dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
|
/* Passive HDMI dongles can sometimes fail here without retrying*/
|
||||||
sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
|
while (retry_count > 0) {
|
||||||
|
if (i2c_read(ddc,
|
||||||
|
DP_HDMI_DONGLE_ADDRESS,
|
||||||
|
type2_dongle_buf,
|
||||||
|
sizeof(type2_dongle_buf)))
|
||||||
|
break;
|
||||||
|
retry_count--;
|
||||||
|
}
|
||||||
|
if (retry_count == 0) {
|
||||||
|
*dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
|
||||||
|
sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
|
||||||
|
|
||||||
CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf),
|
CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf),
|
||||||
"DP-DVI passive dongle %dMhz: ",
|
"DP-DVI passive dongle %dMhz: ",
|
||||||
DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
|
DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if Type 2 dongle.*/
|
/* Check if Type 2 dongle.*/
|
||||||
|
@ -404,6 +404,9 @@ bool resource_are_streams_timing_synchronizable(
|
|||||||
if (stream1->view_format != stream2->view_format)
|
if (stream1->view_format != stream2->view_format)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (stream1->ignore_msa_timing_param || stream2->ignore_msa_timing_param)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static bool is_dp_and_hdmi_sharable(
|
static bool is_dp_and_hdmi_sharable(
|
||||||
@ -948,7 +951,7 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx)
|
|||||||
data->inits.v_c_bot = dc_fixpt_add(data->inits.v_c, data->ratios.vert_c);
|
data->inits.v_c_bot = dc_fixpt_add(data->inits.v_c, data->ratios.vert_c);
|
||||||
|
|
||||||
}
|
}
|
||||||
static bool are_rect_integer_multiples(struct rect src, struct rect dest)
|
static bool are_rects_integer_multiples(struct rect src, struct rect dest)
|
||||||
{
|
{
|
||||||
if (dest.width >= src.width && dest.width % src.width == 0 &&
|
if (dest.width >= src.width && dest.width % src.width == 0 &&
|
||||||
dest.height >= src.height && dest.height % src.height == 0)
|
dest.height >= src.height && dest.height % src.height == 0)
|
||||||
@ -956,6 +959,38 @@ static bool are_rect_integer_multiples(struct rect src, struct rect dest)
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void calculate_integer_scaling(struct pipe_ctx *pipe_ctx)
|
||||||
|
{
|
||||||
|
if (!pipe_ctx->plane_state->scaling_quality.integer_scaling)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//for Centered Mode
|
||||||
|
if (pipe_ctx->stream->dst.width == pipe_ctx->stream->src.width &&
|
||||||
|
pipe_ctx->stream->dst.height == pipe_ctx->stream->src.height) {
|
||||||
|
// calculate maximum # of replication of src onto addressable
|
||||||
|
unsigned int integer_multiple = min(
|
||||||
|
pipe_ctx->stream->timing.h_addressable / pipe_ctx->stream->src.width,
|
||||||
|
pipe_ctx->stream->timing.v_addressable / pipe_ctx->stream->src.height);
|
||||||
|
|
||||||
|
//scale dst
|
||||||
|
pipe_ctx->stream->dst.width = integer_multiple * pipe_ctx->stream->src.width;
|
||||||
|
pipe_ctx->stream->dst.height = integer_multiple * pipe_ctx->stream->src.height;
|
||||||
|
|
||||||
|
//center dst onto addressable
|
||||||
|
pipe_ctx->stream->dst.x = (pipe_ctx->stream->timing.h_addressable - pipe_ctx->stream->dst.width)/2;
|
||||||
|
pipe_ctx->stream->dst.y = (pipe_ctx->stream->timing.v_addressable - pipe_ctx->stream->dst.height)/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//disable taps if src & dst are integer ratio
|
||||||
|
if (are_rects_integer_multiples(pipe_ctx->stream->src, pipe_ctx->stream->dst)) {
|
||||||
|
pipe_ctx->plane_state->scaling_quality.v_taps = 1;
|
||||||
|
pipe_ctx->plane_state->scaling_quality.h_taps = 1;
|
||||||
|
pipe_ctx->plane_state->scaling_quality.v_taps_c = 1;
|
||||||
|
pipe_ctx->plane_state->scaling_quality.h_taps_c = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
||||||
{
|
{
|
||||||
const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
|
const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
|
||||||
@ -969,6 +1004,8 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
|||||||
pipe_ctx->plane_res.scl_data.format = convert_pixel_format_to_dalsurface(
|
pipe_ctx->plane_res.scl_data.format = convert_pixel_format_to_dalsurface(
|
||||||
pipe_ctx->plane_state->format);
|
pipe_ctx->plane_state->format);
|
||||||
|
|
||||||
|
calculate_integer_scaling(pipe_ctx);
|
||||||
|
|
||||||
calculate_scaling_ratios(pipe_ctx);
|
calculate_scaling_ratios(pipe_ctx);
|
||||||
|
|
||||||
calculate_viewport(pipe_ctx);
|
calculate_viewport(pipe_ctx);
|
||||||
@ -999,13 +1036,6 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
|||||||
res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
|
res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
|
||||||
pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
|
pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
|
||||||
|
|
||||||
if (res &&
|
|
||||||
plane_state->scaling_quality.integer_scaling &&
|
|
||||||
are_rect_integer_multiples(pipe_ctx->plane_res.scl_data.viewport,
|
|
||||||
pipe_ctx->plane_res.scl_data.recout)) {
|
|
||||||
pipe_ctx->plane_res.scl_data.taps.v_taps = 1;
|
|
||||||
pipe_ctx->plane_res.scl_data.taps.h_taps = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
/* Try 24 bpp linebuffer */
|
/* Try 24 bpp linebuffer */
|
||||||
@ -1540,6 +1570,9 @@ bool dc_is_stream_unchanged(
|
|||||||
if (!are_stream_backends_same(old_stream, stream))
|
if (!are_stream_backends_same(old_stream, stream))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (old_stream->ignore_msa_timing_param != stream->ignore_msa_timing_param)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1629,7 +1662,8 @@ static int acquire_first_free_pipe(
|
|||||||
static struct audio *find_first_free_audio(
|
static struct audio *find_first_free_audio(
|
||||||
struct resource_context *res_ctx,
|
struct resource_context *res_ctx,
|
||||||
const struct resource_pool *pool,
|
const struct resource_pool *pool,
|
||||||
enum engine_id id)
|
enum engine_id id,
|
||||||
|
enum dce_version dc_version)
|
||||||
{
|
{
|
||||||
int i, available_audio_count;
|
int i, available_audio_count;
|
||||||
|
|
||||||
@ -1965,7 +1999,7 @@ enum dc_status resource_map_pool_resources(
|
|||||||
dc_is_audio_capable_signal(pipe_ctx->stream->signal) &&
|
dc_is_audio_capable_signal(pipe_ctx->stream->signal) &&
|
||||||
stream->audio_info.mode_count && stream->audio_info.flags.all) {
|
stream->audio_info.mode_count && stream->audio_info.flags.all) {
|
||||||
pipe_ctx->stream_res.audio = find_first_free_audio(
|
pipe_ctx->stream_res.audio = find_first_free_audio(
|
||||||
&context->res_ctx, pool, pipe_ctx->stream_res.stream_enc->id);
|
&context->res_ctx, pool, pipe_ctx->stream_res.stream_enc->id, dc_ctx->dce_version);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Audio assigned in order first come first get.
|
* Audio assigned in order first come first get.
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
#include "inc/hw/dmcu.h"
|
#include "inc/hw/dmcu.h"
|
||||||
#include "dml/display_mode_lib.h"
|
#include "dml/display_mode_lib.h"
|
||||||
|
|
||||||
#define DC_VER "3.2.54"
|
#define DC_VER "3.2.56"
|
||||||
|
|
||||||
#define MAX_SURFACES 3
|
#define MAX_SURFACES 3
|
||||||
#define MAX_PLANES 6
|
#define MAX_PLANES 6
|
||||||
@ -220,6 +220,7 @@ struct dc_config {
|
|||||||
bool allow_seamless_boot_optimization;
|
bool allow_seamless_boot_optimization;
|
||||||
bool power_down_display_on_boot;
|
bool power_down_display_on_boot;
|
||||||
bool edp_not_connected;
|
bool edp_not_connected;
|
||||||
|
bool force_enum_edp;
|
||||||
bool forced_clocks;
|
bool forced_clocks;
|
||||||
bool disable_extended_timeout_support; // Used to disable extended timeout and lttpr feature as well
|
bool disable_extended_timeout_support; // Used to disable extended timeout and lttpr feature as well
|
||||||
bool multi_mon_pp_mclk_switch;
|
bool multi_mon_pp_mclk_switch;
|
||||||
@ -229,6 +230,7 @@ enum visual_confirm {
|
|||||||
VISUAL_CONFIRM_DISABLE = 0,
|
VISUAL_CONFIRM_DISABLE = 0,
|
||||||
VISUAL_CONFIRM_SURFACE = 1,
|
VISUAL_CONFIRM_SURFACE = 1,
|
||||||
VISUAL_CONFIRM_HDR = 2,
|
VISUAL_CONFIRM_HDR = 2,
|
||||||
|
VISUAL_CONFIRM_MPCTREE = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum dcc_option {
|
enum dcc_option {
|
||||||
@ -256,8 +258,9 @@ enum dtm_pstate{
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum dcn_pwr_state {
|
enum dcn_pwr_state {
|
||||||
DCN_PWR_STATE_OPTIMIZED = 0,
|
DCN_PWR_STATE_UNKNOWN = -1,
|
||||||
DCN_PWR_STATE_NORMAL = 1
|
DCN_PWR_STATE_MISSION_MODE = 0,
|
||||||
|
DCN_PWR_STATE_LOW_POWER = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -49,7 +49,8 @@ enum aux_channel_operation_result {
|
|||||||
AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN,
|
AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN,
|
||||||
AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY,
|
AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY,
|
||||||
AUX_CHANNEL_OPERATION_FAILED_TIMEOUT,
|
AUX_CHANNEL_OPERATION_FAILED_TIMEOUT,
|
||||||
AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON
|
AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON,
|
||||||
|
AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -404,6 +404,10 @@ static bool dce_abm_init_backlight(struct abm *abm)
|
|||||||
/* Enable the backlight output */
|
/* Enable the backlight output */
|
||||||
REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1);
|
REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1);
|
||||||
|
|
||||||
|
/* Disable fractional pwm if configured */
|
||||||
|
REG_UPDATE(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN,
|
||||||
|
abm->ctx->dc->config.disable_fractional_pwm ? 0 : 1);
|
||||||
|
|
||||||
/* Unlock group 2 backlight registers */
|
/* Unlock group 2 backlight registers */
|
||||||
REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
|
REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
|
||||||
BL_PWM_GRP1_REG_LOCK, 0);
|
BL_PWM_GRP1_REG_LOCK, 0);
|
||||||
|
@ -432,7 +432,6 @@ static bool dce_aux_configure_timeout(struct ddc_service *ddc,
|
|||||||
{
|
{
|
||||||
uint32_t multiplier = 0;
|
uint32_t multiplier = 0;
|
||||||
uint32_t length = 0;
|
uint32_t length = 0;
|
||||||
uint32_t timeout = 0;
|
|
||||||
struct ddc *ddc_pin = ddc->ddc_pin;
|
struct ddc *ddc_pin = ddc->ddc_pin;
|
||||||
struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
|
struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
|
||||||
struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(aux_engine);
|
struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(aux_engine);
|
||||||
@ -446,25 +445,21 @@ static bool dce_aux_configure_timeout(struct ddc_service *ddc,
|
|||||||
length = timeout_in_us/TIME_OUT_MULTIPLIER_8;
|
length = timeout_in_us/TIME_OUT_MULTIPLIER_8;
|
||||||
if (timeout_in_us % TIME_OUT_MULTIPLIER_8 != 0)
|
if (timeout_in_us % TIME_OUT_MULTIPLIER_8 != 0)
|
||||||
length++;
|
length++;
|
||||||
timeout = length * TIME_OUT_MULTIPLIER_8;
|
|
||||||
} else if (timeout_in_us <= 2 * TIME_OUT_INCREMENT) {
|
} else if (timeout_in_us <= 2 * TIME_OUT_INCREMENT) {
|
||||||
multiplier = 1;
|
multiplier = 1;
|
||||||
length = timeout_in_us/TIME_OUT_MULTIPLIER_16;
|
length = timeout_in_us/TIME_OUT_MULTIPLIER_16;
|
||||||
if (timeout_in_us % TIME_OUT_MULTIPLIER_16 != 0)
|
if (timeout_in_us % TIME_OUT_MULTIPLIER_16 != 0)
|
||||||
length++;
|
length++;
|
||||||
timeout = length * TIME_OUT_MULTIPLIER_16;
|
|
||||||
} else if (timeout_in_us <= 4 * TIME_OUT_INCREMENT) {
|
} else if (timeout_in_us <= 4 * TIME_OUT_INCREMENT) {
|
||||||
multiplier = 2;
|
multiplier = 2;
|
||||||
length = timeout_in_us/TIME_OUT_MULTIPLIER_32;
|
length = timeout_in_us/TIME_OUT_MULTIPLIER_32;
|
||||||
if (timeout_in_us % TIME_OUT_MULTIPLIER_32 != 0)
|
if (timeout_in_us % TIME_OUT_MULTIPLIER_32 != 0)
|
||||||
length++;
|
length++;
|
||||||
timeout = length * TIME_OUT_MULTIPLIER_32;
|
|
||||||
} else if (timeout_in_us > 4 * TIME_OUT_INCREMENT) {
|
} else if (timeout_in_us > 4 * TIME_OUT_INCREMENT) {
|
||||||
multiplier = 3;
|
multiplier = 3;
|
||||||
length = timeout_in_us/TIME_OUT_MULTIPLIER_64;
|
length = timeout_in_us/TIME_OUT_MULTIPLIER_64;
|
||||||
if (timeout_in_us % TIME_OUT_MULTIPLIER_64 != 0)
|
if (timeout_in_us % TIME_OUT_MULTIPLIER_64 != 0)
|
||||||
length++;
|
length++;
|
||||||
timeout = length * TIME_OUT_MULTIPLIER_64;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
length = (length < MAX_TIMEOUT_LENGTH) ? length : MAX_TIMEOUT_LENGTH;
|
length = (length < MAX_TIMEOUT_LENGTH) ? length : MAX_TIMEOUT_LENGTH;
|
||||||
@ -538,8 +533,10 @@ int dce_aux_transfer_raw(struct ddc_service *ddc,
|
|||||||
memset(&aux_rep, 0, sizeof(aux_rep));
|
memset(&aux_rep, 0, sizeof(aux_rep));
|
||||||
|
|
||||||
aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
|
aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
|
||||||
if (!acquire(aux_engine, ddc_pin))
|
if (!acquire(aux_engine, ddc_pin)) {
|
||||||
|
*operation_result = AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE;
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (payload->i2c_over_aux)
|
if (payload->i2c_over_aux)
|
||||||
aux_req.type = AUX_TRANSACTION_TYPE_I2C;
|
aux_req.type = AUX_TRANSACTION_TYPE_I2C;
|
||||||
@ -663,6 +660,7 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON:
|
case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON:
|
||||||
|
case AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE:
|
||||||
case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN:
|
case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN:
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -399,6 +399,37 @@ static const struct dc_plane_cap plane_cap = {
|
|||||||
#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
|
#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int map_transmitter_id_to_phy_instance(
|
||||||
|
enum transmitter transmitter)
|
||||||
|
{
|
||||||
|
switch (transmitter) {
|
||||||
|
case TRANSMITTER_UNIPHY_A:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_B:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_C:
|
||||||
|
return 2;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_D:
|
||||||
|
return 3;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_E:
|
||||||
|
return 4;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_F:
|
||||||
|
return 5;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_G:
|
||||||
|
return 6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void read_dce_straps(
|
static void read_dce_straps(
|
||||||
struct dc_context *ctx,
|
struct dc_context *ctx,
|
||||||
struct resource_straps *straps)
|
struct resource_straps *straps)
|
||||||
@ -579,14 +610,18 @@ struct link_encoder *dce100_link_encoder_create(
|
|||||||
{
|
{
|
||||||
struct dce110_link_encoder *enc110 =
|
struct dce110_link_encoder *enc110 =
|
||||||
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
|
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
|
||||||
|
int link_regs_id;
|
||||||
|
|
||||||
if (!enc110)
|
if (!enc110)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
link_regs_id =
|
||||||
|
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
|
||||||
|
|
||||||
dce110_link_encoder_construct(enc110,
|
dce110_link_encoder_construct(enc110,
|
||||||
enc_init_data,
|
enc_init_data,
|
||||||
&link_enc_feature,
|
&link_enc_feature,
|
||||||
&link_enc_regs[enc_init_data->transmitter],
|
&link_enc_regs[link_regs_id],
|
||||||
&link_enc_aux_regs[enc_init_data->channel - 1],
|
&link_enc_aux_regs[enc_init_data->channel - 1],
|
||||||
&link_enc_hpd_regs[enc_init_data->hpd_source]);
|
&link_enc_hpd_regs[enc_init_data->hpd_source]);
|
||||||
return &enc110->base;
|
return &enc110->base;
|
||||||
|
@ -1421,8 +1421,6 @@ static enum dc_status apply_single_controller_ctx_to_hw(
|
|||||||
static void power_down_encoders(struct dc *dc)
|
static void power_down_encoders(struct dc *dc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
enum connector_id connector_id;
|
|
||||||
enum signal_type signal = SIGNAL_TYPE_NONE;
|
|
||||||
|
|
||||||
/* do not know BIOS back-front mapping, simply blank all. It will not
|
/* do not know BIOS back-front mapping, simply blank all. It will not
|
||||||
* hurt for non-DP
|
* hurt for non-DP
|
||||||
@ -1433,15 +1431,12 @@ static void power_down_encoders(struct dc *dc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < dc->link_count; i++) {
|
for (i = 0; i < dc->link_count; i++) {
|
||||||
connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id);
|
enum signal_type signal = dc->links[i]->connector_signal;
|
||||||
if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) ||
|
|
||||||
(connector_id == CONNECTOR_ID_EDP)) {
|
|
||||||
|
|
||||||
|
if ((signal == SIGNAL_TYPE_EDP) ||
|
||||||
|
(signal == SIGNAL_TYPE_DISPLAY_PORT))
|
||||||
if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
|
if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
|
||||||
dp_receiver_power_ctrl(dc->links[i], false);
|
dp_receiver_power_ctrl(dc->links[i], false);
|
||||||
if (connector_id == CONNECTOR_ID_EDP)
|
|
||||||
signal = SIGNAL_TYPE_EDP;
|
|
||||||
}
|
|
||||||
|
|
||||||
dc->links[i]->link_enc->funcs->disable_output(
|
dc->links[i]->link_enc->funcs->disable_output(
|
||||||
dc->links[i]->link_enc, signal);
|
dc->links[i]->link_enc, signal);
|
||||||
|
@ -448,6 +448,37 @@ static const struct dc_plane_cap underlay_plane_cap = {
|
|||||||
#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
|
#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int map_transmitter_id_to_phy_instance(
|
||||||
|
enum transmitter transmitter)
|
||||||
|
{
|
||||||
|
switch (transmitter) {
|
||||||
|
case TRANSMITTER_UNIPHY_A:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_B:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_C:
|
||||||
|
return 2;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_D:
|
||||||
|
return 3;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_E:
|
||||||
|
return 4;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_F:
|
||||||
|
return 5;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_G:
|
||||||
|
return 6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void read_dce_straps(
|
static void read_dce_straps(
|
||||||
struct dc_context *ctx,
|
struct dc_context *ctx,
|
||||||
struct resource_straps *straps)
|
struct resource_straps *straps)
|
||||||
@ -625,14 +656,18 @@ static struct link_encoder *dce110_link_encoder_create(
|
|||||||
{
|
{
|
||||||
struct dce110_link_encoder *enc110 =
|
struct dce110_link_encoder *enc110 =
|
||||||
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
|
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
|
||||||
|
int link_regs_id;
|
||||||
|
|
||||||
if (!enc110)
|
if (!enc110)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
link_regs_id =
|
||||||
|
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
|
||||||
|
|
||||||
dce110_link_encoder_construct(enc110,
|
dce110_link_encoder_construct(enc110,
|
||||||
enc_init_data,
|
enc_init_data,
|
||||||
&link_enc_feature,
|
&link_enc_feature,
|
||||||
&link_enc_regs[enc_init_data->transmitter],
|
&link_enc_regs[link_regs_id],
|
||||||
&link_enc_aux_regs[enc_init_data->channel - 1],
|
&link_enc_aux_regs[enc_init_data->channel - 1],
|
||||||
&link_enc_hpd_regs[enc_init_data->hpd_source]);
|
&link_enc_hpd_regs[enc_init_data->hpd_source]);
|
||||||
return &enc110->base;
|
return &enc110->base;
|
||||||
|
@ -425,6 +425,37 @@ static const struct dc_plane_cap plane_cap = {
|
|||||||
#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
|
#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int map_transmitter_id_to_phy_instance(
|
||||||
|
enum transmitter transmitter)
|
||||||
|
{
|
||||||
|
switch (transmitter) {
|
||||||
|
case TRANSMITTER_UNIPHY_A:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_B:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_C:
|
||||||
|
return 2;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_D:
|
||||||
|
return 3;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_E:
|
||||||
|
return 4;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_F:
|
||||||
|
return 5;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_G:
|
||||||
|
return 6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void read_dce_straps(
|
static void read_dce_straps(
|
||||||
struct dc_context *ctx,
|
struct dc_context *ctx,
|
||||||
struct resource_straps *straps)
|
struct resource_straps *straps)
|
||||||
@ -583,14 +614,18 @@ struct link_encoder *dce112_link_encoder_create(
|
|||||||
{
|
{
|
||||||
struct dce110_link_encoder *enc110 =
|
struct dce110_link_encoder *enc110 =
|
||||||
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
|
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
|
||||||
|
int link_regs_id;
|
||||||
|
|
||||||
if (!enc110)
|
if (!enc110)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
link_regs_id =
|
||||||
|
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
|
||||||
|
|
||||||
dce110_link_encoder_construct(enc110,
|
dce110_link_encoder_construct(enc110,
|
||||||
enc_init_data,
|
enc_init_data,
|
||||||
&link_enc_feature,
|
&link_enc_feature,
|
||||||
&link_enc_regs[enc_init_data->transmitter],
|
&link_enc_regs[link_regs_id],
|
||||||
&link_enc_aux_regs[enc_init_data->channel - 1],
|
&link_enc_aux_regs[enc_init_data->channel - 1],
|
||||||
&link_enc_hpd_regs[enc_init_data->hpd_source]);
|
&link_enc_hpd_regs[enc_init_data->hpd_source]);
|
||||||
return &enc110->base;
|
return &enc110->base;
|
||||||
|
@ -364,6 +364,37 @@ static const struct dce_audio_mask audio_mask = {
|
|||||||
DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
|
DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int map_transmitter_id_to_phy_instance(
|
||||||
|
enum transmitter transmitter)
|
||||||
|
{
|
||||||
|
switch (transmitter) {
|
||||||
|
case TRANSMITTER_UNIPHY_A:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_B:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_C:
|
||||||
|
return 2;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_D:
|
||||||
|
return 3;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_E:
|
||||||
|
return 4;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_F:
|
||||||
|
return 5;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_G:
|
||||||
|
return 6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define clk_src_regs(index, id)\
|
#define clk_src_regs(index, id)\
|
||||||
[index] = {\
|
[index] = {\
|
||||||
CS_COMMON_REG_LIST_DCE_112(id),\
|
CS_COMMON_REG_LIST_DCE_112(id),\
|
||||||
@ -666,14 +697,18 @@ static struct link_encoder *dce120_link_encoder_create(
|
|||||||
{
|
{
|
||||||
struct dce110_link_encoder *enc110 =
|
struct dce110_link_encoder *enc110 =
|
||||||
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
|
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
|
||||||
|
int link_regs_id;
|
||||||
|
|
||||||
if (!enc110)
|
if (!enc110)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
link_regs_id =
|
||||||
|
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
|
||||||
|
|
||||||
dce110_link_encoder_construct(enc110,
|
dce110_link_encoder_construct(enc110,
|
||||||
enc_init_data,
|
enc_init_data,
|
||||||
&link_enc_feature,
|
&link_enc_feature,
|
||||||
&link_enc_regs[enc_init_data->transmitter],
|
&link_enc_regs[link_regs_id],
|
||||||
&link_enc_aux_regs[enc_init_data->channel - 1],
|
&link_enc_aux_regs[enc_init_data->channel - 1],
|
||||||
&link_enc_hpd_regs[enc_init_data->hpd_source]);
|
&link_enc_hpd_regs[enc_init_data->hpd_source]);
|
||||||
|
|
||||||
|
@ -439,6 +439,37 @@ static const struct dce_abm_mask abm_mask = {
|
|||||||
#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
|
#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int map_transmitter_id_to_phy_instance(
|
||||||
|
enum transmitter transmitter)
|
||||||
|
{
|
||||||
|
switch (transmitter) {
|
||||||
|
case TRANSMITTER_UNIPHY_A:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_B:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_C:
|
||||||
|
return 2;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_D:
|
||||||
|
return 3;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_E:
|
||||||
|
return 4;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_F:
|
||||||
|
return 5;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_G:
|
||||||
|
return 6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void read_dce_straps(
|
static void read_dce_straps(
|
||||||
struct dc_context *ctx,
|
struct dc_context *ctx,
|
||||||
struct resource_straps *straps)
|
struct resource_straps *straps)
|
||||||
@ -680,14 +711,18 @@ struct link_encoder *dce80_link_encoder_create(
|
|||||||
{
|
{
|
||||||
struct dce110_link_encoder *enc110 =
|
struct dce110_link_encoder *enc110 =
|
||||||
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
|
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
|
||||||
|
int link_regs_id;
|
||||||
|
|
||||||
if (!enc110)
|
if (!enc110)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
link_regs_id =
|
||||||
|
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
|
||||||
|
|
||||||
dce110_link_encoder_construct(enc110,
|
dce110_link_encoder_construct(enc110,
|
||||||
enc_init_data,
|
enc_init_data,
|
||||||
&link_enc_feature,
|
&link_enc_feature,
|
||||||
&link_enc_regs[enc_init_data->transmitter],
|
&link_enc_regs[link_regs_id],
|
||||||
&link_enc_aux_regs[enc_init_data->channel - 1],
|
&link_enc_aux_regs[enc_init_data->channel - 1],
|
||||||
&link_enc_hpd_regs[enc_init_data->hpd_source]);
|
&link_enc_hpd_regs[enc_init_data->hpd_source]);
|
||||||
return &enc110->base;
|
return &enc110->base;
|
||||||
|
@ -393,6 +393,10 @@ bool cm_helper_translate_curve_to_hw_format(
|
|||||||
rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
|
rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
|
||||||
rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
|
rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
|
||||||
|
|
||||||
|
rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red;
|
||||||
|
rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green;
|
||||||
|
rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue;
|
||||||
|
|
||||||
// All 3 color channels have same x
|
// All 3 color channels have same x
|
||||||
corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2),
|
corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2),
|
||||||
dc_fixpt_from_int(region_start));
|
dc_fixpt_from_int(region_start));
|
||||||
@ -464,13 +468,6 @@ bool cm_helper_translate_curve_to_hw_format(
|
|||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
while (i != hw_points + 1) {
|
while (i != hw_points + 1) {
|
||||||
if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
|
|
||||||
rgb_plus_1->red = rgb->red;
|
|
||||||
if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
|
|
||||||
rgb_plus_1->green = rgb->green;
|
|
||||||
if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
|
|
||||||
rgb_plus_1->blue = rgb->blue;
|
|
||||||
|
|
||||||
rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
|
rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
|
||||||
rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
|
rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
|
||||||
rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);
|
rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);
|
||||||
@ -562,6 +559,10 @@ bool cm_helper_translate_curve_to_degamma_hw_format(
|
|||||||
rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
|
rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
|
||||||
rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
|
rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
|
||||||
|
|
||||||
|
rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red;
|
||||||
|
rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green;
|
||||||
|
rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue;
|
||||||
|
|
||||||
corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2),
|
corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2),
|
||||||
dc_fixpt_from_int(region_start));
|
dc_fixpt_from_int(region_start));
|
||||||
corner_points[0].green.x = corner_points[0].red.x;
|
corner_points[0].green.x = corner_points[0].red.x;
|
||||||
@ -624,13 +625,6 @@ bool cm_helper_translate_curve_to_degamma_hw_format(
|
|||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
while (i != hw_points + 1) {
|
while (i != hw_points + 1) {
|
||||||
if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
|
|
||||||
rgb_plus_1->red = rgb->red;
|
|
||||||
if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
|
|
||||||
rgb_plus_1->green = rgb->green;
|
|
||||||
if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
|
|
||||||
rgb_plus_1->blue = rgb->blue;
|
|
||||||
|
|
||||||
rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
|
rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
|
||||||
rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
|
rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
|
||||||
rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);
|
rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);
|
||||||
|
@ -1304,6 +1304,10 @@ static void dcn10_init_hw(struct dc *dc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dc->hwss.enable_power_gating_plane(dc->hwseq, true);
|
dc->hwss.enable_power_gating_plane(dc->hwseq, true);
|
||||||
|
|
||||||
|
if (dc->clk_mgr->funcs->notify_wm_ranges)
|
||||||
|
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dcn10_reset_hw_ctx_wrap(
|
static void dcn10_reset_hw_ctx_wrap(
|
||||||
|
@ -479,6 +479,28 @@ static const struct dcn_hubbub_mask hubbub_mask = {
|
|||||||
HUBBUB_MASK_SH_LIST_DCN10(_MASK)
|
HUBBUB_MASK_SH_LIST_DCN10(_MASK)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int map_transmitter_id_to_phy_instance(
|
||||||
|
enum transmitter transmitter)
|
||||||
|
{
|
||||||
|
switch (transmitter) {
|
||||||
|
case TRANSMITTER_UNIPHY_A:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_B:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_C:
|
||||||
|
return 2;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_D:
|
||||||
|
return 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define clk_src_regs(index, pllid)\
|
#define clk_src_regs(index, pllid)\
|
||||||
[index] = {\
|
[index] = {\
|
||||||
CS_COMMON_REG_LIST_DCN1_0(index, pllid),\
|
CS_COMMON_REG_LIST_DCN1_0(index, pllid),\
|
||||||
@ -762,14 +784,18 @@ struct link_encoder *dcn10_link_encoder_create(
|
|||||||
{
|
{
|
||||||
struct dcn10_link_encoder *enc10 =
|
struct dcn10_link_encoder *enc10 =
|
||||||
kzalloc(sizeof(struct dcn10_link_encoder), GFP_KERNEL);
|
kzalloc(sizeof(struct dcn10_link_encoder), GFP_KERNEL);
|
||||||
|
int link_regs_id;
|
||||||
|
|
||||||
if (!enc10)
|
if (!enc10)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
link_regs_id =
|
||||||
|
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
|
||||||
|
|
||||||
dcn10_link_encoder_construct(enc10,
|
dcn10_link_encoder_construct(enc10,
|
||||||
enc_init_data,
|
enc_init_data,
|
||||||
&link_enc_feature,
|
&link_enc_feature,
|
||||||
&link_enc_regs[enc_init_data->transmitter],
|
&link_enc_regs[link_regs_id],
|
||||||
&link_enc_aux_regs[enc_init_data->channel - 1],
|
&link_enc_aux_regs[enc_init_data->channel - 1],
|
||||||
&link_enc_hpd_regs[enc_init_data->hpd_source],
|
&link_enc_hpd_regs[enc_init_data->hpd_source],
|
||||||
&le_shift,
|
&le_shift,
|
||||||
|
@ -1202,15 +1202,9 @@ static void dcn20_update_dchubp_dpp(
|
|||||||
struct dpp *dpp = pipe_ctx->plane_res.dpp;
|
struct dpp *dpp = pipe_ctx->plane_res.dpp;
|
||||||
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
|
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
|
||||||
|
|
||||||
if (pipe_ctx->update_flags.bits.dppclk) {
|
if (pipe_ctx->update_flags.bits.dppclk)
|
||||||
dpp->funcs->dpp_dppclk_control(dpp, false, true);
|
dpp->funcs->dpp_dppclk_control(dpp, false, true);
|
||||||
|
|
||||||
dc->res_pool->dccg->funcs->update_dpp_dto(
|
|
||||||
dc->res_pool->dccg,
|
|
||||||
dpp->inst,
|
|
||||||
pipe_ctx->plane_res.bw.dppclk_khz);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG
|
/* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG
|
||||||
* VTG is within DCHUBBUB which is commond block share by each pipe HUBP.
|
* VTG is within DCHUBBUB which is commond block share by each pipe HUBP.
|
||||||
* VTG is 1:1 mapping with OTG. Each pipe HUBP will select which VTG
|
* VTG is 1:1 mapping with OTG. Each pipe HUBP will select which VTG
|
||||||
@ -1996,6 +1990,28 @@ static void dcn20_reset_hw_ctx_wrap(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dcn20_get_mpctree_visual_confirm_color(
|
||||||
|
struct pipe_ctx *pipe_ctx,
|
||||||
|
struct tg_color *color)
|
||||||
|
{
|
||||||
|
const struct tg_color pipe_colors[6] = {
|
||||||
|
{MAX_TG_COLOR_VALUE, 0, 0}, // red
|
||||||
|
{MAX_TG_COLOR_VALUE, 0, MAX_TG_COLOR_VALUE}, // yellow
|
||||||
|
{0, MAX_TG_COLOR_VALUE, 0}, // blue
|
||||||
|
{MAX_TG_COLOR_VALUE / 2, 0, MAX_TG_COLOR_VALUE / 2}, // purple
|
||||||
|
{0, 0, MAX_TG_COLOR_VALUE}, // green
|
||||||
|
{MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE * 2 / 3, 0}, // orange
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pipe_ctx *top_pipe = pipe_ctx;
|
||||||
|
|
||||||
|
while (top_pipe->top_pipe) {
|
||||||
|
top_pipe = top_pipe->top_pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
*color = pipe_colors[top_pipe->pipe_idx];
|
||||||
|
}
|
||||||
|
|
||||||
static void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
static void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||||
{
|
{
|
||||||
struct hubp *hubp = pipe_ctx->plane_res.hubp;
|
struct hubp *hubp = pipe_ctx->plane_res.hubp;
|
||||||
@ -2013,6 +2029,9 @@ static void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
|||||||
} else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) {
|
} else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) {
|
||||||
dcn10_get_surface_visual_confirm_color(
|
dcn10_get_surface_visual_confirm_color(
|
||||||
pipe_ctx, &blnd_cfg.black_color);
|
pipe_ctx, &blnd_cfg.black_color);
|
||||||
|
} else if (dc->debug.visual_confirm == VISUAL_CONFIRM_MPCTREE) {
|
||||||
|
dcn20_get_mpctree_visual_confirm_color(
|
||||||
|
pipe_ctx, &blnd_cfg.black_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (per_pixel_alpha)
|
if (per_pixel_alpha)
|
||||||
|
@ -109,5 +109,7 @@ bool dcn20_set_blend_lut(
|
|||||||
struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state);
|
struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state);
|
||||||
bool dcn20_set_shaper_3dlut(
|
bool dcn20_set_shaper_3dlut(
|
||||||
struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state);
|
struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state);
|
||||||
|
void dcn20_get_mpctree_visual_confirm_color(
|
||||||
|
struct pipe_ctx *pipe_ctx,
|
||||||
|
struct tg_color *color);
|
||||||
#endif /* __DC_HWSS_DCN20_H__ */
|
#endif /* __DC_HWSS_DCN20_H__ */
|
||||||
|
@ -742,6 +742,33 @@ static const struct dce110_aux_registers_mask aux_mask = {
|
|||||||
DCN_AUX_MASK_SH_LIST(_MASK)
|
DCN_AUX_MASK_SH_LIST(_MASK)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int map_transmitter_id_to_phy_instance(
|
||||||
|
enum transmitter transmitter)
|
||||||
|
{
|
||||||
|
switch (transmitter) {
|
||||||
|
case TRANSMITTER_UNIPHY_A:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_B:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_C:
|
||||||
|
return 2;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_D:
|
||||||
|
return 3;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_E:
|
||||||
|
return 4;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_F:
|
||||||
|
return 5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
||||||
#define dsc_regsDCN20(id)\
|
#define dsc_regsDCN20(id)\
|
||||||
@ -825,7 +852,7 @@ static const struct resource_caps res_cap_nv14 = {
|
|||||||
.num_audio = 6,
|
.num_audio = 6,
|
||||||
.num_stream_encoder = 5,
|
.num_stream_encoder = 5,
|
||||||
.num_pll = 5,
|
.num_pll = 5,
|
||||||
.num_dwb = 0,
|
.num_dwb = 1,
|
||||||
.num_ddc = 5,
|
.num_ddc = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -836,7 +863,7 @@ static const struct dc_debug_options debug_defaults_drv = {
|
|||||||
.clock_trace = true,
|
.clock_trace = true,
|
||||||
.disable_pplib_clock_request = true,
|
.disable_pplib_clock_request = true,
|
||||||
.pipe_split_policy = MPC_SPLIT_DYNAMIC,
|
.pipe_split_policy = MPC_SPLIT_DYNAMIC,
|
||||||
.force_single_disp_pipe_split = true,
|
.force_single_disp_pipe_split = false,
|
||||||
.disable_dcc = DCC_ENABLE,
|
.disable_dcc = DCC_ENABLE,
|
||||||
.vsr_support = true,
|
.vsr_support = true,
|
||||||
.performance_trace = false,
|
.performance_trace = false,
|
||||||
@ -1056,14 +1083,18 @@ struct link_encoder *dcn20_link_encoder_create(
|
|||||||
{
|
{
|
||||||
struct dcn20_link_encoder *enc20 =
|
struct dcn20_link_encoder *enc20 =
|
||||||
kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
|
kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
|
||||||
|
int link_regs_id;
|
||||||
|
|
||||||
if (!enc20)
|
if (!enc20)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
link_regs_id =
|
||||||
|
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
|
||||||
|
|
||||||
dcn20_link_encoder_construct(enc20,
|
dcn20_link_encoder_construct(enc20,
|
||||||
enc_init_data,
|
enc_init_data,
|
||||||
&link_enc_feature,
|
&link_enc_feature,
|
||||||
&link_enc_regs[enc_init_data->transmitter],
|
&link_enc_regs[link_regs_id],
|
||||||
&link_enc_aux_regs[enc_init_data->channel - 1],
|
&link_enc_aux_regs[enc_init_data->channel - 1],
|
||||||
&link_enc_hpd_regs[enc_init_data->hpd_source],
|
&link_enc_hpd_regs[enc_init_data->hpd_source],
|
||||||
&le_shift,
|
&le_shift,
|
||||||
@ -1612,7 +1643,7 @@ static void swizzle_to_dml_params(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dcn20_split_stream_for_odm(
|
bool dcn20_split_stream_for_odm(
|
||||||
struct resource_context *res_ctx,
|
struct resource_context *res_ctx,
|
||||||
const struct resource_pool *pool,
|
const struct resource_pool *pool,
|
||||||
struct pipe_ctx *prev_odm_pipe,
|
struct pipe_ctx *prev_odm_pipe,
|
||||||
@ -1633,7 +1664,6 @@ static bool dcn20_split_stream_for_odm(
|
|||||||
next_odm_pipe->stream_res.dsc = NULL;
|
next_odm_pipe->stream_res.dsc = NULL;
|
||||||
#endif
|
#endif
|
||||||
if (prev_odm_pipe->next_odm_pipe && prev_odm_pipe->next_odm_pipe != next_odm_pipe) {
|
if (prev_odm_pipe->next_odm_pipe && prev_odm_pipe->next_odm_pipe != next_odm_pipe) {
|
||||||
ASSERT(!next_odm_pipe->next_odm_pipe);
|
|
||||||
next_odm_pipe->next_odm_pipe = prev_odm_pipe->next_odm_pipe;
|
next_odm_pipe->next_odm_pipe = prev_odm_pipe->next_odm_pipe;
|
||||||
next_odm_pipe->next_odm_pipe->prev_odm_pipe = next_odm_pipe;
|
next_odm_pipe->next_odm_pipe->prev_odm_pipe = next_odm_pipe;
|
||||||
}
|
}
|
||||||
@ -1690,7 +1720,7 @@ static bool dcn20_split_stream_for_odm(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dcn20_split_stream_for_mpc(
|
void dcn20_split_stream_for_mpc(
|
||||||
struct resource_context *res_ctx,
|
struct resource_context *res_ctx,
|
||||||
const struct resource_pool *pool,
|
const struct resource_pool *pool,
|
||||||
struct pipe_ctx *primary_pipe,
|
struct pipe_ctx *primary_pipe,
|
||||||
@ -2148,7 +2178,7 @@ void dcn20_set_mcif_arb_params(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
||||||
static bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
|
bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -2183,7 +2213,7 @@ static bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
|
struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
|
||||||
struct resource_context *res_ctx,
|
struct resource_context *res_ctx,
|
||||||
const struct resource_pool *pool,
|
const struct resource_pool *pool,
|
||||||
const struct pipe_ctx *primary_pipe)
|
const struct pipe_ctx *primary_pipe)
|
||||||
@ -2260,25 +2290,11 @@ static struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
|
|||||||
return secondary_pipe;
|
return secondary_pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dcn20_fast_validate_bw(
|
void dcn20_merge_pipes_for_validate(
|
||||||
struct dc *dc,
|
struct dc *dc,
|
||||||
struct dc_state *context,
|
struct dc_state *context)
|
||||||
display_e2e_pipe_params_st *pipes,
|
|
||||||
int *pipe_cnt_out,
|
|
||||||
int *pipe_split_from,
|
|
||||||
int *vlevel_out)
|
|
||||||
{
|
{
|
||||||
bool out = false;
|
int i;
|
||||||
|
|
||||||
int pipe_cnt, i, pipe_idx, vlevel, vlevel_unsplit;
|
|
||||||
bool force_split = false;
|
|
||||||
int split_threshold = dc->res_pool->pipe_count / 2;
|
|
||||||
bool avoid_split = dc->debug.pipe_split_policy != MPC_SPLIT_DYNAMIC;
|
|
||||||
|
|
||||||
|
|
||||||
ASSERT(pipes);
|
|
||||||
if (!pipes)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* merge previously split odm pipes since mode support needs to make the decision */
|
/* merge previously split odm pipes since mode support needs to make the decision */
|
||||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||||
@ -2333,35 +2349,19 @@ bool dcn20_fast_validate_bw(
|
|||||||
if (pipe->plane_state)
|
if (pipe->plane_state)
|
||||||
resource_build_scaling_params(pipe);
|
resource_build_scaling_params(pipe);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dc->res_pool->funcs->populate_dml_pipes)
|
int dcn20_validate_apply_pipe_split_flags(
|
||||||
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
|
struct dc *dc,
|
||||||
&context->res_ctx, pipes);
|
struct dc_state *context,
|
||||||
else
|
int vlevel,
|
||||||
pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
|
bool *split)
|
||||||
&context->res_ctx, pipes);
|
{
|
||||||
|
int i, pipe_idx, vlevel_split;
|
||||||
|
bool force_split = false;
|
||||||
|
bool avoid_split = dc->debug.pipe_split_policy != MPC_SPLIT_DYNAMIC;
|
||||||
|
|
||||||
*pipe_cnt_out = pipe_cnt;
|
/* Single display loop, exits if there is more than one display */
|
||||||
|
|
||||||
if (!pipe_cnt) {
|
|
||||||
out = true;
|
|
||||||
goto validate_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
|
|
||||||
|
|
||||||
if (vlevel > context->bw_ctx.dml.soc.num_states)
|
|
||||||
goto validate_fail;
|
|
||||||
|
|
||||||
if ((context->stream_count > split_threshold && dc->current_state->stream_count <= split_threshold)
|
|
||||||
|| (context->stream_count <= split_threshold && dc->current_state->stream_count > split_threshold))
|
|
||||||
context->commit_hints.full_update_needed = true;
|
|
||||||
|
|
||||||
/*initialize pipe_just_split_from to invalid idx*/
|
|
||||||
for (i = 0; i < MAX_PIPES; i++)
|
|
||||||
pipe_split_from[i] = -1;
|
|
||||||
|
|
||||||
/* Single display only conditionals get set here */
|
|
||||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||||
bool exit_loop = false;
|
bool exit_loop = false;
|
||||||
@ -2388,38 +2388,107 @@ bool dcn20_fast_validate_bw(
|
|||||||
if (exit_loop)
|
if (exit_loop)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* TODO: fix dc bugs and remove this split threshold thing */
|
||||||
if (context->stream_count > split_threshold)
|
if (context->stream_count > dc->res_pool->pipe_count / 2)
|
||||||
avoid_split = true;
|
avoid_split = true;
|
||||||
|
|
||||||
vlevel_unsplit = vlevel;
|
/* Avoid split loop looks for lowest voltage level that allows most unsplit pipes possible */
|
||||||
|
if (avoid_split) {
|
||||||
|
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
|
||||||
|
if (!context->res_ctx.pipe_ctx[i].stream)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (vlevel_split = vlevel; vlevel <= context->bw_ctx.dml.soc.num_states; vlevel++)
|
||||||
|
if (context->bw_ctx.dml.vba.NoOfDPP[vlevel][0][pipe_idx] == 1)
|
||||||
|
break;
|
||||||
|
/* Impossible to not split this pipe */
|
||||||
|
if (vlevel > context->bw_ctx.dml.soc.num_states)
|
||||||
|
vlevel = vlevel_split;
|
||||||
|
pipe_idx++;
|
||||||
|
}
|
||||||
|
context->bw_ctx.dml.vba.maxMpcComb = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Split loop sets which pipe should be split based on dml outputs and dc flags */
|
||||||
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
|
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
|
||||||
|
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||||
|
|
||||||
if (!context->res_ctx.pipe_ctx[i].stream)
|
if (!context->res_ctx.pipe_ctx[i].stream)
|
||||||
continue;
|
continue;
|
||||||
for (; vlevel_unsplit <= context->bw_ctx.dml.soc.num_states; vlevel_unsplit++)
|
|
||||||
if (context->bw_ctx.dml.vba.NoOfDPP[vlevel_unsplit][0][pipe_idx] == 1)
|
if (force_split || context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] > 1)
|
||||||
break;
|
split[i] = true;
|
||||||
|
if ((pipe->stream->view_format ==
|
||||||
|
VIEW_3D_FORMAT_SIDE_BY_SIDE ||
|
||||||
|
pipe->stream->view_format ==
|
||||||
|
VIEW_3D_FORMAT_TOP_AND_BOTTOM) &&
|
||||||
|
(pipe->stream->timing.timing_3d_format ==
|
||||||
|
TIMING_3D_FORMAT_TOP_AND_BOTTOM ||
|
||||||
|
pipe->stream->timing.timing_3d_format ==
|
||||||
|
TIMING_3D_FORMAT_SIDE_BY_SIDE))
|
||||||
|
split[i] = true;
|
||||||
|
if (dc->debug.force_odm_combine & (1 << pipe->stream_res.tg->inst)) {
|
||||||
|
split[i] = true;
|
||||||
|
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx] = true;
|
||||||
|
}
|
||||||
|
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx] =
|
||||||
|
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx];
|
||||||
|
/* Adjust dppclk when split is forced, do not bother with dispclk */
|
||||||
|
if (split[i] && context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 1)
|
||||||
|
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] /= 2;
|
||||||
pipe_idx++;
|
pipe_idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return vlevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dcn20_fast_validate_bw(
|
||||||
|
struct dc *dc,
|
||||||
|
struct dc_state *context,
|
||||||
|
display_e2e_pipe_params_st *pipes,
|
||||||
|
int *pipe_cnt_out,
|
||||||
|
int *pipe_split_from,
|
||||||
|
int *vlevel_out)
|
||||||
|
{
|
||||||
|
bool out = false;
|
||||||
|
bool split[MAX_PIPES] = { false };
|
||||||
|
int pipe_cnt, i, pipe_idx, vlevel;
|
||||||
|
|
||||||
|
ASSERT(pipes);
|
||||||
|
if (!pipes)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
dcn20_merge_pipes_for_validate(dc, context);
|
||||||
|
|
||||||
|
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, &context->res_ctx, pipes);
|
||||||
|
|
||||||
|
*pipe_cnt_out = pipe_cnt;
|
||||||
|
|
||||||
|
if (!pipe_cnt) {
|
||||||
|
out = true;
|
||||||
|
goto validate_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
|
||||||
|
|
||||||
|
if (vlevel > context->bw_ctx.dml.soc.num_states)
|
||||||
|
goto validate_fail;
|
||||||
|
|
||||||
|
vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split);
|
||||||
|
|
||||||
|
/*initialize pipe_just_split_from to invalid idx*/
|
||||||
|
for (i = 0; i < MAX_PIPES; i++)
|
||||||
|
pipe_split_from[i] = -1;
|
||||||
|
|
||||||
for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) {
|
for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) {
|
||||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||||
struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe;
|
struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe;
|
||||||
bool need_split = true;
|
|
||||||
bool need_split3d;
|
|
||||||
|
|
||||||
if (!pipe->stream || pipe_split_from[i] >= 0)
|
if (!pipe->stream || pipe_split_from[i] >= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pipe_idx++;
|
pipe_idx++;
|
||||||
|
|
||||||
if (dc->debug.force_odm_combine & (1 << pipe->stream_res.tg->inst)) {
|
|
||||||
force_split = true;
|
|
||||||
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx] = true;
|
|
||||||
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx] = true;
|
|
||||||
}
|
|
||||||
if (force_split && context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 1)
|
|
||||||
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] /= 2;
|
|
||||||
if (!pipe->top_pipe && !pipe->plane_state && context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) {
|
if (!pipe->top_pipe && !pipe->plane_state && context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) {
|
||||||
hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe);
|
hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe);
|
||||||
ASSERT(hsplit_pipe);
|
ASSERT(hsplit_pipe);
|
||||||
@ -2437,35 +2506,20 @@ bool dcn20_fast_validate_bw(
|
|||||||
if (pipe->top_pipe && pipe->plane_state == pipe->top_pipe->plane_state)
|
if (pipe->top_pipe && pipe->plane_state == pipe->top_pipe->plane_state)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
need_split3d = ((pipe->stream->view_format ==
|
|
||||||
VIEW_3D_FORMAT_SIDE_BY_SIDE ||
|
|
||||||
pipe->stream->view_format ==
|
|
||||||
VIEW_3D_FORMAT_TOP_AND_BOTTOM) &&
|
|
||||||
(pipe->stream->timing.timing_3d_format ==
|
|
||||||
TIMING_3D_FORMAT_TOP_AND_BOTTOM ||
|
|
||||||
pipe->stream->timing.timing_3d_format ==
|
|
||||||
TIMING_3D_FORMAT_SIDE_BY_SIDE));
|
|
||||||
|
|
||||||
if (avoid_split && vlevel_unsplit <= context->bw_ctx.dml.soc.num_states && !force_split && !need_split3d) {
|
|
||||||
need_split = false;
|
|
||||||
vlevel = vlevel_unsplit;
|
|
||||||
context->bw_ctx.dml.vba.maxMpcComb = 0;
|
|
||||||
} else
|
|
||||||
need_split = context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 2;
|
|
||||||
|
|
||||||
/* We do not support mpo + odm at the moment */
|
/* We do not support mpo + odm at the moment */
|
||||||
if (hsplit_pipe && hsplit_pipe->plane_state != pipe->plane_state
|
if (hsplit_pipe && hsplit_pipe->plane_state != pipe->plane_state
|
||||||
&& context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx])
|
&& context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx])
|
||||||
goto validate_fail;
|
goto validate_fail;
|
||||||
|
|
||||||
if (need_split3d || need_split || force_split) {
|
if (split[i]) {
|
||||||
if (!hsplit_pipe || hsplit_pipe->plane_state != pipe->plane_state) {
|
if (!hsplit_pipe || hsplit_pipe->plane_state != pipe->plane_state) {
|
||||||
/* pipe not split previously needs split */
|
/* pipe not split previously needs split */
|
||||||
hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe);
|
hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe);
|
||||||
ASSERT(hsplit_pipe || force_split);
|
ASSERT(hsplit_pipe);
|
||||||
if (!hsplit_pipe)
|
if (!hsplit_pipe) {
|
||||||
|
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] *= 2;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) {
|
if (context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) {
|
||||||
if (!dcn20_split_stream_for_odm(
|
if (!dcn20_split_stream_for_odm(
|
||||||
&context->res_ctx, dc->res_pool,
|
&context->res_ctx, dc->res_pool,
|
||||||
@ -2504,7 +2558,7 @@ validate_out:
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcn20_calculate_wm(
|
static void dcn20_calculate_wm(
|
||||||
struct dc *dc, struct dc_state *context,
|
struct dc *dc, struct dc_state *context,
|
||||||
display_e2e_pipe_params_st *pipes,
|
display_e2e_pipe_params_st *pipes,
|
||||||
int *out_pipe_cnt,
|
int *out_pipe_cnt,
|
||||||
@ -2525,7 +2579,7 @@ void dcn20_calculate_wm(
|
|||||||
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
|
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
|
||||||
if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
|
if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
|
||||||
pipes[pipe_cnt].pipe.dest.odm_combine =
|
pipes[pipe_cnt].pipe.dest.odm_combine =
|
||||||
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx];
|
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx];
|
||||||
else
|
else
|
||||||
pipes[pipe_cnt].pipe.dest.odm_combine = 0;
|
pipes[pipe_cnt].pipe.dest.odm_combine = 0;
|
||||||
pipe_idx++;
|
pipe_idx++;
|
||||||
@ -2534,7 +2588,7 @@ void dcn20_calculate_wm(
|
|||||||
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
|
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
|
||||||
if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
|
if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
|
||||||
pipes[pipe_cnt].pipe.dest.odm_combine =
|
pipes[pipe_cnt].pipe.dest.odm_combine =
|
||||||
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_split_from[i]];
|
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_split_from[i]];
|
||||||
else
|
else
|
||||||
pipes[pipe_cnt].pipe.dest.odm_combine = 0;
|
pipes[pipe_cnt].pipe.dest.odm_combine = 0;
|
||||||
}
|
}
|
||||||
@ -2580,6 +2634,7 @@ void dcn20_calculate_wm(
|
|||||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||||
context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
|
context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (vlevel < 2) {
|
if (vlevel < 2) {
|
||||||
@ -2905,6 +2960,7 @@ static struct resource_funcs dcn20_res_pool_funcs = {
|
|||||||
.populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context,
|
.populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context,
|
||||||
.get_default_swizzle_mode = dcn20_get_default_swizzle_mode,
|
.get_default_swizzle_mode = dcn20_get_default_swizzle_mode,
|
||||||
.set_mcif_arb_params = dcn20_set_mcif_arb_params,
|
.set_mcif_arb_params = dcn20_set_mcif_arb_params,
|
||||||
|
.populate_dml_pipes = dcn20_populate_dml_pipes_from_context,
|
||||||
.find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link
|
.find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2913,8 +2969,6 @@ bool dcn20_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)
|
|||||||
int i;
|
int i;
|
||||||
uint32_t pipe_count = pool->res_cap->num_dwb;
|
uint32_t pipe_count = pool->res_cap->num_dwb;
|
||||||
|
|
||||||
ASSERT(pipe_count > 0);
|
|
||||||
|
|
||||||
for (i = 0; i < pipe_count; i++) {
|
for (i = 0; i < pipe_count; i++) {
|
||||||
struct dcn20_dwbc *dwbc20 = kzalloc(sizeof(struct dcn20_dwbc),
|
struct dcn20_dwbc *dwbc20 = kzalloc(sizeof(struct dcn20_dwbc),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
@ -2983,7 +3037,7 @@ static void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cap_soc_clocks(
|
void dcn20_cap_soc_clocks(
|
||||||
struct _vcs_dpi_soc_bounding_box_st *bb,
|
struct _vcs_dpi_soc_bounding_box_st *bb,
|
||||||
struct pp_smu_nv_clock_table max_clocks)
|
struct pp_smu_nv_clock_table max_clocks)
|
||||||
{
|
{
|
||||||
@ -3050,7 +3104,7 @@ static void cap_soc_clocks(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
|
void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
|
||||||
struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states)
|
struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states)
|
||||||
{
|
{
|
||||||
struct _vcs_dpi_voltage_scaling_st calculated_states[MAX_CLOCK_LIMIT_STATES];
|
struct _vcs_dpi_voltage_scaling_st calculated_states[MAX_CLOCK_LIMIT_STATES];
|
||||||
@ -3065,10 +3119,14 @@ static void update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_
|
|||||||
|
|
||||||
if (dc->bb_overrides.min_dcfclk_mhz > 0)
|
if (dc->bb_overrides.min_dcfclk_mhz > 0)
|
||||||
min_dcfclk = dc->bb_overrides.min_dcfclk_mhz;
|
min_dcfclk = dc->bb_overrides.min_dcfclk_mhz;
|
||||||
else
|
else {
|
||||||
// Accounting for SOC/DCF relationship, we can go as high as
|
if (ASICREV_IS_NAVI12_P(dc->ctx->asic_id.hw_internal_rev))
|
||||||
// 506Mhz in Vmin. We need to code 507 since SMU will round down to 506.
|
min_dcfclk = 310;
|
||||||
min_dcfclk = 507;
|
else
|
||||||
|
// Accounting for SOC/DCF relationship, we can go as high as
|
||||||
|
// 506Mhz in Vmin.
|
||||||
|
min_dcfclk = 506;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_states; i++) {
|
for (i = 0; i < num_states; i++) {
|
||||||
int min_fclk_required_by_uclk;
|
int min_fclk_required_by_uclk;
|
||||||
@ -3108,7 +3166,7 @@ static void update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_
|
|||||||
bb->clock_limits[num_calculated_states].state = bb->num_states;
|
bb->clock_limits[num_calculated_states].state = bb->num_states;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
|
void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
|
||||||
{
|
{
|
||||||
kernel_fpu_begin();
|
kernel_fpu_begin();
|
||||||
if ((int)(bb->sr_exit_time_us * 1000) != dc->bb_overrides.sr_exit_time_ns
|
if ((int)(bb->sr_exit_time_us * 1000) != dc->bb_overrides.sr_exit_time_ns
|
||||||
@ -3307,14 +3365,14 @@ static bool init_soc_bounding_box(struct dc *dc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (clock_limits_available && uclk_states_available && num_states)
|
if (clock_limits_available && uclk_states_available && num_states)
|
||||||
update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states);
|
dcn20_update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states);
|
||||||
else if (clock_limits_available)
|
else if (clock_limits_available)
|
||||||
cap_soc_clocks(loaded_bb, max_clocks);
|
dcn20_cap_soc_clocks(loaded_bb, max_clocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator;
|
loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator;
|
||||||
loaded_ip->max_num_dpp = pool->base.pipe_count;
|
loaded_ip->max_num_dpp = pool->base.pipe_count;
|
||||||
patch_bounding_box(dc, loaded_bb);
|
dcn20_patch_bounding_box(dc, loaded_bb);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,12 @@ struct display_stream_compressor *dcn20_dsc_create(
|
|||||||
struct dc_context *ctx, uint32_t inst);
|
struct dc_context *ctx, uint32_t inst);
|
||||||
void dcn20_dsc_destroy(struct display_stream_compressor **dsc);
|
void dcn20_dsc_destroy(struct display_stream_compressor **dsc);
|
||||||
|
|
||||||
|
void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb);
|
||||||
|
void dcn20_cap_soc_clocks(
|
||||||
|
struct _vcs_dpi_soc_bounding_box_st *bb,
|
||||||
|
struct pp_smu_nv_clock_table max_clocks);
|
||||||
|
void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
|
||||||
|
struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states);
|
||||||
struct hubp *dcn20_hubp_create(
|
struct hubp *dcn20_hubp_create(
|
||||||
struct dc_context *ctx,
|
struct dc_context *ctx,
|
||||||
uint32_t inst);
|
uint32_t inst);
|
||||||
@ -113,6 +119,31 @@ void dcn20_set_mcif_arb_params(
|
|||||||
display_e2e_pipe_params_st *pipes,
|
display_e2e_pipe_params_st *pipes,
|
||||||
int pipe_cnt);
|
int pipe_cnt);
|
||||||
bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate);
|
bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate);
|
||||||
|
void dcn20_merge_pipes_for_validate(
|
||||||
|
struct dc *dc,
|
||||||
|
struct dc_state *context);
|
||||||
|
int dcn20_validate_apply_pipe_split_flags(
|
||||||
|
struct dc *dc,
|
||||||
|
struct dc_state *context,
|
||||||
|
int vlevel,
|
||||||
|
bool *split);
|
||||||
|
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
||||||
|
bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx);
|
||||||
|
#endif
|
||||||
|
void dcn20_split_stream_for_mpc(
|
||||||
|
struct resource_context *res_ctx,
|
||||||
|
const struct resource_pool *pool,
|
||||||
|
struct pipe_ctx *primary_pipe,
|
||||||
|
struct pipe_ctx *secondary_pipe);
|
||||||
|
bool dcn20_split_stream_for_odm(
|
||||||
|
struct resource_context *res_ctx,
|
||||||
|
const struct resource_pool *pool,
|
||||||
|
struct pipe_ctx *prev_odm_pipe,
|
||||||
|
struct pipe_ctx *next_odm_pipe);
|
||||||
|
struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
|
||||||
|
struct resource_context *res_ctx,
|
||||||
|
const struct resource_pool *pool,
|
||||||
|
const struct pipe_ctx *primary_pipe);
|
||||||
bool dcn20_fast_validate_bw(
|
bool dcn20_fast_validate_bw(
|
||||||
struct dc *dc,
|
struct dc *dc,
|
||||||
struct dc_state *context,
|
struct dc_state *context,
|
||||||
|
@ -83,8 +83,8 @@
|
|||||||
|
|
||||||
struct _vcs_dpi_ip_params_st dcn2_1_ip = {
|
struct _vcs_dpi_ip_params_st dcn2_1_ip = {
|
||||||
.odm_capable = 1,
|
.odm_capable = 1,
|
||||||
.gpuvm_enable = 0,
|
.gpuvm_enable = 1,
|
||||||
.hostvm_enable = 0,
|
.hostvm_enable = 1,
|
||||||
.gpuvm_max_page_table_levels = 1,
|
.gpuvm_max_page_table_levels = 1,
|
||||||
.hostvm_max_page_table_levels = 4,
|
.hostvm_max_page_table_levels = 4,
|
||||||
.hostvm_cached_page_table_levels = 2,
|
.hostvm_cached_page_table_levels = 2,
|
||||||
@ -669,6 +669,9 @@ static const struct dcn10_stream_encoder_mask se_mask = {
|
|||||||
|
|
||||||
static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu);
|
static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu);
|
||||||
|
|
||||||
|
static int dcn21_populate_dml_pipes_from_context(
|
||||||
|
struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes);
|
||||||
|
|
||||||
static struct input_pixel_processor *dcn21_ipp_create(
|
static struct input_pixel_processor *dcn21_ipp_create(
|
||||||
struct dc_context *ctx, uint32_t inst)
|
struct dc_context *ctx, uint32_t inst)
|
||||||
{
|
{
|
||||||
@ -833,7 +836,7 @@ static const struct dc_debug_options debug_defaults_drv = {
|
|||||||
.clock_trace = true,
|
.clock_trace = true,
|
||||||
.disable_pplib_clock_request = true,
|
.disable_pplib_clock_request = true,
|
||||||
.pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP,
|
.pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP,
|
||||||
.force_single_disp_pipe_split = true,
|
.force_single_disp_pipe_split = false,
|
||||||
.disable_dcc = DCC_ENABLE,
|
.disable_dcc = DCC_ENABLE,
|
||||||
.vsr_support = true,
|
.vsr_support = true,
|
||||||
.performance_trace = false,
|
.performance_trace = false,
|
||||||
@ -1006,6 +1009,7 @@ static void calculate_wm_set_for_vlevel(
|
|||||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||||
wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
|
wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
|
||||||
wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
|
wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
|
||||||
|
wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;
|
||||||
#endif
|
#endif
|
||||||
dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
|
dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
|
||||||
|
|
||||||
@ -1083,7 +1087,7 @@ void dcn21_calculate_wm(
|
|||||||
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
|
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
|
||||||
&context->res_ctx, pipes);
|
&context->res_ctx, pipes);
|
||||||
else
|
else
|
||||||
pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
|
pipe_cnt = dcn21_populate_dml_pipes_from_context(dc,
|
||||||
&context->res_ctx, pipes);
|
&context->res_ctx, pipes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1333,6 +1337,12 @@ struct display_stream_compressor *dcn21_dsc_create(
|
|||||||
|
|
||||||
static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
|
static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
TODO: Fix this function to calcualte correct values.
|
||||||
|
There are known issues with this function currently
|
||||||
|
that will need to be investigated. Use hardcoded known good values for now.
|
||||||
|
|
||||||
|
|
||||||
struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
|
struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
|
||||||
struct clk_limit_table *clk_table = &bw_params->clk_table;
|
struct clk_limit_table *clk_table = &bw_params->clk_table;
|
||||||
int i;
|
int i;
|
||||||
@ -1347,11 +1357,11 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
|
|||||||
dcn2_1_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
|
dcn2_1_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
|
||||||
dcn2_1_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
|
dcn2_1_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
|
||||||
dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
|
dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
|
||||||
/* This is probably wrong, TODO: find correct calculation */
|
|
||||||
dcn2_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 16 / 1000;
|
dcn2_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 16 / 1000;
|
||||||
}
|
}
|
||||||
dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - i];
|
dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - i];
|
||||||
dcn2_1_soc.num_states = i;
|
dcn2_1_soc.num_states = i;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Temporary Place holder until we can get them from fuse */
|
/* Temporary Place holder until we can get them from fuse */
|
||||||
@ -1552,19 +1562,48 @@ static const struct dcn10_link_enc_mask le_mask = {
|
|||||||
LINK_ENCODER_MASK_SH_LIST_DCN20(_MASK)
|
LINK_ENCODER_MASK_SH_LIST_DCN20(_MASK)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int map_transmitter_id_to_phy_instance(
|
||||||
|
enum transmitter transmitter)
|
||||||
|
{
|
||||||
|
switch (transmitter) {
|
||||||
|
case TRANSMITTER_UNIPHY_A:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_B:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_C:
|
||||||
|
return 2;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_D:
|
||||||
|
return 3;
|
||||||
|
break;
|
||||||
|
case TRANSMITTER_UNIPHY_E:
|
||||||
|
return 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct link_encoder *dcn21_link_encoder_create(
|
static struct link_encoder *dcn21_link_encoder_create(
|
||||||
const struct encoder_init_data *enc_init_data)
|
const struct encoder_init_data *enc_init_data)
|
||||||
{
|
{
|
||||||
struct dcn21_link_encoder *enc21 =
|
struct dcn21_link_encoder *enc21 =
|
||||||
kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL);
|
kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL);
|
||||||
|
int link_regs_id;
|
||||||
|
|
||||||
if (!enc21)
|
if (!enc21)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
link_regs_id =
|
||||||
|
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
|
||||||
|
|
||||||
dcn21_link_encoder_construct(enc21,
|
dcn21_link_encoder_construct(enc21,
|
||||||
enc_init_data,
|
enc_init_data,
|
||||||
&link_enc_feature,
|
&link_enc_feature,
|
||||||
&link_enc_regs[enc_init_data->transmitter],
|
&link_enc_regs[link_regs_id],
|
||||||
&link_enc_aux_regs[enc_init_data->channel - 1],
|
&link_enc_aux_regs[enc_init_data->channel - 1],
|
||||||
&link_enc_hpd_regs[enc_init_data->hpd_source],
|
&link_enc_hpd_regs[enc_init_data->hpd_source],
|
||||||
&le_shift,
|
&le_shift,
|
||||||
@ -1585,10 +1624,29 @@ static uint32_t read_pipe_fuses(struct dc_context *ctx)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dcn21_populate_dml_pipes_from_context(
|
||||||
|
struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes)
|
||||||
|
{
|
||||||
|
uint32_t pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, res_ctx, pipes);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||||
|
|
||||||
|
if (!res_ctx->pipe_ctx[i].stream)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pipes[i].pipe.src.hostvm = 1;
|
||||||
|
pipes[i].pipe.src.gpuvm = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pipe_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
static struct resource_funcs dcn21_res_pool_funcs = {
|
static struct resource_funcs dcn21_res_pool_funcs = {
|
||||||
.destroy = dcn21_destroy_resource_pool,
|
.destroy = dcn21_destroy_resource_pool,
|
||||||
.link_enc_create = dcn21_link_encoder_create,
|
.link_enc_create = dcn21_link_encoder_create,
|
||||||
.validate_bandwidth = dcn21_validate_bandwidth,
|
.validate_bandwidth = dcn21_validate_bandwidth,
|
||||||
|
.populate_dml_pipes = dcn21_populate_dml_pipes_from_context,
|
||||||
.add_stream_to_ctx = dcn20_add_stream_to_ctx,
|
.add_stream_to_ctx = dcn20_add_stream_to_ctx,
|
||||||
.remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
|
.remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
|
||||||
.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
|
.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
|
||||||
@ -1608,6 +1666,7 @@ static bool construct(
|
|||||||
struct dc_context *ctx = dc->ctx;
|
struct dc_context *ctx = dc->ctx;
|
||||||
struct irq_service_init_data init_data;
|
struct irq_service_init_data init_data;
|
||||||
uint32_t pipe_fuses = read_pipe_fuses(ctx);
|
uint32_t pipe_fuses = read_pipe_fuses(ctx);
|
||||||
|
uint32_t num_pipes;
|
||||||
|
|
||||||
ctx->dc_bios->regs = &bios_regs;
|
ctx->dc_bios->regs = &bios_regs;
|
||||||
|
|
||||||
@ -1721,6 +1780,14 @@ static bool construct(
|
|||||||
|
|
||||||
pool->base.pp_smu = dcn21_pp_smu_create(ctx);
|
pool->base.pp_smu = dcn21_pp_smu_create(ctx);
|
||||||
|
|
||||||
|
num_pipes = dcn2_1_ip.max_num_dpp;
|
||||||
|
|
||||||
|
for (i = 0; i < dcn2_1_ip.max_num_dpp; i++)
|
||||||
|
if (pipe_fuses & 1 << i)
|
||||||
|
num_pipes--;
|
||||||
|
dcn2_1_ip.max_num_dpp = num_pipes;
|
||||||
|
dcn2_1_ip.max_num_otg = num_pipes;
|
||||||
|
|
||||||
dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
|
dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
|
||||||
|
|
||||||
init_data.ctx = dc->ctx;
|
init_data.ctx = dc->ctx;
|
||||||
|
@ -251,8 +251,8 @@ struct pp_smu_funcs_nv {
|
|||||||
|
|
||||||
#define PP_SMU_NUM_SOCCLK_DPM_LEVELS 8
|
#define PP_SMU_NUM_SOCCLK_DPM_LEVELS 8
|
||||||
#define PP_SMU_NUM_DCFCLK_DPM_LEVELS 8
|
#define PP_SMU_NUM_DCFCLK_DPM_LEVELS 8
|
||||||
#define PP_SMU_NUM_FCLK_DPM_LEVELS 8
|
#define PP_SMU_NUM_FCLK_DPM_LEVELS 4
|
||||||
#define PP_SMU_NUM_MEMCLK_DPM_LEVELS 8
|
#define PP_SMU_NUM_MEMCLK_DPM_LEVELS 4
|
||||||
|
|
||||||
struct dpm_clock {
|
struct dpm_clock {
|
||||||
uint32_t Freq; // In MHz
|
uint32_t Freq; // In MHz
|
||||||
|
@ -2577,7 +2577,8 @@ static void dml20_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPer
|
|||||||
mode_lib->vba.MinActiveDRAMClockChangeMargin
|
mode_lib->vba.MinActiveDRAMClockChangeMargin
|
||||||
+ mode_lib->vba.DRAMClockChangeLatency;
|
+ mode_lib->vba.DRAMClockChangeLatency;
|
||||||
|
|
||||||
if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
|
if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 50) {
|
||||||
|
mode_lib->vba.DRAMClockChangeWatermark += 25;
|
||||||
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
|
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
|
||||||
} else {
|
} else {
|
||||||
if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
|
if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
|
||||||
|
@ -2611,7 +2611,8 @@ static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndP
|
|||||||
mode_lib->vba.MinActiveDRAMClockChangeMargin
|
mode_lib->vba.MinActiveDRAMClockChangeMargin
|
||||||
+ mode_lib->vba.DRAMClockChangeLatency;
|
+ mode_lib->vba.DRAMClockChangeLatency;
|
||||||
|
|
||||||
if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
|
if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 50) {
|
||||||
|
mode_lib->vba.DRAMClockChangeWatermark += 25;
|
||||||
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
|
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
|
||||||
} else {
|
} else {
|
||||||
if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
|
if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
|
||||||
|
@ -318,6 +318,7 @@ struct _vcs_dpi_display_pipe_dest_params_st {
|
|||||||
unsigned int vupdate_width;
|
unsigned int vupdate_width;
|
||||||
unsigned int vready_offset;
|
unsigned int vready_offset;
|
||||||
unsigned char interlaced;
|
unsigned char interlaced;
|
||||||
|
unsigned char embedded;
|
||||||
double pixel_rate_mhz;
|
double pixel_rate_mhz;
|
||||||
unsigned char synchronized_vblank_all_planes;
|
unsigned char synchronized_vblank_all_planes;
|
||||||
unsigned char otg_inst;
|
unsigned char otg_inst;
|
||||||
|
@ -375,6 +375,7 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib)
|
|||||||
|
|
||||||
mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
|
mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
|
||||||
|
|
||||||
|
mode_lib->vba.EmbeddedPanel[mode_lib->vba.NumberOfActivePlanes] = dst->embedded;
|
||||||
mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
|
mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
|
||||||
mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
|
mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
|
||||||
(enum scan_direction_class) (src->source_scan);
|
(enum scan_direction_class) (src->source_scan);
|
||||||
@ -432,6 +433,8 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib)
|
|||||||
dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
|
dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
|
||||||
mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
|
mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
|
||||||
dst->odm_combine;
|
dst->odm_combine;
|
||||||
|
mode_lib->vba.ODMCombineTypeEnabled[mode_lib->vba.NumberOfActivePlanes] =
|
||||||
|
dst->odm_combine;
|
||||||
mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
|
mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
|
||||||
(enum output_format_class) (dout->output_format);
|
(enum output_format_class) (dout->output_format);
|
||||||
mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] =
|
mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] =
|
||||||
|
@ -387,6 +387,7 @@ struct vba_vars_st {
|
|||||||
|
|
||||||
/* vba mode support */
|
/* vba mode support */
|
||||||
/*inputs*/
|
/*inputs*/
|
||||||
|
bool EmbeddedPanel[DC__NUM_DPP__MAX];
|
||||||
bool SupportGFX7CompatibleTilingIn32bppAnd64bpp;
|
bool SupportGFX7CompatibleTilingIn32bppAnd64bpp;
|
||||||
double MaxHSCLRatio;
|
double MaxHSCLRatio;
|
||||||
double MaxVSCLRatio;
|
double MaxVSCLRatio;
|
||||||
|
@ -174,9 +174,7 @@ static bool hdmi_14_process_transaction(
|
|||||||
link->ctx,
|
link->ctx,
|
||||||
link,
|
link,
|
||||||
&i2c_command);
|
&i2c_command);
|
||||||
|
kfree(buff);
|
||||||
if (buff)
|
|
||||||
kfree(buff);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -398,10 +398,6 @@ struct dc_state {
|
|||||||
|
|
||||||
struct clk_mgr *clk_mgr;
|
struct clk_mgr *clk_mgr;
|
||||||
|
|
||||||
struct {
|
|
||||||
bool full_update_needed : 1;
|
|
||||||
} commit_hints;
|
|
||||||
|
|
||||||
struct kref refcount;
|
struct kref refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -149,7 +149,6 @@ struct wm_table {
|
|||||||
struct clk_bw_params {
|
struct clk_bw_params {
|
||||||
unsigned int vram_type;
|
unsigned int vram_type;
|
||||||
unsigned int num_channels;
|
unsigned int num_channels;
|
||||||
unsigned int dispclk_vco_khz;
|
|
||||||
struct clk_limit_table clk_table;
|
struct clk_limit_table clk_table;
|
||||||
struct wm_table wm_table;
|
struct wm_table wm_table;
|
||||||
};
|
};
|
||||||
@ -184,6 +183,7 @@ struct clk_mgr_funcs {
|
|||||||
|
|
||||||
bool (*are_clock_states_equal) (struct dc_clocks *a,
|
bool (*are_clock_states_equal) (struct dc_clocks *a,
|
||||||
struct dc_clocks *b);
|
struct dc_clocks *b);
|
||||||
|
void (*notify_wm_ranges)(struct clk_mgr *clk_mgr);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct clk_mgr {
|
struct clk_mgr {
|
||||||
@ -192,6 +192,7 @@ struct clk_mgr {
|
|||||||
struct dc_clocks clks;
|
struct dc_clocks clks;
|
||||||
bool psr_allow_active_cache;
|
bool psr_allow_active_cache;
|
||||||
int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes
|
int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes
|
||||||
|
int dentist_vco_freq_khz;
|
||||||
#ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
#ifdef CONFIG_DRM_AMD_DC_DCN2_1
|
||||||
struct clk_bw_params *bw_params;
|
struct clk_bw_params *bw_params;
|
||||||
#endif
|
#endif
|
||||||
|
@ -225,8 +225,6 @@ struct clk_mgr_internal {
|
|||||||
struct state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES];
|
struct state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES];
|
||||||
|
|
||||||
/*TODO: figure out which of the below fields should be here vs in asic specific portion */
|
/*TODO: figure out which of the below fields should be here vs in asic specific portion */
|
||||||
int dentist_vco_freq_khz;
|
|
||||||
|
|
||||||
/* Cache the status of DFS-bypass feature*/
|
/* Cache the status of DFS-bypass feature*/
|
||||||
bool dfs_bypass_enabled;
|
bool dfs_bypass_enabled;
|
||||||
/* True if the DFS-bypass feature is enabled and active. */
|
/* True if the DFS-bypass feature is enabled and active. */
|
||||||
|
@ -373,7 +373,42 @@ static struct fixed31_32 translate_from_linear_space(
|
|||||||
return dc_fixpt_mul(args->arg, args->a1);
|
return dc_fixpt_mul(args->arg, args->a1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct fixed31_32 calculate_gamma22(struct fixed31_32 arg)
|
|
||||||
|
static struct fixed31_32 translate_from_linear_space_long(
|
||||||
|
struct translate_from_linear_space_args *args)
|
||||||
|
{
|
||||||
|
const struct fixed31_32 one = dc_fixpt_from_int(1);
|
||||||
|
|
||||||
|
if (dc_fixpt_lt(one, args->arg))
|
||||||
|
return one;
|
||||||
|
|
||||||
|
if (dc_fixpt_le(args->arg, dc_fixpt_neg(args->a0)))
|
||||||
|
return dc_fixpt_sub(
|
||||||
|
args->a2,
|
||||||
|
dc_fixpt_mul(
|
||||||
|
dc_fixpt_add(
|
||||||
|
one,
|
||||||
|
args->a3),
|
||||||
|
dc_fixpt_pow(
|
||||||
|
dc_fixpt_neg(args->arg),
|
||||||
|
dc_fixpt_recip(args->gamma))));
|
||||||
|
else if (dc_fixpt_le(args->a0, args->arg))
|
||||||
|
return dc_fixpt_sub(
|
||||||
|
dc_fixpt_mul(
|
||||||
|
dc_fixpt_add(
|
||||||
|
one,
|
||||||
|
args->a3),
|
||||||
|
dc_fixpt_pow(
|
||||||
|
args->arg,
|
||||||
|
dc_fixpt_recip(args->gamma))),
|
||||||
|
args->a2);
|
||||||
|
else
|
||||||
|
return dc_fixpt_mul(
|
||||||
|
args->arg,
|
||||||
|
args->a1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct fixed31_32 calculate_gamma22(struct fixed31_32 arg, bool use_eetf)
|
||||||
{
|
{
|
||||||
struct fixed31_32 gamma = dc_fixpt_from_fraction(22, 10);
|
struct fixed31_32 gamma = dc_fixpt_from_fraction(22, 10);
|
||||||
|
|
||||||
@ -384,9 +419,13 @@ static struct fixed31_32 calculate_gamma22(struct fixed31_32 arg)
|
|||||||
scratch_gamma_args.a3 = dc_fixpt_zero;
|
scratch_gamma_args.a3 = dc_fixpt_zero;
|
||||||
scratch_gamma_args.gamma = gamma;
|
scratch_gamma_args.gamma = gamma;
|
||||||
|
|
||||||
|
if (use_eetf)
|
||||||
|
return translate_from_linear_space_long(&scratch_gamma_args);
|
||||||
|
|
||||||
return translate_from_linear_space(&scratch_gamma_args);
|
return translate_from_linear_space(&scratch_gamma_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct fixed31_32 translate_to_linear_space(
|
static struct fixed31_32 translate_to_linear_space(
|
||||||
struct fixed31_32 arg,
|
struct fixed31_32 arg,
|
||||||
struct fixed31_32 a0,
|
struct fixed31_32 a0,
|
||||||
@ -920,11 +959,7 @@ static bool build_freesync_hdr(struct pwl_float_data_ex *rgb_regamma,
|
|||||||
if (fs_params->max_display < 100) // cap at 100 at the top
|
if (fs_params->max_display < 100) // cap at 100 at the top
|
||||||
max_display = dc_fixpt_from_int(100);
|
max_display = dc_fixpt_from_int(100);
|
||||||
|
|
||||||
if (fs_params->min_content < fs_params->min_display)
|
// only max used, we don't adjust min luminance
|
||||||
use_eetf = true;
|
|
||||||
else
|
|
||||||
min_content = min_display;
|
|
||||||
|
|
||||||
if (fs_params->max_content > fs_params->max_display)
|
if (fs_params->max_content > fs_params->max_display)
|
||||||
use_eetf = true;
|
use_eetf = true;
|
||||||
else
|
else
|
||||||
@ -950,7 +985,7 @@ static bool build_freesync_hdr(struct pwl_float_data_ex *rgb_regamma,
|
|||||||
if (dc_fixpt_lt(scaledX, dc_fixpt_zero))
|
if (dc_fixpt_lt(scaledX, dc_fixpt_zero))
|
||||||
output = dc_fixpt_zero;
|
output = dc_fixpt_zero;
|
||||||
else
|
else
|
||||||
output = calculate_gamma22(scaledX);
|
output = calculate_gamma22(scaledX, use_eetf);
|
||||||
|
|
||||||
rgb->r = output;
|
rgb->r = output;
|
||||||
rgb->g = output;
|
rgb->g = output;
|
||||||
@ -2173,5 +2208,3 @@ bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans,
|
|||||||
rgb_degamma_alloc_fail:
|
rgb_degamma_alloc_fail:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,6 +143,8 @@ enum PP_FEATURE_MASK {
|
|||||||
enum DC_FEATURE_MASK {
|
enum DC_FEATURE_MASK {
|
||||||
DC_FBC_MASK = 0x1,
|
DC_FBC_MASK = 0x1,
|
||||||
DC_MULTI_MON_PP_MCLK_SWITCH_MASK = 0x2,
|
DC_MULTI_MON_PP_MCLK_SWITCH_MASK = 0x2,
|
||||||
|
DC_DISABLE_FRACTIONAL_PWM_MASK = 0x4,
|
||||||
|
DC_PSR_MASK = 0x8,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum amd_dpm_forced_level;
|
enum amd_dpm_forced_level;
|
||||||
|
@ -24,6 +24,18 @@
|
|||||||
|
|
||||||
// addressBlock: uvd0_mmsch_dec
|
// addressBlock: uvd0_mmsch_dec
|
||||||
// base address: 0x1e000
|
// base address: 0x1e000
|
||||||
|
#define mmMMSCH_VF_VMID 0x000b
|
||||||
|
#define mmMMSCH_VF_VMID_BASE_IDX 0
|
||||||
|
#define mmMMSCH_VF_CTX_ADDR_LO 0x000c
|
||||||
|
#define mmMMSCH_VF_CTX_ADDR_LO_BASE_IDX 0
|
||||||
|
#define mmMMSCH_VF_CTX_ADDR_HI 0x000d
|
||||||
|
#define mmMMSCH_VF_CTX_ADDR_HI_BASE_IDX 0
|
||||||
|
#define mmMMSCH_VF_CTX_SIZE 0x000e
|
||||||
|
#define mmMMSCH_VF_CTX_SIZE_BASE_IDX 0
|
||||||
|
#define mmMMSCH_VF_MAILBOX_HOST 0x0012
|
||||||
|
#define mmMMSCH_VF_MAILBOX_HOST_BASE_IDX 0
|
||||||
|
#define mmMMSCH_VF_MAILBOX_RESP 0x0013
|
||||||
|
#define mmMMSCH_VF_MAILBOX_RESP_BASE_IDX 0
|
||||||
|
|
||||||
|
|
||||||
// addressBlock: uvd0_jpegnpdec
|
// addressBlock: uvd0_jpegnpdec
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -25,6 +25,7 @@
|
|||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
#include "amdgpu.h"
|
#include "amdgpu.h"
|
||||||
#include "amdgpu_smu.h"
|
#include "amdgpu_smu.h"
|
||||||
|
#include "smu_internal.h"
|
||||||
#include "atomfirmware.h"
|
#include "atomfirmware.h"
|
||||||
#include "amdgpu_atomfirmware.h"
|
#include "amdgpu_atomfirmware.h"
|
||||||
#include "smu_v11_0.h"
|
#include "smu_v11_0.h"
|
||||||
@ -36,6 +37,12 @@
|
|||||||
#include "smu_v11_0_pptable.h"
|
#include "smu_v11_0_pptable.h"
|
||||||
#include "arcturus_ppsmc.h"
|
#include "arcturus_ppsmc.h"
|
||||||
#include "nbio/nbio_7_4_sh_mask.h"
|
#include "nbio/nbio_7_4_sh_mask.h"
|
||||||
|
#include "amdgpu_xgmi.h"
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include "amdgpu_ras.h"
|
||||||
|
|
||||||
|
#define to_amdgpu_device(x) (container_of(x, struct amdgpu_ras, eeprom_control.eeprom_accessor))->adev
|
||||||
|
|
||||||
#define CTF_OFFSET_EDGE 5
|
#define CTF_OFFSET_EDGE 5
|
||||||
#define CTF_OFFSET_HOTSPOT 5
|
#define CTF_OFFSET_HOTSPOT 5
|
||||||
@ -171,6 +178,7 @@ static struct smu_11_0_cmn2aisc_mapping arcturus_table_map[SMU_TABLE_COUNT] = {
|
|||||||
TAB_MAP(SMU_METRICS),
|
TAB_MAP(SMU_METRICS),
|
||||||
TAB_MAP(DRIVER_SMU_CONFIG),
|
TAB_MAP(DRIVER_SMU_CONFIG),
|
||||||
TAB_MAP(OVERDRIVE),
|
TAB_MAP(OVERDRIVE),
|
||||||
|
TAB_MAP(I2C_COMMANDS),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct smu_11_0_cmn2aisc_mapping arcturus_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
|
static struct smu_11_0_cmn2aisc_mapping arcturus_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
|
||||||
@ -293,6 +301,9 @@ static int arcturus_tables_init(struct smu_context *smu, struct smu_table *table
|
|||||||
SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
|
SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
|
||||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
|
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
|
||||||
|
|
||||||
|
SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t),
|
||||||
|
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
|
||||||
|
|
||||||
smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
|
smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
|
||||||
if (!smu_table->metrics_table)
|
if (!smu_table->metrics_table)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -617,12 +628,17 @@ static int arcturus_print_clk_levels(struct smu_context *smu,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For DPM disabled case, there will be only one clock level.
|
||||||
|
* And it's safe to assume that is always the current clock.
|
||||||
|
*/
|
||||||
for (i = 0; i < clocks.num_levels; i++)
|
for (i = 0; i < clocks.num_levels; i++)
|
||||||
size += sprintf(buf + size, "%d: %uMhz %s\n", i,
|
size += sprintf(buf + size, "%d: %uMhz %s\n", i,
|
||||||
clocks.data[i].clocks_in_khz / 1000,
|
clocks.data[i].clocks_in_khz / 1000,
|
||||||
arcturus_freqs_in_same_level(
|
(clocks.num_levels == 1) ? "*" :
|
||||||
|
(arcturus_freqs_in_same_level(
|
||||||
clocks.data[i].clocks_in_khz / 1000,
|
clocks.data[i].clocks_in_khz / 1000,
|
||||||
now / 100) ? "*" : "");
|
now / 100) ? "*" : ""));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SMU_MCLK:
|
case SMU_MCLK:
|
||||||
@ -642,9 +658,10 @@ static int arcturus_print_clk_levels(struct smu_context *smu,
|
|||||||
for (i = 0; i < clocks.num_levels; i++)
|
for (i = 0; i < clocks.num_levels; i++)
|
||||||
size += sprintf(buf + size, "%d: %uMhz %s\n",
|
size += sprintf(buf + size, "%d: %uMhz %s\n",
|
||||||
i, clocks.data[i].clocks_in_khz / 1000,
|
i, clocks.data[i].clocks_in_khz / 1000,
|
||||||
arcturus_freqs_in_same_level(
|
(clocks.num_levels == 1) ? "*" :
|
||||||
|
(arcturus_freqs_in_same_level(
|
||||||
clocks.data[i].clocks_in_khz / 1000,
|
clocks.data[i].clocks_in_khz / 1000,
|
||||||
now / 100) ? "*" : "");
|
now / 100) ? "*" : ""));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SMU_SOCCLK:
|
case SMU_SOCCLK:
|
||||||
@ -664,9 +681,10 @@ static int arcturus_print_clk_levels(struct smu_context *smu,
|
|||||||
for (i = 0; i < clocks.num_levels; i++)
|
for (i = 0; i < clocks.num_levels; i++)
|
||||||
size += sprintf(buf + size, "%d: %uMhz %s\n",
|
size += sprintf(buf + size, "%d: %uMhz %s\n",
|
||||||
i, clocks.data[i].clocks_in_khz / 1000,
|
i, clocks.data[i].clocks_in_khz / 1000,
|
||||||
arcturus_freqs_in_same_level(
|
(clocks.num_levels == 1) ? "*" :
|
||||||
|
(arcturus_freqs_in_same_level(
|
||||||
clocks.data[i].clocks_in_khz / 1000,
|
clocks.data[i].clocks_in_khz / 1000,
|
||||||
now / 100) ? "*" : "");
|
now / 100) ? "*" : ""));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SMU_FCLK:
|
case SMU_FCLK:
|
||||||
@ -686,9 +704,10 @@ static int arcturus_print_clk_levels(struct smu_context *smu,
|
|||||||
for (i = 0; i < single_dpm_table->count; i++)
|
for (i = 0; i < single_dpm_table->count; i++)
|
||||||
size += sprintf(buf + size, "%d: %uMhz %s\n",
|
size += sprintf(buf + size, "%d: %uMhz %s\n",
|
||||||
i, single_dpm_table->dpm_levels[i].value,
|
i, single_dpm_table->dpm_levels[i].value,
|
||||||
arcturus_freqs_in_same_level(
|
(clocks.num_levels == 1) ? "*" :
|
||||||
|
(arcturus_freqs_in_same_level(
|
||||||
clocks.data[i].clocks_in_khz / 1000,
|
clocks.data[i].clocks_in_khz / 1000,
|
||||||
now / 100) ? "*" : "");
|
now / 100) ? "*" : ""));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -763,8 +782,6 @@ static int arcturus_force_clk_levels(struct smu_context *smu,
|
|||||||
uint32_t soft_min_level, soft_max_level;
|
uint32_t soft_min_level, soft_max_level;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(&(smu->mutex));
|
|
||||||
|
|
||||||
soft_min_level = mask ? (ffs(mask) - 1) : 0;
|
soft_min_level = mask ? (ffs(mask) - 1) : 0;
|
||||||
soft_max_level = mask ? (fls(mask) - 1) : 0;
|
soft_max_level = mask ? (fls(mask) - 1) : 0;
|
||||||
|
|
||||||
@ -799,91 +816,19 @@ static int arcturus_force_clk_levels(struct smu_context *smu,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SMU_MCLK:
|
case SMU_MCLK:
|
||||||
single_dpm_table = &(dpm_table->mem_table);
|
|
||||||
|
|
||||||
if (soft_max_level >= single_dpm_table->count) {
|
|
||||||
pr_err("Clock level specified %d is over max allowed %d\n",
|
|
||||||
soft_max_level, single_dpm_table->count - 1);
|
|
||||||
ret = -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
single_dpm_table->dpm_state.soft_min_level =
|
|
||||||
single_dpm_table->dpm_levels[soft_min_level].value;
|
|
||||||
single_dpm_table->dpm_state.soft_max_level =
|
|
||||||
single_dpm_table->dpm_levels[soft_max_level].value;
|
|
||||||
|
|
||||||
ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_UCLK_MASK);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("Failed to upload boot level to lowest!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_UCLK_MASK);
|
|
||||||
if (ret)
|
|
||||||
pr_err("Failed to upload dpm max level to highest!\n");
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SMU_SOCCLK:
|
case SMU_SOCCLK:
|
||||||
single_dpm_table = &(dpm_table->soc_table);
|
|
||||||
|
|
||||||
if (soft_max_level >= single_dpm_table->count) {
|
|
||||||
pr_err("Clock level specified %d is over max allowed %d\n",
|
|
||||||
soft_max_level, single_dpm_table->count - 1);
|
|
||||||
ret = -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
single_dpm_table->dpm_state.soft_min_level =
|
|
||||||
single_dpm_table->dpm_levels[soft_min_level].value;
|
|
||||||
single_dpm_table->dpm_state.soft_max_level =
|
|
||||||
single_dpm_table->dpm_levels[soft_max_level].value;
|
|
||||||
|
|
||||||
ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_SOCCLK_MASK);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("Failed to upload boot level to lowest!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_SOCCLK_MASK);
|
|
||||||
if (ret)
|
|
||||||
pr_err("Failed to upload dpm max level to highest!\n");
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SMU_FCLK:
|
case SMU_FCLK:
|
||||||
single_dpm_table = &(dpm_table->fclk_table);
|
/*
|
||||||
|
* Should not arrive here since Arcturus does not
|
||||||
if (soft_max_level >= single_dpm_table->count) {
|
* support mclk/socclk/fclk softmin/softmax settings
|
||||||
pr_err("Clock level specified %d is over max allowed %d\n",
|
*/
|
||||||
soft_max_level, single_dpm_table->count - 1);
|
ret = -EINVAL;
|
||||||
ret = -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
single_dpm_table->dpm_state.soft_min_level =
|
|
||||||
single_dpm_table->dpm_levels[soft_min_level].value;
|
|
||||||
single_dpm_table->dpm_state.soft_max_level =
|
|
||||||
single_dpm_table->dpm_levels[soft_max_level].value;
|
|
||||||
|
|
||||||
ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_FCLK_MASK);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("Failed to upload boot level to lowest!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_FCLK_MASK);
|
|
||||||
if (ret)
|
|
||||||
pr_err("Failed to upload dpm max level to highest!\n");
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&(smu->mutex));
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1050,7 +995,7 @@ static int arcturus_read_sensor(struct smu_context *smu,
|
|||||||
*size = 4;
|
*size = 4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = smu_smc_read_sensor(smu, sensor, data, size);
|
ret = smu_v11_0_read_sensor(smu, sensor, data, size);
|
||||||
}
|
}
|
||||||
mutex_unlock(&smu->sensor_lock);
|
mutex_unlock(&smu->sensor_lock);
|
||||||
|
|
||||||
@ -1193,6 +1138,7 @@ static int arcturus_force_dpm_limit_value(struct smu_context *smu, bool highest)
|
|||||||
{
|
{
|
||||||
struct arcturus_dpm_table *dpm_table =
|
struct arcturus_dpm_table *dpm_table =
|
||||||
(struct arcturus_dpm_table *)smu->smu_dpm.dpm_context;
|
(struct arcturus_dpm_table *)smu->smu_dpm.dpm_context;
|
||||||
|
struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(smu->adev, 0);
|
||||||
uint32_t soft_level;
|
uint32_t soft_level;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -1206,40 +1152,27 @@ static int arcturus_force_dpm_limit_value(struct smu_context *smu, bool highest)
|
|||||||
dpm_table->gfx_table.dpm_state.soft_max_level =
|
dpm_table->gfx_table.dpm_state.soft_max_level =
|
||||||
dpm_table->gfx_table.dpm_levels[soft_level].value;
|
dpm_table->gfx_table.dpm_levels[soft_level].value;
|
||||||
|
|
||||||
/* uclk */
|
ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_GFXCLK_MASK);
|
||||||
if (highest)
|
|
||||||
soft_level = arcturus_find_highest_dpm_level(&(dpm_table->mem_table));
|
|
||||||
else
|
|
||||||
soft_level = arcturus_find_lowest_dpm_level(&(dpm_table->mem_table));
|
|
||||||
|
|
||||||
dpm_table->mem_table.dpm_state.soft_min_level =
|
|
||||||
dpm_table->mem_table.dpm_state.soft_max_level =
|
|
||||||
dpm_table->mem_table.dpm_levels[soft_level].value;
|
|
||||||
|
|
||||||
/* socclk */
|
|
||||||
if (highest)
|
|
||||||
soft_level = arcturus_find_highest_dpm_level(&(dpm_table->soc_table));
|
|
||||||
else
|
|
||||||
soft_level = arcturus_find_lowest_dpm_level(&(dpm_table->soc_table));
|
|
||||||
|
|
||||||
dpm_table->soc_table.dpm_state.soft_min_level =
|
|
||||||
dpm_table->soc_table.dpm_state.soft_max_level =
|
|
||||||
dpm_table->soc_table.dpm_levels[soft_level].value;
|
|
||||||
|
|
||||||
ret = arcturus_upload_dpm_level(smu, false, 0xFFFFFFFF);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("Failed to upload boot level to %s!\n",
|
pr_err("Failed to upload boot level to %s!\n",
|
||||||
highest ? "highest" : "lowest");
|
highest ? "highest" : "lowest");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = arcturus_upload_dpm_level(smu, true, 0xFFFFFFFF);
|
ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_GFXCLK_MASK);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("Failed to upload dpm max level to %s!\n!",
|
pr_err("Failed to upload dpm max level to %s!\n!",
|
||||||
highest ? "highest" : "lowest");
|
highest ? "highest" : "lowest");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hive)
|
||||||
|
/*
|
||||||
|
* Force XGMI Pstate to highest or lowest
|
||||||
|
* TODO: revise this when xgmi dpm is functional
|
||||||
|
*/
|
||||||
|
ret = smu_v11_0_set_xgmi_pstate(smu, highest ? 1 : 0);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1247,6 +1180,7 @@ static int arcturus_unforce_dpm_levels(struct smu_context *smu)
|
|||||||
{
|
{
|
||||||
struct arcturus_dpm_table *dpm_table =
|
struct arcturus_dpm_table *dpm_table =
|
||||||
(struct arcturus_dpm_table *)smu->smu_dpm.dpm_context;
|
(struct arcturus_dpm_table *)smu->smu_dpm.dpm_context;
|
||||||
|
struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(smu->adev, 0);
|
||||||
uint32_t soft_min_level, soft_max_level;
|
uint32_t soft_min_level, soft_max_level;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -1258,34 +1192,25 @@ static int arcturus_unforce_dpm_levels(struct smu_context *smu)
|
|||||||
dpm_table->gfx_table.dpm_state.soft_max_level =
|
dpm_table->gfx_table.dpm_state.soft_max_level =
|
||||||
dpm_table->gfx_table.dpm_levels[soft_max_level].value;
|
dpm_table->gfx_table.dpm_levels[soft_max_level].value;
|
||||||
|
|
||||||
/* uclk */
|
ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_GFXCLK_MASK);
|
||||||
soft_min_level = arcturus_find_lowest_dpm_level(&(dpm_table->mem_table));
|
|
||||||
soft_max_level = arcturus_find_highest_dpm_level(&(dpm_table->mem_table));
|
|
||||||
dpm_table->mem_table.dpm_state.soft_min_level =
|
|
||||||
dpm_table->gfx_table.dpm_levels[soft_min_level].value;
|
|
||||||
dpm_table->mem_table.dpm_state.soft_max_level =
|
|
||||||
dpm_table->gfx_table.dpm_levels[soft_max_level].value;
|
|
||||||
|
|
||||||
/* socclk */
|
|
||||||
soft_min_level = arcturus_find_lowest_dpm_level(&(dpm_table->soc_table));
|
|
||||||
soft_max_level = arcturus_find_highest_dpm_level(&(dpm_table->soc_table));
|
|
||||||
dpm_table->soc_table.dpm_state.soft_min_level =
|
|
||||||
dpm_table->soc_table.dpm_levels[soft_min_level].value;
|
|
||||||
dpm_table->soc_table.dpm_state.soft_max_level =
|
|
||||||
dpm_table->soc_table.dpm_levels[soft_max_level].value;
|
|
||||||
|
|
||||||
ret = arcturus_upload_dpm_level(smu, false, 0xFFFFFFFF);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("Failed to upload DPM Bootup Levels!");
|
pr_err("Failed to upload DPM Bootup Levels!");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = arcturus_upload_dpm_level(smu, true, 0xFFFFFFFF);
|
ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_GFXCLK_MASK);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("Failed to upload DPM Max Levels!");
|
pr_err("Failed to upload DPM Max Levels!");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hive)
|
||||||
|
/*
|
||||||
|
* Reset XGMI Pstate back to default
|
||||||
|
* TODO: revise this when xgmi dpm is functional
|
||||||
|
*/
|
||||||
|
ret = smu_v11_0_set_xgmi_pstate(smu, 0);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1927,6 +1852,224 @@ static int arcturus_dpm_set_uvd_enable(struct smu_context *smu, bool enable)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void arcturus_fill_eeprom_i2c_req(SwI2cRequest_t *req, bool write,
|
||||||
|
uint8_t address, uint32_t numbytes,
|
||||||
|
uint8_t *data)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
BUG_ON(numbytes > MAX_SW_I2C_COMMANDS);
|
||||||
|
|
||||||
|
req->I2CcontrollerPort = 0;
|
||||||
|
req->I2CSpeed = 2;
|
||||||
|
req->SlaveAddress = address;
|
||||||
|
req->NumCmds = numbytes;
|
||||||
|
|
||||||
|
for (i = 0; i < numbytes; i++) {
|
||||||
|
SwI2cCmd_t *cmd = &req->SwI2cCmds[i];
|
||||||
|
|
||||||
|
/* First 2 bytes are always write for lower 2b EEPROM address */
|
||||||
|
if (i < 2)
|
||||||
|
cmd->Cmd = 1;
|
||||||
|
else
|
||||||
|
cmd->Cmd = write;
|
||||||
|
|
||||||
|
|
||||||
|
/* Add RESTART for read after address filled */
|
||||||
|
cmd->CmdConfig |= (i == 2 && !write) ? CMDCONFIG_RESTART_MASK : 0;
|
||||||
|
|
||||||
|
/* Add STOP in the end */
|
||||||
|
cmd->CmdConfig |= (i == (numbytes - 1)) ? CMDCONFIG_STOP_MASK : 0;
|
||||||
|
|
||||||
|
/* Fill with data regardless if read or write to simplify code */
|
||||||
|
cmd->RegisterAddr = data[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int arcturus_i2c_eeprom_read_data(struct i2c_adapter *control,
|
||||||
|
uint8_t address,
|
||||||
|
uint8_t *data,
|
||||||
|
uint32_t numbytes)
|
||||||
|
{
|
||||||
|
uint32_t i, ret = 0;
|
||||||
|
SwI2cRequest_t req;
|
||||||
|
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||||
|
struct smu_table_context *smu_table = &adev->smu.smu_table;
|
||||||
|
struct smu_table *table = &smu_table->tables[SMU_TABLE_I2C_COMMANDS];
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
arcturus_fill_eeprom_i2c_req(&req, false, address, numbytes, data);
|
||||||
|
|
||||||
|
mutex_lock(&adev->smu.mutex);
|
||||||
|
/* Now read data starting with that address */
|
||||||
|
ret = smu_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req,
|
||||||
|
true);
|
||||||
|
mutex_unlock(&adev->smu.mutex);
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
SwI2cRequest_t *res = (SwI2cRequest_t *)table->cpu_addr;
|
||||||
|
|
||||||
|
/* Assume SMU fills res.SwI2cCmds[i].Data with read bytes */
|
||||||
|
for (i = 0; i < numbytes; i++)
|
||||||
|
data[i] = res->SwI2cCmds[i].Data;
|
||||||
|
|
||||||
|
pr_debug("arcturus_i2c_eeprom_read_data, address = %x, bytes = %d, data :",
|
||||||
|
(uint16_t)address, numbytes);
|
||||||
|
|
||||||
|
print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE,
|
||||||
|
8, 1, data, numbytes, false);
|
||||||
|
} else
|
||||||
|
pr_err("arcturus_i2c_eeprom_read_data - error occurred :%x", ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int arcturus_i2c_eeprom_write_data(struct i2c_adapter *control,
|
||||||
|
uint8_t address,
|
||||||
|
uint8_t *data,
|
||||||
|
uint32_t numbytes)
|
||||||
|
{
|
||||||
|
uint32_t ret;
|
||||||
|
SwI2cRequest_t req;
|
||||||
|
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
arcturus_fill_eeprom_i2c_req(&req, true, address, numbytes, data);
|
||||||
|
|
||||||
|
mutex_lock(&adev->smu.mutex);
|
||||||
|
ret = smu_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req, true);
|
||||||
|
mutex_unlock(&adev->smu.mutex);
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
pr_debug("arcturus_i2c_write(), address = %x, bytes = %d , data: ",
|
||||||
|
(uint16_t)address, numbytes);
|
||||||
|
|
||||||
|
print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE,
|
||||||
|
8, 1, data, numbytes, false);
|
||||||
|
/*
|
||||||
|
* According to EEPROM spec there is a MAX of 10 ms required for
|
||||||
|
* EEPROM to flush internal RX buffer after STOP was issued at the
|
||||||
|
* end of write transaction. During this time the EEPROM will not be
|
||||||
|
* responsive to any more commands - so wait a bit more.
|
||||||
|
*/
|
||||||
|
msleep(10);
|
||||||
|
|
||||||
|
} else
|
||||||
|
pr_err("arcturus_i2c_write- error occurred :%x", ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int arcturus_i2c_eeprom_i2c_xfer(struct i2c_adapter *i2c_adap,
|
||||||
|
struct i2c_msg *msgs, int num)
|
||||||
|
{
|
||||||
|
uint32_t i, j, ret, data_size, data_chunk_size, next_eeprom_addr = 0;
|
||||||
|
uint8_t *data_ptr, data_chunk[MAX_SW_I2C_COMMANDS] = { 0 };
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
/*
|
||||||
|
* SMU interface allows at most MAX_SW_I2C_COMMANDS bytes of data at
|
||||||
|
* once and hence the data needs to be spliced into chunks and sent each
|
||||||
|
* chunk separately
|
||||||
|
*/
|
||||||
|
data_size = msgs[i].len - 2;
|
||||||
|
data_chunk_size = MAX_SW_I2C_COMMANDS - 2;
|
||||||
|
next_eeprom_addr = (msgs[i].buf[0] << 8 & 0xff00) | (msgs[i].buf[1] & 0xff);
|
||||||
|
data_ptr = msgs[i].buf + 2;
|
||||||
|
|
||||||
|
for (j = 0; j < data_size / data_chunk_size; j++) {
|
||||||
|
/* Insert the EEPROM dest addess, bits 0-15 */
|
||||||
|
data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff);
|
||||||
|
data_chunk[1] = (next_eeprom_addr & 0xff);
|
||||||
|
|
||||||
|
if (msgs[i].flags & I2C_M_RD) {
|
||||||
|
ret = arcturus_i2c_eeprom_read_data(i2c_adap,
|
||||||
|
(uint8_t)msgs[i].addr,
|
||||||
|
data_chunk, MAX_SW_I2C_COMMANDS);
|
||||||
|
|
||||||
|
memcpy(data_ptr, data_chunk + 2, data_chunk_size);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
memcpy(data_chunk + 2, data_ptr, data_chunk_size);
|
||||||
|
|
||||||
|
ret = arcturus_i2c_eeprom_write_data(i2c_adap,
|
||||||
|
(uint8_t)msgs[i].addr,
|
||||||
|
data_chunk, MAX_SW_I2C_COMMANDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
num = -EIO;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
next_eeprom_addr += data_chunk_size;
|
||||||
|
data_ptr += data_chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data_size % data_chunk_size) {
|
||||||
|
data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff);
|
||||||
|
data_chunk[1] = (next_eeprom_addr & 0xff);
|
||||||
|
|
||||||
|
if (msgs[i].flags & I2C_M_RD) {
|
||||||
|
ret = arcturus_i2c_eeprom_read_data(i2c_adap,
|
||||||
|
(uint8_t)msgs[i].addr,
|
||||||
|
data_chunk, (data_size % data_chunk_size) + 2);
|
||||||
|
|
||||||
|
memcpy(data_ptr, data_chunk + 2, data_size % data_chunk_size);
|
||||||
|
} else {
|
||||||
|
memcpy(data_chunk + 2, data_ptr, data_size % data_chunk_size);
|
||||||
|
|
||||||
|
ret = arcturus_i2c_eeprom_write_data(i2c_adap,
|
||||||
|
(uint8_t)msgs[i].addr,
|
||||||
|
data_chunk, (data_size % data_chunk_size) + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
num = -EIO;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 arcturus_i2c_eeprom_i2c_func(struct i2c_adapter *adap)
|
||||||
|
{
|
||||||
|
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct i2c_algorithm arcturus_i2c_eeprom_i2c_algo = {
|
||||||
|
.master_xfer = arcturus_i2c_eeprom_i2c_xfer,
|
||||||
|
.functionality = arcturus_i2c_eeprom_i2c_func,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int arcturus_i2c_eeprom_control_init(struct i2c_adapter *control)
|
||||||
|
{
|
||||||
|
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||||
|
int res;
|
||||||
|
|
||||||
|
control->owner = THIS_MODULE;
|
||||||
|
control->class = I2C_CLASS_SPD;
|
||||||
|
control->dev.parent = &adev->pdev->dev;
|
||||||
|
control->algo = &arcturus_i2c_eeprom_i2c_algo;
|
||||||
|
snprintf(control->name, sizeof(control->name), "RAS EEPROM");
|
||||||
|
|
||||||
|
res = i2c_add_adapter(control);
|
||||||
|
if (res)
|
||||||
|
DRM_ERROR("Failed to register hw i2c, err: %d\n", res);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void arcturus_i2c_eeprom_control_fini(struct i2c_adapter *control)
|
||||||
|
{
|
||||||
|
i2c_del_adapter(control);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct pptable_funcs arcturus_ppt_funcs = {
|
static const struct pptable_funcs arcturus_ppt_funcs = {
|
||||||
/* translate smu index into arcturus specific index */
|
/* translate smu index into arcturus specific index */
|
||||||
.get_smu_msg_index = arcturus_get_smu_msg_index,
|
.get_smu_msg_index = arcturus_get_smu_msg_index,
|
||||||
@ -1966,6 +2109,57 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
|
|||||||
.get_power_limit = arcturus_get_power_limit,
|
.get_power_limit = arcturus_get_power_limit,
|
||||||
.is_dpm_running = arcturus_is_dpm_running,
|
.is_dpm_running = arcturus_is_dpm_running,
|
||||||
.dpm_set_uvd_enable = arcturus_dpm_set_uvd_enable,
|
.dpm_set_uvd_enable = arcturus_dpm_set_uvd_enable,
|
||||||
|
.i2c_eeprom_init = arcturus_i2c_eeprom_control_init,
|
||||||
|
.i2c_eeprom_fini = arcturus_i2c_eeprom_control_fini,
|
||||||
|
.init_microcode = smu_v11_0_init_microcode,
|
||||||
|
.load_microcode = smu_v11_0_load_microcode,
|
||||||
|
.init_smc_tables = smu_v11_0_init_smc_tables,
|
||||||
|
.fini_smc_tables = smu_v11_0_fini_smc_tables,
|
||||||
|
.init_power = smu_v11_0_init_power,
|
||||||
|
.fini_power = smu_v11_0_fini_power,
|
||||||
|
.check_fw_status = smu_v11_0_check_fw_status,
|
||||||
|
.setup_pptable = smu_v11_0_setup_pptable,
|
||||||
|
.get_vbios_bootup_values = smu_v11_0_get_vbios_bootup_values,
|
||||||
|
.get_clk_info_from_vbios = smu_v11_0_get_clk_info_from_vbios,
|
||||||
|
.check_pptable = smu_v11_0_check_pptable,
|
||||||
|
.parse_pptable = smu_v11_0_parse_pptable,
|
||||||
|
.populate_smc_tables = smu_v11_0_populate_smc_pptable,
|
||||||
|
.check_fw_version = smu_v11_0_check_fw_version,
|
||||||
|
.write_pptable = smu_v11_0_write_pptable,
|
||||||
|
.set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep,
|
||||||
|
.set_tool_table_location = smu_v11_0_set_tool_table_location,
|
||||||
|
.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
|
||||||
|
.system_features_control = smu_v11_0_system_features_control,
|
||||||
|
.send_smc_msg = smu_v11_0_send_msg,
|
||||||
|
.send_smc_msg_with_param = smu_v11_0_send_msg_with_param,
|
||||||
|
.read_smc_arg = smu_v11_0_read_arg,
|
||||||
|
.init_display_count = smu_v11_0_init_display_count,
|
||||||
|
.set_allowed_mask = smu_v11_0_set_allowed_mask,
|
||||||
|
.get_enabled_mask = smu_v11_0_get_enabled_mask,
|
||||||
|
.notify_display_change = smu_v11_0_notify_display_change,
|
||||||
|
.set_power_limit = smu_v11_0_set_power_limit,
|
||||||
|
.get_current_clk_freq = smu_v11_0_get_current_clk_freq,
|
||||||
|
.init_max_sustainable_clocks = smu_v11_0_init_max_sustainable_clocks,
|
||||||
|
.start_thermal_control = smu_v11_0_start_thermal_control,
|
||||||
|
.stop_thermal_control = smu_v11_0_stop_thermal_control,
|
||||||
|
.set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk,
|
||||||
|
.display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
|
||||||
|
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
|
||||||
|
.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
|
||||||
|
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
|
||||||
|
.set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
|
||||||
|
.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
|
||||||
|
.gfx_off_control = smu_v11_0_gfx_off_control,
|
||||||
|
.register_irq_handler = smu_v11_0_register_irq_handler,
|
||||||
|
.set_azalia_d3_pme = smu_v11_0_set_azalia_d3_pme,
|
||||||
|
.get_max_sustainable_clocks_by_dc = smu_v11_0_get_max_sustainable_clocks_by_dc,
|
||||||
|
.baco_is_support= smu_v11_0_baco_is_support,
|
||||||
|
.baco_get_state = smu_v11_0_baco_get_state,
|
||||||
|
.baco_set_state = smu_v11_0_baco_set_state,
|
||||||
|
.baco_reset = smu_v11_0_baco_reset,
|
||||||
|
.get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq,
|
||||||
|
.set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
|
||||||
|
.override_pcie_parameters = smu_v11_0_override_pcie_parameters,
|
||||||
};
|
};
|
||||||
|
|
||||||
void arcturus_set_ppt_funcs(struct smu_context *smu)
|
void arcturus_set_ppt_funcs(struct smu_context *smu)
|
||||||
|
@ -5096,9 +5096,7 @@ static void vega10_odn_update_soc_table(struct pp_hwmgr *hwmgr,
|
|||||||
|
|
||||||
if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) {
|
if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) {
|
||||||
podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk;
|
podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk;
|
||||||
for (i = 0; i < podn_vdd_dep->count - 1; i++)
|
for (i = 0; i < podn_vdd_dep->count; i++)
|
||||||
od_vddc_lookup_table->entries[i].us_vdd = podn_vdd_dep->entries[i].vddc;
|
|
||||||
if (od_vddc_lookup_table->entries[i].us_vdd < podn_vdd_dep->entries[i].vddc)
|
|
||||||
od_vddc_lookup_table->entries[i].us_vdd = podn_vdd_dep->entries[i].vddc;
|
od_vddc_lookup_table->entries[i].us_vdd = podn_vdd_dep->entries[i].vddc;
|
||||||
} else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) {
|
} else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) {
|
||||||
podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk;
|
podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk;
|
||||||
|
@ -347,7 +347,6 @@ struct smu_context
|
|||||||
struct amdgpu_device *adev;
|
struct amdgpu_device *adev;
|
||||||
struct amdgpu_irq_src *irq_source;
|
struct amdgpu_irq_src *irq_source;
|
||||||
|
|
||||||
const struct smu_funcs *funcs;
|
|
||||||
const struct pptable_funcs *ppt_funcs;
|
const struct pptable_funcs *ppt_funcs;
|
||||||
struct mutex mutex;
|
struct mutex mutex;
|
||||||
struct mutex sensor_lock;
|
struct mutex sensor_lock;
|
||||||
@ -394,6 +393,8 @@ struct smu_context
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct i2c_adapter;
|
||||||
|
|
||||||
struct pptable_funcs {
|
struct pptable_funcs {
|
||||||
int (*alloc_dpm_context)(struct smu_context *smu);
|
int (*alloc_dpm_context)(struct smu_context *smu);
|
||||||
int (*store_powerplay_table)(struct smu_context *smu);
|
int (*store_powerplay_table)(struct smu_context *smu);
|
||||||
@ -470,17 +471,15 @@ struct pptable_funcs {
|
|||||||
uint32_t dpm_level, uint32_t *freq);
|
uint32_t dpm_level, uint32_t *freq);
|
||||||
int (*set_df_cstate)(struct smu_context *smu, enum pp_df_cstate state);
|
int (*set_df_cstate)(struct smu_context *smu, enum pp_df_cstate state);
|
||||||
int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap);
|
int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap);
|
||||||
|
int (*i2c_eeprom_init)(struct i2c_adapter *control);
|
||||||
|
void (*i2c_eeprom_fini)(struct i2c_adapter *control);
|
||||||
int (*get_dpm_clock_table)(struct smu_context *smu, struct dpm_clocks *clock_table);
|
int (*get_dpm_clock_table)(struct smu_context *smu, struct dpm_clocks *clock_table);
|
||||||
};
|
|
||||||
|
|
||||||
struct smu_funcs
|
|
||||||
{
|
|
||||||
int (*init_microcode)(struct smu_context *smu);
|
int (*init_microcode)(struct smu_context *smu);
|
||||||
|
int (*load_microcode)(struct smu_context *smu);
|
||||||
int (*init_smc_tables)(struct smu_context *smu);
|
int (*init_smc_tables)(struct smu_context *smu);
|
||||||
int (*fini_smc_tables)(struct smu_context *smu);
|
int (*fini_smc_tables)(struct smu_context *smu);
|
||||||
int (*init_power)(struct smu_context *smu);
|
int (*init_power)(struct smu_context *smu);
|
||||||
int (*fini_power)(struct smu_context *smu);
|
int (*fini_power)(struct smu_context *smu);
|
||||||
int (*load_microcode)(struct smu_context *smu);
|
|
||||||
int (*check_fw_status)(struct smu_context *smu);
|
int (*check_fw_status)(struct smu_context *smu);
|
||||||
int (*setup_pptable)(struct smu_context *smu);
|
int (*setup_pptable)(struct smu_context *smu);
|
||||||
int (*get_vbios_bootup_values)(struct smu_context *smu);
|
int (*get_vbios_bootup_values)(struct smu_context *smu);
|
||||||
@ -510,8 +509,6 @@ struct smu_funcs
|
|||||||
int (*init_max_sustainable_clocks)(struct smu_context *smu);
|
int (*init_max_sustainable_clocks)(struct smu_context *smu);
|
||||||
int (*start_thermal_control)(struct smu_context *smu);
|
int (*start_thermal_control)(struct smu_context *smu);
|
||||||
int (*stop_thermal_control)(struct smu_context *smu);
|
int (*stop_thermal_control)(struct smu_context *smu);
|
||||||
int (*read_sensor)(struct smu_context *smu, enum amd_pp_sensors sensor,
|
|
||||||
void *data, uint32_t *size);
|
|
||||||
int (*set_deep_sleep_dcefclk)(struct smu_context *smu, uint32_t clk);
|
int (*set_deep_sleep_dcefclk)(struct smu_context *smu, uint32_t clk);
|
||||||
int (*set_active_display_count)(struct smu_context *smu, uint32_t count);
|
int (*set_active_display_count)(struct smu_context *smu, uint32_t count);
|
||||||
int (*store_cc6_data)(struct smu_context *smu, uint32_t separation_time,
|
int (*store_cc6_data)(struct smu_context *smu, uint32_t separation_time,
|
||||||
@ -553,235 +550,83 @@ struct smu_funcs
|
|||||||
int (*override_pcie_parameters)(struct smu_context *smu);
|
int (*override_pcie_parameters)(struct smu_context *smu);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define smu_init_microcode(smu) \
|
int smu_load_microcode(struct smu_context *smu);
|
||||||
((smu)->funcs->init_microcode ? (smu)->funcs->init_microcode((smu)) : 0)
|
|
||||||
#define smu_init_smc_tables(smu) \
|
|
||||||
((smu)->funcs->init_smc_tables ? (smu)->funcs->init_smc_tables((smu)) : 0)
|
|
||||||
#define smu_fini_smc_tables(smu) \
|
|
||||||
((smu)->funcs->fini_smc_tables ? (smu)->funcs->fini_smc_tables((smu)) : 0)
|
|
||||||
#define smu_init_power(smu) \
|
|
||||||
((smu)->funcs->init_power ? (smu)->funcs->init_power((smu)) : 0)
|
|
||||||
#define smu_fini_power(smu) \
|
|
||||||
((smu)->funcs->fini_power ? (smu)->funcs->fini_power((smu)) : 0)
|
|
||||||
#define smu_load_microcode(smu) \
|
|
||||||
((smu)->funcs->load_microcode ? (smu)->funcs->load_microcode((smu)) : 0)
|
|
||||||
#define smu_check_fw_status(smu) \
|
|
||||||
((smu)->funcs->check_fw_status ? (smu)->funcs->check_fw_status((smu)) : 0)
|
|
||||||
#define smu_setup_pptable(smu) \
|
|
||||||
((smu)->funcs->setup_pptable ? (smu)->funcs->setup_pptable((smu)) : 0)
|
|
||||||
#define smu_powergate_sdma(smu, gate) \
|
|
||||||
((smu)->funcs->powergate_sdma ? (smu)->funcs->powergate_sdma((smu), (gate)) : 0)
|
|
||||||
#define smu_powergate_vcn(smu, gate) \
|
|
||||||
((smu)->funcs->powergate_vcn ? (smu)->funcs->powergate_vcn((smu), (gate)) : 0)
|
|
||||||
#define smu_set_gfx_cgpg(smu, enabled) \
|
|
||||||
((smu)->funcs->set_gfx_cgpg ? (smu)->funcs->set_gfx_cgpg((smu), (enabled)) : 0)
|
|
||||||
#define smu_get_vbios_bootup_values(smu) \
|
|
||||||
((smu)->funcs->get_vbios_bootup_values ? (smu)->funcs->get_vbios_bootup_values((smu)) : 0)
|
|
||||||
#define smu_get_clk_info_from_vbios(smu) \
|
|
||||||
((smu)->funcs->get_clk_info_from_vbios ? (smu)->funcs->get_clk_info_from_vbios((smu)) : 0)
|
|
||||||
#define smu_check_pptable(smu) \
|
|
||||||
((smu)->funcs->check_pptable ? (smu)->funcs->check_pptable((smu)) : 0)
|
|
||||||
#define smu_parse_pptable(smu) \
|
|
||||||
((smu)->funcs->parse_pptable ? (smu)->funcs->parse_pptable((smu)) : 0)
|
|
||||||
#define smu_populate_smc_tables(smu) \
|
|
||||||
((smu)->funcs->populate_smc_tables ? (smu)->funcs->populate_smc_tables((smu)) : 0)
|
|
||||||
#define smu_check_fw_version(smu) \
|
|
||||||
((smu)->funcs->check_fw_version ? (smu)->funcs->check_fw_version((smu)) : 0)
|
|
||||||
#define smu_write_pptable(smu) \
|
|
||||||
((smu)->funcs->write_pptable ? (smu)->funcs->write_pptable((smu)) : 0)
|
|
||||||
#define smu_set_min_dcef_deep_sleep(smu) \
|
|
||||||
((smu)->funcs->set_min_dcef_deep_sleep ? (smu)->funcs->set_min_dcef_deep_sleep((smu)) : 0)
|
|
||||||
#define smu_set_tool_table_location(smu) \
|
|
||||||
((smu)->funcs->set_tool_table_location ? (smu)->funcs->set_tool_table_location((smu)) : 0)
|
|
||||||
#define smu_notify_memory_pool_location(smu) \
|
|
||||||
((smu)->funcs->notify_memory_pool_location ? (smu)->funcs->notify_memory_pool_location((smu)) : 0)
|
|
||||||
#define smu_gfx_off_control(smu, enable) \
|
|
||||||
((smu)->funcs->gfx_off_control ? (smu)->funcs->gfx_off_control((smu), (enable)) : 0)
|
|
||||||
#define smu_set_last_dcef_min_deep_sleep_clk(smu) \
|
|
||||||
((smu)->funcs->set_last_dcef_min_deep_sleep_clk ? (smu)->funcs->set_last_dcef_min_deep_sleep_clk((smu)) : 0)
|
|
||||||
#define smu_system_features_control(smu, en) \
|
|
||||||
((smu)->funcs->system_features_control ? (smu)->funcs->system_features_control((smu), (en)) : 0)
|
|
||||||
#define smu_init_max_sustainable_clocks(smu) \
|
|
||||||
((smu)->funcs->init_max_sustainable_clocks ? (smu)->funcs->init_max_sustainable_clocks((smu)) : 0)
|
|
||||||
#define smu_set_default_od_settings(smu, initialize) \
|
|
||||||
((smu)->ppt_funcs->set_default_od_settings ? (smu)->ppt_funcs->set_default_od_settings((smu), (initialize)) : 0)
|
|
||||||
#define smu_set_fan_speed_rpm(smu, speed) \
|
|
||||||
((smu)->funcs->set_fan_speed_rpm ? (smu)->funcs->set_fan_speed_rpm((smu), (speed)) : 0)
|
|
||||||
#define smu_send_smc_msg(smu, msg) \
|
|
||||||
((smu)->funcs->send_smc_msg? (smu)->funcs->send_smc_msg((smu), (msg)) : 0)
|
|
||||||
#define smu_send_smc_msg_with_param(smu, msg, param) \
|
|
||||||
((smu)->funcs->send_smc_msg_with_param? (smu)->funcs->send_smc_msg_with_param((smu), (msg), (param)) : 0)
|
|
||||||
#define smu_read_smc_arg(smu, arg) \
|
|
||||||
((smu)->funcs->read_smc_arg? (smu)->funcs->read_smc_arg((smu), (arg)) : 0)
|
|
||||||
#define smu_alloc_dpm_context(smu) \
|
|
||||||
((smu)->ppt_funcs->alloc_dpm_context ? (smu)->ppt_funcs->alloc_dpm_context((smu)) : 0)
|
|
||||||
#define smu_init_display_count(smu, count) \
|
|
||||||
((smu)->funcs->init_display_count ? (smu)->funcs->init_display_count((smu), (count)) : 0)
|
|
||||||
#define smu_feature_set_allowed_mask(smu) \
|
|
||||||
((smu)->funcs->set_allowed_mask? (smu)->funcs->set_allowed_mask((smu)) : 0)
|
|
||||||
#define smu_feature_get_enabled_mask(smu, mask, num) \
|
|
||||||
((smu)->funcs->get_enabled_mask? (smu)->funcs->get_enabled_mask((smu), (mask), (num)) : 0)
|
|
||||||
#define smu_is_dpm_running(smu) \
|
|
||||||
((smu)->ppt_funcs->is_dpm_running ? (smu)->ppt_funcs->is_dpm_running((smu)) : 0)
|
|
||||||
#define smu_notify_display_change(smu) \
|
|
||||||
((smu)->funcs->notify_display_change? (smu)->funcs->notify_display_change((smu)) : 0)
|
|
||||||
#define smu_store_powerplay_table(smu) \
|
|
||||||
((smu)->ppt_funcs->store_powerplay_table ? (smu)->ppt_funcs->store_powerplay_table((smu)) : 0)
|
|
||||||
#define smu_check_powerplay_table(smu) \
|
|
||||||
((smu)->ppt_funcs->check_powerplay_table ? (smu)->ppt_funcs->check_powerplay_table((smu)) : 0)
|
|
||||||
#define smu_append_powerplay_table(smu) \
|
|
||||||
((smu)->ppt_funcs->append_powerplay_table ? (smu)->ppt_funcs->append_powerplay_table((smu)) : 0)
|
|
||||||
#define smu_set_default_dpm_table(smu) \
|
|
||||||
((smu)->ppt_funcs->set_default_dpm_table ? (smu)->ppt_funcs->set_default_dpm_table((smu)) : 0)
|
|
||||||
#define smu_populate_umd_state_clk(smu) \
|
|
||||||
((smu)->ppt_funcs->populate_umd_state_clk ? (smu)->ppt_funcs->populate_umd_state_clk((smu)) : 0)
|
|
||||||
#define smu_set_default_od8_settings(smu) \
|
|
||||||
((smu)->ppt_funcs->set_default_od8_settings ? (smu)->ppt_funcs->set_default_od8_settings((smu)) : 0)
|
|
||||||
#define smu_get_power_limit(smu, limit, def) \
|
|
||||||
((smu)->ppt_funcs->get_power_limit ? (smu)->ppt_funcs->get_power_limit((smu), (limit), (def)) : 0)
|
|
||||||
#define smu_set_power_limit(smu, limit) \
|
|
||||||
((smu)->funcs->set_power_limit ? (smu)->funcs->set_power_limit((smu), (limit)) : 0)
|
|
||||||
#define smu_get_current_clk_freq(smu, clk_id, value) \
|
|
||||||
((smu)->funcs->get_current_clk_freq? (smu)->funcs->get_current_clk_freq((smu), (clk_id), (value)) : 0)
|
|
||||||
#define smu_print_clk_levels(smu, clk_type, buf) \
|
|
||||||
((smu)->ppt_funcs->print_clk_levels ? (smu)->ppt_funcs->print_clk_levels((smu), (clk_type), (buf)) : 0)
|
|
||||||
#define smu_get_od_percentage(smu, type) \
|
|
||||||
((smu)->ppt_funcs->get_od_percentage ? (smu)->ppt_funcs->get_od_percentage((smu), (type)) : 0)
|
|
||||||
#define smu_set_od_percentage(smu, type, value) \
|
|
||||||
((smu)->ppt_funcs->set_od_percentage ? (smu)->ppt_funcs->set_od_percentage((smu), (type), (value)) : 0)
|
|
||||||
#define smu_od_edit_dpm_table(smu, type, input, size) \
|
|
||||||
((smu)->ppt_funcs->od_edit_dpm_table ? (smu)->ppt_funcs->od_edit_dpm_table((smu), (type), (input), (size)) : 0)
|
|
||||||
#define smu_tables_init(smu, tab) \
|
|
||||||
((smu)->ppt_funcs->tables_init ? (smu)->ppt_funcs->tables_init((smu), (tab)) : 0)
|
|
||||||
#define smu_set_thermal_fan_table(smu) \
|
|
||||||
((smu)->ppt_funcs->set_thermal_fan_table ? (smu)->ppt_funcs->set_thermal_fan_table((smu)) : 0)
|
|
||||||
#define smu_start_thermal_control(smu) \
|
|
||||||
((smu)->funcs->start_thermal_control? (smu)->funcs->start_thermal_control((smu)) : 0)
|
|
||||||
#define smu_stop_thermal_control(smu) \
|
|
||||||
((smu)->funcs->stop_thermal_control? (smu)->funcs->stop_thermal_control((smu)) : 0)
|
|
||||||
#define smu_read_sensor(smu, sensor, data, size) \
|
|
||||||
((smu)->ppt_funcs->read_sensor? (smu)->ppt_funcs->read_sensor((smu), (sensor), (data), (size)) : 0)
|
|
||||||
#define smu_smc_read_sensor(smu, sensor, data, size) \
|
|
||||||
((smu)->funcs->read_sensor? (smu)->funcs->read_sensor((smu), (sensor), (data), (size)) : -EINVAL)
|
|
||||||
#define smu_get_power_profile_mode(smu, buf) \
|
|
||||||
((smu)->ppt_funcs->get_power_profile_mode ? (smu)->ppt_funcs->get_power_profile_mode((smu), buf) : 0)
|
|
||||||
#define smu_set_power_profile_mode(smu, param, param_size) \
|
|
||||||
((smu)->ppt_funcs->set_power_profile_mode ? (smu)->ppt_funcs->set_power_profile_mode((smu), (param), (param_size)) : 0)
|
|
||||||
#define smu_pre_display_config_changed(smu) \
|
|
||||||
((smu)->ppt_funcs->pre_display_config_changed ? (smu)->ppt_funcs->pre_display_config_changed((smu)) : 0)
|
|
||||||
#define smu_display_config_changed(smu) \
|
|
||||||
((smu)->ppt_funcs->display_config_changed ? (smu)->ppt_funcs->display_config_changed((smu)) : 0)
|
|
||||||
#define smu_apply_clocks_adjust_rules(smu) \
|
|
||||||
((smu)->ppt_funcs->apply_clocks_adjust_rules ? (smu)->ppt_funcs->apply_clocks_adjust_rules((smu)) : 0)
|
|
||||||
#define smu_notify_smc_dispaly_config(smu) \
|
|
||||||
((smu)->ppt_funcs->notify_smc_dispaly_config ? (smu)->ppt_funcs->notify_smc_dispaly_config((smu)) : 0)
|
|
||||||
#define smu_force_dpm_limit_value(smu, highest) \
|
|
||||||
((smu)->ppt_funcs->force_dpm_limit_value ? (smu)->ppt_funcs->force_dpm_limit_value((smu), (highest)) : 0)
|
|
||||||
#define smu_unforce_dpm_levels(smu) \
|
|
||||||
((smu)->ppt_funcs->unforce_dpm_levels ? (smu)->ppt_funcs->unforce_dpm_levels((smu)) : 0)
|
|
||||||
#define smu_get_profiling_clk_mask(smu, level, sclk_mask, mclk_mask, soc_mask) \
|
|
||||||
((smu)->ppt_funcs->get_profiling_clk_mask ? (smu)->ppt_funcs->get_profiling_clk_mask((smu), (level), (sclk_mask), (mclk_mask), (soc_mask)) : 0)
|
|
||||||
#define smu_set_cpu_power_state(smu) \
|
|
||||||
((smu)->ppt_funcs->set_cpu_power_state ? (smu)->ppt_funcs->set_cpu_power_state((smu)) : 0)
|
|
||||||
#define smu_get_fan_control_mode(smu) \
|
|
||||||
((smu)->funcs->get_fan_control_mode ? (smu)->funcs->get_fan_control_mode((smu)) : 0)
|
|
||||||
#define smu_set_fan_control_mode(smu, value) \
|
|
||||||
((smu)->funcs->set_fan_control_mode ? (smu)->funcs->set_fan_control_mode((smu), (value)) : 0)
|
|
||||||
#define smu_get_fan_speed_percent(smu, speed) \
|
|
||||||
((smu)->ppt_funcs->get_fan_speed_percent ? (smu)->ppt_funcs->get_fan_speed_percent((smu), (speed)) : 0)
|
|
||||||
#define smu_set_fan_speed_percent(smu, speed) \
|
|
||||||
((smu)->funcs->set_fan_speed_percent ? (smu)->funcs->set_fan_speed_percent((smu), (speed)) : 0)
|
|
||||||
#define smu_get_fan_speed_rpm(smu, speed) \
|
|
||||||
((smu)->ppt_funcs->get_fan_speed_rpm ? (smu)->ppt_funcs->get_fan_speed_rpm((smu), (speed)) : 0)
|
|
||||||
|
|
||||||
#define smu_msg_get_index(smu, msg) \
|
int smu_check_fw_status(struct smu_context *smu);
|
||||||
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_msg_index? (smu)->ppt_funcs->get_smu_msg_index((smu), (msg)) : -EINVAL) : -EINVAL)
|
|
||||||
#define smu_clk_get_index(smu, msg) \
|
|
||||||
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_clk_index? (smu)->ppt_funcs->get_smu_clk_index((smu), (msg)) : -EINVAL) : -EINVAL)
|
|
||||||
#define smu_feature_get_index(smu, msg) \
|
|
||||||
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_feature_index? (smu)->ppt_funcs->get_smu_feature_index((smu), (msg)) : -EINVAL) : -EINVAL)
|
|
||||||
#define smu_table_get_index(smu, tab) \
|
|
||||||
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_table_index? (smu)->ppt_funcs->get_smu_table_index((smu), (tab)) : -EINVAL) : -EINVAL)
|
|
||||||
#define smu_power_get_index(smu, src) \
|
|
||||||
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_power_index? (smu)->ppt_funcs->get_smu_power_index((smu), (src)) : -EINVAL) : -EINVAL)
|
|
||||||
#define smu_workload_get_type(smu, profile) \
|
|
||||||
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_workload_type? (smu)->ppt_funcs->get_workload_type((smu), (profile)) : -EINVAL) : -EINVAL)
|
|
||||||
#define smu_run_btc(smu) \
|
|
||||||
((smu)->ppt_funcs? ((smu)->ppt_funcs->run_btc? (smu)->ppt_funcs->run_btc((smu)) : 0) : 0)
|
|
||||||
#define smu_get_allowed_feature_mask(smu, feature_mask, num) \
|
|
||||||
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_allowed_feature_mask? (smu)->ppt_funcs->get_allowed_feature_mask((smu), (feature_mask), (num)) : 0) : 0)
|
|
||||||
#define smu_set_deep_sleep_dcefclk(smu, clk) \
|
|
||||||
((smu)->funcs->set_deep_sleep_dcefclk ? (smu)->funcs->set_deep_sleep_dcefclk((smu), (clk)) : 0)
|
|
||||||
#define smu_set_active_display_count(smu, count) \
|
|
||||||
((smu)->funcs->set_active_display_count ? (smu)->funcs->set_active_display_count((smu), (count)) : 0)
|
|
||||||
#define smu_store_cc6_data(smu, st, cc6_dis, pst_dis, pst_sw_dis) \
|
|
||||||
((smu)->funcs->store_cc6_data ? (smu)->funcs->store_cc6_data((smu), (st), (cc6_dis), (pst_dis), (pst_sw_dis)) : 0)
|
|
||||||
#define smu_get_clock_by_type(smu, type, clocks) \
|
|
||||||
((smu)->funcs->get_clock_by_type ? (smu)->funcs->get_clock_by_type((smu), (type), (clocks)) : 0)
|
|
||||||
#define smu_get_max_high_clocks(smu, clocks) \
|
|
||||||
((smu)->funcs->get_max_high_clocks ? (smu)->funcs->get_max_high_clocks((smu), (clocks)) : 0)
|
|
||||||
#define smu_get_clock_by_type_with_latency(smu, clk_type, clocks) \
|
|
||||||
((smu)->ppt_funcs->get_clock_by_type_with_latency ? (smu)->ppt_funcs->get_clock_by_type_with_latency((smu), (clk_type), (clocks)) : 0)
|
|
||||||
#define smu_get_clock_by_type_with_voltage(smu, type, clocks) \
|
|
||||||
((smu)->ppt_funcs->get_clock_by_type_with_voltage ? (smu)->ppt_funcs->get_clock_by_type_with_voltage((smu), (type), (clocks)) : 0)
|
|
||||||
#define smu_display_clock_voltage_request(smu, clock_req) \
|
|
||||||
((smu)->funcs->display_clock_voltage_request ? (smu)->funcs->display_clock_voltage_request((smu), (clock_req)) : 0)
|
|
||||||
#define smu_display_disable_memory_clock_switch(smu, disable_memory_clock_switch) \
|
|
||||||
((smu)->ppt_funcs->display_disable_memory_clock_switch ? (smu)->ppt_funcs->display_disable_memory_clock_switch((smu), (disable_memory_clock_switch)) : -EINVAL)
|
|
||||||
#define smu_get_dal_power_level(smu, clocks) \
|
|
||||||
((smu)->funcs->get_dal_power_level ? (smu)->funcs->get_dal_power_level((smu), (clocks)) : 0)
|
|
||||||
#define smu_get_perf_level(smu, designation, level) \
|
|
||||||
((smu)->funcs->get_perf_level ? (smu)->funcs->get_perf_level((smu), (designation), (level)) : 0)
|
|
||||||
#define smu_get_current_shallow_sleep_clocks(smu, clocks) \
|
|
||||||
((smu)->funcs->get_current_shallow_sleep_clocks ? (smu)->funcs->get_current_shallow_sleep_clocks((smu), (clocks)) : 0)
|
|
||||||
#define smu_notify_smu_enable_pwe(smu) \
|
|
||||||
((smu)->funcs->notify_smu_enable_pwe ? (smu)->funcs->notify_smu_enable_pwe((smu)) : 0)
|
|
||||||
#define smu_dpm_set_uvd_enable(smu, enable) \
|
|
||||||
((smu)->ppt_funcs->dpm_set_uvd_enable ? (smu)->ppt_funcs->dpm_set_uvd_enable((smu), (enable)) : 0)
|
|
||||||
#define smu_dpm_set_vce_enable(smu, enable) \
|
|
||||||
((smu)->ppt_funcs->dpm_set_vce_enable ? (smu)->ppt_funcs->dpm_set_vce_enable((smu), (enable)) : 0)
|
|
||||||
#define smu_set_xgmi_pstate(smu, pstate) \
|
|
||||||
((smu)->funcs->set_xgmi_pstate ? (smu)->funcs->set_xgmi_pstate((smu), (pstate)) : 0)
|
|
||||||
#define smu_set_watermarks_table(smu, tab, clock_ranges) \
|
|
||||||
((smu)->ppt_funcs->set_watermarks_table ? (smu)->ppt_funcs->set_watermarks_table((smu), (tab), (clock_ranges)) : 0)
|
|
||||||
#define smu_get_current_clk_freq_by_table(smu, clk_type, value) \
|
|
||||||
((smu)->ppt_funcs->get_current_clk_freq_by_table ? (smu)->ppt_funcs->get_current_clk_freq_by_table((smu), (clk_type), (value)) : 0)
|
|
||||||
#define smu_thermal_temperature_range_update(smu, range, rw) \
|
|
||||||
((smu)->ppt_funcs->thermal_temperature_range_update? (smu)->ppt_funcs->thermal_temperature_range_update((smu), (range), (rw)) : 0)
|
|
||||||
#define smu_get_thermal_temperature_range(smu, range) \
|
|
||||||
((smu)->ppt_funcs->get_thermal_temperature_range? (smu)->ppt_funcs->get_thermal_temperature_range((smu), (range)) : 0)
|
|
||||||
#define smu_register_irq_handler(smu) \
|
|
||||||
((smu)->funcs->register_irq_handler ? (smu)->funcs->register_irq_handler(smu) : 0)
|
|
||||||
#define smu_set_azalia_d3_pme(smu) \
|
|
||||||
((smu)->funcs->set_azalia_d3_pme ? (smu)->funcs->set_azalia_d3_pme((smu)) : 0)
|
|
||||||
#define smu_get_dpm_ultimate_freq(smu, param, min, max) \
|
|
||||||
((smu)->funcs->get_dpm_ultimate_freq ? (smu)->funcs->get_dpm_ultimate_freq((smu), (param), (min), (max)) : 0)
|
|
||||||
#define smu_get_max_sustainable_clocks_by_dc(smu, max_clocks) \
|
|
||||||
((smu)->funcs->get_max_sustainable_clocks_by_dc ? (smu)->funcs->get_max_sustainable_clocks_by_dc((smu), (max_clocks)) : 0)
|
|
||||||
#define smu_baco_is_support(smu) \
|
|
||||||
((smu)->funcs->baco_is_support? (smu)->funcs->baco_is_support((smu)) : false)
|
|
||||||
#define smu_baco_get_state(smu, state) \
|
|
||||||
((smu)->funcs->baco_get_state? (smu)->funcs->baco_get_state((smu), (state)) : 0)
|
|
||||||
#define smu_baco_reset(smu) \
|
|
||||||
((smu)->funcs->baco_reset? (smu)->funcs->baco_reset((smu)) : 0)
|
|
||||||
#define smu_mode2_reset(smu) \
|
|
||||||
((smu)->funcs->mode2_reset? (smu)->funcs->mode2_reset((smu)) : 0)
|
|
||||||
#define smu_asic_set_performance_level(smu, level) \
|
|
||||||
((smu)->ppt_funcs->set_performance_level? (smu)->ppt_funcs->set_performance_level((smu), (level)) : -EINVAL);
|
|
||||||
#define smu_dump_pptable(smu) \
|
|
||||||
((smu)->ppt_funcs->dump_pptable ? (smu)->ppt_funcs->dump_pptable((smu)) : 0)
|
|
||||||
#define smu_get_dpm_clk_limited(smu, clk_type, dpm_level, freq) \
|
|
||||||
((smu)->ppt_funcs->get_dpm_clk_limited ? (smu)->ppt_funcs->get_dpm_clk_limited((smu), (clk_type), (dpm_level), (freq)) : -EINVAL)
|
|
||||||
#define smu_set_soft_freq_limited_range(smu, clk_type, min, max) \
|
|
||||||
((smu)->funcs->set_soft_freq_limited_range ? (smu)->funcs->set_soft_freq_limited_range((smu), (clk_type), (min), (max)) : -EINVAL)
|
|
||||||
#define smu_get_dpm_clock_table(smu, clock_table) \
|
|
||||||
((smu)->ppt_funcs->get_dpm_clock_table ? (smu)->ppt_funcs->get_dpm_clock_table((smu), (clock_table)) : -EINVAL)
|
|
||||||
|
|
||||||
#define smu_override_pcie_parameters(smu) \
|
int smu_set_gfx_cgpg(struct smu_context *smu, bool enabled);
|
||||||
((smu)->funcs->override_pcie_parameters ? (smu)->funcs->override_pcie_parameters((smu)) : 0)
|
|
||||||
|
|
||||||
#define smu_update_pcie_parameters(smu, pcie_gen_cap, pcie_width_cap) \
|
#define smu_i2c_eeprom_init(smu, control) \
|
||||||
((smu)->ppt_funcs->update_pcie_parameters ? (smu)->ppt_funcs->update_pcie_parameters((smu), (pcie_gen_cap), (pcie_width_cap)) : 0)
|
((smu)->ppt_funcs->i2c_eeprom_init ? (smu)->ppt_funcs->i2c_eeprom_init((control)) : -EINVAL)
|
||||||
|
#define smu_i2c_eeprom_fini(smu, control) \
|
||||||
|
((smu)->ppt_funcs->i2c_eeprom_fini ? (smu)->ppt_funcs->i2c_eeprom_fini((control)) : -EINVAL)
|
||||||
|
|
||||||
|
int smu_set_fan_speed_rpm(struct smu_context *smu, uint32_t speed);
|
||||||
|
|
||||||
|
int smu_get_power_limit(struct smu_context *smu,
|
||||||
|
uint32_t *limit,
|
||||||
|
bool def,
|
||||||
|
bool lock_needed);
|
||||||
|
|
||||||
|
int smu_set_power_limit(struct smu_context *smu, uint32_t limit);
|
||||||
|
int smu_print_clk_levels(struct smu_context *smu, enum smu_clk_type clk_type, char *buf);
|
||||||
|
int smu_get_od_percentage(struct smu_context *smu, enum smu_clk_type type);
|
||||||
|
int smu_set_od_percentage(struct smu_context *smu, enum smu_clk_type type, uint32_t value);
|
||||||
|
|
||||||
|
int smu_od_edit_dpm_table(struct smu_context *smu,
|
||||||
|
enum PP_OD_DPM_TABLE_COMMAND type,
|
||||||
|
long *input, uint32_t size);
|
||||||
|
|
||||||
|
int smu_read_sensor(struct smu_context *smu,
|
||||||
|
enum amd_pp_sensors sensor,
|
||||||
|
void *data, uint32_t *size);
|
||||||
|
int smu_get_power_profile_mode(struct smu_context *smu, char *buf);
|
||||||
|
|
||||||
|
int smu_set_power_profile_mode(struct smu_context *smu,
|
||||||
|
long *param,
|
||||||
|
uint32_t param_size,
|
||||||
|
bool lock_needed);
|
||||||
|
int smu_get_fan_control_mode(struct smu_context *smu);
|
||||||
|
int smu_set_fan_control_mode(struct smu_context *smu, int value);
|
||||||
|
int smu_get_fan_speed_percent(struct smu_context *smu, uint32_t *speed);
|
||||||
|
int smu_set_fan_speed_percent(struct smu_context *smu, uint32_t speed);
|
||||||
|
int smu_get_fan_speed_rpm(struct smu_context *smu, uint32_t *speed);
|
||||||
|
|
||||||
|
int smu_set_deep_sleep_dcefclk(struct smu_context *smu, int clk);
|
||||||
|
int smu_set_active_display_count(struct smu_context *smu, uint32_t count);
|
||||||
|
|
||||||
|
int smu_get_clock_by_type(struct smu_context *smu,
|
||||||
|
enum amd_pp_clock_type type,
|
||||||
|
struct amd_pp_clocks *clocks);
|
||||||
|
|
||||||
|
int smu_get_max_high_clocks(struct smu_context *smu,
|
||||||
|
struct amd_pp_simple_clock_info *clocks);
|
||||||
|
|
||||||
|
int smu_get_clock_by_type_with_latency(struct smu_context *smu,
|
||||||
|
enum smu_clk_type clk_type,
|
||||||
|
struct pp_clock_levels_with_latency *clocks);
|
||||||
|
|
||||||
|
int smu_get_clock_by_type_with_voltage(struct smu_context *smu,
|
||||||
|
enum amd_pp_clock_type type,
|
||||||
|
struct pp_clock_levels_with_voltage *clocks);
|
||||||
|
|
||||||
|
int smu_display_clock_voltage_request(struct smu_context *smu,
|
||||||
|
struct pp_display_clock_request *clock_req);
|
||||||
|
int smu_display_disable_memory_clock_switch(struct smu_context *smu, bool disable_memory_clock_switch);
|
||||||
|
int smu_notify_smu_enable_pwe(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_set_xgmi_pstate(struct smu_context *smu,
|
||||||
|
uint32_t pstate);
|
||||||
|
|
||||||
|
int smu_set_azalia_d3_pme(struct smu_context *smu);
|
||||||
|
|
||||||
|
bool smu_baco_is_support(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_baco_get_state(struct smu_context *smu, enum smu_baco_state *state);
|
||||||
|
|
||||||
|
int smu_baco_reset(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_mode2_reset(struct smu_context *smu);
|
||||||
|
|
||||||
extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table,
|
extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table,
|
||||||
uint16_t *size, uint8_t *frev, uint8_t *crev,
|
uint16_t *size, uint8_t *frev, uint8_t *crev,
|
||||||
@ -829,7 +674,8 @@ extern int smu_get_current_clocks(struct smu_context *smu,
|
|||||||
extern int smu_dpm_set_power_gate(struct smu_context *smu,uint32_t block_type, bool gate);
|
extern int smu_dpm_set_power_gate(struct smu_context *smu,uint32_t block_type, bool gate);
|
||||||
extern int smu_handle_task(struct smu_context *smu,
|
extern int smu_handle_task(struct smu_context *smu,
|
||||||
enum amd_dpm_forced_level level,
|
enum amd_dpm_forced_level level,
|
||||||
enum amd_pp_task task_id);
|
enum amd_pp_task task_id,
|
||||||
|
bool lock_needed);
|
||||||
int smu_switch_power_profile(struct smu_context *smu,
|
int smu_switch_power_profile(struct smu_context *smu,
|
||||||
enum PP_SMC_POWER_PROFILE type,
|
enum PP_SMC_POWER_PROFILE type,
|
||||||
bool en);
|
bool en);
|
||||||
@ -839,7 +685,7 @@ int smu_get_dpm_freq_by_index(struct smu_context *smu, enum smu_clk_type clk_typ
|
|||||||
int smu_get_dpm_level_count(struct smu_context *smu, enum smu_clk_type clk_type,
|
int smu_get_dpm_level_count(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||||
uint32_t *value);
|
uint32_t *value);
|
||||||
int smu_get_dpm_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
int smu_get_dpm_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||||
uint32_t *min, uint32_t *max);
|
uint32_t *min, uint32_t *max, bool lock_needed);
|
||||||
int smu_set_soft_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
int smu_set_soft_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||||
uint32_t min, uint32_t max);
|
uint32_t min, uint32_t max);
|
||||||
int smu_set_hard_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
int smu_set_hard_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||||
@ -854,10 +700,21 @@ size_t smu_sys_get_pp_feature_mask(struct smu_context *smu, char *buf);
|
|||||||
int smu_sys_set_pp_feature_mask(struct smu_context *smu, uint64_t new_mask);
|
int smu_sys_set_pp_feature_mask(struct smu_context *smu, uint64_t new_mask);
|
||||||
int smu_force_clk_levels(struct smu_context *smu,
|
int smu_force_clk_levels(struct smu_context *smu,
|
||||||
enum smu_clk_type clk_type,
|
enum smu_clk_type clk_type,
|
||||||
uint32_t mask);
|
uint32_t mask,
|
||||||
|
bool lock_needed);
|
||||||
int smu_set_mp1_state(struct smu_context *smu,
|
int smu_set_mp1_state(struct smu_context *smu,
|
||||||
enum pp_mp1_state mp1_state);
|
enum pp_mp1_state mp1_state);
|
||||||
int smu_set_df_cstate(struct smu_context *smu,
|
int smu_set_df_cstate(struct smu_context *smu,
|
||||||
enum pp_df_cstate state);
|
enum pp_df_cstate state);
|
||||||
|
|
||||||
|
int smu_get_max_sustainable_clocks_by_dc(struct smu_context *smu,
|
||||||
|
struct pp_smu_nv_clock_table *max_clocks);
|
||||||
|
|
||||||
|
int smu_get_uclk_dpm_states(struct smu_context *smu,
|
||||||
|
unsigned int *clock_values_in_khz,
|
||||||
|
unsigned int *num_states);
|
||||||
|
|
||||||
|
int smu_get_dpm_clock_table(struct smu_context *smu,
|
||||||
|
struct dpm_clocks *clock_table);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -423,18 +423,30 @@ typedef enum {
|
|||||||
} PwrConfig_e;
|
} PwrConfig_e;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
XGMI_LINK_RATE_12 = 0, // 12Gbps
|
XGMI_LINK_RATE_2 = 2, // 2Gbps
|
||||||
XGMI_LINK_RATE_16, // 16Gbps
|
XGMI_LINK_RATE_4 = 4, // 4Gbps
|
||||||
XGMI_LINK_RATE_22, // 22Gbps
|
XGMI_LINK_RATE_8 = 8, // 8Gbps
|
||||||
XGMI_LINK_RATE_25, // 25Gbps
|
XGMI_LINK_RATE_12 = 12, // 12Gbps
|
||||||
|
XGMI_LINK_RATE_16 = 16, // 16Gbps
|
||||||
|
XGMI_LINK_RATE_17 = 17, // 17Gbps
|
||||||
|
XGMI_LINK_RATE_18 = 18, // 18Gbps
|
||||||
|
XGMI_LINK_RATE_19 = 19, // 19Gbps
|
||||||
|
XGMI_LINK_RATE_20 = 20, // 20Gbps
|
||||||
|
XGMI_LINK_RATE_21 = 21, // 21Gbps
|
||||||
|
XGMI_LINK_RATE_22 = 22, // 22Gbps
|
||||||
|
XGMI_LINK_RATE_23 = 23, // 23Gbps
|
||||||
|
XGMI_LINK_RATE_24 = 24, // 24Gbps
|
||||||
|
XGMI_LINK_RATE_25 = 25, // 25Gbps
|
||||||
XGMI_LINK_RATE_COUNT
|
XGMI_LINK_RATE_COUNT
|
||||||
} XGMI_LINK_RATE_e;
|
} XGMI_LINK_RATE_e;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
XGMI_LINK_WIDTH_2 = 0, // x2
|
XGMI_LINK_WIDTH_1 = 1, // x1
|
||||||
XGMI_LINK_WIDTH_4, // x4
|
XGMI_LINK_WIDTH_2 = 2, // x2
|
||||||
XGMI_LINK_WIDTH_8, // x8
|
XGMI_LINK_WIDTH_4 = 4, // x4
|
||||||
XGMI_LINK_WIDTH_16, // x16
|
XGMI_LINK_WIDTH_8 = 8, // x8
|
||||||
|
XGMI_LINK_WIDTH_9 = 9, // x9
|
||||||
|
XGMI_LINK_WIDTH_16 = 16, // x16
|
||||||
XGMI_LINK_WIDTH_COUNT
|
XGMI_LINK_WIDTH_COUNT
|
||||||
} XGMI_LINK_WIDTH_e;
|
} XGMI_LINK_WIDTH_e;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#define SMU11_DRIVER_IF_VERSION_INV 0xFFFFFFFF
|
#define SMU11_DRIVER_IF_VERSION_INV 0xFFFFFFFF
|
||||||
#define SMU11_DRIVER_IF_VERSION_VG20 0x13
|
#define SMU11_DRIVER_IF_VERSION_VG20 0x13
|
||||||
#define SMU11_DRIVER_IF_VERSION_ARCT 0x0D
|
#define SMU11_DRIVER_IF_VERSION_ARCT 0x0F
|
||||||
#define SMU11_DRIVER_IF_VERSION_NV10 0x33
|
#define SMU11_DRIVER_IF_VERSION_NV10 0x33
|
||||||
#define SMU11_DRIVER_IF_VERSION_NV14 0x34
|
#define SMU11_DRIVER_IF_VERSION_NV14 0x34
|
||||||
|
|
||||||
@ -130,6 +130,124 @@ enum smu_v11_0_baco_seq {
|
|||||||
BACO_SEQ_COUNT,
|
BACO_SEQ_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
void smu_v11_0_set_smu_funcs(struct smu_context *smu);
|
int smu_v11_0_init_microcode(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_load_microcode(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_init_smc_tables(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_fini_smc_tables(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_init_power(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_fini_power(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_check_fw_status(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_setup_pptable(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_get_vbios_bootup_values(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_get_clk_info_from_vbios(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_check_pptable(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_parse_pptable(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_populate_smc_pptable(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_check_fw_version(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_write_pptable(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_set_min_dcef_deep_sleep(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_set_tool_table_location(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_notify_memory_pool_location(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_system_features_control(struct smu_context *smu,
|
||||||
|
bool en);
|
||||||
|
|
||||||
|
int smu_v11_0_send_msg(struct smu_context *smu, uint16_t msg);
|
||||||
|
|
||||||
|
int
|
||||||
|
smu_v11_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
|
||||||
|
uint32_t param);
|
||||||
|
|
||||||
|
int smu_v11_0_read_arg(struct smu_context *smu, uint32_t *arg);
|
||||||
|
|
||||||
|
int smu_v11_0_init_display_count(struct smu_context *smu, uint32_t count);
|
||||||
|
|
||||||
|
int smu_v11_0_set_allowed_mask(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_get_enabled_mask(struct smu_context *smu,
|
||||||
|
uint32_t *feature_mask, uint32_t num);
|
||||||
|
|
||||||
|
int smu_v11_0_notify_display_change(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n);
|
||||||
|
|
||||||
|
int smu_v11_0_get_current_clk_freq(struct smu_context *smu,
|
||||||
|
enum smu_clk_type clk_id,
|
||||||
|
uint32_t *value);
|
||||||
|
|
||||||
|
int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_start_thermal_control(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_stop_thermal_control(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_read_sensor(struct smu_context *smu,
|
||||||
|
enum amd_pp_sensors sensor,
|
||||||
|
void *data, uint32_t *size);
|
||||||
|
|
||||||
|
int smu_v11_0_set_deep_sleep_dcefclk(struct smu_context *smu, uint32_t clk);
|
||||||
|
|
||||||
|
int
|
||||||
|
smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
|
||||||
|
struct pp_display_clock_request
|
||||||
|
*clock_req);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
smu_v11_0_get_fan_control_mode(struct smu_context *smu);
|
||||||
|
|
||||||
|
int
|
||||||
|
smu_v11_0_set_fan_control_mode(struct smu_context *smu,
|
||||||
|
uint32_t mode);
|
||||||
|
|
||||||
|
int
|
||||||
|
smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed);
|
||||||
|
|
||||||
|
int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu,
|
||||||
|
uint32_t speed);
|
||||||
|
|
||||||
|
int smu_v11_0_set_xgmi_pstate(struct smu_context *smu,
|
||||||
|
uint32_t pstate);
|
||||||
|
|
||||||
|
int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable);
|
||||||
|
|
||||||
|
int smu_v11_0_register_irq_handler(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_set_azalia_d3_pme(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_get_max_sustainable_clocks_by_dc(struct smu_context *smu,
|
||||||
|
struct pp_smu_nv_clock_table *max_clocks);
|
||||||
|
|
||||||
|
bool smu_v11_0_baco_is_support(struct smu_context *smu);
|
||||||
|
|
||||||
|
enum smu_baco_state smu_v11_0_baco_get_state(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state);
|
||||||
|
|
||||||
|
int smu_v11_0_baco_reset(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v11_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||||
|
uint32_t *min, uint32_t *max);
|
||||||
|
|
||||||
|
int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||||
|
uint32_t min, uint32_t max);
|
||||||
|
|
||||||
|
int smu_v11_0_override_pcie_parameters(struct smu_context *smu);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,6 +37,45 @@ struct smu_12_0_cmn2aisc_mapping {
|
|||||||
int map_to;
|
int map_to;
|
||||||
};
|
};
|
||||||
|
|
||||||
void smu_v12_0_set_smu_funcs(struct smu_context *smu);
|
int smu_v12_0_send_msg_without_waiting(struct smu_context *smu,
|
||||||
|
uint16_t msg);
|
||||||
|
|
||||||
|
int smu_v12_0_read_arg(struct smu_context *smu, uint32_t *arg);
|
||||||
|
|
||||||
|
int smu_v12_0_wait_for_response(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v12_0_send_msg(struct smu_context *smu, uint16_t msg);
|
||||||
|
|
||||||
|
int
|
||||||
|
smu_v12_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
|
||||||
|
uint32_t param);
|
||||||
|
|
||||||
|
int smu_v12_0_check_fw_status(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v12_0_check_fw_version(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v12_0_powergate_sdma(struct smu_context *smu, bool gate);
|
||||||
|
|
||||||
|
int smu_v12_0_powergate_vcn(struct smu_context *smu, bool gate);
|
||||||
|
|
||||||
|
int smu_v12_0_set_gfx_cgpg(struct smu_context *smu, bool enable);
|
||||||
|
|
||||||
|
uint32_t smu_v12_0_get_gfxoff_status(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v12_0_gfx_off_control(struct smu_context *smu, bool enable);
|
||||||
|
|
||||||
|
int smu_v12_0_init_smc_tables(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v12_0_fini_smc_tables(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v12_0_populate_smc_tables(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v12_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||||
|
uint32_t *min, uint32_t *max);
|
||||||
|
|
||||||
|
int smu_v12_0_mode2_reset(struct smu_context *smu);
|
||||||
|
|
||||||
|
int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||||
|
uint32_t min, uint32_t max);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include "amdgpu.h"
|
#include "amdgpu.h"
|
||||||
#include "amdgpu_smu.h"
|
#include "amdgpu_smu.h"
|
||||||
|
#include "smu_internal.h"
|
||||||
#include "atomfirmware.h"
|
#include "atomfirmware.h"
|
||||||
#include "amdgpu_atomfirmware.h"
|
#include "amdgpu_atomfirmware.h"
|
||||||
#include "smu_v11_0.h"
|
#include "smu_v11_0.h"
|
||||||
@ -796,13 +797,13 @@ static int navi10_populate_umd_state_clk(struct smu_context *smu)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint32_t min_sclk_freq = 0, min_mclk_freq = 0;
|
uint32_t min_sclk_freq = 0, min_mclk_freq = 0;
|
||||||
|
|
||||||
ret = smu_get_dpm_freq_range(smu, SMU_SCLK, &min_sclk_freq, NULL);
|
ret = smu_get_dpm_freq_range(smu, SMU_SCLK, &min_sclk_freq, NULL, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
smu->pstate_sclk = min_sclk_freq * 100;
|
smu->pstate_sclk = min_sclk_freq * 100;
|
||||||
|
|
||||||
ret = smu_get_dpm_freq_range(smu, SMU_MCLK, &min_mclk_freq, NULL);
|
ret = smu_get_dpm_freq_range(smu, SMU_MCLK, &min_mclk_freq, NULL, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -855,7 +856,7 @@ static int navi10_pre_display_config_changed(struct smu_context *smu)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
|
if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
|
||||||
ret = smu_get_dpm_freq_range(smu, SMU_UCLK, NULL, &max_freq);
|
ret = smu_get_dpm_freq_range(smu, SMU_UCLK, NULL, &max_freq, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = smu_set_hard_freq_range(smu, SMU_UCLK, 0, max_freq);
|
ret = smu_set_hard_freq_range(smu, SMU_UCLK, 0, max_freq);
|
||||||
@ -905,7 +906,7 @@ static int navi10_force_dpm_limit_value(struct smu_context *smu, bool highest)
|
|||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(clks); i++) {
|
for (i = 0; i < ARRAY_SIZE(clks); i++) {
|
||||||
clk_type = clks[i];
|
clk_type = clks[i];
|
||||||
ret = smu_get_dpm_freq_range(smu, clk_type, &min_freq, &max_freq);
|
ret = smu_get_dpm_freq_range(smu, clk_type, &min_freq, &max_freq, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -932,7 +933,7 @@ static int navi10_unforce_dpm_levels(struct smu_context *smu)
|
|||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(clks); i++) {
|
for (i = 0; i < ARRAY_SIZE(clks); i++) {
|
||||||
clk_type = clks[i];
|
clk_type = clks[i];
|
||||||
ret = smu_get_dpm_freq_range(smu, clk_type, &min_freq, &max_freq);
|
ret = smu_get_dpm_freq_range(smu, clk_type, &min_freq, &max_freq, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -1267,7 +1268,9 @@ static int navi10_notify_smc_dispaly_config(struct smu_context *smu)
|
|||||||
if (smu_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
|
if (smu_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
|
||||||
clock_req.clock_type = amd_pp_dcef_clock;
|
clock_req.clock_type = amd_pp_dcef_clock;
|
||||||
clock_req.clock_freq_in_khz = min_clocks.dcef_clock * 10;
|
clock_req.clock_freq_in_khz = min_clocks.dcef_clock * 10;
|
||||||
if (!smu_display_clock_voltage_request(smu, &clock_req)) {
|
|
||||||
|
ret = smu_v11_0_display_clock_voltage_request(smu, &clock_req);
|
||||||
|
if (!ret) {
|
||||||
if (smu_feature_is_supported(smu, SMU_FEATURE_DS_DCEFCLK_BIT)) {
|
if (smu_feature_is_supported(smu, SMU_FEATURE_DS_DCEFCLK_BIT)) {
|
||||||
ret = smu_send_smc_msg_with_param(smu,
|
ret = smu_send_smc_msg_with_param(smu,
|
||||||
SMU_MSG_SetMinDeepSleepDcefclk,
|
SMU_MSG_SetMinDeepSleepDcefclk,
|
||||||
@ -1421,7 +1424,7 @@ static int navi10_read_sensor(struct smu_context *smu,
|
|||||||
*size = 4;
|
*size = 4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = smu_smc_read_sensor(smu, sensor, data, size);
|
ret = smu_v11_0_read_sensor(smu, sensor, data, size);
|
||||||
}
|
}
|
||||||
mutex_unlock(&smu->sensor_lock);
|
mutex_unlock(&smu->sensor_lock);
|
||||||
|
|
||||||
@ -1690,6 +1693,55 @@ static const struct pptable_funcs navi10_ppt_funcs = {
|
|||||||
.display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch,
|
.display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch,
|
||||||
.get_power_limit = navi10_get_power_limit,
|
.get_power_limit = navi10_get_power_limit,
|
||||||
.update_pcie_parameters = navi10_update_pcie_parameters,
|
.update_pcie_parameters = navi10_update_pcie_parameters,
|
||||||
|
.init_microcode = smu_v11_0_init_microcode,
|
||||||
|
.load_microcode = smu_v11_0_load_microcode,
|
||||||
|
.init_smc_tables = smu_v11_0_init_smc_tables,
|
||||||
|
.fini_smc_tables = smu_v11_0_fini_smc_tables,
|
||||||
|
.init_power = smu_v11_0_init_power,
|
||||||
|
.fini_power = smu_v11_0_fini_power,
|
||||||
|
.check_fw_status = smu_v11_0_check_fw_status,
|
||||||
|
.setup_pptable = smu_v11_0_setup_pptable,
|
||||||
|
.get_vbios_bootup_values = smu_v11_0_get_vbios_bootup_values,
|
||||||
|
.get_clk_info_from_vbios = smu_v11_0_get_clk_info_from_vbios,
|
||||||
|
.check_pptable = smu_v11_0_check_pptable,
|
||||||
|
.parse_pptable = smu_v11_0_parse_pptable,
|
||||||
|
.populate_smc_tables = smu_v11_0_populate_smc_pptable,
|
||||||
|
.check_fw_version = smu_v11_0_check_fw_version,
|
||||||
|
.write_pptable = smu_v11_0_write_pptable,
|
||||||
|
.set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep,
|
||||||
|
.set_tool_table_location = smu_v11_0_set_tool_table_location,
|
||||||
|
.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
|
||||||
|
.system_features_control = smu_v11_0_system_features_control,
|
||||||
|
.send_smc_msg = smu_v11_0_send_msg,
|
||||||
|
.send_smc_msg_with_param = smu_v11_0_send_msg_with_param,
|
||||||
|
.read_smc_arg = smu_v11_0_read_arg,
|
||||||
|
.init_display_count = smu_v11_0_init_display_count,
|
||||||
|
.set_allowed_mask = smu_v11_0_set_allowed_mask,
|
||||||
|
.get_enabled_mask = smu_v11_0_get_enabled_mask,
|
||||||
|
.notify_display_change = smu_v11_0_notify_display_change,
|
||||||
|
.set_power_limit = smu_v11_0_set_power_limit,
|
||||||
|
.get_current_clk_freq = smu_v11_0_get_current_clk_freq,
|
||||||
|
.init_max_sustainable_clocks = smu_v11_0_init_max_sustainable_clocks,
|
||||||
|
.start_thermal_control = smu_v11_0_start_thermal_control,
|
||||||
|
.stop_thermal_control = smu_v11_0_stop_thermal_control,
|
||||||
|
.set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk,
|
||||||
|
.display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
|
||||||
|
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
|
||||||
|
.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
|
||||||
|
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
|
||||||
|
.set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
|
||||||
|
.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
|
||||||
|
.gfx_off_control = smu_v11_0_gfx_off_control,
|
||||||
|
.register_irq_handler = smu_v11_0_register_irq_handler,
|
||||||
|
.set_azalia_d3_pme = smu_v11_0_set_azalia_d3_pme,
|
||||||
|
.get_max_sustainable_clocks_by_dc = smu_v11_0_get_max_sustainable_clocks_by_dc,
|
||||||
|
.baco_is_support= smu_v11_0_baco_is_support,
|
||||||
|
.baco_get_state = smu_v11_0_baco_get_state,
|
||||||
|
.baco_set_state = smu_v11_0_baco_set_state,
|
||||||
|
.baco_reset = smu_v11_0_baco_reset,
|
||||||
|
.get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq,
|
||||||
|
.set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
|
||||||
|
.override_pcie_parameters = smu_v11_0_override_pcie_parameters,
|
||||||
};
|
};
|
||||||
|
|
||||||
void navi10_set_ppt_funcs(struct smu_context *smu)
|
void navi10_set_ppt_funcs(struct smu_context *smu)
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "amdgpu.h"
|
#include "amdgpu.h"
|
||||||
#include "amdgpu_smu.h"
|
#include "amdgpu_smu.h"
|
||||||
|
#include "smu_internal.h"
|
||||||
#include "soc15_common.h"
|
#include "soc15_common.h"
|
||||||
#include "smu_v12_0_ppsmc.h"
|
#include "smu_v12_0_ppsmc.h"
|
||||||
#include "smu12_driver_if.h"
|
#include "smu12_driver_if.h"
|
||||||
@ -194,7 +195,7 @@ static int renoir_print_clk_levels(struct smu_context *smu,
|
|||||||
case SMU_SCLK:
|
case SMU_SCLK:
|
||||||
/* retirve table returned paramters unit is MHz */
|
/* retirve table returned paramters unit is MHz */
|
||||||
cur_value = metrics.ClockFrequency[CLOCK_GFXCLK];
|
cur_value = metrics.ClockFrequency[CLOCK_GFXCLK];
|
||||||
ret = smu_get_dpm_freq_range(smu, SMU_GFXCLK, &min, &max);
|
ret = smu_get_dpm_freq_range(smu, SMU_GFXCLK, &min, &max, false);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
/* driver only know min/max gfx_clk, Add level 1 for all other gfx clks */
|
/* driver only know min/max gfx_clk, Add level 1 for all other gfx clks */
|
||||||
if (cur_value == max)
|
if (cur_value == max)
|
||||||
@ -251,7 +252,6 @@ static enum amd_pm_state_type renoir_get_current_power_state(struct smu_context
|
|||||||
!smu_dpm_ctx->dpm_current_power_state)
|
!smu_dpm_ctx->dpm_current_power_state)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
mutex_lock(&(smu->mutex));
|
|
||||||
switch (smu_dpm_ctx->dpm_current_power_state->classification.ui_label) {
|
switch (smu_dpm_ctx->dpm_current_power_state->classification.ui_label) {
|
||||||
case SMU_STATE_UI_LABEL_BATTERY:
|
case SMU_STATE_UI_LABEL_BATTERY:
|
||||||
pm_type = POWER_STATE_TYPE_BATTERY;
|
pm_type = POWER_STATE_TYPE_BATTERY;
|
||||||
@ -269,7 +269,6 @@ static enum amd_pm_state_type renoir_get_current_power_state(struct smu_context
|
|||||||
pm_type = POWER_STATE_TYPE_DEFAULT;
|
pm_type = POWER_STATE_TYPE_DEFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mutex_unlock(&(smu->mutex));
|
|
||||||
|
|
||||||
return pm_type;
|
return pm_type;
|
||||||
}
|
}
|
||||||
@ -283,7 +282,7 @@ static int renoir_dpm_set_uvd_enable(struct smu_context *smu, bool enable)
|
|||||||
if (enable) {
|
if (enable) {
|
||||||
/* vcn dpm on is a prerequisite for vcn power gate messages */
|
/* vcn dpm on is a prerequisite for vcn power gate messages */
|
||||||
if (smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
|
if (smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
|
||||||
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 1);
|
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -314,7 +313,7 @@ static int renoir_force_dpm_limit_value(struct smu_context *smu, bool highest)
|
|||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(clks); i++) {
|
for (i = 0; i < ARRAY_SIZE(clks); i++) {
|
||||||
clk_type = clks[i];
|
clk_type = clks[i];
|
||||||
ret = smu_get_dpm_freq_range(smu, clk_type, &min_freq, &max_freq);
|
ret = smu_get_dpm_freq_range(smu, clk_type, &min_freq, &max_freq, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -348,7 +347,7 @@ static int renoir_unforce_dpm_levels(struct smu_context *smu) {
|
|||||||
|
|
||||||
clk_type = clk_feature_map[i].clk_type;
|
clk_type = clk_feature_map[i].clk_type;
|
||||||
|
|
||||||
ret = smu_get_dpm_freq_range(smu, clk_type, &min_freq, &max_freq);
|
ret = smu_get_dpm_freq_range(smu, clk_type, &min_freq, &max_freq, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -469,7 +468,7 @@ static int renoir_force_clk_levels(struct smu_context *smu,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = smu_get_dpm_freq_range(smu, SMU_GFXCLK, &min_freq, &max_freq);
|
ret = smu_get_dpm_freq_range(smu, SMU_GFXCLK, &min_freq, &max_freq, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
|
ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
|
||||||
@ -545,7 +544,7 @@ static int renoir_set_peak_clock_by_device(struct smu_context *smu)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint32_t sclk_freq = 0, uclk_freq = 0;
|
uint32_t sclk_freq = 0, uclk_freq = 0;
|
||||||
|
|
||||||
ret = smu_get_dpm_freq_range(smu, SMU_SCLK, NULL, &sclk_freq);
|
ret = smu_get_dpm_freq_range(smu, SMU_SCLK, NULL, &sclk_freq, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -553,7 +552,7 @@ static int renoir_set_peak_clock_by_device(struct smu_context *smu)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = smu_get_dpm_freq_range(smu, SMU_UCLK, NULL, &uclk_freq);
|
ret = smu_get_dpm_freq_range(smu, SMU_UCLK, NULL, &uclk_freq, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -692,6 +691,21 @@ static const struct pptable_funcs renoir_ppt_funcs = {
|
|||||||
.get_dpm_clock_table = renoir_get_dpm_clock_table,
|
.get_dpm_clock_table = renoir_get_dpm_clock_table,
|
||||||
.set_watermarks_table = renoir_set_watermarks_table,
|
.set_watermarks_table = renoir_set_watermarks_table,
|
||||||
.get_power_profile_mode = renoir_get_power_profile_mode,
|
.get_power_profile_mode = renoir_get_power_profile_mode,
|
||||||
|
.check_fw_status = smu_v12_0_check_fw_status,
|
||||||
|
.check_fw_version = smu_v12_0_check_fw_version,
|
||||||
|
.powergate_sdma = smu_v12_0_powergate_sdma,
|
||||||
|
.powergate_vcn = smu_v12_0_powergate_vcn,
|
||||||
|
.send_smc_msg = smu_v12_0_send_msg,
|
||||||
|
.send_smc_msg_with_param = smu_v12_0_send_msg_with_param,
|
||||||
|
.read_smc_arg = smu_v12_0_read_arg,
|
||||||
|
.set_gfx_cgpg = smu_v12_0_set_gfx_cgpg,
|
||||||
|
.gfx_off_control = smu_v12_0_gfx_off_control,
|
||||||
|
.init_smc_tables = smu_v12_0_init_smc_tables,
|
||||||
|
.fini_smc_tables = smu_v12_0_fini_smc_tables,
|
||||||
|
.populate_smc_tables = smu_v12_0_populate_smc_tables,
|
||||||
|
.get_dpm_ultimate_freq = smu_v12_0_get_dpm_ultimate_freq,
|
||||||
|
.mode2_reset = smu_v12_0_mode2_reset,
|
||||||
|
.set_soft_freq_limited_range = smu_v12_0_set_soft_freq_limited_range,
|
||||||
};
|
};
|
||||||
|
|
||||||
void renoir_set_ppt_funcs(struct smu_context *smu)
|
void renoir_set_ppt_funcs(struct smu_context *smu)
|
||||||
|
204
drivers/gpu/drm/amd/powerplay/smu_internal.h
Normal file
204
drivers/gpu/drm/amd/powerplay/smu_internal.h
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SMU_INTERNAL_H__
|
||||||
|
#define __SMU_INTERNAL_H__
|
||||||
|
|
||||||
|
#include "amdgpu_smu.h"
|
||||||
|
|
||||||
|
#define smu_init_microcode(smu) \
|
||||||
|
((smu)->ppt_funcs->init_microcode ? (smu)->ppt_funcs->init_microcode((smu)) : 0)
|
||||||
|
#define smu_init_smc_tables(smu) \
|
||||||
|
((smu)->ppt_funcs->init_smc_tables ? (smu)->ppt_funcs->init_smc_tables((smu)) : 0)
|
||||||
|
#define smu_fini_smc_tables(smu) \
|
||||||
|
((smu)->ppt_funcs->fini_smc_tables ? (smu)->ppt_funcs->fini_smc_tables((smu)) : 0)
|
||||||
|
#define smu_init_power(smu) \
|
||||||
|
((smu)->ppt_funcs->init_power ? (smu)->ppt_funcs->init_power((smu)) : 0)
|
||||||
|
#define smu_fini_power(smu) \
|
||||||
|
((smu)->ppt_funcs->fini_power ? (smu)->ppt_funcs->fini_power((smu)) : 0)
|
||||||
|
|
||||||
|
#define smu_setup_pptable(smu) \
|
||||||
|
((smu)->ppt_funcs->setup_pptable ? (smu)->ppt_funcs->setup_pptable((smu)) : 0)
|
||||||
|
#define smu_powergate_sdma(smu, gate) \
|
||||||
|
((smu)->ppt_funcs->powergate_sdma ? (smu)->ppt_funcs->powergate_sdma((smu), (gate)) : 0)
|
||||||
|
#define smu_powergate_vcn(smu, gate) \
|
||||||
|
((smu)->ppt_funcs->powergate_vcn ? (smu)->ppt_funcs->powergate_vcn((smu), (gate)) : 0)
|
||||||
|
|
||||||
|
#define smu_get_vbios_bootup_values(smu) \
|
||||||
|
((smu)->ppt_funcs->get_vbios_bootup_values ? (smu)->ppt_funcs->get_vbios_bootup_values((smu)) : 0)
|
||||||
|
#define smu_get_clk_info_from_vbios(smu) \
|
||||||
|
((smu)->ppt_funcs->get_clk_info_from_vbios ? (smu)->ppt_funcs->get_clk_info_from_vbios((smu)) : 0)
|
||||||
|
#define smu_check_pptable(smu) \
|
||||||
|
((smu)->ppt_funcs->check_pptable ? (smu)->ppt_funcs->check_pptable((smu)) : 0)
|
||||||
|
#define smu_parse_pptable(smu) \
|
||||||
|
((smu)->ppt_funcs->parse_pptable ? (smu)->ppt_funcs->parse_pptable((smu)) : 0)
|
||||||
|
#define smu_populate_smc_tables(smu) \
|
||||||
|
((smu)->ppt_funcs->populate_smc_tables ? (smu)->ppt_funcs->populate_smc_tables((smu)) : 0)
|
||||||
|
#define smu_check_fw_version(smu) \
|
||||||
|
((smu)->ppt_funcs->check_fw_version ? (smu)->ppt_funcs->check_fw_version((smu)) : 0)
|
||||||
|
#define smu_write_pptable(smu) \
|
||||||
|
((smu)->ppt_funcs->write_pptable ? (smu)->ppt_funcs->write_pptable((smu)) : 0)
|
||||||
|
#define smu_set_min_dcef_deep_sleep(smu) \
|
||||||
|
((smu)->ppt_funcs->set_min_dcef_deep_sleep ? (smu)->ppt_funcs->set_min_dcef_deep_sleep((smu)) : 0)
|
||||||
|
#define smu_set_tool_table_location(smu) \
|
||||||
|
((smu)->ppt_funcs->set_tool_table_location ? (smu)->ppt_funcs->set_tool_table_location((smu)) : 0)
|
||||||
|
#define smu_notify_memory_pool_location(smu) \
|
||||||
|
((smu)->ppt_funcs->notify_memory_pool_location ? (smu)->ppt_funcs->notify_memory_pool_location((smu)) : 0)
|
||||||
|
#define smu_gfx_off_control(smu, enable) \
|
||||||
|
((smu)->ppt_funcs->gfx_off_control ? (smu)->ppt_funcs->gfx_off_control((smu), (enable)) : 0)
|
||||||
|
|
||||||
|
#define smu_set_last_dcef_min_deep_sleep_clk(smu) \
|
||||||
|
((smu)->ppt_funcs->set_last_dcef_min_deep_sleep_clk ? (smu)->ppt_funcs->set_last_dcef_min_deep_sleep_clk((smu)) : 0)
|
||||||
|
#define smu_system_features_control(smu, en) \
|
||||||
|
((smu)->ppt_funcs->system_features_control ? (smu)->ppt_funcs->system_features_control((smu), (en)) : 0)
|
||||||
|
#define smu_init_max_sustainable_clocks(smu) \
|
||||||
|
((smu)->ppt_funcs->init_max_sustainable_clocks ? (smu)->ppt_funcs->init_max_sustainable_clocks((smu)) : 0)
|
||||||
|
#define smu_set_default_od_settings(smu, initialize) \
|
||||||
|
((smu)->ppt_funcs->set_default_od_settings ? (smu)->ppt_funcs->set_default_od_settings((smu), (initialize)) : 0)
|
||||||
|
|
||||||
|
#define smu_send_smc_msg(smu, msg) \
|
||||||
|
((smu)->ppt_funcs->send_smc_msg? (smu)->ppt_funcs->send_smc_msg((smu), (msg)) : 0)
|
||||||
|
#define smu_send_smc_msg_with_param(smu, msg, param) \
|
||||||
|
((smu)->ppt_funcs->send_smc_msg_with_param? (smu)->ppt_funcs->send_smc_msg_with_param((smu), (msg), (param)) : 0)
|
||||||
|
#define smu_read_smc_arg(smu, arg) \
|
||||||
|
((smu)->ppt_funcs->read_smc_arg? (smu)->ppt_funcs->read_smc_arg((smu), (arg)) : 0)
|
||||||
|
#define smu_alloc_dpm_context(smu) \
|
||||||
|
((smu)->ppt_funcs->alloc_dpm_context ? (smu)->ppt_funcs->alloc_dpm_context((smu)) : 0)
|
||||||
|
#define smu_init_display_count(smu, count) \
|
||||||
|
((smu)->ppt_funcs->init_display_count ? (smu)->ppt_funcs->init_display_count((smu), (count)) : 0)
|
||||||
|
#define smu_feature_set_allowed_mask(smu) \
|
||||||
|
((smu)->ppt_funcs->set_allowed_mask? (smu)->ppt_funcs->set_allowed_mask((smu)) : 0)
|
||||||
|
#define smu_feature_get_enabled_mask(smu, mask, num) \
|
||||||
|
((smu)->ppt_funcs->get_enabled_mask? (smu)->ppt_funcs->get_enabled_mask((smu), (mask), (num)) : 0)
|
||||||
|
#define smu_is_dpm_running(smu) \
|
||||||
|
((smu)->ppt_funcs->is_dpm_running ? (smu)->ppt_funcs->is_dpm_running((smu)) : 0)
|
||||||
|
#define smu_notify_display_change(smu) \
|
||||||
|
((smu)->ppt_funcs->notify_display_change? (smu)->ppt_funcs->notify_display_change((smu)) : 0)
|
||||||
|
#define smu_store_powerplay_table(smu) \
|
||||||
|
((smu)->ppt_funcs->store_powerplay_table ? (smu)->ppt_funcs->store_powerplay_table((smu)) : 0)
|
||||||
|
#define smu_check_powerplay_table(smu) \
|
||||||
|
((smu)->ppt_funcs->check_powerplay_table ? (smu)->ppt_funcs->check_powerplay_table((smu)) : 0)
|
||||||
|
#define smu_append_powerplay_table(smu) \
|
||||||
|
((smu)->ppt_funcs->append_powerplay_table ? (smu)->ppt_funcs->append_powerplay_table((smu)) : 0)
|
||||||
|
#define smu_set_default_dpm_table(smu) \
|
||||||
|
((smu)->ppt_funcs->set_default_dpm_table ? (smu)->ppt_funcs->set_default_dpm_table((smu)) : 0)
|
||||||
|
#define smu_populate_umd_state_clk(smu) \
|
||||||
|
((smu)->ppt_funcs->populate_umd_state_clk ? (smu)->ppt_funcs->populate_umd_state_clk((smu)) : 0)
|
||||||
|
#define smu_set_default_od8_settings(smu) \
|
||||||
|
((smu)->ppt_funcs->set_default_od8_settings ? (smu)->ppt_funcs->set_default_od8_settings((smu)) : 0)
|
||||||
|
|
||||||
|
#define smu_get_current_clk_freq(smu, clk_id, value) \
|
||||||
|
((smu)->ppt_funcs->get_current_clk_freq? (smu)->ppt_funcs->get_current_clk_freq((smu), (clk_id), (value)) : 0)
|
||||||
|
|
||||||
|
#define smu_tables_init(smu, tab) \
|
||||||
|
((smu)->ppt_funcs->tables_init ? (smu)->ppt_funcs->tables_init((smu), (tab)) : 0)
|
||||||
|
#define smu_set_thermal_fan_table(smu) \
|
||||||
|
((smu)->ppt_funcs->set_thermal_fan_table ? (smu)->ppt_funcs->set_thermal_fan_table((smu)) : 0)
|
||||||
|
#define smu_start_thermal_control(smu) \
|
||||||
|
((smu)->ppt_funcs->start_thermal_control? (smu)->ppt_funcs->start_thermal_control((smu)) : 0)
|
||||||
|
#define smu_stop_thermal_control(smu) \
|
||||||
|
((smu)->ppt_funcs->stop_thermal_control? (smu)->ppt_funcs->stop_thermal_control((smu)) : 0)
|
||||||
|
|
||||||
|
#define smu_smc_read_sensor(smu, sensor, data, size) \
|
||||||
|
((smu)->ppt_funcs->read_sensor? (smu)->ppt_funcs->read_sensor((smu), (sensor), (data), (size)) : -EINVAL)
|
||||||
|
|
||||||
|
#define smu_pre_display_config_changed(smu) \
|
||||||
|
((smu)->ppt_funcs->pre_display_config_changed ? (smu)->ppt_funcs->pre_display_config_changed((smu)) : 0)
|
||||||
|
#define smu_display_config_changed(smu) \
|
||||||
|
((smu)->ppt_funcs->display_config_changed ? (smu)->ppt_funcs->display_config_changed((smu)) : 0)
|
||||||
|
#define smu_apply_clocks_adjust_rules(smu) \
|
||||||
|
((smu)->ppt_funcs->apply_clocks_adjust_rules ? (smu)->ppt_funcs->apply_clocks_adjust_rules((smu)) : 0)
|
||||||
|
#define smu_notify_smc_dispaly_config(smu) \
|
||||||
|
((smu)->ppt_funcs->notify_smc_dispaly_config ? (smu)->ppt_funcs->notify_smc_dispaly_config((smu)) : 0)
|
||||||
|
#define smu_force_dpm_limit_value(smu, highest) \
|
||||||
|
((smu)->ppt_funcs->force_dpm_limit_value ? (smu)->ppt_funcs->force_dpm_limit_value((smu), (highest)) : 0)
|
||||||
|
#define smu_unforce_dpm_levels(smu) \
|
||||||
|
((smu)->ppt_funcs->unforce_dpm_levels ? (smu)->ppt_funcs->unforce_dpm_levels((smu)) : 0)
|
||||||
|
#define smu_get_profiling_clk_mask(smu, level, sclk_mask, mclk_mask, soc_mask) \
|
||||||
|
((smu)->ppt_funcs->get_profiling_clk_mask ? (smu)->ppt_funcs->get_profiling_clk_mask((smu), (level), (sclk_mask), (mclk_mask), (soc_mask)) : 0)
|
||||||
|
#define smu_set_cpu_power_state(smu) \
|
||||||
|
((smu)->ppt_funcs->set_cpu_power_state ? (smu)->ppt_funcs->set_cpu_power_state((smu)) : 0)
|
||||||
|
|
||||||
|
#define smu_msg_get_index(smu, msg) \
|
||||||
|
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_msg_index? (smu)->ppt_funcs->get_smu_msg_index((smu), (msg)) : -EINVAL) : -EINVAL)
|
||||||
|
#define smu_clk_get_index(smu, msg) \
|
||||||
|
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_clk_index? (smu)->ppt_funcs->get_smu_clk_index((smu), (msg)) : -EINVAL) : -EINVAL)
|
||||||
|
#define smu_feature_get_index(smu, msg) \
|
||||||
|
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_feature_index? (smu)->ppt_funcs->get_smu_feature_index((smu), (msg)) : -EINVAL) : -EINVAL)
|
||||||
|
#define smu_table_get_index(smu, tab) \
|
||||||
|
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_table_index? (smu)->ppt_funcs->get_smu_table_index((smu), (tab)) : -EINVAL) : -EINVAL)
|
||||||
|
#define smu_power_get_index(smu, src) \
|
||||||
|
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_power_index? (smu)->ppt_funcs->get_smu_power_index((smu), (src)) : -EINVAL) : -EINVAL)
|
||||||
|
#define smu_workload_get_type(smu, profile) \
|
||||||
|
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_workload_type? (smu)->ppt_funcs->get_workload_type((smu), (profile)) : -EINVAL) : -EINVAL)
|
||||||
|
#define smu_run_btc(smu) \
|
||||||
|
((smu)->ppt_funcs? ((smu)->ppt_funcs->run_btc? (smu)->ppt_funcs->run_btc((smu)) : 0) : 0)
|
||||||
|
#define smu_get_allowed_feature_mask(smu, feature_mask, num) \
|
||||||
|
((smu)->ppt_funcs? ((smu)->ppt_funcs->get_allowed_feature_mask? (smu)->ppt_funcs->get_allowed_feature_mask((smu), (feature_mask), (num)) : 0) : 0)
|
||||||
|
|
||||||
|
|
||||||
|
#define smu_store_cc6_data(smu, st, cc6_dis, pst_dis, pst_sw_dis) \
|
||||||
|
((smu)->ppt_funcs->store_cc6_data ? (smu)->ppt_funcs->store_cc6_data((smu), (st), (cc6_dis), (pst_dis), (pst_sw_dis)) : 0)
|
||||||
|
|
||||||
|
#define smu_get_dal_power_level(smu, clocks) \
|
||||||
|
((smu)->ppt_funcs->get_dal_power_level ? (smu)->ppt_funcs->get_dal_power_level((smu), (clocks)) : 0)
|
||||||
|
#define smu_get_perf_level(smu, designation, level) \
|
||||||
|
((smu)->ppt_funcs->get_perf_level ? (smu)->ppt_funcs->get_perf_level((smu), (designation), (level)) : 0)
|
||||||
|
#define smu_get_current_shallow_sleep_clocks(smu, clocks) \
|
||||||
|
((smu)->ppt_funcs->get_current_shallow_sleep_clocks ? (smu)->ppt_funcs->get_current_shallow_sleep_clocks((smu), (clocks)) : 0)
|
||||||
|
|
||||||
|
#define smu_dpm_set_uvd_enable(smu, enable) \
|
||||||
|
((smu)->ppt_funcs->dpm_set_uvd_enable ? (smu)->ppt_funcs->dpm_set_uvd_enable((smu), (enable)) : 0)
|
||||||
|
#define smu_dpm_set_vce_enable(smu, enable) \
|
||||||
|
((smu)->ppt_funcs->dpm_set_vce_enable ? (smu)->ppt_funcs->dpm_set_vce_enable((smu), (enable)) : 0)
|
||||||
|
|
||||||
|
#define smu_set_watermarks_table(smu, tab, clock_ranges) \
|
||||||
|
((smu)->ppt_funcs->set_watermarks_table ? (smu)->ppt_funcs->set_watermarks_table((smu), (tab), (clock_ranges)) : 0)
|
||||||
|
#define smu_get_current_clk_freq_by_table(smu, clk_type, value) \
|
||||||
|
((smu)->ppt_funcs->get_current_clk_freq_by_table ? (smu)->ppt_funcs->get_current_clk_freq_by_table((smu), (clk_type), (value)) : 0)
|
||||||
|
#define smu_thermal_temperature_range_update(smu, range, rw) \
|
||||||
|
((smu)->ppt_funcs->thermal_temperature_range_update? (smu)->ppt_funcs->thermal_temperature_range_update((smu), (range), (rw)) : 0)
|
||||||
|
#define smu_get_thermal_temperature_range(smu, range) \
|
||||||
|
((smu)->ppt_funcs->get_thermal_temperature_range? (smu)->ppt_funcs->get_thermal_temperature_range((smu), (range)) : 0)
|
||||||
|
#define smu_register_irq_handler(smu) \
|
||||||
|
((smu)->ppt_funcs->register_irq_handler ? (smu)->ppt_funcs->register_irq_handler(smu) : 0)
|
||||||
|
|
||||||
|
#define smu_get_dpm_ultimate_freq(smu, param, min, max) \
|
||||||
|
((smu)->ppt_funcs->get_dpm_ultimate_freq ? (smu)->ppt_funcs->get_dpm_ultimate_freq((smu), (param), (min), (max)) : 0)
|
||||||
|
|
||||||
|
#define smu_asic_set_performance_level(smu, level) \
|
||||||
|
((smu)->ppt_funcs->set_performance_level? (smu)->ppt_funcs->set_performance_level((smu), (level)) : -EINVAL);
|
||||||
|
#define smu_dump_pptable(smu) \
|
||||||
|
((smu)->ppt_funcs->dump_pptable ? (smu)->ppt_funcs->dump_pptable((smu)) : 0)
|
||||||
|
#define smu_get_dpm_clk_limited(smu, clk_type, dpm_level, freq) \
|
||||||
|
((smu)->ppt_funcs->get_dpm_clk_limited ? (smu)->ppt_funcs->get_dpm_clk_limited((smu), (clk_type), (dpm_level), (freq)) : -EINVAL)
|
||||||
|
|
||||||
|
#define smu_set_soft_freq_limited_range(smu, clk_type, min, max) \
|
||||||
|
((smu)->ppt_funcs->set_soft_freq_limited_range ? (smu)->ppt_funcs->set_soft_freq_limited_range((smu), (clk_type), (min), (max)) : -EINVAL)
|
||||||
|
|
||||||
|
#define smu_override_pcie_parameters(smu) \
|
||||||
|
((smu)->ppt_funcs->override_pcie_parameters ? (smu)->ppt_funcs->override_pcie_parameters((smu)) : 0)
|
||||||
|
|
||||||
|
#define smu_update_pcie_parameters(smu, pcie_gen_cap, pcie_width_cap) \
|
||||||
|
((smu)->ppt_funcs->update_pcie_parameters ? (smu)->ppt_funcs->update_pcie_parameters((smu), (pcie_gen_cap), (pcie_width_cap)) : 0)
|
||||||
|
|
||||||
|
#endif
|
@ -27,14 +27,12 @@
|
|||||||
#include "pp_debug.h"
|
#include "pp_debug.h"
|
||||||
#include "amdgpu.h"
|
#include "amdgpu.h"
|
||||||
#include "amdgpu_smu.h"
|
#include "amdgpu_smu.h"
|
||||||
|
#include "smu_internal.h"
|
||||||
#include "atomfirmware.h"
|
#include "atomfirmware.h"
|
||||||
#include "amdgpu_atomfirmware.h"
|
#include "amdgpu_atomfirmware.h"
|
||||||
#include "smu_v11_0.h"
|
#include "smu_v11_0.h"
|
||||||
#include "soc15_common.h"
|
#include "soc15_common.h"
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
#include "vega20_ppt.h"
|
|
||||||
#include "arcturus_ppt.h"
|
|
||||||
#include "navi10_ppt.h"
|
|
||||||
#include "amd_pcie.h"
|
#include "amd_pcie.h"
|
||||||
|
|
||||||
#include "asic_reg/thm/thm_11_0_2_offset.h"
|
#include "asic_reg/thm/thm_11_0_2_offset.h"
|
||||||
@ -62,7 +60,7 @@ static int smu_v11_0_send_msg_without_waiting(struct smu_context *smu,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_read_arg(struct smu_context *smu, uint32_t *arg)
|
int smu_v11_0_read_arg(struct smu_context *smu, uint32_t *arg)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
|
|
||||||
@ -89,7 +87,7 @@ static int smu_v11_0_wait_for_response(struct smu_context *smu)
|
|||||||
return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90) == 0x1 ? 0 : -EIO;
|
return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90) == 0x1 ? 0 : -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_send_msg(struct smu_context *smu, uint16_t msg)
|
int smu_v11_0_send_msg(struct smu_context *smu, uint16_t msg)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
int ret = 0, index = 0;
|
int ret = 0, index = 0;
|
||||||
@ -114,7 +112,7 @@ static int smu_v11_0_send_msg(struct smu_context *smu, uint16_t msg)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
smu_v11_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
|
smu_v11_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
|
||||||
uint32_t param)
|
uint32_t param)
|
||||||
{
|
{
|
||||||
@ -145,7 +143,7 @@ smu_v11_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_init_microcode(struct smu_context *smu)
|
int smu_v11_0_init_microcode(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
const char *chip_name;
|
const char *chip_name;
|
||||||
@ -207,7 +205,7 @@ out:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_load_microcode(struct smu_context *smu)
|
int smu_v11_0_load_microcode(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
const uint32_t *src;
|
const uint32_t *src;
|
||||||
@ -245,7 +243,7 @@ static int smu_v11_0_load_microcode(struct smu_context *smu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_check_fw_status(struct smu_context *smu)
|
int smu_v11_0_check_fw_status(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
uint32_t mp1_fw_flags;
|
uint32_t mp1_fw_flags;
|
||||||
@ -260,7 +258,7 @@ static int smu_v11_0_check_fw_status(struct smu_context *smu)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_check_fw_version(struct smu_context *smu)
|
int smu_v11_0_check_fw_version(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
uint32_t if_version = 0xff, smu_version = 0xff;
|
uint32_t if_version = 0xff, smu_version = 0xff;
|
||||||
uint16_t smu_major;
|
uint16_t smu_major;
|
||||||
@ -355,7 +353,7 @@ static int smu_v11_0_set_pptable_v2_1(struct smu_context *smu, void **table,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_setup_pptable(struct smu_context *smu)
|
int smu_v11_0_setup_pptable(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
const struct smc_firmware_header_v1_0 *hdr;
|
const struct smc_firmware_header_v1_0 *hdr;
|
||||||
@ -434,7 +432,7 @@ static int smu_v11_0_fini_dpm_context(struct smu_context *smu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_init_smc_tables(struct smu_context *smu)
|
int smu_v11_0_init_smc_tables(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_table_context *smu_table = &smu->smu_table;
|
struct smu_table_context *smu_table = &smu->smu_table;
|
||||||
struct smu_table *tables = NULL;
|
struct smu_table *tables = NULL;
|
||||||
@ -461,7 +459,7 @@ static int smu_v11_0_init_smc_tables(struct smu_context *smu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_fini_smc_tables(struct smu_context *smu)
|
int smu_v11_0_fini_smc_tables(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_table_context *smu_table = &smu->smu_table;
|
struct smu_table_context *smu_table = &smu->smu_table;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -481,7 +479,7 @@ static int smu_v11_0_fini_smc_tables(struct smu_context *smu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_init_power(struct smu_context *smu)
|
int smu_v11_0_init_power(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_power_context *smu_power = &smu->smu_power;
|
struct smu_power_context *smu_power = &smu->smu_power;
|
||||||
|
|
||||||
@ -499,7 +497,7 @@ static int smu_v11_0_init_power(struct smu_context *smu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_fini_power(struct smu_context *smu)
|
int smu_v11_0_fini_power(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_power_context *smu_power = &smu->smu_power;
|
struct smu_power_context *smu_power = &smu->smu_power;
|
||||||
|
|
||||||
@ -576,7 +574,7 @@ int smu_v11_0_get_vbios_bootup_values(struct smu_context *smu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_get_clk_info_from_vbios(struct smu_context *smu)
|
int smu_v11_0_get_clk_info_from_vbios(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
int ret, index;
|
int ret, index;
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
@ -673,7 +671,7 @@ static int smu_v11_0_get_clk_info_from_vbios(struct smu_context *smu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_notify_memory_pool_location(struct smu_context *smu)
|
int smu_v11_0_notify_memory_pool_location(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_table_context *smu_table = &smu->smu_table;
|
struct smu_table_context *smu_table = &smu->smu_table;
|
||||||
struct smu_table *memory_pool = &smu_table->memory_pool;
|
struct smu_table *memory_pool = &smu_table->memory_pool;
|
||||||
@ -719,7 +717,7 @@ static int smu_v11_0_notify_memory_pool_location(struct smu_context *smu)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_check_pptable(struct smu_context *smu)
|
int smu_v11_0_check_pptable(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -727,7 +725,7 @@ static int smu_v11_0_check_pptable(struct smu_context *smu)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_parse_pptable(struct smu_context *smu)
|
int smu_v11_0_parse_pptable(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -751,7 +749,7 @@ static int smu_v11_0_parse_pptable(struct smu_context *smu)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_populate_smc_pptable(struct smu_context *smu)
|
int smu_v11_0_populate_smc_pptable(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -760,7 +758,7 @@ static int smu_v11_0_populate_smc_pptable(struct smu_context *smu)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_write_pptable(struct smu_context *smu)
|
int smu_v11_0_write_pptable(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_table_context *table_context = &smu->smu_table;
|
struct smu_table_context *table_context = &smu->smu_table;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -771,7 +769,7 @@ static int smu_v11_0_write_pptable(struct smu_context *smu)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_set_deep_sleep_dcefclk(struct smu_context *smu, uint32_t clk)
|
int smu_v11_0_set_deep_sleep_dcefclk(struct smu_context *smu, uint32_t clk)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -783,7 +781,7 @@ static int smu_v11_0_set_deep_sleep_dcefclk(struct smu_context *smu, uint32_t cl
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_set_min_dcef_deep_sleep(struct smu_context *smu)
|
int smu_v11_0_set_min_dcef_deep_sleep(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_table_context *table_context = &smu->smu_table;
|
struct smu_table_context *table_context = &smu->smu_table;
|
||||||
|
|
||||||
@ -792,11 +790,10 @@ static int smu_v11_0_set_min_dcef_deep_sleep(struct smu_context *smu)
|
|||||||
if (!table_context)
|
if (!table_context)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return smu_set_deep_sleep_dcefclk(smu,
|
return smu_v11_0_set_deep_sleep_dcefclk(smu, table_context->boot_values.dcefclk / 100);
|
||||||
table_context->boot_values.dcefclk / 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_set_tool_table_location(struct smu_context *smu)
|
int smu_v11_0_set_tool_table_location(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct smu_table *tool_table = &smu->smu_table.tables[SMU_TABLE_PMSTATUSLOG];
|
struct smu_table *tool_table = &smu->smu_table.tables[SMU_TABLE_PMSTATUSLOG];
|
||||||
@ -814,7 +811,7 @@ static int smu_v11_0_set_tool_table_location(struct smu_context *smu)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_init_display_count(struct smu_context *smu, uint32_t count)
|
int smu_v11_0_init_display_count(struct smu_context *smu, uint32_t count)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -826,7 +823,7 @@ static int smu_v11_0_init_display_count(struct smu_context *smu, uint32_t count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int smu_v11_0_set_allowed_mask(struct smu_context *smu)
|
int smu_v11_0_set_allowed_mask(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_feature *feature = &smu->smu_feature;
|
struct smu_feature *feature = &smu->smu_feature;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -853,7 +850,7 @@ failed:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_get_enabled_mask(struct smu_context *smu,
|
int smu_v11_0_get_enabled_mask(struct smu_context *smu,
|
||||||
uint32_t *feature_mask, uint32_t num)
|
uint32_t *feature_mask, uint32_t num)
|
||||||
{
|
{
|
||||||
uint32_t feature_mask_high = 0, feature_mask_low = 0;
|
uint32_t feature_mask_high = 0, feature_mask_low = 0;
|
||||||
@ -882,7 +879,7 @@ static int smu_v11_0_get_enabled_mask(struct smu_context *smu,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_system_features_control(struct smu_context *smu,
|
int smu_v11_0_system_features_control(struct smu_context *smu,
|
||||||
bool en)
|
bool en)
|
||||||
{
|
{
|
||||||
struct smu_feature *feature = &smu->smu_feature;
|
struct smu_feature *feature = &smu->smu_feature;
|
||||||
@ -908,7 +905,7 @@ static int smu_v11_0_system_features_control(struct smu_context *smu,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_notify_display_change(struct smu_context *smu)
|
int smu_v11_0_notify_display_change(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -966,7 +963,7 @@ smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
|
int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks;
|
struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -1046,7 +1043,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n)
|
int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -1074,7 +1071,7 @@ static int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_get_current_clk_freq(struct smu_context *smu,
|
int smu_v11_0_get_current_clk_freq(struct smu_context *smu,
|
||||||
enum smu_clk_type clk_id,
|
enum smu_clk_type clk_id,
|
||||||
uint32_t *value)
|
uint32_t *value)
|
||||||
{
|
{
|
||||||
@ -1153,7 +1150,7 @@ static int smu_v11_0_enable_thermal_alert(struct smu_context *smu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_start_thermal_control(struct smu_context *smu)
|
int smu_v11_0_start_thermal_control(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct smu_temperature_range range;
|
struct smu_temperature_range range;
|
||||||
@ -1195,7 +1192,7 @@ static int smu_v11_0_start_thermal_control(struct smu_context *smu)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_stop_thermal_control(struct smu_context *smu)
|
int smu_v11_0_stop_thermal_control(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
|
|
||||||
@ -1228,7 +1225,7 @@ static int smu_v11_0_get_gfx_vdd(struct smu_context *smu, uint32_t *value)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_read_sensor(struct smu_context *smu,
|
int smu_v11_0_read_sensor(struct smu_context *smu,
|
||||||
enum amd_pp_sensors sensor,
|
enum amd_pp_sensors sensor,
|
||||||
void *data, uint32_t *size)
|
void *data, uint32_t *size)
|
||||||
{
|
{
|
||||||
@ -1265,7 +1262,7 @@ static int smu_v11_0_read_sensor(struct smu_context *smu,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
|
smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
|
||||||
struct pp_display_clock_request
|
struct pp_display_clock_request
|
||||||
*clock_req)
|
*clock_req)
|
||||||
@ -1308,9 +1305,7 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
|
|||||||
if (clk_select == SMU_UCLK && smu->disable_uclk_switch)
|
if (clk_select == SMU_UCLK && smu->disable_uclk_switch)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
mutex_lock(&smu->mutex);
|
|
||||||
ret = smu_set_hard_freq_range(smu, clk_select, clk_freq, 0);
|
ret = smu_set_hard_freq_range(smu, clk_select, clk_freq, 0);
|
||||||
mutex_unlock(&smu->mutex);
|
|
||||||
|
|
||||||
if(clk_select == SMU_UCLK)
|
if(clk_select == SMU_UCLK)
|
||||||
smu->hard_min_uclk_req_from_dal = clk_freq;
|
smu->hard_min_uclk_req_from_dal = clk_freq;
|
||||||
@ -1320,7 +1315,7 @@ failed:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable)
|
int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
@ -1333,12 +1328,10 @@ static int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable)
|
|||||||
case CHIP_NAVI12:
|
case CHIP_NAVI12:
|
||||||
if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
|
if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
|
||||||
return 0;
|
return 0;
|
||||||
mutex_lock(&smu->mutex);
|
|
||||||
if (enable)
|
if (enable)
|
||||||
ret = smu_send_smc_msg(smu, SMU_MSG_AllowGfxOff);
|
ret = smu_send_smc_msg(smu, SMU_MSG_AllowGfxOff);
|
||||||
else
|
else
|
||||||
ret = smu_send_smc_msg(smu, SMU_MSG_DisallowGfxOff);
|
ret = smu_send_smc_msg(smu, SMU_MSG_DisallowGfxOff);
|
||||||
mutex_unlock(&smu->mutex);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1347,7 +1340,7 @@ static int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
uint32_t
|
||||||
smu_v11_0_get_fan_control_mode(struct smu_context *smu)
|
smu_v11_0_get_fan_control_mode(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
if (!smu_feature_is_enabled(smu, SMU_FEATURE_FAN_CONTROL_BIT))
|
if (!smu_feature_is_enabled(smu, SMU_FEATURE_FAN_CONTROL_BIT))
|
||||||
@ -1387,7 +1380,7 @@ smu_v11_0_set_fan_static_mode(struct smu_context *smu, uint32_t mode)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed)
|
smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
@ -1416,7 +1409,7 @@ smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed)
|
|||||||
return smu_v11_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC);
|
return smu_v11_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
smu_v11_0_set_fan_control_mode(struct smu_context *smu,
|
smu_v11_0_set_fan_control_mode(struct smu_context *smu,
|
||||||
uint32_t mode)
|
uint32_t mode)
|
||||||
{
|
{
|
||||||
@ -1444,7 +1437,7 @@ smu_v11_0_set_fan_control_mode(struct smu_context *smu,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu,
|
int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu,
|
||||||
uint32_t speed)
|
uint32_t speed)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
@ -1454,10 +1447,9 @@ static int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu,
|
|||||||
if (!speed)
|
if (!speed)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
mutex_lock(&(smu->mutex));
|
|
||||||
ret = smu_v11_0_auto_fan_control(smu, 0);
|
ret = smu_v11_0_auto_fan_control(smu, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto set_fan_speed_rpm_failed;
|
return ret;
|
||||||
|
|
||||||
crystal_clock_freq = amdgpu_asic_get_xclk(adev);
|
crystal_clock_freq = amdgpu_asic_get_xclk(adev);
|
||||||
tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);
|
tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);
|
||||||
@ -1468,23 +1460,19 @@ static int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu,
|
|||||||
|
|
||||||
ret = smu_v11_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC_RPM);
|
ret = smu_v11_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC_RPM);
|
||||||
|
|
||||||
set_fan_speed_rpm_failed:
|
|
||||||
mutex_unlock(&(smu->mutex));
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define XGMI_STATE_D0 1
|
#define XGMI_STATE_D0 1
|
||||||
#define XGMI_STATE_D3 0
|
#define XGMI_STATE_D3 0
|
||||||
|
|
||||||
static int smu_v11_0_set_xgmi_pstate(struct smu_context *smu,
|
int smu_v11_0_set_xgmi_pstate(struct smu_context *smu,
|
||||||
uint32_t pstate)
|
uint32_t pstate)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
mutex_lock(&(smu->mutex));
|
|
||||||
ret = smu_send_smc_msg_with_param(smu,
|
ret = smu_send_smc_msg_with_param(smu,
|
||||||
SMU_MSG_SetXgmiMode,
|
SMU_MSG_SetXgmiMode,
|
||||||
pstate ? XGMI_STATE_D0 : XGMI_STATE_D3);
|
pstate ? XGMI_STATE_D0 : XGMI_STATE_D3);
|
||||||
mutex_unlock(&(smu->mutex));
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1531,7 +1519,7 @@ static const struct amdgpu_irq_src_funcs smu_v11_0_irq_funcs =
|
|||||||
.process = smu_v11_0_irq_process,
|
.process = smu_v11_0_irq_process,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int smu_v11_0_register_irq_handler(struct smu_context *smu)
|
int smu_v11_0_register_irq_handler(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
struct amdgpu_irq_src *irq_src = smu->irq_source;
|
struct amdgpu_irq_src *irq_src = smu->irq_source;
|
||||||
@ -1563,7 +1551,7 @@ static int smu_v11_0_register_irq_handler(struct smu_context *smu)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_get_max_sustainable_clocks_by_dc(struct smu_context *smu,
|
int smu_v11_0_get_max_sustainable_clocks_by_dc(struct smu_context *smu,
|
||||||
struct pp_smu_nv_clock_table *max_clocks)
|
struct pp_smu_nv_clock_table *max_clocks)
|
||||||
{
|
{
|
||||||
struct smu_table_context *table_context = &smu->smu_table;
|
struct smu_table_context *table_context = &smu->smu_table;
|
||||||
@ -1593,13 +1581,11 @@ static int smu_v11_0_get_max_sustainable_clocks_by_dc(struct smu_context *smu,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_set_azalia_d3_pme(struct smu_context *smu)
|
int smu_v11_0_set_azalia_d3_pme(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(&smu->mutex);
|
|
||||||
ret = smu_send_smc_msg(smu, SMU_MSG_BacoAudioD3PME);
|
ret = smu_send_smc_msg(smu, SMU_MSG_BacoAudioD3PME);
|
||||||
mutex_unlock(&smu->mutex);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1609,7 +1595,7 @@ static int smu_v11_0_baco_set_armd3_sequence(struct smu_context *smu, enum smu_v
|
|||||||
return smu_send_smc_msg_with_param(smu, SMU_MSG_ArmD3, baco_seq);
|
return smu_send_smc_msg_with_param(smu, SMU_MSG_ArmD3, baco_seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool smu_v11_0_baco_is_support(struct smu_context *smu)
|
bool smu_v11_0_baco_is_support(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
struct smu_baco_context *smu_baco = &smu->smu_baco;
|
struct smu_baco_context *smu_baco = &smu->smu_baco;
|
||||||
@ -1633,7 +1619,7 @@ static bool smu_v11_0_baco_is_support(struct smu_context *smu)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum smu_baco_state smu_v11_0_baco_get_state(struct smu_context *smu)
|
enum smu_baco_state smu_v11_0_baco_get_state(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_baco_context *smu_baco = &smu->smu_baco;
|
struct smu_baco_context *smu_baco = &smu->smu_baco;
|
||||||
enum smu_baco_state baco_state;
|
enum smu_baco_state baco_state;
|
||||||
@ -1645,7 +1631,7 @@ static enum smu_baco_state smu_v11_0_baco_get_state(struct smu_context *smu)
|
|||||||
return baco_state;
|
return baco_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state)
|
int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct smu_baco_context *smu_baco = &smu->smu_baco;
|
struct smu_baco_context *smu_baco = &smu->smu_baco;
|
||||||
@ -1669,7 +1655,7 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_baco_reset(struct smu_context *smu)
|
int smu_v11_0_baco_reset(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -1690,13 +1676,12 @@ static int smu_v11_0_baco_reset(struct smu_context *smu)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type,
|
int smu_v11_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||||
uint32_t *min, uint32_t *max)
|
uint32_t *min, uint32_t *max)
|
||||||
{
|
{
|
||||||
int ret = 0, clk_id = 0;
|
int ret = 0, clk_id = 0;
|
||||||
uint32_t param = 0;
|
uint32_t param = 0;
|
||||||
|
|
||||||
mutex_lock(&smu->mutex);
|
|
||||||
clk_id = smu_clk_get_index(smu, clk_type);
|
clk_id = smu_clk_get_index(smu, clk_type);
|
||||||
if (clk_id < 0) {
|
if (clk_id < 0) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
@ -1723,11 +1708,10 @@ static int smu_v11_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk
|
|||||||
}
|
}
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
mutex_unlock(&smu->mutex);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||||
uint32_t min, uint32_t max)
|
uint32_t min, uint32_t max)
|
||||||
{
|
{
|
||||||
int ret = 0, clk_id = 0;
|
int ret = 0, clk_id = 0;
|
||||||
@ -1756,7 +1740,7 @@ static int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu, enum s
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v11_0_override_pcie_parameters(struct smu_context *smu)
|
int smu_v11_0_override_pcie_parameters(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
uint32_t pcie_gen = 0, pcie_width = 0;
|
uint32_t pcie_gen = 0, pcie_width = 0;
|
||||||
@ -1796,79 +1780,3 @@ static int smu_v11_0_override_pcie_parameters(struct smu_context *smu)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const struct smu_funcs smu_v11_0_funcs = {
|
|
||||||
.init_microcode = smu_v11_0_init_microcode,
|
|
||||||
.load_microcode = smu_v11_0_load_microcode,
|
|
||||||
.check_fw_status = smu_v11_0_check_fw_status,
|
|
||||||
.check_fw_version = smu_v11_0_check_fw_version,
|
|
||||||
.send_smc_msg = smu_v11_0_send_msg,
|
|
||||||
.send_smc_msg_with_param = smu_v11_0_send_msg_with_param,
|
|
||||||
.read_smc_arg = smu_v11_0_read_arg,
|
|
||||||
.setup_pptable = smu_v11_0_setup_pptable,
|
|
||||||
.init_smc_tables = smu_v11_0_init_smc_tables,
|
|
||||||
.fini_smc_tables = smu_v11_0_fini_smc_tables,
|
|
||||||
.init_power = smu_v11_0_init_power,
|
|
||||||
.fini_power = smu_v11_0_fini_power,
|
|
||||||
.get_vbios_bootup_values = smu_v11_0_get_vbios_bootup_values,
|
|
||||||
.get_clk_info_from_vbios = smu_v11_0_get_clk_info_from_vbios,
|
|
||||||
.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
|
|
||||||
.check_pptable = smu_v11_0_check_pptable,
|
|
||||||
.parse_pptable = smu_v11_0_parse_pptable,
|
|
||||||
.populate_smc_tables = smu_v11_0_populate_smc_pptable,
|
|
||||||
.write_pptable = smu_v11_0_write_pptable,
|
|
||||||
.set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep,
|
|
||||||
.set_tool_table_location = smu_v11_0_set_tool_table_location,
|
|
||||||
.init_display_count = smu_v11_0_init_display_count,
|
|
||||||
.set_allowed_mask = smu_v11_0_set_allowed_mask,
|
|
||||||
.get_enabled_mask = smu_v11_0_get_enabled_mask,
|
|
||||||
.system_features_control = smu_v11_0_system_features_control,
|
|
||||||
.notify_display_change = smu_v11_0_notify_display_change,
|
|
||||||
.set_power_limit = smu_v11_0_set_power_limit,
|
|
||||||
.get_current_clk_freq = smu_v11_0_get_current_clk_freq,
|
|
||||||
.init_max_sustainable_clocks = smu_v11_0_init_max_sustainable_clocks,
|
|
||||||
.start_thermal_control = smu_v11_0_start_thermal_control,
|
|
||||||
.stop_thermal_control = smu_v11_0_stop_thermal_control,
|
|
||||||
.read_sensor = smu_v11_0_read_sensor,
|
|
||||||
.set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk,
|
|
||||||
.display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
|
|
||||||
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
|
|
||||||
.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
|
|
||||||
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
|
|
||||||
.set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
|
|
||||||
.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
|
|
||||||
.gfx_off_control = smu_v11_0_gfx_off_control,
|
|
||||||
.register_irq_handler = smu_v11_0_register_irq_handler,
|
|
||||||
.set_azalia_d3_pme = smu_v11_0_set_azalia_d3_pme,
|
|
||||||
.get_max_sustainable_clocks_by_dc = smu_v11_0_get_max_sustainable_clocks_by_dc,
|
|
||||||
.baco_is_support = smu_v11_0_baco_is_support,
|
|
||||||
.baco_get_state = smu_v11_0_baco_get_state,
|
|
||||||
.baco_set_state = smu_v11_0_baco_set_state,
|
|
||||||
.baco_reset = smu_v11_0_baco_reset,
|
|
||||||
.get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq,
|
|
||||||
.set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
|
|
||||||
.override_pcie_parameters = smu_v11_0_override_pcie_parameters,
|
|
||||||
};
|
|
||||||
|
|
||||||
void smu_v11_0_set_smu_funcs(struct smu_context *smu)
|
|
||||||
{
|
|
||||||
struct amdgpu_device *adev = smu->adev;
|
|
||||||
|
|
||||||
smu->funcs = &smu_v11_0_funcs;
|
|
||||||
switch (adev->asic_type) {
|
|
||||||
case CHIP_VEGA20:
|
|
||||||
vega20_set_ppt_funcs(smu);
|
|
||||||
break;
|
|
||||||
case CHIP_ARCTURUS:
|
|
||||||
arcturus_set_ppt_funcs(smu);
|
|
||||||
break;
|
|
||||||
case CHIP_NAVI10:
|
|
||||||
case CHIP_NAVI14:
|
|
||||||
case CHIP_NAVI12:
|
|
||||||
navi10_set_ppt_funcs(smu);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
pr_warn("Unknown asic for smu11\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -24,12 +24,12 @@
|
|||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
#include "amdgpu.h"
|
#include "amdgpu.h"
|
||||||
#include "amdgpu_smu.h"
|
#include "amdgpu_smu.h"
|
||||||
|
#include "smu_internal.h"
|
||||||
#include "atomfirmware.h"
|
#include "atomfirmware.h"
|
||||||
#include "amdgpu_atomfirmware.h"
|
#include "amdgpu_atomfirmware.h"
|
||||||
#include "smu_v12_0.h"
|
#include "smu_v12_0.h"
|
||||||
#include "soc15_common.h"
|
#include "soc15_common.h"
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
#include "renoir_ppt.h"
|
|
||||||
|
|
||||||
#include "asic_reg/mp/mp_12_0_0_offset.h"
|
#include "asic_reg/mp/mp_12_0_0_offset.h"
|
||||||
#include "asic_reg/mp/mp_12_0_0_sh_mask.h"
|
#include "asic_reg/mp/mp_12_0_0_sh_mask.h"
|
||||||
@ -41,7 +41,7 @@
|
|||||||
#define SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS_MASK 0x00000006L
|
#define SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS_MASK 0x00000006L
|
||||||
#define SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS__SHIFT 0x1
|
#define SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS__SHIFT 0x1
|
||||||
|
|
||||||
static int smu_v12_0_send_msg_without_waiting(struct smu_context *smu,
|
int smu_v12_0_send_msg_without_waiting(struct smu_context *smu,
|
||||||
uint16_t msg)
|
uint16_t msg)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
@ -50,7 +50,7 @@ static int smu_v12_0_send_msg_without_waiting(struct smu_context *smu,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_read_arg(struct smu_context *smu, uint32_t *arg)
|
int smu_v12_0_read_arg(struct smu_context *smu, uint32_t *arg)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ static int smu_v12_0_read_arg(struct smu_context *smu, uint32_t *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_wait_for_response(struct smu_context *smu)
|
int smu_v12_0_wait_for_response(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
uint32_t cur_value, i;
|
uint32_t cur_value, i;
|
||||||
@ -77,7 +77,7 @@ static int smu_v12_0_wait_for_response(struct smu_context *smu)
|
|||||||
return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90) == 0x1 ? 0 : -EIO;
|
return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90) == 0x1 ? 0 : -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_send_msg(struct smu_context *smu, uint16_t msg)
|
int smu_v12_0_send_msg(struct smu_context *smu, uint16_t msg)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
int ret = 0, index = 0;
|
int ret = 0, index = 0;
|
||||||
@ -102,7 +102,7 @@ static int smu_v12_0_send_msg(struct smu_context *smu, uint16_t msg)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
smu_v12_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
|
smu_v12_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
|
||||||
uint32_t param)
|
uint32_t param)
|
||||||
{
|
{
|
||||||
@ -132,7 +132,7 @@ smu_v12_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_check_fw_status(struct smu_context *smu)
|
int smu_v12_0_check_fw_status(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
uint32_t mp1_fw_flags;
|
uint32_t mp1_fw_flags;
|
||||||
@ -147,7 +147,7 @@ static int smu_v12_0_check_fw_status(struct smu_context *smu)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_check_fw_version(struct smu_context *smu)
|
int smu_v12_0_check_fw_version(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
uint32_t if_version = 0xff, smu_version = 0xff;
|
uint32_t if_version = 0xff, smu_version = 0xff;
|
||||||
uint16_t smu_major;
|
uint16_t smu_major;
|
||||||
@ -181,7 +181,7 @@ static int smu_v12_0_check_fw_version(struct smu_context *smu)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_powergate_sdma(struct smu_context *smu, bool gate)
|
int smu_v12_0_powergate_sdma(struct smu_context *smu, bool gate)
|
||||||
{
|
{
|
||||||
if (!(smu->adev->flags & AMD_IS_APU))
|
if (!(smu->adev->flags & AMD_IS_APU))
|
||||||
return 0;
|
return 0;
|
||||||
@ -192,7 +192,7 @@ static int smu_v12_0_powergate_sdma(struct smu_context *smu, bool gate)
|
|||||||
return smu_send_smc_msg(smu, SMU_MSG_PowerUpSdma);
|
return smu_send_smc_msg(smu, SMU_MSG_PowerUpSdma);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_powergate_vcn(struct smu_context *smu, bool gate)
|
int smu_v12_0_powergate_vcn(struct smu_context *smu, bool gate)
|
||||||
{
|
{
|
||||||
if (!(smu->adev->flags & AMD_IS_APU))
|
if (!(smu->adev->flags & AMD_IS_APU))
|
||||||
return 0;
|
return 0;
|
||||||
@ -203,7 +203,7 @@ static int smu_v12_0_powergate_vcn(struct smu_context *smu, bool gate)
|
|||||||
return smu_send_smc_msg(smu, SMU_MSG_PowerUpVcn);
|
return smu_send_smc_msg(smu, SMU_MSG_PowerUpVcn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_set_gfx_cgpg(struct smu_context *smu, bool enable)
|
int smu_v12_0_set_gfx_cgpg(struct smu_context *smu, bool enable)
|
||||||
{
|
{
|
||||||
if (!(smu->adev->pg_flags & AMD_PG_SUPPORT_GFX_PG))
|
if (!(smu->adev->pg_flags & AMD_PG_SUPPORT_GFX_PG))
|
||||||
return 0;
|
return 0;
|
||||||
@ -224,7 +224,7 @@ static int smu_v12_0_set_gfx_cgpg(struct smu_context *smu, bool enable)
|
|||||||
* Returns 2=Not in GFXOFF.
|
* Returns 2=Not in GFXOFF.
|
||||||
* Returns 3=Transition into GFXOFF.
|
* Returns 3=Transition into GFXOFF.
|
||||||
*/
|
*/
|
||||||
static uint32_t smu_v12_0_get_gfxoff_status(struct smu_context *smu)
|
uint32_t smu_v12_0_get_gfxoff_status(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
uint32_t gfxOff_Status = 0;
|
uint32_t gfxOff_Status = 0;
|
||||||
@ -237,7 +237,7 @@ static uint32_t smu_v12_0_get_gfxoff_status(struct smu_context *smu)
|
|||||||
return gfxOff_Status;
|
return gfxOff_Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_gfx_off_control(struct smu_context *smu, bool enable)
|
int smu_v12_0_gfx_off_control(struct smu_context *smu, bool enable)
|
||||||
{
|
{
|
||||||
int ret = 0, timeout = 500;
|
int ret = 0, timeout = 500;
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ static int smu_v12_0_gfx_off_control(struct smu_context *smu, bool enable)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_init_smc_tables(struct smu_context *smu)
|
int smu_v12_0_init_smc_tables(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_table_context *smu_table = &smu->smu_table;
|
struct smu_table_context *smu_table = &smu->smu_table;
|
||||||
struct smu_table *tables = NULL;
|
struct smu_table *tables = NULL;
|
||||||
@ -279,7 +279,7 @@ static int smu_v12_0_init_smc_tables(struct smu_context *smu)
|
|||||||
return smu_tables_init(smu, tables);
|
return smu_tables_init(smu, tables);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_fini_smc_tables(struct smu_context *smu)
|
int smu_v12_0_fini_smc_tables(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_table_context *smu_table = &smu->smu_table;
|
struct smu_table_context *smu_table = &smu->smu_table;
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ static int smu_v12_0_fini_smc_tables(struct smu_context *smu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_populate_smc_tables(struct smu_context *smu)
|
int smu_v12_0_populate_smc_tables(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_table_context *smu_table = &smu->smu_table;
|
struct smu_table_context *smu_table = &smu->smu_table;
|
||||||
struct smu_table *table = NULL;
|
struct smu_table *table = NULL;
|
||||||
@ -310,14 +310,12 @@ static int smu_v12_0_populate_smc_tables(struct smu_context *smu)
|
|||||||
return smu_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false);
|
return smu_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type,
|
int smu_v12_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||||
uint32_t *min, uint32_t *max)
|
uint32_t *min, uint32_t *max)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint32_t mclk_mask, soc_mask;
|
uint32_t mclk_mask, soc_mask;
|
||||||
|
|
||||||
mutex_lock(&smu->mutex);
|
|
||||||
|
|
||||||
if (max) {
|
if (max) {
|
||||||
ret = smu_get_profiling_clk_mask(smu, AMD_DPM_FORCED_LEVEL_PROFILE_PEAK,
|
ret = smu_get_profiling_clk_mask(smu, AMD_DPM_FORCED_LEVEL_PROFILE_PEAK,
|
||||||
NULL,
|
NULL,
|
||||||
@ -387,15 +385,14 @@ static int smu_v12_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
failed:
|
failed:
|
||||||
mutex_unlock(&smu->mutex);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_mode2_reset(struct smu_context *smu){
|
int smu_v12_0_mode2_reset(struct smu_context *smu){
|
||||||
return smu_v12_0_send_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, SMU_RESET_MODE_2);
|
return smu_v12_0_send_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, SMU_RESET_MODE_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||||
uint32_t min, uint32_t max)
|
uint32_t min, uint32_t max)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -448,36 +445,3 @@ static int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum s
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct smu_funcs smu_v12_0_funcs = {
|
|
||||||
.check_fw_status = smu_v12_0_check_fw_status,
|
|
||||||
.check_fw_version = smu_v12_0_check_fw_version,
|
|
||||||
.powergate_sdma = smu_v12_0_powergate_sdma,
|
|
||||||
.powergate_vcn = smu_v12_0_powergate_vcn,
|
|
||||||
.send_smc_msg = smu_v12_0_send_msg,
|
|
||||||
.send_smc_msg_with_param = smu_v12_0_send_msg_with_param,
|
|
||||||
.read_smc_arg = smu_v12_0_read_arg,
|
|
||||||
.set_gfx_cgpg = smu_v12_0_set_gfx_cgpg,
|
|
||||||
.gfx_off_control = smu_v12_0_gfx_off_control,
|
|
||||||
.init_smc_tables = smu_v12_0_init_smc_tables,
|
|
||||||
.fini_smc_tables = smu_v12_0_fini_smc_tables,
|
|
||||||
.populate_smc_tables = smu_v12_0_populate_smc_tables,
|
|
||||||
.get_dpm_ultimate_freq = smu_v12_0_get_dpm_ultimate_freq,
|
|
||||||
.mode2_reset = smu_v12_0_mode2_reset,
|
|
||||||
.set_soft_freq_limited_range = smu_v12_0_set_soft_freq_limited_range,
|
|
||||||
};
|
|
||||||
|
|
||||||
void smu_v12_0_set_smu_funcs(struct smu_context *smu)
|
|
||||||
{
|
|
||||||
struct amdgpu_device *adev = smu->adev;
|
|
||||||
|
|
||||||
smu->funcs = &smu_v12_0_funcs;
|
|
||||||
|
|
||||||
switch (adev->asic_type) {
|
|
||||||
case CHIP_RENOIR:
|
|
||||||
renoir_set_ppt_funcs(smu);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
pr_warn("Unknown asic for smu12\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
#include "amdgpu.h"
|
#include "amdgpu.h"
|
||||||
#include "amdgpu_smu.h"
|
#include "amdgpu_smu.h"
|
||||||
|
#include "smu_internal.h"
|
||||||
#include "atomfirmware.h"
|
#include "atomfirmware.h"
|
||||||
#include "amdgpu_atomfirmware.h"
|
#include "amdgpu_atomfirmware.h"
|
||||||
#include "smu_v11_0.h"
|
#include "smu_v11_0.h"
|
||||||
@ -635,7 +636,6 @@ amd_pm_state_type vega20_get_current_power_state(struct smu_context *smu)
|
|||||||
!smu_dpm_ctx->dpm_current_power_state)
|
!smu_dpm_ctx->dpm_current_power_state)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
mutex_lock(&(smu->mutex));
|
|
||||||
switch (smu_dpm_ctx->dpm_current_power_state->classification.ui_label) {
|
switch (smu_dpm_ctx->dpm_current_power_state->classification.ui_label) {
|
||||||
case SMU_STATE_UI_LABEL_BATTERY:
|
case SMU_STATE_UI_LABEL_BATTERY:
|
||||||
pm_type = POWER_STATE_TYPE_BATTERY;
|
pm_type = POWER_STATE_TYPE_BATTERY;
|
||||||
@ -653,7 +653,6 @@ amd_pm_state_type vega20_get_current_power_state(struct smu_context *smu)
|
|||||||
pm_type = POWER_STATE_TYPE_DEFAULT;
|
pm_type = POWER_STATE_TYPE_DEFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mutex_unlock(&(smu->mutex));
|
|
||||||
|
|
||||||
return pm_type;
|
return pm_type;
|
||||||
}
|
}
|
||||||
@ -1277,8 +1276,6 @@ static int vega20_force_clk_levels(struct smu_context *smu,
|
|||||||
uint32_t soft_min_level, soft_max_level, hard_min_level;
|
uint32_t soft_min_level, soft_max_level, hard_min_level;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(&(smu->mutex));
|
|
||||||
|
|
||||||
soft_min_level = mask ? (ffs(mask) - 1) : 0;
|
soft_min_level = mask ? (ffs(mask) - 1) : 0;
|
||||||
soft_max_level = mask ? (fls(mask) - 1) : 0;
|
soft_max_level = mask ? (fls(mask) - 1) : 0;
|
||||||
|
|
||||||
@ -1431,7 +1428,6 @@ static int vega20_force_clk_levels(struct smu_context *smu,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&(smu->mutex));
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1446,8 +1442,6 @@ static int vega20_get_clock_by_type_with_latency(struct smu_context *smu,
|
|||||||
|
|
||||||
dpm_table = smu_dpm->dpm_context;
|
dpm_table = smu_dpm->dpm_context;
|
||||||
|
|
||||||
mutex_lock(&smu->mutex);
|
|
||||||
|
|
||||||
switch (clk_type) {
|
switch (clk_type) {
|
||||||
case SMU_GFXCLK:
|
case SMU_GFXCLK:
|
||||||
single_dpm_table = &(dpm_table->gfx_table);
|
single_dpm_table = &(dpm_table->gfx_table);
|
||||||
@ -1469,7 +1463,6 @@ static int vega20_get_clock_by_type_with_latency(struct smu_context *smu,
|
|||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&smu->mutex);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2255,7 +2248,7 @@ vega20_notify_smc_dispaly_config(struct smu_context *smu)
|
|||||||
if (smu_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
|
if (smu_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
|
||||||
clock_req.clock_type = amd_pp_dcef_clock;
|
clock_req.clock_type = amd_pp_dcef_clock;
|
||||||
clock_req.clock_freq_in_khz = min_clocks.dcef_clock * 10;
|
clock_req.clock_freq_in_khz = min_clocks.dcef_clock * 10;
|
||||||
if (!smu->funcs->display_clock_voltage_request(smu, &clock_req)) {
|
if (!smu_v11_0_display_clock_voltage_request(smu, &clock_req)) {
|
||||||
if (smu_feature_is_supported(smu, SMU_FEATURE_DS_DCEFCLK_BIT)) {
|
if (smu_feature_is_supported(smu, SMU_FEATURE_DS_DCEFCLK_BIT)) {
|
||||||
ret = smu_send_smc_msg_with_param(smu,
|
ret = smu_send_smc_msg_with_param(smu,
|
||||||
SMU_MSG_SetMinDeepSleepDcefclk,
|
SMU_MSG_SetMinDeepSleepDcefclk,
|
||||||
@ -2542,8 +2535,6 @@ static int vega20_set_od_percentage(struct smu_context *smu,
|
|||||||
int feature_enabled;
|
int feature_enabled;
|
||||||
PPCLK_e clk_id;
|
PPCLK_e clk_id;
|
||||||
|
|
||||||
mutex_lock(&(smu->mutex));
|
|
||||||
|
|
||||||
dpm_table = smu_dpm->dpm_context;
|
dpm_table = smu_dpm->dpm_context;
|
||||||
golden_table = smu_dpm->golden_dpm_context;
|
golden_table = smu_dpm->golden_dpm_context;
|
||||||
|
|
||||||
@ -2593,11 +2584,10 @@ static int vega20_set_od_percentage(struct smu_context *smu,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = smu_handle_task(smu, smu_dpm->dpm_level,
|
ret = smu_handle_task(smu, smu_dpm->dpm_level,
|
||||||
AMD_PP_TASK_READJUST_POWER_STATE);
|
AMD_PP_TASK_READJUST_POWER_STATE,
|
||||||
|
false);
|
||||||
|
|
||||||
set_od_failed:
|
set_od_failed:
|
||||||
mutex_unlock(&(smu->mutex));
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2822,10 +2812,9 @@ static int vega20_odn_edit_dpm_table(struct smu_context *smu,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type == PP_OD_COMMIT_DPM_TABLE) {
|
if (type == PP_OD_COMMIT_DPM_TABLE) {
|
||||||
mutex_lock(&(smu->mutex));
|
|
||||||
ret = smu_handle_task(smu, smu_dpm->dpm_level,
|
ret = smu_handle_task(smu, smu_dpm->dpm_level,
|
||||||
AMD_PP_TASK_READJUST_POWER_STATE);
|
AMD_PP_TASK_READJUST_POWER_STATE,
|
||||||
mutex_unlock(&(smu->mutex));
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -3042,7 +3031,7 @@ static int vega20_read_sensor(struct smu_context *smu,
|
|||||||
*size = 4;
|
*size = 4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = smu_smc_read_sensor(smu, sensor, data, size);
|
ret = smu_v11_0_read_sensor(smu, sensor, data, size);
|
||||||
}
|
}
|
||||||
mutex_unlock(&smu->sensor_lock);
|
mutex_unlock(&smu->sensor_lock);
|
||||||
|
|
||||||
@ -3223,7 +3212,56 @@ static const struct pptable_funcs vega20_ppt_funcs = {
|
|||||||
.set_watermarks_table = vega20_set_watermarks_table,
|
.set_watermarks_table = vega20_set_watermarks_table,
|
||||||
.get_thermal_temperature_range = vega20_get_thermal_temperature_range,
|
.get_thermal_temperature_range = vega20_get_thermal_temperature_range,
|
||||||
.set_df_cstate = vega20_set_df_cstate,
|
.set_df_cstate = vega20_set_df_cstate,
|
||||||
.update_pcie_parameters = vega20_update_pcie_parameters
|
.update_pcie_parameters = vega20_update_pcie_parameters,
|
||||||
|
.init_microcode = smu_v11_0_init_microcode,
|
||||||
|
.load_microcode = smu_v11_0_load_microcode,
|
||||||
|
.init_smc_tables = smu_v11_0_init_smc_tables,
|
||||||
|
.fini_smc_tables = smu_v11_0_fini_smc_tables,
|
||||||
|
.init_power = smu_v11_0_init_power,
|
||||||
|
.fini_power = smu_v11_0_fini_power,
|
||||||
|
.check_fw_status = smu_v11_0_check_fw_status,
|
||||||
|
.setup_pptable = smu_v11_0_setup_pptable,
|
||||||
|
.get_vbios_bootup_values = smu_v11_0_get_vbios_bootup_values,
|
||||||
|
.get_clk_info_from_vbios = smu_v11_0_get_clk_info_from_vbios,
|
||||||
|
.check_pptable = smu_v11_0_check_pptable,
|
||||||
|
.parse_pptable = smu_v11_0_parse_pptable,
|
||||||
|
.populate_smc_tables = smu_v11_0_populate_smc_pptable,
|
||||||
|
.check_fw_version = smu_v11_0_check_fw_version,
|
||||||
|
.write_pptable = smu_v11_0_write_pptable,
|
||||||
|
.set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep,
|
||||||
|
.set_tool_table_location = smu_v11_0_set_tool_table_location,
|
||||||
|
.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
|
||||||
|
.system_features_control = smu_v11_0_system_features_control,
|
||||||
|
.send_smc_msg = smu_v11_0_send_msg,
|
||||||
|
.send_smc_msg_with_param = smu_v11_0_send_msg_with_param,
|
||||||
|
.read_smc_arg = smu_v11_0_read_arg,
|
||||||
|
.init_display_count = smu_v11_0_init_display_count,
|
||||||
|
.set_allowed_mask = smu_v11_0_set_allowed_mask,
|
||||||
|
.get_enabled_mask = smu_v11_0_get_enabled_mask,
|
||||||
|
.notify_display_change = smu_v11_0_notify_display_change,
|
||||||
|
.set_power_limit = smu_v11_0_set_power_limit,
|
||||||
|
.get_current_clk_freq = smu_v11_0_get_current_clk_freq,
|
||||||
|
.init_max_sustainable_clocks = smu_v11_0_init_max_sustainable_clocks,
|
||||||
|
.start_thermal_control = smu_v11_0_start_thermal_control,
|
||||||
|
.stop_thermal_control = smu_v11_0_stop_thermal_control,
|
||||||
|
.set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk,
|
||||||
|
.display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
|
||||||
|
.get_fan_control_mode = smu_v11_0_get_fan_control_mode,
|
||||||
|
.set_fan_control_mode = smu_v11_0_set_fan_control_mode,
|
||||||
|
.set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
|
||||||
|
.set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
|
||||||
|
.set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
|
||||||
|
.gfx_off_control = smu_v11_0_gfx_off_control,
|
||||||
|
.register_irq_handler = smu_v11_0_register_irq_handler,
|
||||||
|
.set_azalia_d3_pme = smu_v11_0_set_azalia_d3_pme,
|
||||||
|
.get_max_sustainable_clocks_by_dc = smu_v11_0_get_max_sustainable_clocks_by_dc,
|
||||||
|
.baco_is_support= smu_v11_0_baco_is_support,
|
||||||
|
.baco_get_state = smu_v11_0_baco_get_state,
|
||||||
|
.baco_set_state = smu_v11_0_baco_set_state,
|
||||||
|
.baco_reset = smu_v11_0_baco_reset,
|
||||||
|
.get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq,
|
||||||
|
.set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
|
||||||
|
.override_pcie_parameters = smu_v11_0_override_pcie_parameters,
|
||||||
};
|
};
|
||||||
|
|
||||||
void vega20_set_ppt_funcs(struct smu_context *smu)
|
void vega20_set_ppt_funcs(struct smu_context *smu)
|
||||||
|
@ -221,9 +221,7 @@ int ci_get_temp(struct radeon_device *rdev)
|
|||||||
else
|
else
|
||||||
actual_temp = temp & 0x1ff;
|
actual_temp = temp & 0x1ff;
|
||||||
|
|
||||||
actual_temp = actual_temp * 1000;
|
return actual_temp * 1000;
|
||||||
|
|
||||||
return actual_temp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get temperature in millidegrees */
|
/* get temperature in millidegrees */
|
||||||
@ -239,9 +237,7 @@ int kv_get_temp(struct radeon_device *rdev)
|
|||||||
else
|
else
|
||||||
actual_temp = 0;
|
actual_temp = 0;
|
||||||
|
|
||||||
actual_temp = actual_temp * 1000;
|
return actual_temp * 1000;
|
||||||
|
|
||||||
return actual_temp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -379,11 +379,25 @@ radeon_pci_remove(struct pci_dev *pdev)
|
|||||||
static void
|
static void
|
||||||
radeon_pci_shutdown(struct pci_dev *pdev)
|
radeon_pci_shutdown(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_PPC64
|
||||||
|
struct drm_device *ddev = pci_get_drvdata(pdev);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* if we are running in a VM, make sure the device
|
/* if we are running in a VM, make sure the device
|
||||||
* torn down properly on reboot/shutdown
|
* torn down properly on reboot/shutdown
|
||||||
*/
|
*/
|
||||||
if (radeon_device_is_virtual())
|
if (radeon_device_is_virtual())
|
||||||
radeon_pci_remove(pdev);
|
radeon_pci_remove(pdev);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC64
|
||||||
|
/* Some adapters need to be suspended before a
|
||||||
|
* shutdown occurs in order to prevent an error
|
||||||
|
* during kexec.
|
||||||
|
* Make this power specific becauase it breaks
|
||||||
|
* some non-power boards.
|
||||||
|
*/
|
||||||
|
radeon_suspend_kms(ddev, true, true, false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int radeon_pmops_suspend(struct device *dev)
|
static int radeon_pmops_suspend(struct device *dev)
|
||||||
|
@ -479,6 +479,7 @@ void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched)
|
|||||||
struct drm_sched_job *s_job, *tmp;
|
struct drm_sched_job *s_job, *tmp;
|
||||||
uint64_t guilty_context;
|
uint64_t guilty_context;
|
||||||
bool found_guilty = false;
|
bool found_guilty = false;
|
||||||
|
struct dma_fence *fence;
|
||||||
|
|
||||||
list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) {
|
list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) {
|
||||||
struct drm_sched_fence *s_fence = s_job->s_fence;
|
struct drm_sched_fence *s_fence = s_job->s_fence;
|
||||||
@ -492,7 +493,16 @@ void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched)
|
|||||||
dma_fence_set_error(&s_fence->finished, -ECANCELED);
|
dma_fence_set_error(&s_fence->finished, -ECANCELED);
|
||||||
|
|
||||||
dma_fence_put(s_job->s_fence->parent);
|
dma_fence_put(s_job->s_fence->parent);
|
||||||
s_job->s_fence->parent = sched->ops->run_job(s_job);
|
fence = sched->ops->run_job(s_job);
|
||||||
|
|
||||||
|
if (IS_ERR_OR_NULL(fence)) {
|
||||||
|
s_job->s_fence->parent = NULL;
|
||||||
|
dma_fence_set_error(&s_fence->finished, PTR_ERR(fence));
|
||||||
|
} else {
|
||||||
|
s_job->s_fence->parent = fence;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_sched_resubmit_jobs);
|
EXPORT_SYMBOL(drm_sched_resubmit_jobs);
|
||||||
@ -725,7 +735,7 @@ static int drm_sched_main(void *param)
|
|||||||
fence = sched->ops->run_job(sched_job);
|
fence = sched->ops->run_job(sched_job);
|
||||||
drm_sched_fence_scheduled(s_fence);
|
drm_sched_fence_scheduled(s_fence);
|
||||||
|
|
||||||
if (fence) {
|
if (!IS_ERR_OR_NULL(fence)) {
|
||||||
s_fence->parent = dma_fence_get(fence);
|
s_fence->parent = dma_fence_get(fence);
|
||||||
r = dma_fence_add_callback(fence, &sched_job->cb,
|
r = dma_fence_add_callback(fence, &sched_job->cb,
|
||||||
drm_sched_process_job);
|
drm_sched_process_job);
|
||||||
@ -735,8 +745,11 @@ static int drm_sched_main(void *param)
|
|||||||
DRM_ERROR("fence add callback failed (%d)\n",
|
DRM_ERROR("fence add callback failed (%d)\n",
|
||||||
r);
|
r);
|
||||||
dma_fence_put(fence);
|
dma_fence_put(fence);
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
|
dma_fence_set_error(&s_fence->finished, PTR_ERR(fence));
|
||||||
drm_sched_process_job(NULL, &sched_job->cb);
|
drm_sched_process_job(NULL, &sched_job->cb);
|
||||||
|
}
|
||||||
|
|
||||||
wake_up(&sched->job_scheduled);
|
wake_up(&sched->job_scheduled);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user