mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-01 06:33:07 +00:00
Merge tag 'amd-drm-next-6.3-2023-01-06' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-6.3-2023-01-06: amdgpu: - secure display support for multiple displays - DML optimizations - DCN 3.2 updates - PSR updates - DP 2.1 updates - SR-IOV RAS updates - VCN RAS support - SMU 13.x updates - Switch 1 element arrays to flexible arrays - Add RAS support for DF 4.3 - Stack size improvements - S0ix rework - Soft reset fix - Allow 0 as a vram limit on APUs - Display fixes - Misc code cleanups - Documentation fixes - Handle profiling modes for SMU13.x amdkfd: - Error handling fixes - PASID fixes radeon: - Switch 1 element arrays to flexible arrays drm: - Add DP adaptive sync DPCD definitions UAPI: - Add new INFO queries for peak and min sclk/mclk for profile modes on newer chips Proposed mesa patch: https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/278 Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230106222037.7870-1-alexander.deucher@amd.com
This commit is contained in:
commit
45be204806
138 changed files with 1980 additions and 1000 deletions
|
@ -81,7 +81,8 @@ amdgpu-y += \
|
|||
# add DF block
|
||||
amdgpu-y += \
|
||||
df_v1_7.o \
|
||||
df_v3_6.o
|
||||
df_v3_6.o \
|
||||
df_v4_3.o
|
||||
|
||||
# add GMC block
|
||||
amdgpu-y += \
|
||||
|
|
|
@ -149,7 +149,7 @@ struct amdgpu_watchdog_timer
|
|||
* Modules parameters.
|
||||
*/
|
||||
extern int amdgpu_modeset;
|
||||
extern int amdgpu_vram_limit;
|
||||
extern unsigned int amdgpu_vram_limit;
|
||||
extern int amdgpu_vis_vram_limit;
|
||||
extern int amdgpu_gart_size;
|
||||
extern int amdgpu_gtt_size;
|
||||
|
@ -194,6 +194,7 @@ extern int amdgpu_emu_mode;
|
|||
extern uint amdgpu_smu_memory_pool_size;
|
||||
extern int amdgpu_smu_pptable_id;
|
||||
extern uint amdgpu_dc_feature_mask;
|
||||
extern uint amdgpu_freesync_vid_mode;
|
||||
extern uint amdgpu_dc_debug_mask;
|
||||
extern uint amdgpu_dc_visual_confirm;
|
||||
extern uint amdgpu_dm_abm_level;
|
||||
|
@ -607,7 +608,7 @@ int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data,
|
|||
struct drm_file *filp);
|
||||
|
||||
/* VRAM scratch page for HDP bug, default vram page */
|
||||
struct amdgpu_vram_scratch {
|
||||
struct amdgpu_mem_scratch {
|
||||
struct amdgpu_bo *robj;
|
||||
volatile uint32_t *ptr;
|
||||
u64 gpu_addr;
|
||||
|
@ -754,6 +755,11 @@ struct amdgpu_mqd {
|
|||
#define AMDGPU_PRODUCT_NAME_LEN 64
|
||||
struct amdgpu_reset_domain;
|
||||
|
||||
/*
|
||||
* Non-zero (true) if the GPU has VRAM. Zero (false) otherwise.
|
||||
*/
|
||||
#define AMDGPU_HAS_VRAM(_adev) ((_adev)->gmc.real_vram_size)
|
||||
|
||||
struct amdgpu_device {
|
||||
struct device *dev;
|
||||
struct pci_dev *pdev;
|
||||
|
@ -847,7 +853,7 @@ struct amdgpu_device {
|
|||
|
||||
/* memory management */
|
||||
struct amdgpu_mman mman;
|
||||
struct amdgpu_vram_scratch vram_scratch;
|
||||
struct amdgpu_mem_scratch mem_scratch;
|
||||
struct amdgpu_wb wb;
|
||||
atomic64_t num_bytes_moved;
|
||||
atomic64_t num_evictions;
|
||||
|
@ -869,7 +875,7 @@ struct amdgpu_device {
|
|||
struct amdgpu_vkms_output *amdgpu_vkms_output;
|
||||
struct amdgpu_mode_info mode_info;
|
||||
/* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */
|
||||
struct work_struct hotplug_work;
|
||||
struct delayed_work hotplug_work;
|
||||
struct amdgpu_irq_src crtc_irq;
|
||||
struct amdgpu_irq_src vline0_irq;
|
||||
struct amdgpu_irq_src vupdate_irq;
|
||||
|
|
|
@ -996,13 +996,33 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
|
|||
}
|
||||
}
|
||||
|
||||
if (amdgpu_connector->detected_hpd_without_ddc) {
|
||||
force = true;
|
||||
amdgpu_connector->detected_hpd_without_ddc = false;
|
||||
}
|
||||
|
||||
if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {
|
||||
ret = connector->status;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (amdgpu_connector->ddc_bus)
|
||||
if (amdgpu_connector->ddc_bus) {
|
||||
dret = amdgpu_display_ddc_probe(amdgpu_connector, false);
|
||||
|
||||
/* Sometimes the pins required for the DDC probe on DVI
|
||||
* connectors don't make contact at the same time that the ones
|
||||
* for HPD do. If the DDC probe fails even though we had an HPD
|
||||
* signal, try again later
|
||||
*/
|
||||
if (!dret && !force &&
|
||||
amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) {
|
||||
DRM_DEBUG_KMS("hpd detected without ddc, retrying in 1 second\n");
|
||||
amdgpu_connector->detected_hpd_without_ddc = true;
|
||||
schedule_delayed_work(&adev->hotplug_work,
|
||||
msecs_to_jiffies(1000));
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
if (dret) {
|
||||
amdgpu_connector->detected_by_load = false;
|
||||
amdgpu_connector_free_edid(connector);
|
||||
|
|
|
@ -924,32 +924,33 @@ static int amdgpu_device_asic_init(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_vram_scratch_init - allocate the VRAM scratch page
|
||||
* amdgpu_device_mem_scratch_init - allocate the VRAM scratch page
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Allocates a scratch page of VRAM for use by various things in the
|
||||
* driver.
|
||||
*/
|
||||
static int amdgpu_device_vram_scratch_init(struct amdgpu_device *adev)
|
||||
static int amdgpu_device_mem_scratch_init(struct amdgpu_device *adev)
|
||||
{
|
||||
return amdgpu_bo_create_kernel(adev, AMDGPU_GPU_PAGE_SIZE,
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&adev->vram_scratch.robj,
|
||||
&adev->vram_scratch.gpu_addr,
|
||||
(void **)&adev->vram_scratch.ptr);
|
||||
return amdgpu_bo_create_kernel(adev, AMDGPU_GPU_PAGE_SIZE, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->mem_scratch.robj,
|
||||
&adev->mem_scratch.gpu_addr,
|
||||
(void **)&adev->mem_scratch.ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_vram_scratch_fini - Free the VRAM scratch page
|
||||
* amdgpu_device_mem_scratch_fini - Free the VRAM scratch page
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Frees the VRAM scratch page.
|
||||
*/
|
||||
static void amdgpu_device_vram_scratch_fini(struct amdgpu_device *adev)
|
||||
static void amdgpu_device_mem_scratch_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
amdgpu_bo_free_kernel(&adev->vram_scratch.robj, NULL, NULL);
|
||||
amdgpu_bo_free_kernel(&adev->mem_scratch.robj, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2390,9 +2391,9 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
|||
if (amdgpu_sriov_vf(adev))
|
||||
amdgpu_virt_exchange_data(adev);
|
||||
|
||||
r = amdgpu_device_vram_scratch_init(adev);
|
||||
r = amdgpu_device_mem_scratch_init(adev);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu_vram_scratch_init failed %d\n", r);
|
||||
DRM_ERROR("amdgpu_mem_scratch_init failed %d\n", r);
|
||||
goto init_failed;
|
||||
}
|
||||
r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
|
||||
|
@ -2410,7 +2411,8 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
|||
/* right after GMC hw init, we create CSA */
|
||||
if (amdgpu_mcbp) {
|
||||
r = amdgpu_allocate_static_csa(adev, &adev->virt.csa_obj,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
AMDGPU_CSA_SIZE);
|
||||
if (r) {
|
||||
DRM_ERROR("allocate CSA failed %d\n", r);
|
||||
|
@ -2581,9 +2583,10 @@ int amdgpu_device_set_cg_state(struct amdgpu_device *adev,
|
|||
i = state == AMD_CG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
|
||||
if (!adev->ip_blocks[i].status.late_initialized)
|
||||
continue;
|
||||
/* skip CG for GFX on S0ix */
|
||||
/* skip CG for GFX, SDMA on S0ix */
|
||||
if (adev->in_s0ix &&
|
||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX)
|
||||
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
|
||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SDMA))
|
||||
continue;
|
||||
/* skip CG for VCE/UVD, it's handled specially */
|
||||
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
|
||||
|
@ -2617,9 +2620,10 @@ int amdgpu_device_set_pg_state(struct amdgpu_device *adev,
|
|||
i = state == AMD_PG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
|
||||
if (!adev->ip_blocks[i].status.late_initialized)
|
||||
continue;
|
||||
/* skip PG for GFX on S0ix */
|
||||
/* skip PG for GFX, SDMA on S0ix */
|
||||
if (adev->in_s0ix &&
|
||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX)
|
||||
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
|
||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SDMA))
|
||||
continue;
|
||||
/* skip CG for VCE/UVD, it's handled specially */
|
||||
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
|
||||
|
@ -2871,7 +2875,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
|
|||
amdgpu_ucode_free_bo(adev);
|
||||
amdgpu_free_static_csa(&adev->virt.csa_obj);
|
||||
amdgpu_device_wb_fini(adev);
|
||||
amdgpu_device_vram_scratch_fini(adev);
|
||||
amdgpu_device_mem_scratch_fini(adev);
|
||||
amdgpu_ib_pool_fini(adev);
|
||||
}
|
||||
|
||||
|
@ -3027,6 +3031,12 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
|
|||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_MES))
|
||||
continue;
|
||||
|
||||
/* SDMA 5.x+ is part of GFX power domain so it's covered by GFXOFF */
|
||||
if (adev->in_s0ix &&
|
||||
(adev->ip_versions[SDMA0_HWIP][0] >= IP_VERSION(5, 0, 0)) &&
|
||||
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SDMA))
|
||||
continue;
|
||||
|
||||
/* XXX handle errors */
|
||||
r = adev->ip_blocks[i].version->funcs->suspend(adev);
|
||||
/* XXX handle errors */
|
||||
|
@ -3227,15 +3237,6 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
|
|||
return r;
|
||||
}
|
||||
adev->ip_blocks[i].status.hw = true;
|
||||
|
||||
if (adev->in_s0ix && adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) {
|
||||
/* disable gfxoff for IP resume. The gfxoff will be re-enabled in
|
||||
* amdgpu_device_resume() after IP resume.
|
||||
*/
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
DRM_DEBUG("will disable gfxoff for re-initializing other blocks\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -4221,13 +4222,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
|||
/* Make sure IB tests flushed */
|
||||
flush_delayed_work(&adev->delayed_init_work);
|
||||
|
||||
if (adev->in_s0ix) {
|
||||
/* re-enable gfxoff after IP resume. This re-enables gfxoff after
|
||||
* it was disabled for IP resume in amdgpu_device_ip_resume_phase2().
|
||||
*/
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
DRM_DEBUG("will enable gfxoff for the mission mode\n");
|
||||
}
|
||||
if (fbcon)
|
||||
drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false);
|
||||
|
||||
|
@ -4608,11 +4602,6 @@ bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev)
|
|||
if (!amdgpu_ras_is_poison_mode_supported(adev))
|
||||
return true;
|
||||
|
||||
if (!amdgpu_device_ip_check_soft_reset(adev)) {
|
||||
dev_info(adev->dev,"Timeout, but no hardware hang detected.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return true;
|
||||
|
||||
|
@ -4737,7 +4726,8 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
|
|||
if (!need_full_reset)
|
||||
need_full_reset = amdgpu_device_ip_need_full_reset(adev);
|
||||
|
||||
if (!need_full_reset && amdgpu_gpu_recovery) {
|
||||
if (!need_full_reset && amdgpu_gpu_recovery &&
|
||||
amdgpu_device_ip_check_soft_reset(adev)) {
|
||||
amdgpu_device_ip_pre_soft_reset(adev);
|
||||
r = amdgpu_device_ip_soft_reset(adev);
|
||||
amdgpu_device_ip_post_soft_reset(adev);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "gmc_v9_0.h"
|
||||
#include "df_v1_7.h"
|
||||
#include "df_v3_6.h"
|
||||
#include "df_v4_3.h"
|
||||
#include "nbio_v6_1.h"
|
||||
#include "nbio_v7_0.h"
|
||||
#include "nbio_v7_4.h"
|
||||
|
@ -2329,6 +2330,9 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(3, 5, 2):
|
||||
adev->df.funcs = &df_v1_7_funcs;
|
||||
break;
|
||||
case IP_VERSION(4, 3, 0):
|
||||
adev->df.funcs = &df_v4_3_funcs;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
void amdgpu_display_hotplug_work_func(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
|
||||
hotplug_work);
|
||||
hotplug_work.work);
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct drm_mode_config *mode_config = &dev->mode_config;
|
||||
struct drm_connector *connector;
|
||||
|
|
|
@ -105,13 +105,15 @@
|
|||
* - 3.46.0 - To enable hot plug amdgpu tests in libdrm
|
||||
* - 3.47.0 - Add AMDGPU_GEM_CREATE_DISCARDABLE and AMDGPU_VM_NOALLOC flags
|
||||
* - 3.48.0 - Add IP discovery version info to HW INFO
|
||||
* 3.49.0 - Add gang submit into CS IOCTL
|
||||
* - 3.49.0 - Add gang submit into CS IOCTL
|
||||
* - 3.50.0 - Update AMDGPU_INFO_DEV_INFO IOCTL for minimum engine and memory clock
|
||||
* Update AMDGPU_INFO_SENSOR IOCTL for PEAK_PSTATE engine and memory clock
|
||||
*/
|
||||
#define KMS_DRIVER_MAJOR 3
|
||||
#define KMS_DRIVER_MINOR 49
|
||||
#define KMS_DRIVER_MINOR 50
|
||||
#define KMS_DRIVER_PATCHLEVEL 0
|
||||
|
||||
int amdgpu_vram_limit;
|
||||
unsigned int amdgpu_vram_limit = UINT_MAX;
|
||||
int amdgpu_vis_vram_limit;
|
||||
int amdgpu_gart_size = -1; /* auto */
|
||||
int amdgpu_gtt_size = -1; /* auto */
|
||||
|
@ -181,6 +183,7 @@ int amdgpu_mes_kiq;
|
|||
int amdgpu_noretry = -1;
|
||||
int amdgpu_force_asic_type = -1;
|
||||
int amdgpu_tmz = -1; /* auto */
|
||||
uint amdgpu_freesync_vid_mode;
|
||||
int amdgpu_reset_method = -1; /* auto */
|
||||
int amdgpu_num_kcq = -1;
|
||||
int amdgpu_smartshift_bias;
|
||||
|
@ -879,6 +882,32 @@ module_param_named(backlight, amdgpu_backlight, bint, 0444);
|
|||
MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto (default), 0 = off, 1 = on)");
|
||||
module_param_named(tmz, amdgpu_tmz, int, 0444);
|
||||
|
||||
/**
|
||||
* DOC: freesync_video (uint)
|
||||
* Enable the optimization to adjust front porch timing to achieve seamless
|
||||
* mode change experience when setting a freesync supported mode for which full
|
||||
* modeset is not needed.
|
||||
*
|
||||
* The Display Core will add a set of modes derived from the base FreeSync
|
||||
* video mode into the corresponding connector's mode list based on commonly
|
||||
* used refresh rates and VRR range of the connected display, when users enable
|
||||
* this feature. From the userspace perspective, they can see a seamless mode
|
||||
* change experience when the change between different refresh rates under the
|
||||
* same resolution. Additionally, userspace applications such as Video playback
|
||||
* can read this modeset list and change the refresh rate based on the video
|
||||
* frame rate. Finally, the userspace can also derive an appropriate mode for a
|
||||
* particular refresh rate based on the FreeSync Mode and add it to the
|
||||
* connector's mode list.
|
||||
*
|
||||
* Note: This is an experimental feature.
|
||||
*
|
||||
* The default value: 0 (off).
|
||||
*/
|
||||
MODULE_PARM_DESC(
|
||||
freesync_video,
|
||||
"Enable freesync modesetting optimization feature (0 = off (default), 1 = on)");
|
||||
module_param_named(freesync_video, amdgpu_freesync_vid_mode, uint, 0444);
|
||||
|
||||
/**
|
||||
* DOC: reset_method (int)
|
||||
* GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco)
|
||||
|
|
|
@ -372,8 +372,11 @@ int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev,
|
|||
* KIQ MQD no matter SRIOV or Bare-metal
|
||||
*/
|
||||
r = amdgpu_bo_create_kernel(adev, mqd_size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM, &ring->mqd_obj,
|
||||
&ring->mqd_gpu_addr, &ring->mqd_ptr);
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&ring->mqd_obj,
|
||||
&ring->mqd_gpu_addr,
|
||||
&ring->mqd_ptr);
|
||||
if (r) {
|
||||
dev_warn(adev->dev, "failed to create ring mqd ob (%d)", r);
|
||||
return r;
|
||||
|
|
|
@ -202,13 +202,20 @@ uint64_t amdgpu_gmc_agp_addr(struct ttm_buffer_object *bo)
|
|||
void amdgpu_gmc_vram_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc,
|
||||
u64 base)
|
||||
{
|
||||
uint64_t vis_limit = (uint64_t)amdgpu_vis_vram_limit << 20;
|
||||
uint64_t limit = (uint64_t)amdgpu_vram_limit << 20;
|
||||
|
||||
mc->vram_start = base;
|
||||
mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
|
||||
if (limit && limit < mc->real_vram_size)
|
||||
if (limit < mc->real_vram_size)
|
||||
mc->real_vram_size = limit;
|
||||
|
||||
if (vis_limit && vis_limit < mc->visible_vram_size)
|
||||
mc->visible_vram_size = vis_limit;
|
||||
|
||||
if (mc->real_vram_size < mc->visible_vram_size)
|
||||
mc->visible_vram_size = mc->real_vram_size;
|
||||
|
||||
if (mc->xgmi.num_physical_nodes == 0) {
|
||||
mc->fb_start = mc->vram_start;
|
||||
mc->fb_end = mc->vram_end;
|
||||
|
|
|
@ -785,9 +785,15 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|||
if (adev->pm.dpm_enabled) {
|
||||
dev_info->max_engine_clock = amdgpu_dpm_get_sclk(adev, false) * 10;
|
||||
dev_info->max_memory_clock = amdgpu_dpm_get_mclk(adev, false) * 10;
|
||||
dev_info->min_engine_clock = amdgpu_dpm_get_sclk(adev, true) * 10;
|
||||
dev_info->min_memory_clock = amdgpu_dpm_get_mclk(adev, true) * 10;
|
||||
} else {
|
||||
dev_info->max_engine_clock = adev->clock.default_sclk * 10;
|
||||
dev_info->max_memory_clock = adev->clock.default_mclk * 10;
|
||||
dev_info->max_engine_clock =
|
||||
dev_info->min_engine_clock =
|
||||
adev->clock.default_sclk * 10;
|
||||
dev_info->max_memory_clock =
|
||||
dev_info->min_memory_clock =
|
||||
adev->clock.default_mclk * 10;
|
||||
}
|
||||
dev_info->enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask;
|
||||
dev_info->num_rb_pipes = adev->gfx.config.max_backends_per_se *
|
||||
|
@ -1014,6 +1020,24 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|||
}
|
||||
ui32 /= 100;
|
||||
break;
|
||||
case AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_SCLK:
|
||||
/* get peak pstate sclk in Mhz */
|
||||
if (amdgpu_dpm_read_sensor(adev,
|
||||
AMDGPU_PP_SENSOR_PEAK_PSTATE_SCLK,
|
||||
(void *)&ui32, &ui32_size)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
ui32 /= 100;
|
||||
break;
|
||||
case AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_MCLK:
|
||||
/* get peak pstate mclk in Mhz */
|
||||
if (amdgpu_dpm_read_sensor(adev,
|
||||
AMDGPU_PP_SENSOR_PEAK_PSTATE_MCLK,
|
||||
(void *)&ui32, &ui32_size)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
ui32 /= 100;
|
||||
break;
|
||||
default:
|
||||
DRM_DEBUG_KMS("Invalid request %d\n",
|
||||
info->sensor_info.type);
|
||||
|
|
|
@ -534,6 +534,7 @@ struct amdgpu_connector {
|
|||
void *con_priv;
|
||||
bool dac_load_detect;
|
||||
bool detected_by_load; /* if the connection status was determined by load */
|
||||
bool detected_hpd_without_ddc; /* if an HPD signal was detected on DVI, but ddc probing failed */
|
||||
uint16_t connector_object_id;
|
||||
struct amdgpu_hpd hpd;
|
||||
struct amdgpu_router router;
|
||||
|
|
|
@ -66,7 +66,8 @@ static int psp_ring_init(struct psp_context *psp,
|
|||
/* allocate 4k Page of Local Frame Buffer memory for ring */
|
||||
ring->ring_size = 0x1000;
|
||||
ret = amdgpu_bo_create_kernel(adev, ring->ring_size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->firmware.rbuf,
|
||||
&ring->ring_mem_mc_addr,
|
||||
(void **)&ring->ring_mem);
|
||||
|
@ -797,9 +798,13 @@ static int psp_tmr_init(struct psp_context *psp)
|
|||
|
||||
if (!psp->tmr_bo) {
|
||||
pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
|
||||
ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&psp->tmr_bo, &psp->tmr_mc_addr, pptr);
|
||||
ret = amdgpu_bo_create_kernel(psp->adev, tmr_size,
|
||||
PSP_TMR_ALIGNMENT,
|
||||
AMDGPU_HAS_VRAM(psp->adev) ?
|
||||
AMDGPU_GEM_DOMAIN_VRAM :
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&psp->tmr_bo, &psp->tmr_mc_addr,
|
||||
pptr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -1092,7 +1097,8 @@ int psp_ta_init_shared_buf(struct psp_context *psp,
|
|||
* physical) for ta to host memory
|
||||
*/
|
||||
return amdgpu_bo_create_kernel(psp->adev, mem_ctx->shared_mem_size,
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&mem_ctx->shared_bo,
|
||||
&mem_ctx->shared_mc_addr,
|
||||
&mem_ctx->shared_buf);
|
||||
|
@ -1901,7 +1907,7 @@ int psp_rap_invoke(struct psp_context *psp, uint32_t ta_cmd_id, enum ta_rap_stat
|
|||
static int psp_securedisplay_initialize(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
struct securedisplay_cmd *securedisplay_cmd;
|
||||
struct ta_securedisplay_cmd *securedisplay_cmd;
|
||||
|
||||
/*
|
||||
* TODO: bypass the initialize in sriov for now
|
||||
|
@ -3444,9 +3450,9 @@ static ssize_t psp_usbc_pd_fw_sysfs_write(struct device *dev,
|
|||
|
||||
/* LFB address which is aligned to 1MB boundary per PSP request */
|
||||
ret = amdgpu_bo_create_kernel(adev, usbc_pd_fw->size, 0x100000,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&fw_buf_bo,
|
||||
&fw_pri_mc_addr,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&fw_buf_bo, &fw_pri_mc_addr,
|
||||
&fw_pri_cpu_addr);
|
||||
if (ret)
|
||||
goto rel_buf;
|
||||
|
|
|
@ -706,13 +706,23 @@ static int __amdgpu_ras_feature_enable(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_ras_check_feature_allowed(struct amdgpu_device *adev,
|
||||
struct ras_common_if *head)
|
||||
{
|
||||
if (amdgpu_ras_is_feature_allowed(adev, head) ||
|
||||
amdgpu_ras_is_poison_mode_supported(adev))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* wrapper of psp_ras_enable_features */
|
||||
int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
|
||||
struct ras_common_if *head, bool enable)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
union ta_ras_cmd_input *info;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (!con)
|
||||
return -EINVAL;
|
||||
|
@ -736,7 +746,8 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
|
|||
}
|
||||
|
||||
/* Do not enable if it is not allowed. */
|
||||
WARN_ON(enable && !amdgpu_ras_is_feature_allowed(adev, head));
|
||||
if (enable && !amdgpu_ras_check_feature_allowed(adev, head))
|
||||
goto out;
|
||||
|
||||
/* Only enable ras feature operation handle on host side */
|
||||
if (head->block == AMDGPU_RAS_BLOCK__GFX &&
|
||||
|
@ -754,7 +765,6 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
|
|||
|
||||
/* setup the obj */
|
||||
__amdgpu_ras_feature_enable(adev, head, enable);
|
||||
ret = 0;
|
||||
out:
|
||||
if (head->block == AMDGPU_RAS_BLOCK__GFX)
|
||||
kfree(info);
|
||||
|
@ -1087,6 +1097,10 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
|
|||
info->head.block,
|
||||
info->head.sub_block_index);
|
||||
|
||||
/* inject on guest isn't allowed, return success directly */
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
if (!obj)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -1122,11 +1136,54 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
|
|||
}
|
||||
|
||||
/**
|
||||
* amdgpu_ras_query_error_count -- Get error counts of all IPs
|
||||
* amdgpu_ras_query_error_count_helper -- Get error counter for specific IP
|
||||
* @adev: pointer to AMD GPU device
|
||||
* @ce_count: pointer to an integer to be set to the count of correctible errors.
|
||||
* @ue_count: pointer to an integer to be set to the count of uncorrectible errors.
|
||||
* @query_info: pointer to ras_query_if
|
||||
*
|
||||
* Return 0 for query success or do nothing, otherwise return an error
|
||||
* on failures
|
||||
*/
|
||||
static int amdgpu_ras_query_error_count_helper(struct amdgpu_device *adev,
|
||||
unsigned long *ce_count,
|
||||
unsigned long *ue_count,
|
||||
struct ras_query_if *query_info)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!query_info)
|
||||
/* do nothing if query_info is not specified */
|
||||
return 0;
|
||||
|
||||
ret = amdgpu_ras_query_error_status(adev, query_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*ce_count += query_info->ce_count;
|
||||
*ue_count += query_info->ue_count;
|
||||
|
||||
/* some hardware/IP supports read to clear
|
||||
* no need to explictly reset the err status after the query call */
|
||||
if (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 2) &&
|
||||
adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 4)) {
|
||||
if (amdgpu_ras_reset_error_status(adev, query_info->head.block))
|
||||
dev_warn(adev->dev,
|
||||
"Failed to reset error counter and error status\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_ras_query_error_count -- Get error counts of all IPs or specific IP
|
||||
* @adev: pointer to AMD GPU device
|
||||
* @ce_count: pointer to an integer to be set to the count of correctible errors.
|
||||
* @ue_count: pointer to an integer to be set to the count of uncorrectible
|
||||
* errors.
|
||||
* @query_info: pointer to ras_query_if if the query request is only for
|
||||
* specific ip block; if info is NULL, then the qurey request is for
|
||||
* all the ip blocks that support query ras error counters/status
|
||||
*
|
||||
* If set, @ce_count or @ue_count, count and return the corresponding
|
||||
* error counts in those integer pointers. Return 0 if the device
|
||||
|
@ -1134,11 +1191,13 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
|
|||
*/
|
||||
int amdgpu_ras_query_error_count(struct amdgpu_device *adev,
|
||||
unsigned long *ce_count,
|
||||
unsigned long *ue_count)
|
||||
unsigned long *ue_count,
|
||||
struct ras_query_if *query_info)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
struct ras_manager *obj;
|
||||
unsigned long ce, ue;
|
||||
int ret;
|
||||
|
||||
if (!adev->ras_enabled || !con)
|
||||
return -EOPNOTSUPP;
|
||||
|
@ -1150,25 +1209,22 @@ int amdgpu_ras_query_error_count(struct amdgpu_device *adev,
|
|||
|
||||
ce = 0;
|
||||
ue = 0;
|
||||
if (!query_info) {
|
||||
/* query all the ip blocks that support ras query interface */
|
||||
list_for_each_entry(obj, &con->head, node) {
|
||||
struct ras_query_if info = {
|
||||
.head = obj->head,
|
||||
};
|
||||
int res;
|
||||
|
||||
res = amdgpu_ras_query_error_status(adev, &info);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
if (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 2) &&
|
||||
adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 4)) {
|
||||
if (amdgpu_ras_reset_error_status(adev, info.head.block))
|
||||
dev_warn(adev->dev, "Failed to reset error counter and error status");
|
||||
ret = amdgpu_ras_query_error_count_helper(adev, &ce, &ue, &info);
|
||||
}
|
||||
} else {
|
||||
/* query specific ip block */
|
||||
ret = amdgpu_ras_query_error_count_helper(adev, &ce, &ue, query_info);
|
||||
}
|
||||
|
||||
ce += info.ce_count;
|
||||
ue += info.ue_count;
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (ce_count)
|
||||
*ce_count = ce;
|
||||
|
@ -2344,10 +2400,17 @@ static void amdgpu_ras_check_supported(struct amdgpu_device *adev)
|
|||
|
||||
if (amdgpu_atomfirmware_sram_ecc_supported(adev)) {
|
||||
dev_info(adev->dev, "SRAM ECC is active.\n");
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
adev->ras_hw_enabled |= ~(1 << AMDGPU_RAS_BLOCK__UMC |
|
||||
1 << AMDGPU_RAS_BLOCK__DF);
|
||||
else
|
||||
adev->ras_hw_enabled |= (1 << AMDGPU_RAS_BLOCK__PCIE_BIF |
|
||||
1 << AMDGPU_RAS_BLOCK__SDMA |
|
||||
1 << AMDGPU_RAS_BLOCK__GFX);
|
||||
|
||||
/* VCN/JPEG RAS can be supported on both bare metal and
|
||||
* SRIOV environment
|
||||
*/
|
||||
if (adev->ip_versions[VCN_HWIP][0] == IP_VERSION(2, 6, 0) ||
|
||||
adev->ip_versions[VCN_HWIP][0] == IP_VERSION(4, 0, 0))
|
||||
adev->ras_hw_enabled |= (1 << AMDGPU_RAS_BLOCK__VCN |
|
||||
|
@ -2355,11 +2418,6 @@ static void amdgpu_ras_check_supported(struct amdgpu_device *adev)
|
|||
else
|
||||
adev->ras_hw_enabled &= ~(1 << AMDGPU_RAS_BLOCK__VCN |
|
||||
1 << AMDGPU_RAS_BLOCK__JPEG);
|
||||
} else {
|
||||
adev->ras_hw_enabled |= (1 << AMDGPU_RAS_BLOCK__PCIE_BIF |
|
||||
1 << AMDGPU_RAS_BLOCK__SDMA |
|
||||
1 << AMDGPU_RAS_BLOCK__GFX);
|
||||
}
|
||||
} else {
|
||||
dev_info(adev->dev, "SRAM ECC is not presented.\n");
|
||||
}
|
||||
|
@ -2395,7 +2453,7 @@ static void amdgpu_ras_counte_dw(struct work_struct *work)
|
|||
|
||||
/* Cache new values.
|
||||
*/
|
||||
if (amdgpu_ras_query_error_count(adev, &ce_count, &ue_count) == 0) {
|
||||
if (amdgpu_ras_query_error_count(adev, &ce_count, &ue_count, NULL) == 0) {
|
||||
atomic_set(&con->ras_ce_count, ce_count);
|
||||
atomic_set(&con->ras_ue_count, ue_count);
|
||||
}
|
||||
|
@ -2405,11 +2463,42 @@ static void amdgpu_ras_counte_dw(struct work_struct *work)
|
|||
pm_runtime_put_autosuspend(dev->dev);
|
||||
}
|
||||
|
||||
static void amdgpu_ras_query_poison_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
bool df_poison, umc_poison;
|
||||
|
||||
/* poison setting is useless on SRIOV guest */
|
||||
if (amdgpu_sriov_vf(adev) || !con)
|
||||
return;
|
||||
|
||||
/* Init poison supported flag, the default value is false */
|
||||
if (adev->gmc.xgmi.connected_to_cpu) {
|
||||
/* enabled by default when GPU is connected to CPU */
|
||||
con->poison_supported = true;
|
||||
} else if (adev->df.funcs &&
|
||||
adev->df.funcs->query_ras_poison_mode &&
|
||||
adev->umc.ras &&
|
||||
adev->umc.ras->query_ras_poison_mode) {
|
||||
df_poison =
|
||||
adev->df.funcs->query_ras_poison_mode(adev);
|
||||
umc_poison =
|
||||
adev->umc.ras->query_ras_poison_mode(adev);
|
||||
|
||||
/* Only poison is set in both DF and UMC, we can support it */
|
||||
if (df_poison && umc_poison)
|
||||
con->poison_supported = true;
|
||||
else if (df_poison != umc_poison)
|
||||
dev_warn(adev->dev,
|
||||
"Poison setting is inconsistent in DF/UMC(%d:%d)!\n",
|
||||
df_poison, umc_poison);
|
||||
}
|
||||
}
|
||||
|
||||
int amdgpu_ras_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
int r;
|
||||
bool df_poison, umc_poison;
|
||||
|
||||
if (con)
|
||||
return 0;
|
||||
|
@ -2484,26 +2573,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
|
|||
goto release_con;
|
||||
}
|
||||
|
||||
/* Init poison supported flag, the default value is false */
|
||||
if (adev->gmc.xgmi.connected_to_cpu) {
|
||||
/* enabled by default when GPU is connected to CPU */
|
||||
con->poison_supported = true;
|
||||
}
|
||||
else if (adev->df.funcs &&
|
||||
adev->df.funcs->query_ras_poison_mode &&
|
||||
adev->umc.ras &&
|
||||
adev->umc.ras->query_ras_poison_mode) {
|
||||
df_poison =
|
||||
adev->df.funcs->query_ras_poison_mode(adev);
|
||||
umc_poison =
|
||||
adev->umc.ras->query_ras_poison_mode(adev);
|
||||
/* Only poison is set in both DF and UMC, we can support it */
|
||||
if (df_poison && umc_poison)
|
||||
con->poison_supported = true;
|
||||
else if (df_poison != umc_poison)
|
||||
dev_warn(adev->dev, "Poison setting is inconsistent in DF/UMC(%d:%d)!\n",
|
||||
df_poison, umc_poison);
|
||||
}
|
||||
amdgpu_ras_query_poison_mode(adev);
|
||||
|
||||
if (amdgpu_ras_fs_init(adev)) {
|
||||
r = -EINVAL;
|
||||
|
@ -2564,6 +2634,7 @@ int amdgpu_ras_block_late_init(struct amdgpu_device *adev,
|
|||
{
|
||||
struct amdgpu_ras_block_object *ras_obj = NULL;
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
struct ras_query_if *query_info;
|
||||
unsigned long ue_count, ce_count;
|
||||
int r;
|
||||
|
||||
|
@ -2605,11 +2676,17 @@ int amdgpu_ras_block_late_init(struct amdgpu_device *adev,
|
|||
|
||||
/* Those are the cached values at init.
|
||||
*/
|
||||
if (amdgpu_ras_query_error_count(adev, &ce_count, &ue_count) == 0) {
|
||||
query_info = kzalloc(sizeof(struct ras_query_if), GFP_KERNEL);
|
||||
if (!query_info)
|
||||
return -ENOMEM;
|
||||
memcpy(&query_info->head, ras_block, sizeof(struct ras_common_if));
|
||||
|
||||
if (amdgpu_ras_query_error_count(adev, &ce_count, &ue_count, query_info) == 0) {
|
||||
atomic_set(&con->ras_ce_count, ce_count);
|
||||
atomic_set(&con->ras_ue_count, ue_count);
|
||||
}
|
||||
|
||||
kfree(query_info);
|
||||
return 0;
|
||||
|
||||
interrupt:
|
||||
|
|
|
@ -540,7 +540,8 @@ void amdgpu_ras_suspend(struct amdgpu_device *adev);
|
|||
|
||||
int amdgpu_ras_query_error_count(struct amdgpu_device *adev,
|
||||
unsigned long *ce_count,
|
||||
unsigned long *ue_count);
|
||||
unsigned long *ue_count,
|
||||
struct ras_query_if *query_info);
|
||||
|
||||
/* error handling functions */
|
||||
int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
|
||||
|
|
|
@ -93,7 +93,8 @@ int amdgpu_gfx_rlc_init_sr(struct amdgpu_device *adev, u32 dws)
|
|||
|
||||
/* allocate save restore block */
|
||||
r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.rlc.save_restore_obj,
|
||||
&adev->gfx.rlc.save_restore_gpu_addr,
|
||||
(void **)&adev->gfx.rlc.sr_ptr);
|
||||
|
@ -130,7 +131,8 @@ int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev)
|
|||
/* allocate clear state block */
|
||||
adev->gfx.rlc.clear_state_size = dws = adev->gfx.rlc.funcs->get_csb_size(adev);
|
||||
r = amdgpu_bo_create_kernel(adev, dws * 4, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.rlc.clear_state_obj,
|
||||
&adev->gfx.rlc.clear_state_gpu_addr,
|
||||
(void **)&adev->gfx.rlc.cs_ptr);
|
||||
|
@ -156,7 +158,8 @@ int amdgpu_gfx_rlc_init_cpt(struct amdgpu_device *adev)
|
|||
int r;
|
||||
|
||||
r = amdgpu_bo_create_reserved(adev, adev->gfx.rlc.cp_table_size,
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.rlc.cp_table_obj,
|
||||
&adev->gfx.rlc.cp_table_gpu_addr,
|
||||
(void **)&adev->gfx.rlc.cp_table_ptr);
|
||||
|
|
|
@ -77,11 +77,11 @@ void psp_securedisplay_parse_resp_status(struct psp_context *psp,
|
|||
}
|
||||
}
|
||||
|
||||
void psp_prep_securedisplay_cmd_buf(struct psp_context *psp, struct securedisplay_cmd **cmd,
|
||||
void psp_prep_securedisplay_cmd_buf(struct psp_context *psp, struct ta_securedisplay_cmd **cmd,
|
||||
enum ta_securedisplay_command command_id)
|
||||
{
|
||||
*cmd = (struct securedisplay_cmd *)psp->securedisplay_context.context.mem_context.shared_buf;
|
||||
memset(*cmd, 0, sizeof(struct securedisplay_cmd));
|
||||
*cmd = (struct ta_securedisplay_cmd *)psp->securedisplay_context.context.mem_context.shared_buf;
|
||||
memset(*cmd, 0, sizeof(struct ta_securedisplay_cmd));
|
||||
(*cmd)->status = TA_SECUREDISPLAY_STATUS__GENERIC_FAILURE;
|
||||
(*cmd)->cmd_id = command_id;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ static ssize_t amdgpu_securedisplay_debugfs_write(struct file *f, const char __u
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
struct securedisplay_cmd *securedisplay_cmd;
|
||||
struct ta_securedisplay_cmd *securedisplay_cmd;
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
uint32_t phy_id;
|
||||
uint32_t op;
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
void amdgpu_securedisplay_debugfs_init(struct amdgpu_device *adev);
|
||||
void psp_securedisplay_parse_resp_status(struct psp_context *psp,
|
||||
enum ta_securedisplay_status status);
|
||||
void psp_prep_securedisplay_cmd_buf(struct psp_context *psp, struct securedisplay_cmd **cmd,
|
||||
void psp_prep_securedisplay_cmd_buf(struct psp_context *psp, struct ta_securedisplay_cmd **cmd,
|
||||
enum ta_securedisplay_command command_id);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1718,7 +1718,6 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
|||
{
|
||||
uint64_t gtt_size;
|
||||
int r;
|
||||
u64 vis_vram_limit;
|
||||
|
||||
mutex_init(&adev->mman.gtt_window_lock);
|
||||
|
||||
|
@ -1741,12 +1740,6 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
|||
return r;
|
||||
}
|
||||
|
||||
/* Reduce size of CPU-visible VRAM if requested */
|
||||
vis_vram_limit = (u64)amdgpu_vis_vram_limit * 1024 * 1024;
|
||||
if (amdgpu_vis_vram_limit > 0 &&
|
||||
vis_vram_limit <= adev->gmc.visible_vram_size)
|
||||
adev->gmc.visible_vram_size = vis_vram_limit;
|
||||
|
||||
/* Change the size here instead of the init above so only lpfn is affected */
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
#ifdef CONFIG_64BIT
|
||||
|
|
|
@ -169,6 +169,7 @@ int amdgpu_umc_poison_handler(struct amdgpu_device *adev, bool reset)
|
|||
{
|
||||
int ret = AMDGPU_RAS_SUCCESS;
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
if (!adev->gmc.xgmi.connected_to_cpu) {
|
||||
struct ras_err_data err_data = {0, 0, 0, NULL};
|
||||
struct ras_common_if head = {
|
||||
|
@ -189,6 +190,13 @@ int amdgpu_umc_poison_handler(struct amdgpu_device *adev, bool reset)
|
|||
kgd2kfd_set_sram_ecc_flag(adev->kfd.dev);
|
||||
amdgpu_ras_reset_gpu(adev);
|
||||
}
|
||||
} else {
|
||||
if (adev->virt.ops && adev->virt.ops->ras_poison_handler)
|
||||
adev->virt.ops->ras_poison_handler(adev);
|
||||
else
|
||||
dev_warn(adev->dev,
|
||||
"No ras_poison_handler interface in SRIOV!\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -331,8 +331,11 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
|
|||
if (adev->uvd.harvest_config & (1 << j))
|
||||
continue;
|
||||
r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM, &adev->uvd.inst[j].vcpu_bo,
|
||||
&adev->uvd.inst[j].gpu_addr, &adev->uvd.inst[j].cpu_addr);
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->uvd.inst[j].vcpu_bo,
|
||||
&adev->uvd.inst[j].gpu_addr,
|
||||
&adev->uvd.inst[j].cpu_addr);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r);
|
||||
return r;
|
||||
|
|
|
@ -186,7 +186,9 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
|
|||
(binary_id << 8));
|
||||
|
||||
r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM, &adev->vce.vcpu_bo,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->vce.vcpu_bo,
|
||||
&adev->vce.gpu_addr, &adev->vce.cpu_addr);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "(%d) failed to allocate VCE bo\n", r);
|
||||
|
|
|
@ -274,8 +274,11 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
|||
continue;
|
||||
|
||||
r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].vcpu_bo,
|
||||
&adev->vcn.inst[i].gpu_addr, &adev->vcn.inst[i].cpu_addr);
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->vcn.inst[i].vcpu_bo,
|
||||
&adev->vcn.inst[i].gpu_addr,
|
||||
&adev->vcn.inst[i].cpu_addr);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r);
|
||||
return r;
|
||||
|
@ -296,8 +299,11 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
|||
|
||||
if (adev->vcn.indirect_sram) {
|
||||
r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].dpg_sram_bo,
|
||||
&adev->vcn.inst[i].dpg_sram_gpu_addr, &adev->vcn.inst[i].dpg_sram_cpu_addr);
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->vcn.inst[i].dpg_sram_bo,
|
||||
&adev->vcn.inst[i].dpg_sram_gpu_addr,
|
||||
&adev->vcn.inst[i].dpg_sram_cpu_addr);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "VCN %d (%d) failed to allocate DPG bo\n", i, r);
|
||||
return r;
|
||||
|
@ -1250,8 +1256,16 @@ int amdgpu_vcn_process_poison_irq(struct amdgpu_device *adev,
|
|||
if (!ras_if)
|
||||
return 0;
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
ih_data.head = *ras_if;
|
||||
amdgpu_ras_interrupt_dispatch(adev, &ih_data);
|
||||
} else {
|
||||
if (adev->virt.ops && adev->virt.ops->ras_poison_handler)
|
||||
adev->virt.ops->ras_poison_handler(adev);
|
||||
else
|
||||
dev_warn(adev->dev,
|
||||
"No ras_poison_handler interface in SRIOV for VCN!\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -232,7 +232,8 @@ int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
|
||||
r = amdgpu_bo_create_kernel(adev, PAGE_SIZE, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->virt.mm_table.bo,
|
||||
&adev->virt.mm_table.gpu_addr,
|
||||
(void *)&adev->virt.mm_table.cpu_addr);
|
||||
|
|
|
@ -88,6 +88,7 @@ struct amdgpu_virt_ops {
|
|||
int (*wait_reset)(struct amdgpu_device *adev);
|
||||
void (*trans_msg)(struct amdgpu_device *adev, enum idh_request req,
|
||||
u32 data1, u32 data2, u32 data3);
|
||||
void (*ras_poison_handler)(struct amdgpu_device *adev);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -2837,7 +2837,7 @@ static int dce_v10_0_sw_init(void *handle)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
INIT_WORK(&adev->hotplug_work,
|
||||
INIT_DELAYED_WORK(&adev->hotplug_work,
|
||||
amdgpu_display_hotplug_work_func);
|
||||
|
||||
drm_kms_helper_poll_init(adev_to_drm(adev));
|
||||
|
@ -2902,7 +2902,7 @@ static int dce_v10_0_hw_fini(void *handle)
|
|||
|
||||
dce_v10_0_pageflip_interrupt_fini(adev);
|
||||
|
||||
flush_work(&adev->hotplug_work);
|
||||
flush_delayed_work(&adev->hotplug_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3302,7 +3302,7 @@ static int dce_v10_0_hpd_irq(struct amdgpu_device *adev,
|
|||
|
||||
if (disp_int & mask) {
|
||||
dce_v10_0_hpd_int_ack(adev, hpd);
|
||||
schedule_work(&adev->hotplug_work);
|
||||
schedule_delayed_work(&adev->hotplug_work, 0);
|
||||
DRM_DEBUG("IH: HPD%d\n", hpd + 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -2956,7 +2956,7 @@ static int dce_v11_0_sw_init(void *handle)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
INIT_WORK(&adev->hotplug_work,
|
||||
INIT_DELAYED_WORK(&adev->hotplug_work,
|
||||
amdgpu_display_hotplug_work_func);
|
||||
|
||||
drm_kms_helper_poll_init(adev_to_drm(adev));
|
||||
|
@ -3032,7 +3032,7 @@ static int dce_v11_0_hw_fini(void *handle)
|
|||
|
||||
dce_v11_0_pageflip_interrupt_fini(adev);
|
||||
|
||||
flush_work(&adev->hotplug_work);
|
||||
flush_delayed_work(&adev->hotplug_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3426,7 +3426,7 @@ static int dce_v11_0_hpd_irq(struct amdgpu_device *adev,
|
|||
|
||||
if (disp_int & mask) {
|
||||
dce_v11_0_hpd_int_ack(adev, hpd);
|
||||
schedule_work(&adev->hotplug_work);
|
||||
schedule_delayed_work(&adev->hotplug_work, 0);
|
||||
DRM_DEBUG("IH: HPD%d\n", hpd + 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -2715,7 +2715,7 @@ static int dce_v6_0_sw_init(void *handle)
|
|||
return r;
|
||||
|
||||
/* Pre-DCE11 */
|
||||
INIT_WORK(&adev->hotplug_work,
|
||||
INIT_DELAYED_WORK(&adev->hotplug_work,
|
||||
amdgpu_display_hotplug_work_func);
|
||||
|
||||
drm_kms_helper_poll_init(adev_to_drm(adev));
|
||||
|
@ -2776,7 +2776,7 @@ static int dce_v6_0_hw_fini(void *handle)
|
|||
|
||||
dce_v6_0_pageflip_interrupt_fini(adev);
|
||||
|
||||
flush_work(&adev->hotplug_work);
|
||||
flush_delayed_work(&adev->hotplug_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3103,7 +3103,7 @@ static int dce_v6_0_hpd_irq(struct amdgpu_device *adev,
|
|||
tmp = RREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd]);
|
||||
tmp |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK;
|
||||
WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp);
|
||||
schedule_work(&adev->hotplug_work);
|
||||
schedule_delayed_work(&adev->hotplug_work, 0);
|
||||
DRM_DEBUG("IH: HPD%d\n", hpd + 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -2739,7 +2739,7 @@ static int dce_v8_0_sw_init(void *handle)
|
|||
return r;
|
||||
|
||||
/* Pre-DCE11 */
|
||||
INIT_WORK(&adev->hotplug_work,
|
||||
INIT_DELAYED_WORK(&adev->hotplug_work,
|
||||
amdgpu_display_hotplug_work_func);
|
||||
|
||||
drm_kms_helper_poll_init(adev_to_drm(adev));
|
||||
|
@ -2802,7 +2802,7 @@ static int dce_v8_0_hw_fini(void *handle)
|
|||
|
||||
dce_v8_0_pageflip_interrupt_fini(adev);
|
||||
|
||||
flush_work(&adev->hotplug_work);
|
||||
flush_delayed_work(&adev->hotplug_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3195,7 +3195,7 @@ static int dce_v8_0_hpd_irq(struct amdgpu_device *adev,
|
|||
tmp = RREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd]);
|
||||
tmp |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK;
|
||||
WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp);
|
||||
schedule_work(&adev->hotplug_work);
|
||||
schedule_delayed_work(&adev->hotplug_work, 0);
|
||||
DRM_DEBUG("IH: HPD%d\n", hpd + 1);
|
||||
}
|
||||
|
||||
|
|
61
drivers/gpu/drm/amd/amdgpu/df_v4_3.c
Normal file
61
drivers/gpu/drm/amd/amdgpu/df_v4_3.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 2022 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.
|
||||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "df_v4_3.h"
|
||||
|
||||
#include "df/df_4_3_offset.h"
|
||||
#include "df/df_4_3_sh_mask.h"
|
||||
|
||||
static bool df_v4_3_query_ras_poison_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t hw_assert_msklo, hw_assert_mskhi;
|
||||
uint32_t v0, v1, v28, v31;
|
||||
|
||||
hw_assert_msklo = RREG32_SOC15(DF, 0,
|
||||
regDF_CS_UMC_AON0_HardwareAssertMaskLow);
|
||||
hw_assert_mskhi = RREG32_SOC15(DF, 0,
|
||||
regDF_NCS_PG0_HardwareAssertMaskHigh);
|
||||
|
||||
v0 = REG_GET_FIELD(hw_assert_msklo,
|
||||
DF_CS_UMC_AON0_HardwareAssertMaskLow, HWAssertMsk0);
|
||||
v1 = REG_GET_FIELD(hw_assert_msklo,
|
||||
DF_CS_UMC_AON0_HardwareAssertMaskLow, HWAssertMsk1);
|
||||
v28 = REG_GET_FIELD(hw_assert_mskhi,
|
||||
DF_NCS_PG0_HardwareAssertMaskHigh, HWAssertMsk28);
|
||||
v31 = REG_GET_FIELD(hw_assert_mskhi,
|
||||
DF_NCS_PG0_HardwareAssertMaskHigh, HWAssertMsk31);
|
||||
|
||||
if (v0 && v1 && v28 && v31)
|
||||
return true;
|
||||
else if (!v0 && !v1 && !v28 && !v31)
|
||||
return false;
|
||||
else {
|
||||
dev_warn(adev->dev, "DF poison setting is inconsistent(%d:%d:%d:%d)!\n",
|
||||
v0, v1, v28, v31);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const struct amdgpu_df_funcs df_v4_3_funcs = {
|
||||
.query_ras_poison_mode = df_v4_3_query_ras_poison_mode,
|
||||
};
|
31
drivers/gpu/drm/amd/amdgpu/df_v4_3.h
Normal file
31
drivers/gpu/drm/amd/amdgpu/df_v4_3.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2022 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 __DF_V4_3_H__
|
||||
#define __DF_V4_3_H__
|
||||
|
||||
#include "soc15_common.h"
|
||||
|
||||
extern const struct amdgpu_df_funcs df_v4_3_funcs;
|
||||
|
||||
#endif
|
|
@ -987,7 +987,8 @@ static int gfx_v11_0_rlc_autoload_buffer_init(struct amdgpu_device *adev)
|
|||
total_size = gfx_v11_0_calc_toc_total_size(adev);
|
||||
|
||||
r = amdgpu_bo_create_reserved(adev, total_size, 64 * 1024,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.rlc.rlc_autoload_bo,
|
||||
&adev->gfx.rlc.rlc_autoload_gpu_addr,
|
||||
(void **)&adev->gfx.rlc.rlc_autoload_ptr);
|
||||
|
@ -2649,7 +2650,9 @@ static int gfx_v11_0_cp_gfx_load_pfp_microcode_rs64(struct amdgpu_device *adev)
|
|||
|
||||
/* 64kb align */
|
||||
r = amdgpu_bo_create_reserved(adev, fw_ucode_size,
|
||||
64 * 1024, AMDGPU_GEM_DOMAIN_VRAM,
|
||||
64 * 1024,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.pfp.pfp_fw_obj,
|
||||
&adev->gfx.pfp.pfp_fw_gpu_addr,
|
||||
(void **)&adev->gfx.pfp.pfp_fw_ptr);
|
||||
|
@ -2660,7 +2663,9 @@ static int gfx_v11_0_cp_gfx_load_pfp_microcode_rs64(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
r = amdgpu_bo_create_reserved(adev, fw_data_size,
|
||||
64 * 1024, AMDGPU_GEM_DOMAIN_VRAM,
|
||||
64 * 1024,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.pfp.pfp_fw_data_obj,
|
||||
&adev->gfx.pfp.pfp_fw_data_gpu_addr,
|
||||
(void **)&adev->gfx.pfp.pfp_fw_data_ptr);
|
||||
|
@ -2863,7 +2868,9 @@ static int gfx_v11_0_cp_gfx_load_me_microcode_rs64(struct amdgpu_device *adev)
|
|||
|
||||
/* 64kb align*/
|
||||
r = amdgpu_bo_create_reserved(adev, fw_ucode_size,
|
||||
64 * 1024, AMDGPU_GEM_DOMAIN_VRAM,
|
||||
64 * 1024,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.me.me_fw_obj,
|
||||
&adev->gfx.me.me_fw_gpu_addr,
|
||||
(void **)&adev->gfx.me.me_fw_ptr);
|
||||
|
@ -2874,7 +2881,9 @@ static int gfx_v11_0_cp_gfx_load_me_microcode_rs64(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
r = amdgpu_bo_create_reserved(adev, fw_data_size,
|
||||
64 * 1024, AMDGPU_GEM_DOMAIN_VRAM,
|
||||
64 * 1024,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.me.me_fw_data_obj,
|
||||
&adev->gfx.me.me_fw_data_gpu_addr,
|
||||
(void **)&adev->gfx.me.me_fw_data_ptr);
|
||||
|
@ -3380,7 +3389,9 @@ static int gfx_v11_0_cp_compute_load_microcode_rs64(struct amdgpu_device *adev)
|
|||
fw_data_size = le32_to_cpu(mec_hdr->data_size_bytes);
|
||||
|
||||
r = amdgpu_bo_create_reserved(adev, fw_ucode_size,
|
||||
64 * 1024, AMDGPU_GEM_DOMAIN_VRAM,
|
||||
64 * 1024,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.mec.mec_fw_obj,
|
||||
&adev->gfx.mec.mec_fw_gpu_addr,
|
||||
(void **)&fw_ucode_ptr);
|
||||
|
@ -3391,7 +3402,9 @@ static int gfx_v11_0_cp_compute_load_microcode_rs64(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
r = amdgpu_bo_create_reserved(adev, fw_data_size,
|
||||
64 * 1024, AMDGPU_GEM_DOMAIN_VRAM,
|
||||
64 * 1024,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.mec.mec_fw_data_obj,
|
||||
&adev->gfx.mec.mec_fw_data_gpu_addr,
|
||||
(void **)&fw_data_ptr);
|
||||
|
|
|
@ -2375,7 +2375,8 @@ static int gfx_v6_0_rlc_init(struct amdgpu_device *adev)
|
|||
dws = adev->gfx.rlc.clear_state_size + (256 / 4);
|
||||
|
||||
r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.rlc.clear_state_obj,
|
||||
&adev->gfx.rlc.clear_state_gpu_addr,
|
||||
(void **)&adev->gfx.rlc.cs_ptr);
|
||||
|
|
|
@ -2772,7 +2772,8 @@ static int gfx_v7_0_mec_init(struct amdgpu_device *adev)
|
|||
* GFX7_MEC_HPD_SIZE * 2;
|
||||
|
||||
r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.mec.hpd_eop_obj,
|
||||
&adev->gfx.mec.hpd_eop_gpu_addr,
|
||||
(void **)&hpd);
|
||||
|
|
|
@ -1340,7 +1340,8 @@ static int gfx_v8_0_mec_init(struct amdgpu_device *adev)
|
|||
mec_hpd_size = adev->gfx.num_compute_rings * GFX8_MEC_HPD_SIZE;
|
||||
if (mec_hpd_size) {
|
||||
r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.mec.hpd_eop_obj,
|
||||
&adev->gfx.mec.hpd_eop_gpu_addr,
|
||||
(void **)&hpd);
|
||||
|
|
|
@ -1783,7 +1783,8 @@ static int gfx_v9_0_mec_init(struct amdgpu_device *adev)
|
|||
mec_hpd_size = adev->gfx.num_compute_rings * GFX9_MEC_HPD_SIZE;
|
||||
if (mec_hpd_size) {
|
||||
r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->gfx.mec.hpd_eop_obj,
|
||||
&adev->gfx.mec.hpd_eop_gpu_addr,
|
||||
(void **)&hpd);
|
||||
|
|
|
@ -120,7 +120,7 @@ static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr);
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr);
|
||||
WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
|
||||
|
|
|
@ -165,7 +165,7 @@ static void gfxhub_v2_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr);
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr);
|
||||
WREG32_SOC15(GC, 0, mmGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
WREG32_SOC15(GC, 0, mmGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
|
||||
|
|
|
@ -167,7 +167,7 @@ static void gfxhub_v2_1_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr);
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr);
|
||||
WREG32_SOC15(GC, 0, mmGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
WREG32_SOC15(GC, 0, mmGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
|
||||
|
|
|
@ -163,7 +163,7 @@ static void gfxhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
adev->gmc.vram_end >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start
|
||||
value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start
|
||||
+ adev->vm_manager.vram_base_offset;
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
|
|
|
@ -169,7 +169,7 @@ static void gfxhub_v3_0_3_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
adev->gmc.vram_end >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start
|
||||
value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start
|
||||
+ adev->vm_manager.vram_base_offset;
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
|
|
|
@ -78,12 +78,24 @@ gmc_v10_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
|
|||
/* MM HUB */
|
||||
amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_MMHUB_0, false);
|
||||
/* GFX HUB */
|
||||
/* This works because this interrupt is only
|
||||
* enabled at init/resume and disabled in
|
||||
* fini/suspend, so the overall state doesn't
|
||||
* change over the course of suspend/resume.
|
||||
*/
|
||||
if (!adev->in_s0ix)
|
||||
amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_GFXHUB_0, false);
|
||||
break;
|
||||
case AMDGPU_IRQ_STATE_ENABLE:
|
||||
/* MM HUB */
|
||||
amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_MMHUB_0, true);
|
||||
/* GFX HUB */
|
||||
/* This works because this interrupt is only
|
||||
* enabled at init/resume and disabled in
|
||||
* fini/suspend, so the overall state doesn't
|
||||
* change over the course of suspend/resume.
|
||||
*/
|
||||
if (!adev->in_s0ix)
|
||||
amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_GFXHUB_0, true);
|
||||
break;
|
||||
default:
|
||||
|
@ -835,10 +847,7 @@ static int gmc_v10_0_mc_init(struct amdgpu_device *adev)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* In case the PCI BAR is larger than the actual amount of vram */
|
||||
adev->gmc.visible_vram_size = adev->gmc.aper_size;
|
||||
if (adev->gmc.visible_vram_size > adev->gmc.real_vram_size)
|
||||
adev->gmc.visible_vram_size = adev->gmc.real_vram_size;
|
||||
|
||||
/* set the gart size */
|
||||
if (amdgpu_gart_size == -1) {
|
||||
|
@ -1061,9 +1070,12 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
|
||||
|
||||
if (!adev->in_s0ix) {
|
||||
r = adev->gfxhub.funcs->gart_enable(adev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = adev->mmhub.funcs->gart_enable(adev);
|
||||
if (r)
|
||||
|
@ -1077,9 +1089,11 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev)
|
|||
value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ?
|
||||
false : true;
|
||||
|
||||
if (!adev->in_s0ix)
|
||||
adev->gfxhub.funcs->set_fault_enable_default(adev, value);
|
||||
adev->mmhub.funcs->set_fault_enable_default(adev, value);
|
||||
gmc_v10_0_flush_gpu_tlb(adev, 0, AMDGPU_MMHUB_0, 0);
|
||||
if (!adev->in_s0ix)
|
||||
gmc_v10_0_flush_gpu_tlb(adev, 0, AMDGPU_GFXHUB_0, 0);
|
||||
|
||||
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
|
||||
|
@ -1101,7 +1115,7 @@ static int gmc_v10_0_hw_init(void *handle)
|
|||
* harvestable groups in gc_utcl2 need to be programmed before any GFX block
|
||||
* register setup within GMC, or else system hang when harvesting SA.
|
||||
*/
|
||||
if (adev->gfxhub.funcs && adev->gfxhub.funcs->utcl2_harvest)
|
||||
if (!adev->in_s0ix && adev->gfxhub.funcs && adev->gfxhub.funcs->utcl2_harvest)
|
||||
adev->gfxhub.funcs->utcl2_harvest(adev);
|
||||
|
||||
r = gmc_v10_0_gart_enable(adev);
|
||||
|
@ -1129,6 +1143,7 @@ static int gmc_v10_0_hw_init(void *handle)
|
|||
*/
|
||||
static void gmc_v10_0_gart_disable(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!adev->in_s0ix)
|
||||
adev->gfxhub.funcs->gart_disable(adev);
|
||||
adev->mmhub.funcs->gart_disable(adev);
|
||||
}
|
||||
|
|
|
@ -64,12 +64,24 @@ gmc_v11_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
|
|||
/* MM HUB */
|
||||
amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_MMHUB_0, false);
|
||||
/* GFX HUB */
|
||||
/* This works because this interrupt is only
|
||||
* enabled at init/resume and disabled in
|
||||
* fini/suspend, so the overall state doesn't
|
||||
* change over the course of suspend/resume.
|
||||
*/
|
||||
if (!adev->in_s0ix)
|
||||
amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_GFXHUB_0, false);
|
||||
break;
|
||||
case AMDGPU_IRQ_STATE_ENABLE:
|
||||
/* MM HUB */
|
||||
amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_MMHUB_0, true);
|
||||
/* GFX HUB */
|
||||
/* This works because this interrupt is only
|
||||
* enabled at init/resume and disabled in
|
||||
* fini/suspend, so the overall state doesn't
|
||||
* change over the course of suspend/resume.
|
||||
*/
|
||||
if (!adev->in_s0ix)
|
||||
amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_GFXHUB_0, true);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -258,7 +258,7 @@ static void gmc_v6_0_mc_program(struct amdgpu_device *adev)
|
|||
WREG32(mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
adev->gmc.vram_end >> 12);
|
||||
WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
|
||||
adev->vram_scratch.gpu_addr >> 12);
|
||||
adev->mem_scratch.gpu_addr >> 12);
|
||||
WREG32(mmMC_VM_AGP_BASE, 0);
|
||||
WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF);
|
||||
WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF);
|
||||
|
|
|
@ -292,7 +292,7 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev)
|
|||
WREG32(mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
adev->gmc.vram_end >> 12);
|
||||
WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
|
||||
adev->vram_scratch.gpu_addr >> 12);
|
||||
adev->mem_scratch.gpu_addr >> 12);
|
||||
WREG32(mmMC_VM_AGP_BASE, 0);
|
||||
WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF);
|
||||
WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF);
|
||||
|
@ -389,10 +389,7 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* In case the PCI BAR is larger than the actual amount of vram */
|
||||
adev->gmc.visible_vram_size = adev->gmc.aper_size;
|
||||
if (adev->gmc.visible_vram_size > adev->gmc.real_vram_size)
|
||||
adev->gmc.visible_vram_size = adev->gmc.real_vram_size;
|
||||
|
||||
/* set the gart size */
|
||||
if (amdgpu_gart_size == -1) {
|
||||
|
|
|
@ -474,7 +474,7 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev)
|
|||
WREG32(mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
adev->gmc.vram_end >> 12);
|
||||
WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
|
||||
adev->vram_scratch.gpu_addr >> 12);
|
||||
adev->mem_scratch.gpu_addr >> 12);
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
tmp = ((adev->gmc.vram_end >> 24) & 0xFFFF) << 16;
|
||||
|
@ -587,10 +587,7 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* In case the PCI BAR is larger than the actual amount of vram */
|
||||
adev->gmc.visible_vram_size = adev->gmc.aper_size;
|
||||
if (adev->gmc.visible_vram_size > adev->gmc.real_vram_size)
|
||||
adev->gmc.visible_vram_size = adev->gmc.real_vram_size;
|
||||
|
||||
/* set the gart size */
|
||||
if (amdgpu_gart_size == -1) {
|
||||
|
|
|
@ -484,6 +484,14 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
|
|||
for (i = 0; i < 16; i++) {
|
||||
reg = hub->vm_context0_cntl + i;
|
||||
|
||||
/* This works because this interrupt is only
|
||||
* enabled at init/resume and disabled in
|
||||
* fini/suspend, so the overall state doesn't
|
||||
* change over the course of suspend/resume.
|
||||
*/
|
||||
if (adev->in_s0ix && (j == AMDGPU_GFXHUB_0))
|
||||
continue;
|
||||
|
||||
if (j == AMDGPU_GFXHUB_0)
|
||||
tmp = RREG32_SOC15_IP(GC, reg);
|
||||
else
|
||||
|
@ -504,6 +512,14 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
|
|||
for (i = 0; i < 16; i++) {
|
||||
reg = hub->vm_context0_cntl + i;
|
||||
|
||||
/* This works because this interrupt is only
|
||||
* enabled at init/resume and disabled in
|
||||
* fini/suspend, so the overall state doesn't
|
||||
* change over the course of suspend/resume.
|
||||
*/
|
||||
if (adev->in_s0ix && (j == AMDGPU_GFXHUB_0))
|
||||
continue;
|
||||
|
||||
if (j == AMDGPU_GFXHUB_0)
|
||||
tmp = RREG32_SOC15_IP(GC, reg);
|
||||
else
|
||||
|
@ -1536,10 +1552,7 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
#endif
|
||||
/* In case the PCI BAR is larger than the actual amount of vram */
|
||||
adev->gmc.visible_vram_size = adev->gmc.aper_size;
|
||||
if (adev->gmc.visible_vram_size > adev->gmc.real_vram_size)
|
||||
adev->gmc.visible_vram_size = adev->gmc.real_vram_size;
|
||||
|
||||
/* set the gart size */
|
||||
if (amdgpu_gart_size == -1) {
|
||||
|
@ -1862,9 +1875,12 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
|
||||
|
||||
if (!adev->in_s0ix) {
|
||||
r = adev->gfxhub.funcs->gart_enable(adev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = adev->mmhub.funcs->gart_enable(adev);
|
||||
if (r)
|
||||
|
@ -1911,11 +1927,15 @@ static int gmc_v9_0_hw_init(void *handle)
|
|||
value = true;
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
if (!adev->in_s0ix)
|
||||
adev->gfxhub.funcs->set_fault_enable_default(adev, value);
|
||||
adev->mmhub.funcs->set_fault_enable_default(adev, value);
|
||||
}
|
||||
for (i = 0; i < adev->num_vmhubs; ++i)
|
||||
for (i = 0; i < adev->num_vmhubs; ++i) {
|
||||
if (adev->in_s0ix && (i == AMDGPU_GFXHUB_0))
|
||||
continue;
|
||||
gmc_v9_0_flush_gpu_tlb(adev, 0, i, 0);
|
||||
}
|
||||
|
||||
if (adev->umc.funcs && adev->umc.funcs->init_registers)
|
||||
adev->umc.funcs->init_registers(adev);
|
||||
|
@ -1939,6 +1959,7 @@ static int gmc_v9_0_hw_init(void *handle)
|
|||
*/
|
||||
static void gmc_v9_0_gart_disable(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!adev->in_s0ix)
|
||||
adev->gfxhub.funcs->gart_disable(adev);
|
||||
adev->mmhub.funcs->gart_disable(adev);
|
||||
}
|
||||
|
|
|
@ -549,7 +549,9 @@ static int mes_v11_0_allocate_ucode_buffer(struct amdgpu_device *adev,
|
|||
fw_size = le32_to_cpu(mes_hdr->mes_ucode_size_bytes);
|
||||
|
||||
r = amdgpu_bo_create_reserved(adev, fw_size,
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
|
||||
PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->mes.ucode_fw_obj[pipe],
|
||||
&adev->mes.ucode_fw_gpu_addr[pipe],
|
||||
(void **)&adev->mes.ucode_fw_ptr[pipe]);
|
||||
|
@ -582,7 +584,9 @@ static int mes_v11_0_allocate_ucode_data_buffer(struct amdgpu_device *adev,
|
|||
fw_size = le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes);
|
||||
|
||||
r = amdgpu_bo_create_reserved(adev, fw_size,
|
||||
64 * 1024, AMDGPU_GEM_DOMAIN_VRAM,
|
||||
64 * 1024,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->mes.data_fw_obj[pipe],
|
||||
&adev->mes.data_fw_gpu_addr[pipe],
|
||||
(void **)&adev->mes.data_fw_ptr[pipe]);
|
||||
|
|
|
@ -114,7 +114,7 @@ static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
return;
|
||||
|
||||
/* Set default page address. */
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr);
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr);
|
||||
WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
|
||||
|
|
|
@ -134,7 +134,7 @@ static void mmhub_v1_7_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
/* Set default page address. */
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr);
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr);
|
||||
WREG32_SOC15(MMHUB, 0, regMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
WREG32_SOC15(MMHUB, 0, regMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
|
||||
|
|
|
@ -234,7 +234,7 @@ static void mmhub_v2_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
/* Set default page address. */
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr);
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
|
||||
|
|
|
@ -164,7 +164,7 @@ static void mmhub_v2_3_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr);
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
|
||||
|
|
|
@ -188,7 +188,7 @@ static void mmhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
/* Set default page address. */
|
||||
value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start +
|
||||
value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start +
|
||||
adev->vm_manager.vram_base_offset;
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
|
|
|
@ -188,7 +188,7 @@ static void mmhub_v3_0_1_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
adev->gmc.vram_end >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start +
|
||||
value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start +
|
||||
adev->vm_manager.vram_base_offset;
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
|
|
|
@ -181,7 +181,7 @@ static void mmhub_v3_0_2_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
/* Set default page address. */
|
||||
value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start +
|
||||
value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start +
|
||||
adev->vm_manager.vram_base_offset;
|
||||
WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
|
|
|
@ -136,7 +136,7 @@ static void mmhub_v9_4_init_system_aperture_regs(struct amdgpu_device *adev,
|
|||
max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->vram_scratch.gpu_addr);
|
||||
value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr);
|
||||
WREG32_SOC15_OFFSET(
|
||||
MMHUB, 0,
|
||||
mmVMSHAREDPF0_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
|
|
|
@ -404,6 +404,11 @@ static int xgpu_ai_request_init_data(struct amdgpu_device *adev)
|
|||
return xgpu_ai_send_access_requests(adev, IDH_REQ_GPU_INIT_DATA);
|
||||
}
|
||||
|
||||
static void xgpu_ai_ras_poison_handler(struct amdgpu_device *adev)
|
||||
{
|
||||
xgpu_ai_send_access_requests(adev, IDH_RAS_POISON);
|
||||
}
|
||||
|
||||
const struct amdgpu_virt_ops xgpu_ai_virt_ops = {
|
||||
.req_full_gpu = xgpu_ai_request_full_gpu_access,
|
||||
.rel_full_gpu = xgpu_ai_release_full_gpu_access,
|
||||
|
@ -411,4 +416,5 @@ const struct amdgpu_virt_ops xgpu_ai_virt_ops = {
|
|||
.wait_reset = NULL,
|
||||
.trans_msg = xgpu_ai_mailbox_trans_msg,
|
||||
.req_init_data = xgpu_ai_request_init_data,
|
||||
.ras_poison_handler = xgpu_ai_ras_poison_handler,
|
||||
};
|
||||
|
|
|
@ -39,6 +39,7 @@ enum idh_request {
|
|||
|
||||
IDH_LOG_VF_ERROR = 200,
|
||||
IDH_READY_TO_RESET = 201,
|
||||
IDH_RAS_POISON = 202,
|
||||
};
|
||||
|
||||
enum idh_event {
|
||||
|
|
|
@ -426,6 +426,11 @@ void xgpu_nv_mailbox_put_irq(struct amdgpu_device *adev)
|
|||
amdgpu_irq_put(adev, &adev->virt.rcv_irq, 0);
|
||||
}
|
||||
|
||||
static void xgpu_nv_ras_poison_handler(struct amdgpu_device *adev)
|
||||
{
|
||||
xgpu_nv_send_access_requests(adev, IDH_RAS_POISON);
|
||||
}
|
||||
|
||||
const struct amdgpu_virt_ops xgpu_nv_virt_ops = {
|
||||
.req_full_gpu = xgpu_nv_request_full_gpu_access,
|
||||
.rel_full_gpu = xgpu_nv_release_full_gpu_access,
|
||||
|
@ -433,4 +438,5 @@ const struct amdgpu_virt_ops xgpu_nv_virt_ops = {
|
|||
.reset_gpu = xgpu_nv_request_reset,
|
||||
.wait_reset = NULL,
|
||||
.trans_msg = xgpu_nv_mailbox_trans_msg,
|
||||
.ras_poison_handler = xgpu_nv_ras_poison_handler,
|
||||
};
|
||||
|
|
|
@ -39,6 +39,7 @@ enum idh_request {
|
|||
|
||||
IDH_LOG_VF_ERROR = 200,
|
||||
IDH_READY_TO_RESET = 201,
|
||||
IDH_RAS_POISON = 202,
|
||||
};
|
||||
|
||||
enum idh_event {
|
||||
|
|
|
@ -809,12 +809,6 @@ static int sdma_v5_2_start(struct amdgpu_device *adev)
|
|||
msleep(1000);
|
||||
}
|
||||
|
||||
/* TODO: check whether can submit a doorbell request to raise
|
||||
* a doorbell fence to exit gfxoff.
|
||||
*/
|
||||
if (adev->in_s0ix)
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
|
||||
sdma_v5_2_soft_reset(adev);
|
||||
/* unhalt the MEs */
|
||||
sdma_v5_2_enable(adev, true);
|
||||
|
@ -823,8 +817,6 @@ static int sdma_v5_2_start(struct amdgpu_device *adev)
|
|||
|
||||
/* start the gfx rings and rlc compute queues */
|
||||
r = sdma_v5_2_gfx_resume(adev);
|
||||
if (adev->in_s0ix)
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
if (r)
|
||||
return r;
|
||||
r = sdma_v5_2_rlc_resume(adev);
|
||||
|
|
|
@ -55,10 +55,10 @@ enum ta_securedisplay_status {
|
|||
TA_SECUREDISPLAY_STATUS__MAX = 0x7FFFFFFF,/* Maximum Value for status*/
|
||||
};
|
||||
|
||||
/** @enum ta_securedisplay_max_phy
|
||||
/** @enum ta_securedisplay_phy_ID
|
||||
* Physical ID number to use for reading corresponding DIO Scratch register for ROI
|
||||
*/
|
||||
enum ta_securedisplay_max_phy {
|
||||
enum ta_securedisplay_phy_ID {
|
||||
TA_SECUREDISPLAY_PHY0 = 0,
|
||||
TA_SECUREDISPLAY_PHY1 = 1,
|
||||
TA_SECUREDISPLAY_PHY2 = 2,
|
||||
|
@ -139,15 +139,15 @@ union ta_securedisplay_cmd_output {
|
|||
uint32_t reserved[4];
|
||||
};
|
||||
|
||||
/** @struct securedisplay_cmd
|
||||
* Secure Display Command which is shared buffer memory
|
||||
*/
|
||||
struct securedisplay_cmd {
|
||||
uint32_t cmd_id; /* +0 Bytes Command ID */
|
||||
enum ta_securedisplay_status status; /* +4 Bytes Status of Secure Display TA */
|
||||
uint32_t reserved[2]; /* +8 Bytes Reserved */
|
||||
union ta_securedisplay_cmd_input securedisplay_in_message; /* +16 Bytes Input Buffer */
|
||||
union ta_securedisplay_cmd_output securedisplay_out_message;/* +32 Bytes Output Buffer */
|
||||
/** @struct ta_securedisplay_cmd
|
||||
* Secure display command which is shared buffer memory
|
||||
*/
|
||||
struct ta_securedisplay_cmd {
|
||||
uint32_t cmd_id; /**< +0 Bytes Command ID */
|
||||
enum ta_securedisplay_status status; /**< +4 Bytes Status code returned by the secure display TA */
|
||||
uint32_t reserved[2]; /**< +8 Bytes Reserved */
|
||||
union ta_securedisplay_cmd_input securedisplay_in_message; /**< +16 Bytes Command input buffer */
|
||||
union ta_securedisplay_cmd_output securedisplay_out_message; /**< +32 Bytes Command output buffer */
|
||||
/**@note Total 48 Bytes */
|
||||
};
|
||||
|
||||
|
|
|
@ -340,29 +340,13 @@ static void umc_v8_10_err_cnt_init(struct amdgpu_device *adev)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t umc_v8_10_query_ras_poison_mode_per_channel(
|
||||
struct amdgpu_device *adev,
|
||||
uint32_t umc_reg_offset)
|
||||
{
|
||||
uint32_t ecc_ctrl_addr, ecc_ctrl;
|
||||
|
||||
ecc_ctrl_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0, regUMCCH0_0_GeccCtrl);
|
||||
ecc_ctrl = RREG32_PCIE((ecc_ctrl_addr +
|
||||
umc_reg_offset) * 4);
|
||||
|
||||
return REG_GET_FIELD(ecc_ctrl, UMCCH0_0_GeccCtrl, UCFatalEn);
|
||||
}
|
||||
|
||||
static bool umc_v8_10_query_ras_poison_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t umc_reg_offset = 0;
|
||||
|
||||
/* Enabling fatal error in umc node0 instance0 channel0 will be
|
||||
* considered as fatal error mode
|
||||
/*
|
||||
* Force return true, because UMCCH0_0_GeccCtrl
|
||||
* is not accessible from host side
|
||||
*/
|
||||
umc_reg_offset = get_umc_v8_10_reg_offset(adev, 0, 0, 0);
|
||||
return !umc_v8_10_query_ras_poison_mode_per_channel(adev, umc_reg_offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct amdgpu_ras_block_hw_ops umc_v8_10_ras_hw_ops = {
|
||||
|
|
|
@ -262,23 +262,12 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
|
|||
f2g = &gfx_v8_kfd2kgd;
|
||||
break;
|
||||
case CHIP_FIJI:
|
||||
gfx_target_version = 80003;
|
||||
f2g = &gfx_v8_kfd2kgd;
|
||||
break;
|
||||
case CHIP_POLARIS10:
|
||||
gfx_target_version = 80003;
|
||||
f2g = &gfx_v8_kfd2kgd;
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
gfx_target_version = 80003;
|
||||
if (!vf)
|
||||
f2g = &gfx_v8_kfd2kgd;
|
||||
break;
|
||||
case CHIP_POLARIS12:
|
||||
gfx_target_version = 80003;
|
||||
if (!vf)
|
||||
f2g = &gfx_v8_kfd2kgd;
|
||||
break;
|
||||
case CHIP_VEGAM:
|
||||
gfx_target_version = 80003;
|
||||
if (!vf)
|
||||
|
|
|
@ -801,7 +801,7 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev,
|
|||
|
||||
p2plink->attr.name = "properties";
|
||||
p2plink->attr.mode = KFD_SYSFS_FILE_MODE;
|
||||
sysfs_attr_init(&iolink->attr);
|
||||
sysfs_attr_init(&p2plink->attr);
|
||||
ret = sysfs_create_file(p2plink->kobj, &p2plink->attr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
|
@ -210,7 +210,7 @@ static void amdgpu_dm_destroy_drm_device(struct amdgpu_display_manager *dm);
|
|||
|
||||
static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
|
||||
struct amdgpu_dm_connector *amdgpu_dm_connector,
|
||||
uint32_t link_index,
|
||||
u32 link_index,
|
||||
struct amdgpu_encoder *amdgpu_encoder);
|
||||
static int amdgpu_dm_encoder_init(struct drm_device *dev,
|
||||
struct amdgpu_encoder *aencoder,
|
||||
|
@ -262,7 +262,7 @@ static u32 dm_vblank_get_counter(struct amdgpu_device *adev, int crtc)
|
|||
static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,
|
||||
u32 *vbl, u32 *position)
|
||||
{
|
||||
uint32_t v_blank_start, v_blank_end, h_position, v_position;
|
||||
u32 v_blank_start, v_blank_end, h_position, v_position;
|
||||
|
||||
if ((crtc < 0) || (crtc >= adev->mode_info.num_crtc))
|
||||
return -EINVAL;
|
||||
|
@ -361,7 +361,7 @@ static void dm_pflip_high_irq(void *interrupt_params)
|
|||
struct amdgpu_device *adev = irq_params->adev;
|
||||
unsigned long flags;
|
||||
struct drm_pending_vblank_event *e;
|
||||
uint32_t vpos, hpos, v_blank_start, v_blank_end;
|
||||
u32 vpos, hpos, v_blank_start, v_blank_end;
|
||||
bool vrr_active;
|
||||
|
||||
amdgpu_crtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_PFLIP);
|
||||
|
@ -648,7 +648,7 @@ static void dmub_hpd_callback(struct amdgpu_device *adev,
|
|||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
struct dc_link *link;
|
||||
uint8_t link_index = 0;
|
||||
u8 link_index = 0;
|
||||
struct drm_device *dev;
|
||||
|
||||
if (adev == NULL)
|
||||
|
@ -749,7 +749,7 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params)
|
|||
struct amdgpu_device *adev = irq_params->adev;
|
||||
struct amdgpu_display_manager *dm = &adev->dm;
|
||||
struct dmcub_trace_buf_entry entry = { 0 };
|
||||
uint32_t count = 0;
|
||||
u32 count = 0;
|
||||
struct dmub_hpd_work *dmub_hpd_wrk;
|
||||
struct dc_link *plink = NULL;
|
||||
|
||||
|
@ -1015,7 +1015,7 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
|
|||
struct dmub_srv_hw_params hw_params;
|
||||
enum dmub_status status;
|
||||
const unsigned char *fw_inst_const, *fw_bss_data;
|
||||
uint32_t i, fw_inst_const_size, fw_bss_data_size;
|
||||
u32 i, fw_inst_const_size, fw_bss_data_size;
|
||||
bool has_hw_support;
|
||||
|
||||
if (!dmub_srv)
|
||||
|
@ -1176,10 +1176,10 @@ static void dm_dmub_hw_resume(struct amdgpu_device *adev)
|
|||
|
||||
static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_addr_space_config *pa_config)
|
||||
{
|
||||
uint64_t pt_base;
|
||||
uint32_t logical_addr_low;
|
||||
uint32_t logical_addr_high;
|
||||
uint32_t agp_base, agp_bot, agp_top;
|
||||
u64 pt_base;
|
||||
u32 logical_addr_low;
|
||||
u32 logical_addr_high;
|
||||
u32 agp_base, agp_bot, agp_top;
|
||||
PHYSICAL_ADDRESS_LOC page_table_start, page_table_end, page_table_base;
|
||||
|
||||
memset(pa_config, 0, sizeof(*pa_config));
|
||||
|
@ -1642,7 +1642,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
|||
}
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
adev->dm.crc_rd_wrk = amdgpu_dm_crtc_secure_display_create_work();
|
||||
adev->dm.secure_display_ctxs = amdgpu_dm_crtc_secure_display_create_contexts(adev);
|
||||
if (!adev->dm.secure_display_ctxs) {
|
||||
DRM_ERROR("amdgpu: failed to initialize secure_display_ctxs.\n");
|
||||
}
|
||||
#endif
|
||||
if (dc_is_dmub_outbox_supported(adev->dm.dc)) {
|
||||
init_completion(&adev->dm.dmub_aux_transfer_done);
|
||||
|
@ -1737,10 +1740,15 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
|
|||
amdgpu_dm_destroy_drm_device(&adev->dm);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
if (adev->dm.crc_rd_wrk) {
|
||||
flush_work(&adev->dm.crc_rd_wrk->notify_ta_work);
|
||||
kfree(adev->dm.crc_rd_wrk);
|
||||
adev->dm.crc_rd_wrk = NULL;
|
||||
if (adev->dm.secure_display_ctxs) {
|
||||
for (i = 0; i < adev->dm.dc->caps.max_links; i++) {
|
||||
if (adev->dm.secure_display_ctxs[i].crtc) {
|
||||
flush_work(&adev->dm.secure_display_ctxs[i].notify_ta_work);
|
||||
flush_work(&adev->dm.secure_display_ctxs[i].forward_roi_work);
|
||||
}
|
||||
}
|
||||
kfree(adev->dm.secure_display_ctxs);
|
||||
adev->dm.secure_display_ctxs = NULL;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
|
@ -2080,7 +2088,9 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
|
|||
* TODO: Move this into GART.
|
||||
*/
|
||||
r = amdgpu_bo_create_kernel(adev, region_info.fb_size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM, &adev->dm.dmub_bo,
|
||||
AMDGPU_GEM_DOMAIN_VRAM |
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->dm.dmub_bo,
|
||||
&adev->dm.dmub_bo_gpu_addr,
|
||||
&adev->dm.dmub_bo_cpu_addr);
|
||||
if (r)
|
||||
|
@ -2165,6 +2175,8 @@ static int detect_mst_link_for_all_connectors(struct drm_device *dev)
|
|||
DRM_ERROR("DM_MST: Failed to start MST\n");
|
||||
aconnector->dc_link->type =
|
||||
dc_connection_single;
|
||||
ret = dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx,
|
||||
aconnector->dc_link);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2486,7 +2498,7 @@ struct amdgpu_dm_connector *
|
|||
amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
uint32_t i;
|
||||
u32 i;
|
||||
struct drm_connector_state *new_con_state;
|
||||
struct drm_connector *connector;
|
||||
struct drm_crtc *crtc_from_state;
|
||||
|
@ -2734,12 +2746,14 @@ static int dm_resume(void *handle)
|
|||
drm_for_each_connector_iter(connector, &iter) {
|
||||
aconnector = to_amdgpu_dm_connector(connector);
|
||||
|
||||
if (!aconnector->dc_link)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* this is the case when traversing through already created
|
||||
* MST connectors, should be skipped
|
||||
*/
|
||||
if (aconnector->dc_link &&
|
||||
aconnector->dc_link->type == dc_connection_mst_branch)
|
||||
if (aconnector->dc_link->type == dc_connection_mst_branch)
|
||||
continue;
|
||||
|
||||
mutex_lock(&aconnector->hpd_lock);
|
||||
|
@ -3117,8 +3131,8 @@ static void handle_hpd_irq(void *param)
|
|||
|
||||
static void dm_handle_mst_sideband_msg(struct amdgpu_dm_connector *aconnector)
|
||||
{
|
||||
uint8_t esi[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = { 0 };
|
||||
uint8_t dret;
|
||||
u8 esi[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = { 0 };
|
||||
u8 dret;
|
||||
bool new_irq_handled = false;
|
||||
int dpcd_addr;
|
||||
int dpcd_bytes_to_read;
|
||||
|
@ -3146,7 +3160,7 @@ static void dm_handle_mst_sideband_msg(struct amdgpu_dm_connector *aconnector)
|
|||
|
||||
while (dret == dpcd_bytes_to_read &&
|
||||
process_count < max_process_count) {
|
||||
uint8_t retry;
|
||||
u8 retry;
|
||||
dret = 0;
|
||||
|
||||
process_count++;
|
||||
|
@ -3165,7 +3179,7 @@ static void dm_handle_mst_sideband_msg(struct amdgpu_dm_connector *aconnector)
|
|||
dpcd_bytes_to_read - 1;
|
||||
|
||||
for (retry = 0; retry < 3; retry++) {
|
||||
uint8_t wret;
|
||||
u8 wret;
|
||||
|
||||
wret = drm_dp_dpcd_write(
|
||||
&aconnector->dm_dp_aux.aux,
|
||||
|
@ -4179,12 +4193,12 @@ static void amdgpu_set_panel_orientation(struct drm_connector *connector);
|
|||
static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_display_manager *dm = &adev->dm;
|
||||
int32_t i;
|
||||
s32 i;
|
||||
struct amdgpu_dm_connector *aconnector = NULL;
|
||||
struct amdgpu_encoder *aencoder = NULL;
|
||||
struct amdgpu_mode_info *mode_info = &adev->mode_info;
|
||||
uint32_t link_cnt;
|
||||
int32_t primary_planes;
|
||||
u32 link_cnt;
|
||||
s32 primary_planes;
|
||||
enum dc_connection_type new_connection_type = dc_connection_none;
|
||||
const struct dc_plane_cap *plane;
|
||||
bool psr_feature_enabled = false;
|
||||
|
@ -4701,7 +4715,7 @@ fill_plane_color_attributes(const struct drm_plane_state *plane_state,
|
|||
static int
|
||||
fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
|
||||
const struct drm_plane_state *plane_state,
|
||||
const uint64_t tiling_flags,
|
||||
const u64 tiling_flags,
|
||||
struct dc_plane_info *plane_info,
|
||||
struct dc_plane_address *address,
|
||||
bool tmz_surface,
|
||||
|
@ -4876,7 +4890,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
|
|||
|
||||
static inline void fill_dc_dirty_rect(struct drm_plane *plane,
|
||||
struct rect *dirty_rect, int32_t x,
|
||||
int32_t y, int32_t width, int32_t height,
|
||||
s32 y, s32 width, s32 height,
|
||||
int *i, bool ffu)
|
||||
{
|
||||
if (*i > DC_MAX_DIRTY_RECTS)
|
||||
|
@ -4932,11 +4946,11 @@ static void fill_dc_dirty_rects(struct drm_plane *plane,
|
|||
{
|
||||
struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state);
|
||||
struct rect *dirty_rects = flip_addrs->dirty_rects;
|
||||
uint32_t num_clips;
|
||||
u32 num_clips;
|
||||
struct drm_mode_rect *clips;
|
||||
bool bb_changed;
|
||||
bool fb_changed;
|
||||
uint32_t i = 0;
|
||||
u32 i = 0;
|
||||
|
||||
/*
|
||||
* Cursor plane has it's own dirty rect update interface. See
|
||||
|
@ -5082,7 +5096,7 @@ static enum dc_color_depth
|
|||
convert_color_depth_from_display_info(const struct drm_connector *connector,
|
||||
bool is_y420, int requested_bpc)
|
||||
{
|
||||
uint8_t bpc;
|
||||
u8 bpc;
|
||||
|
||||
if (is_y420) {
|
||||
bpc = 8;
|
||||
|
@ -5626,8 +5640,8 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,
|
|||
uint32_t max_dsc_target_bpp_limit_override)
|
||||
{
|
||||
const struct dc_link_settings *verified_link_cap = NULL;
|
||||
uint32_t link_bw_in_kbps;
|
||||
uint32_t edp_min_bpp_x16, edp_max_bpp_x16;
|
||||
u32 link_bw_in_kbps;
|
||||
u32 edp_min_bpp_x16, edp_max_bpp_x16;
|
||||
struct dc *dc = sink->ctx->dc;
|
||||
struct dc_dsc_bw_range bw_range = {0};
|
||||
struct dc_dsc_config dsc_cfg = {0};
|
||||
|
@ -5684,11 +5698,11 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
|
|||
struct dsc_dec_dpcd_caps *dsc_caps)
|
||||
{
|
||||
struct drm_connector *drm_connector = &aconnector->base;
|
||||
uint32_t link_bandwidth_kbps;
|
||||
u32 link_bandwidth_kbps;
|
||||
struct dc *dc = sink->ctx->dc;
|
||||
uint32_t max_supported_bw_in_kbps, timing_bw_in_kbps;
|
||||
uint32_t dsc_max_supported_bw_in_kbps;
|
||||
uint32_t max_dsc_target_bpp_limit_override =
|
||||
u32 max_supported_bw_in_kbps, timing_bw_in_kbps;
|
||||
u32 dsc_max_supported_bw_in_kbps;
|
||||
u32 max_dsc_target_bpp_limit_override =
|
||||
drm_connector->display_info.max_dsc_bpp;
|
||||
|
||||
link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
|
||||
|
@ -5835,7 +5849,8 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||
*/
|
||||
DRM_DEBUG_DRIVER("No preferred mode found\n");
|
||||
} else {
|
||||
recalculate_timing = is_freesync_video_mode(&mode, aconnector);
|
||||
recalculate_timing = amdgpu_freesync_vid_mode &&
|
||||
is_freesync_video_mode(&mode, aconnector);
|
||||
if (recalculate_timing) {
|
||||
freesync_mode = get_highest_refresh_rate_mode(aconnector, false);
|
||||
drm_mode_copy(&saved_mode, &mode);
|
||||
|
@ -6909,7 +6924,7 @@ static uint add_fs_modes(struct amdgpu_dm_connector *aconnector)
|
|||
const struct drm_display_mode *m;
|
||||
struct drm_display_mode *new_mode;
|
||||
uint i;
|
||||
uint32_t new_modes_count = 0;
|
||||
u32 new_modes_count = 0;
|
||||
|
||||
/* Standard FPS values
|
||||
*
|
||||
|
@ -6923,7 +6938,7 @@ static uint add_fs_modes(struct amdgpu_dm_connector *aconnector)
|
|||
* 60 - Commonly used
|
||||
* 48,72,96,120 - Multiples of 24
|
||||
*/
|
||||
static const uint32_t common_rates[] = {
|
||||
static const u32 common_rates[] = {
|
||||
23976, 24000, 25000, 29970, 30000,
|
||||
48000, 50000, 60000, 72000, 96000, 120000
|
||||
};
|
||||
|
@ -6939,8 +6954,8 @@ static uint add_fs_modes(struct amdgpu_dm_connector *aconnector)
|
|||
return 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(common_rates); i++) {
|
||||
uint64_t target_vtotal, target_vtotal_diff;
|
||||
uint64_t num, den;
|
||||
u64 target_vtotal, target_vtotal_diff;
|
||||
u64 num, den;
|
||||
|
||||
if (drm_mode_vrefresh(m) * 1000 < common_rates[i])
|
||||
continue;
|
||||
|
@ -6986,7 +7001,7 @@ static void amdgpu_dm_connector_add_freesync_modes(struct drm_connector *connect
|
|||
struct amdgpu_dm_connector *amdgpu_dm_connector =
|
||||
to_amdgpu_dm_connector(connector);
|
||||
|
||||
if (!edid)
|
||||
if (!(amdgpu_freesync_vid_mode && edid))
|
||||
return;
|
||||
|
||||
if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10)
|
||||
|
@ -7182,7 +7197,7 @@ create_i2c(struct ddc_service *ddc_service,
|
|||
*/
|
||||
static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
|
||||
struct amdgpu_dm_connector *aconnector,
|
||||
uint32_t link_index,
|
||||
u32 link_index,
|
||||
struct amdgpu_encoder *aencoder)
|
||||
{
|
||||
int res = 0;
|
||||
|
@ -7367,27 +7382,55 @@ is_scaling_state_different(const struct dm_connector_state *dm_state,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
static bool is_content_protection_different(struct drm_connector_state *state,
|
||||
const struct drm_connector_state *old_state,
|
||||
const struct drm_connector *connector, struct hdcp_workqueue *hdcp_w)
|
||||
static bool is_content_protection_different(struct drm_crtc_state *new_crtc_state,
|
||||
struct drm_crtc_state *old_crtc_state,
|
||||
struct drm_connector_state *new_conn_state,
|
||||
struct drm_connector_state *old_conn_state,
|
||||
const struct drm_connector *connector,
|
||||
struct hdcp_workqueue *hdcp_w)
|
||||
{
|
||||
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
|
||||
struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state);
|
||||
|
||||
/* Handle: Type0/1 change */
|
||||
if (old_state->hdcp_content_type != state->hdcp_content_type &&
|
||||
state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
|
||||
state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
|
||||
pr_debug("[HDCP_DM] connector->index: %x connect_status: %x dpms: %x\n",
|
||||
connector->index, connector->status, connector->dpms);
|
||||
pr_debug("[HDCP_DM] state protection old: %x new: %x\n",
|
||||
old_conn_state->content_protection, new_conn_state->content_protection);
|
||||
|
||||
if (old_crtc_state)
|
||||
pr_debug("[HDCP_DM] old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n",
|
||||
old_crtc_state->enable,
|
||||
old_crtc_state->active,
|
||||
old_crtc_state->mode_changed,
|
||||
old_crtc_state->active_changed,
|
||||
old_crtc_state->connectors_changed);
|
||||
|
||||
if (new_crtc_state)
|
||||
pr_debug("[HDCP_DM] NEW crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n",
|
||||
new_crtc_state->enable,
|
||||
new_crtc_state->active,
|
||||
new_crtc_state->mode_changed,
|
||||
new_crtc_state->active_changed,
|
||||
new_crtc_state->connectors_changed);
|
||||
|
||||
/* hdcp content type change */
|
||||
if (old_conn_state->hdcp_content_type != new_conn_state->hdcp_content_type &&
|
||||
new_conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
|
||||
new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
|
||||
pr_debug("[HDCP_DM] Type0/1 change %s :true\n", __func__);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* CP is being re enabled, ignore this
|
||||
*
|
||||
* Handles: ENABLED -> DESIRED
|
||||
*/
|
||||
if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
|
||||
state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
|
||||
state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
|
||||
/* CP is being re enabled, ignore this */
|
||||
if (old_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
|
||||
new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
|
||||
if (new_crtc_state && new_crtc_state->mode_changed) {
|
||||
new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
|
||||
pr_debug("[HDCP_DM] ENABLED->DESIRED & mode_changed %s :true\n", __func__);
|
||||
return true;
|
||||
};
|
||||
new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
|
||||
pr_debug("[HDCP_DM] ENABLED -> DESIRED %s :false\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -7395,9 +7438,9 @@ static bool is_content_protection_different(struct drm_connector_state *state,
|
|||
*
|
||||
* Handles: UNDESIRED -> ENABLED
|
||||
*/
|
||||
if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
|
||||
state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
|
||||
state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
|
||||
if (old_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
|
||||
new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
|
||||
new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
|
||||
|
||||
/* Stream removed and re-enabled
|
||||
*
|
||||
|
@ -7407,10 +7450,12 @@ static bool is_content_protection_different(struct drm_connector_state *state,
|
|||
*
|
||||
* Handles: DESIRED -> DESIRED (Special case)
|
||||
*/
|
||||
if (!(old_state->crtc && old_state->crtc->enabled) &&
|
||||
state->crtc && state->crtc->enabled &&
|
||||
if (!(old_conn_state->crtc && old_conn_state->crtc->enabled) &&
|
||||
new_conn_state->crtc && new_conn_state->crtc->enabled &&
|
||||
connector->state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
|
||||
dm_con_state->update_hdcp = false;
|
||||
pr_debug("[HDCP_DM] DESIRED->DESIRED (Stream removed and re-enabled) %s :true\n",
|
||||
__func__);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -7422,35 +7467,42 @@ static bool is_content_protection_different(struct drm_connector_state *state,
|
|||
*
|
||||
* Handles: DESIRED -> DESIRED (Special case)
|
||||
*/
|
||||
if (dm_con_state->update_hdcp && state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
|
||||
if (dm_con_state->update_hdcp &&
|
||||
new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
|
||||
connector->dpms == DRM_MODE_DPMS_ON && aconnector->dc_sink != NULL) {
|
||||
dm_con_state->update_hdcp = false;
|
||||
pr_debug("[HDCP_DM] DESIRED->DESIRED (Hot-plug, headless s3, dpms) %s :true\n",
|
||||
__func__);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles: UNDESIRED -> UNDESIRED
|
||||
* DESIRED -> DESIRED
|
||||
* ENABLED -> ENABLED
|
||||
*/
|
||||
if (old_state->content_protection == state->content_protection)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Handles: UNDESIRED -> DESIRED
|
||||
* DESIRED -> UNDESIRED
|
||||
* ENABLED -> UNDESIRED
|
||||
*/
|
||||
if (state->content_protection != DRM_MODE_CONTENT_PROTECTION_ENABLED)
|
||||
if (old_conn_state->content_protection == new_conn_state->content_protection) {
|
||||
if (new_conn_state->content_protection >= DRM_MODE_CONTENT_PROTECTION_DESIRED) {
|
||||
if (new_crtc_state && new_crtc_state->mode_changed) {
|
||||
pr_debug("[HDCP_DM] DESIRED->DESIRED or ENABLE->ENABLE mode_change %s :true\n",
|
||||
__func__);
|
||||
return true;
|
||||
};
|
||||
pr_debug("[HDCP_DM] DESIRED->DESIRED & ENABLE->ENABLE %s :false\n",
|
||||
__func__);
|
||||
return false;
|
||||
};
|
||||
|
||||
/*
|
||||
* Handles: DESIRED -> ENABLED
|
||||
*/
|
||||
pr_debug("[HDCP_DM] UNDESIRED->UNDESIRED %s :false\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (new_conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_ENABLED) {
|
||||
pr_debug("[HDCP_DM] UNDESIRED->DESIRED or DESIRED->UNDESIRED or ENABLED->UNDESIRED %s :true\n",
|
||||
__func__);
|
||||
return true;
|
||||
}
|
||||
|
||||
pr_debug("[HDCP_DM] DESIRED->ENABLED %s :false\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void remove_stream(struct amdgpu_device *adev,
|
||||
struct amdgpu_crtc *acrtc,
|
||||
struct dc_stream_state *stream)
|
||||
|
@ -7666,8 +7718,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||
struct drm_crtc *pcrtc,
|
||||
bool wait_for_vblank)
|
||||
{
|
||||
uint32_t i;
|
||||
uint64_t timestamp_ns;
|
||||
u32 i;
|
||||
u64 timestamp_ns;
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane_state *old_plane_state, *new_plane_state;
|
||||
struct amdgpu_crtc *acrtc_attach = to_amdgpu_crtc(pcrtc);
|
||||
|
@ -7678,7 +7730,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||
to_dm_crtc_state(drm_atomic_get_old_crtc_state(state, pcrtc));
|
||||
int planes_count = 0, vpos, hpos;
|
||||
unsigned long flags;
|
||||
uint32_t target_vblank, last_flip_vblank;
|
||||
u32 target_vblank, last_flip_vblank;
|
||||
bool vrr_active = amdgpu_dm_vrr_active(acrtc_state);
|
||||
bool cursor_update = false;
|
||||
bool pflip_present = false;
|
||||
|
@ -8116,7 +8168,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
struct amdgpu_display_manager *dm = &adev->dm;
|
||||
struct dm_atomic_state *dm_state;
|
||||
struct dc_state *dc_state = NULL, *dc_state_temp = NULL;
|
||||
uint32_t i, j;
|
||||
u32 i, j;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
|
||||
unsigned long flags;
|
||||
|
@ -8290,10 +8342,61 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
|
||||
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
|
||||
|
||||
new_crtc_state = NULL;
|
||||
pr_debug("[HDCP_DM] -------------- i : %x ----------\n", i);
|
||||
|
||||
if (acrtc)
|
||||
if (!connector)
|
||||
continue;
|
||||
|
||||
pr_debug("[HDCP_DM] connector->index: %x connect_status: %x dpms: %x\n",
|
||||
connector->index, connector->status, connector->dpms);
|
||||
pr_debug("[HDCP_DM] state protection old: %x new: %x\n",
|
||||
old_con_state->content_protection, new_con_state->content_protection);
|
||||
|
||||
if (aconnector->dc_sink) {
|
||||
if (aconnector->dc_sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
|
||||
aconnector->dc_sink->sink_signal != SIGNAL_TYPE_NONE) {
|
||||
pr_debug("[HDCP_DM] pipe_ctx dispname=%s\n",
|
||||
aconnector->dc_sink->edid_caps.display_name);
|
||||
}
|
||||
}
|
||||
|
||||
new_crtc_state = NULL;
|
||||
old_crtc_state = NULL;
|
||||
|
||||
if (acrtc) {
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
|
||||
old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base);
|
||||
}
|
||||
|
||||
if (old_crtc_state)
|
||||
pr_debug("old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n",
|
||||
old_crtc_state->enable,
|
||||
old_crtc_state->active,
|
||||
old_crtc_state->mode_changed,
|
||||
old_crtc_state->active_changed,
|
||||
old_crtc_state->connectors_changed);
|
||||
|
||||
if (new_crtc_state)
|
||||
pr_debug("NEW crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n",
|
||||
new_crtc_state->enable,
|
||||
new_crtc_state->active,
|
||||
new_crtc_state->mode_changed,
|
||||
new_crtc_state->active_changed,
|
||||
new_crtc_state->connectors_changed);
|
||||
}
|
||||
|
||||
for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
|
||||
struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
|
||||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
|
||||
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
|
||||
|
||||
new_crtc_state = NULL;
|
||||
old_crtc_state = NULL;
|
||||
|
||||
if (acrtc) {
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
|
||||
old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base);
|
||||
}
|
||||
|
||||
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
|
||||
|
||||
|
@ -8305,11 +8408,44 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (is_content_protection_different(new_con_state, old_con_state, connector, adev->dm.hdcp_workqueue))
|
||||
if (is_content_protection_different(new_crtc_state, old_crtc_state, new_con_state,
|
||||
old_con_state, connector, adev->dm.hdcp_workqueue)) {
|
||||
/* when display is unplugged from mst hub, connctor will
|
||||
* be destroyed within dm_dp_mst_connector_destroy. connector
|
||||
* hdcp perperties, like type, undesired, desired, enabled,
|
||||
* will be lost. So, save hdcp properties into hdcp_work within
|
||||
* amdgpu_dm_atomic_commit_tail. if the same display is
|
||||
* plugged back with same display index, its hdcp properties
|
||||
* will be retrieved from hdcp_work within dm_dp_mst_get_modes
|
||||
*/
|
||||
|
||||
bool enable_encryption = false;
|
||||
|
||||
if (new_con_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED)
|
||||
enable_encryption = true;
|
||||
|
||||
if (aconnector->dc_link && aconnector->dc_sink &&
|
||||
aconnector->dc_link->type == dc_connection_mst_branch) {
|
||||
struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue;
|
||||
struct hdcp_workqueue *hdcp_w =
|
||||
&hdcp_work[aconnector->dc_link->link_index];
|
||||
|
||||
hdcp_w->hdcp_content_type[connector->index] =
|
||||
new_con_state->hdcp_content_type;
|
||||
hdcp_w->content_protection[connector->index] =
|
||||
new_con_state->content_protection;
|
||||
}
|
||||
|
||||
if (new_crtc_state && new_crtc_state->mode_changed &&
|
||||
new_con_state->content_protection >= DRM_MODE_CONTENT_PROTECTION_DESIRED)
|
||||
enable_encryption = true;
|
||||
|
||||
DRM_INFO("[HDCP_DM] hdcp_update_display enable_encryption = %x\n", enable_encryption);
|
||||
|
||||
hdcp_update_display(
|
||||
adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector,
|
||||
new_con_state->hdcp_content_type,
|
||||
new_con_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED);
|
||||
new_con_state->hdcp_content_type, enable_encryption);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -8407,9 +8543,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
enum amdgpu_dm_pipe_crc_source cur_crc_src;
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
struct crc_rd_work *crc_rd_wrk;
|
||||
#endif
|
||||
#endif
|
||||
/* Count number of newly disabled CRTCs for dropping PM refs later. */
|
||||
if (old_crtc_state->active && !new_crtc_state->active)
|
||||
|
@ -8422,9 +8555,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
update_stream_irq_parameters(dm, dm_new_crtc_state);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
crc_rd_wrk = dm->crc_rd_wrk;
|
||||
#endif
|
||||
spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
|
||||
cur_crc_src = acrtc->dm_irq_params.crc_src;
|
||||
spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
|
||||
|
@ -8453,10 +8583,12 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
if (amdgpu_dm_crc_window_is_activated(crtc)) {
|
||||
spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
|
||||
acrtc->dm_irq_params.window_param.update_win = true;
|
||||
|
||||
/**
|
||||
* It takes 2 frames for HW to stably generate CRC when
|
||||
* resuming from suspend, so we set skip_frame_cnt 2.
|
||||
*/
|
||||
acrtc->dm_irq_params.window_param.skip_frame_cnt = 2;
|
||||
spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
crc_rd_wrk->crtc = crtc;
|
||||
spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
@ -8679,15 +8811,22 @@ static void get_freesync_config_for_crtc(
|
|||
struct drm_display_mode *mode = &new_crtc_state->base.mode;
|
||||
int vrefresh = drm_mode_vrefresh(mode);
|
||||
bool fs_vid_mode = false;
|
||||
bool drr_active = false;
|
||||
|
||||
new_crtc_state->vrr_supported = new_con_state->freesync_capable &&
|
||||
vrefresh >= aconnector->min_vfreq &&
|
||||
vrefresh <= aconnector->max_vfreq;
|
||||
|
||||
if (new_crtc_state->vrr_supported) {
|
||||
new_crtc_state->stream->ignore_msa_timing_param = true;
|
||||
fs_vid_mode = new_crtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED;
|
||||
drr_active = new_crtc_state->vrr_supported &&
|
||||
new_crtc_state->freesync_config.state != VRR_STATE_DISABLED &&
|
||||
new_crtc_state->freesync_config.state != VRR_STATE_INACTIVE &&
|
||||
new_crtc_state->freesync_config.state != VRR_STATE_UNSUPPORTED;
|
||||
|
||||
if (drr_active)
|
||||
new_crtc_state->stream->ignore_msa_timing_param = true;
|
||||
|
||||
if (new_crtc_state->vrr_supported) {
|
||||
fs_vid_mode = new_crtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED;
|
||||
config.min_refresh_in_uhz = aconnector->min_vfreq * 1000000;
|
||||
config.max_refresh_in_uhz = aconnector->max_vfreq * 1000000;
|
||||
config.vsif_supported = true;
|
||||
|
@ -8747,7 +8886,7 @@ is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
|
|||
}
|
||||
|
||||
static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state) {
|
||||
uint64_t num, den, res;
|
||||
u64 num, den, res;
|
||||
struct drm_crtc_state *new_crtc_state = &dm_new_crtc_state->base;
|
||||
|
||||
dm_new_crtc_state->freesync_config.state = VRR_STATE_ACTIVE_FIXED;
|
||||
|
@ -8850,7 +8989,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
|
|||
* TODO: Refactor this function to allow this check to work
|
||||
* in all conditions.
|
||||
*/
|
||||
if (dm_new_crtc_state->stream &&
|
||||
if (amdgpu_freesync_vid_mode &&
|
||||
dm_new_crtc_state->stream &&
|
||||
is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state))
|
||||
goto skip_modeset;
|
||||
|
||||
|
@ -8885,7 +9025,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
|
|||
if (!dm_old_crtc_state->stream)
|
||||
goto skip_modeset;
|
||||
|
||||
if (dm_new_crtc_state->stream &&
|
||||
if (amdgpu_freesync_vid_mode && dm_new_crtc_state->stream &&
|
||||
is_timing_unchanged_for_freesync(new_crtc_state,
|
||||
old_crtc_state)) {
|
||||
new_crtc_state->mode_changed = false;
|
||||
|
@ -8897,7 +9037,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
|
|||
set_freesync_fixed_config(dm_new_crtc_state);
|
||||
|
||||
goto skip_modeset;
|
||||
} else if (aconnector &&
|
||||
} else if (amdgpu_freesync_vid_mode && aconnector &&
|
||||
is_freesync_video_mode(&new_crtc_state->mode,
|
||||
aconnector)) {
|
||||
struct drm_display_mode *high_mode;
|
||||
|
@ -9883,7 +10023,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
static bool is_dp_capable_without_timing_msa(struct dc *dc,
|
||||
struct amdgpu_dm_connector *amdgpu_dm_connector)
|
||||
{
|
||||
uint8_t dpcd_data;
|
||||
u8 dpcd_data;
|
||||
bool capable = false;
|
||||
|
||||
if (amdgpu_dm_connector->dc_link &&
|
||||
|
@ -9902,7 +10042,7 @@ static bool is_dp_capable_without_timing_msa(struct dc *dc,
|
|||
static bool dm_edid_parser_send_cea(struct amdgpu_display_manager *dm,
|
||||
unsigned int offset,
|
||||
unsigned int total_length,
|
||||
uint8_t *data,
|
||||
u8 *data,
|
||||
unsigned int length,
|
||||
struct amdgpu_hdmi_vsdb_info *vsdb)
|
||||
{
|
||||
|
@ -9957,7 +10097,7 @@ static bool dm_edid_parser_send_cea(struct amdgpu_display_manager *dm,
|
|||
}
|
||||
|
||||
static bool parse_edid_cea_dmcu(struct amdgpu_display_manager *dm,
|
||||
uint8_t *edid_ext, int len,
|
||||
u8 *edid_ext, int len,
|
||||
struct amdgpu_hdmi_vsdb_info *vsdb_info)
|
||||
{
|
||||
int i;
|
||||
|
@ -9998,7 +10138,7 @@ static bool parse_edid_cea_dmcu(struct amdgpu_display_manager *dm,
|
|||
}
|
||||
|
||||
static bool parse_edid_cea_dmub(struct amdgpu_display_manager *dm,
|
||||
uint8_t *edid_ext, int len,
|
||||
u8 *edid_ext, int len,
|
||||
struct amdgpu_hdmi_vsdb_info *vsdb_info)
|
||||
{
|
||||
int i;
|
||||
|
@ -10014,7 +10154,7 @@ static bool parse_edid_cea_dmub(struct amdgpu_display_manager *dm,
|
|||
}
|
||||
|
||||
static bool parse_edid_cea(struct amdgpu_dm_connector *aconnector,
|
||||
uint8_t *edid_ext, int len,
|
||||
u8 *edid_ext, int len,
|
||||
struct amdgpu_hdmi_vsdb_info *vsdb_info)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(aconnector->base.dev);
|
||||
|
@ -10028,7 +10168,7 @@ static bool parse_edid_cea(struct amdgpu_dm_connector *aconnector,
|
|||
static int parse_hdmi_amd_vsdb(struct amdgpu_dm_connector *aconnector,
|
||||
struct edid *edid, struct amdgpu_hdmi_vsdb_info *vsdb_info)
|
||||
{
|
||||
uint8_t *edid_ext = NULL;
|
||||
u8 *edid_ext = NULL;
|
||||
int i;
|
||||
bool valid_vsdb_found = false;
|
||||
|
||||
|
@ -10204,7 +10344,7 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev)
|
|||
}
|
||||
|
||||
void dm_write_reg_func(const struct dc_context *ctx, uint32_t address,
|
||||
uint32_t value, const char *func_name)
|
||||
u32 value, const char *func_name)
|
||||
{
|
||||
#ifdef DM_CHECK_ADDR_0
|
||||
if (address == 0) {
|
||||
|
@ -10219,7 +10359,7 @@ void dm_write_reg_func(const struct dc_context *ctx, uint32_t address,
|
|||
uint32_t dm_read_reg_func(const struct dc_context *ctx, uint32_t address,
|
||||
const char *func_name)
|
||||
{
|
||||
uint32_t value;
|
||||
u32 value;
|
||||
#ifdef DM_CHECK_ADDR_0
|
||||
if (address == 0) {
|
||||
DC_ERR("invalid register read; address = 0\n");
|
||||
|
|
|
@ -494,11 +494,12 @@ struct amdgpu_display_manager {
|
|||
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
/**
|
||||
* @crc_rd_wrk:
|
||||
* @secure_display_ctxs:
|
||||
*
|
||||
* Work to be executed in a separate thread to communicate with PSP.
|
||||
* Store the ROI information and the work_struct to command dmub and psp for
|
||||
* all crtcs.
|
||||
*/
|
||||
struct crc_rd_work *crc_rd_wrk;
|
||||
struct secure_display_context *secure_display_ctxs;
|
||||
#endif
|
||||
/**
|
||||
* @hpd_rx_offload_wq:
|
||||
|
|
|
@ -101,35 +101,44 @@ static void amdgpu_dm_set_crc_window_default(struct drm_crtc *crtc)
|
|||
|
||||
static void amdgpu_dm_crtc_notify_ta_to_read(struct work_struct *work)
|
||||
{
|
||||
struct crc_rd_work *crc_rd_wrk;
|
||||
struct amdgpu_device *adev;
|
||||
struct secure_display_context *secure_display_ctx;
|
||||
struct psp_context *psp;
|
||||
struct securedisplay_cmd *securedisplay_cmd;
|
||||
struct ta_securedisplay_cmd *securedisplay_cmd;
|
||||
struct drm_crtc *crtc;
|
||||
uint8_t phy_id;
|
||||
struct dc_stream_state *stream;
|
||||
uint8_t phy_inst;
|
||||
int ret;
|
||||
|
||||
crc_rd_wrk = container_of(work, struct crc_rd_work, notify_ta_work);
|
||||
spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
crtc = crc_rd_wrk->crtc;
|
||||
secure_display_ctx = container_of(work, struct secure_display_context, notify_ta_work);
|
||||
crtc = secure_display_ctx->crtc;
|
||||
|
||||
if (!crtc) {
|
||||
spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
adev = drm_to_adev(crtc->dev);
|
||||
psp = &adev->psp;
|
||||
phy_id = crc_rd_wrk->phy_inst;
|
||||
spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
psp = &drm_to_adev(crtc->dev)->psp;
|
||||
|
||||
if (!psp->securedisplay_context.context.initialized) {
|
||||
DRM_DEBUG_DRIVER("Secure Display fails to notify PSP TA\n");
|
||||
return;
|
||||
}
|
||||
|
||||
stream = to_amdgpu_crtc(crtc)->dm_irq_params.stream;
|
||||
phy_inst = stream->link->link_enc_hw_inst;
|
||||
|
||||
/* need lock for multiple crtcs to use the command buffer */
|
||||
mutex_lock(&psp->securedisplay_context.mutex);
|
||||
|
||||
psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,
|
||||
TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC);
|
||||
securedisplay_cmd->securedisplay_in_message.send_roi_crc.phy_id =
|
||||
phy_id;
|
||||
|
||||
securedisplay_cmd->securedisplay_in_message.send_roi_crc.phy_id = phy_inst;
|
||||
|
||||
/* PSP TA is expected to finish data transmission over I2C within current frame,
|
||||
* even there are up to 4 crtcs request to send in this frame.
|
||||
*/
|
||||
ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC);
|
||||
|
||||
if (!ret) {
|
||||
if (securedisplay_cmd->status != TA_SECUREDISPLAY_STATUS__SUCCESS) {
|
||||
psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status);
|
||||
|
@ -142,17 +151,23 @@ static void amdgpu_dm_crtc_notify_ta_to_read(struct work_struct *work)
|
|||
static void
|
||||
amdgpu_dm_forward_crc_window(struct work_struct *work)
|
||||
{
|
||||
struct crc_fw_work *crc_fw_wrk;
|
||||
struct secure_display_context *secure_display_ctx;
|
||||
struct amdgpu_display_manager *dm;
|
||||
struct drm_crtc *crtc;
|
||||
struct dc_stream_state *stream;
|
||||
|
||||
crc_fw_wrk = container_of(work, struct crc_fw_work, forward_roi_work);
|
||||
dm = crc_fw_wrk->dm;
|
||||
secure_display_ctx = container_of(work, struct secure_display_context, forward_roi_work);
|
||||
crtc = secure_display_ctx->crtc;
|
||||
|
||||
if (!crtc)
|
||||
return;
|
||||
|
||||
dm = &drm_to_adev(crtc->dev)->dm;
|
||||
stream = to_amdgpu_crtc(crtc)->dm_irq_params.stream;
|
||||
|
||||
mutex_lock(&dm->dc_lock);
|
||||
dc_stream_forward_crc_window(dm->dc, &crc_fw_wrk->rect, crc_fw_wrk->stream, crc_fw_wrk->is_stop_cmd);
|
||||
dc_stream_forward_crc_window(stream, &secure_display_ctx->rect, false);
|
||||
mutex_unlock(&dm->dc_lock);
|
||||
|
||||
kfree(crc_fw_wrk);
|
||||
}
|
||||
|
||||
bool amdgpu_dm_crc_window_is_activated(struct drm_crtc *crtc)
|
||||
|
@ -189,6 +204,9 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc,
|
|||
struct dm_crtc_state *dm_crtc_state,
|
||||
enum amdgpu_dm_pipe_crc_source source)
|
||||
{
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
int i;
|
||||
#endif
|
||||
struct amdgpu_device *adev = drm_to_adev(crtc->dev);
|
||||
struct dc_stream_state *stream_state = dm_crtc_state->stream;
|
||||
bool enable = amdgpu_dm_is_valid_crc_source(source);
|
||||
|
@ -200,21 +218,18 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc,
|
|||
|
||||
mutex_lock(&adev->dm.dc_lock);
|
||||
|
||||
/* Enable CRTC CRC generation if necessary. */
|
||||
/* Enable or disable CRTC CRC generation */
|
||||
if (dm_is_crc_source_crtc(source) || source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE) {
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
/* Disable secure_display if it was enabled */
|
||||
if (!enable) {
|
||||
if (adev->dm.crc_rd_wrk) {
|
||||
flush_work(&adev->dm.crc_rd_wrk->notify_ta_work);
|
||||
spin_lock_irq(&adev->dm.crc_rd_wrk->crc_rd_work_lock);
|
||||
|
||||
if (adev->dm.crc_rd_wrk->crtc == crtc) {
|
||||
for (i = 0; i < adev->dm.dc->caps.max_links; i++) {
|
||||
if (adev->dm.secure_display_ctxs[i].crtc == crtc) {
|
||||
/* stop ROI update on this crtc */
|
||||
dc_stream_forward_crc_window(stream_state->ctx->dc,
|
||||
NULL, stream_state, true);
|
||||
adev->dm.crc_rd_wrk->crtc = NULL;
|
||||
flush_work(&adev->dm.secure_display_ctxs[i].notify_ta_work);
|
||||
flush_work(&adev->dm.secure_display_ctxs[i].forward_roi_work);
|
||||
dc_stream_forward_crc_window(stream_state, NULL, true);
|
||||
}
|
||||
spin_unlock_irq(&adev->dm.crc_rd_wrk->crc_rd_work_lock);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -347,6 +362,7 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
|
|||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
/* Reset secure_display when we change crc source from debugfs */
|
||||
amdgpu_dm_set_crc_window_default(crtc);
|
||||
#endif
|
||||
|
||||
|
@ -456,14 +472,12 @@ void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc)
|
|||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
|
||||
{
|
||||
struct dc_stream_state *stream_state;
|
||||
struct drm_device *drm_dev = NULL;
|
||||
enum amdgpu_dm_pipe_crc_source cur_crc_src;
|
||||
struct amdgpu_crtc *acrtc = NULL;
|
||||
struct amdgpu_device *adev = NULL;
|
||||
struct crc_rd_work *crc_rd_wrk;
|
||||
struct crc_fw_work *crc_fw_wrk;
|
||||
unsigned long flags1, flags2;
|
||||
struct secure_display_context *secure_display_ctx = NULL;
|
||||
unsigned long flags1;
|
||||
|
||||
if (crtc == NULL)
|
||||
return;
|
||||
|
@ -473,75 +487,74 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
|
|||
drm_dev = crtc->dev;
|
||||
|
||||
spin_lock_irqsave(&drm_dev->event_lock, flags1);
|
||||
stream_state = acrtc->dm_irq_params.stream;
|
||||
cur_crc_src = acrtc->dm_irq_params.crc_src;
|
||||
|
||||
/* Early return if CRC capture is not enabled. */
|
||||
if (!amdgpu_dm_is_valid_crc_source(cur_crc_src))
|
||||
goto cleanup;
|
||||
|
||||
if (!dm_is_crc_source_crtc(cur_crc_src))
|
||||
if (!amdgpu_dm_is_valid_crc_source(cur_crc_src) ||
|
||||
!dm_is_crc_source_crtc(cur_crc_src))
|
||||
goto cleanup;
|
||||
|
||||
if (!acrtc->dm_irq_params.window_param.activated)
|
||||
goto cleanup;
|
||||
|
||||
if (acrtc->dm_irq_params.window_param.update_win) {
|
||||
if (acrtc->dm_irq_params.window_param.skip_frame_cnt) {
|
||||
acrtc->dm_irq_params.window_param.skip_frame_cnt -= 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* prepare work for dmub to update ROI */
|
||||
crc_fw_wrk = kzalloc(sizeof(*crc_fw_wrk), GFP_ATOMIC);
|
||||
if (!crc_fw_wrk)
|
||||
goto cleanup;
|
||||
secure_display_ctx = &adev->dm.secure_display_ctxs[acrtc->crtc_id];
|
||||
if (WARN_ON(secure_display_ctx->crtc != crtc)) {
|
||||
/* We have set the crtc when creating secure_display_context,
|
||||
* don't expect it to be changed here.
|
||||
*/
|
||||
secure_display_ctx->crtc = crtc;
|
||||
}
|
||||
|
||||
INIT_WORK(&crc_fw_wrk->forward_roi_work, amdgpu_dm_forward_crc_window);
|
||||
crc_fw_wrk->dm = &adev->dm;
|
||||
crc_fw_wrk->stream = stream_state;
|
||||
crc_fw_wrk->rect.x = acrtc->dm_irq_params.window_param.x_start;
|
||||
crc_fw_wrk->rect.y = acrtc->dm_irq_params.window_param.y_start;
|
||||
crc_fw_wrk->rect.width = acrtc->dm_irq_params.window_param.x_end -
|
||||
if (acrtc->dm_irq_params.window_param.update_win) {
|
||||
/* prepare work for dmub to update ROI */
|
||||
secure_display_ctx->rect.x = acrtc->dm_irq_params.window_param.x_start;
|
||||
secure_display_ctx->rect.y = acrtc->dm_irq_params.window_param.y_start;
|
||||
secure_display_ctx->rect.width = acrtc->dm_irq_params.window_param.x_end -
|
||||
acrtc->dm_irq_params.window_param.x_start;
|
||||
crc_fw_wrk->rect.height = acrtc->dm_irq_params.window_param.y_end -
|
||||
secure_display_ctx->rect.height = acrtc->dm_irq_params.window_param.y_end -
|
||||
acrtc->dm_irq_params.window_param.y_start;
|
||||
schedule_work(&crc_fw_wrk->forward_roi_work);
|
||||
schedule_work(&secure_display_ctx->forward_roi_work);
|
||||
|
||||
acrtc->dm_irq_params.window_param.update_win = false;
|
||||
|
||||
/* Statically skip 1 frame, because we may need to wait below things
|
||||
* before sending ROI to dmub:
|
||||
* 1. We defer the work by using system workqueue.
|
||||
* 2. We may need to wait for dc_lock before accessing dmub.
|
||||
*/
|
||||
acrtc->dm_irq_params.window_param.skip_frame_cnt = 1;
|
||||
|
||||
} else {
|
||||
if (acrtc->dm_irq_params.window_param.skip_frame_cnt) {
|
||||
acrtc->dm_irq_params.window_param.skip_frame_cnt -= 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (adev->dm.crc_rd_wrk) {
|
||||
crc_rd_wrk = adev->dm.crc_rd_wrk;
|
||||
spin_lock_irqsave(&crc_rd_wrk->crc_rd_work_lock, flags2);
|
||||
crc_rd_wrk->phy_inst = stream_state->link->link_enc_hw_inst;
|
||||
spin_unlock_irqrestore(&crc_rd_wrk->crc_rd_work_lock, flags2);
|
||||
schedule_work(&crc_rd_wrk->notify_ta_work);
|
||||
}
|
||||
/* prepare work for psp to read ROI/CRC and send to I2C */
|
||||
schedule_work(&secure_display_ctx->notify_ta_work);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
spin_unlock_irqrestore(&drm_dev->event_lock, flags1);
|
||||
}
|
||||
|
||||
struct crc_rd_work *amdgpu_dm_crtc_secure_display_create_work(void)
|
||||
struct secure_display_context *
|
||||
amdgpu_dm_crtc_secure_display_create_contexts(struct amdgpu_device *adev)
|
||||
{
|
||||
struct crc_rd_work *crc_rd_wrk = NULL;
|
||||
struct secure_display_context *secure_display_ctxs = NULL;
|
||||
int i;
|
||||
|
||||
crc_rd_wrk = kzalloc(sizeof(*crc_rd_wrk), GFP_KERNEL);
|
||||
secure_display_ctxs = kcalloc(AMDGPU_MAX_CRTCS, sizeof(struct secure_display_context), GFP_KERNEL);
|
||||
|
||||
if (!crc_rd_wrk)
|
||||
if (!secure_display_ctxs)
|
||||
return NULL;
|
||||
|
||||
spin_lock_init(&crc_rd_wrk->crc_rd_work_lock);
|
||||
INIT_WORK(&crc_rd_wrk->notify_ta_work, amdgpu_dm_crtc_notify_ta_to_read);
|
||||
for (i = 0; i < adev->dm.dc->caps.max_links; i++) {
|
||||
INIT_WORK(&secure_display_ctxs[i].forward_roi_work, amdgpu_dm_forward_crc_window);
|
||||
INIT_WORK(&secure_display_ctxs[i].notify_ta_work, amdgpu_dm_crtc_notify_ta_to_read);
|
||||
secure_display_ctxs[i].crtc = &adev->mode_info.crtcs[i]->base;
|
||||
}
|
||||
|
||||
return crc_rd_wrk;
|
||||
return secure_display_ctxs;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -45,7 +45,7 @@ struct crc_window_param {
|
|||
uint16_t y_start;
|
||||
uint16_t x_end;
|
||||
uint16_t y_end;
|
||||
/* CRC windwo is activated or not*/
|
||||
/* CRC window is activated or not*/
|
||||
bool activated;
|
||||
/* Update crc window during vertical blank or not */
|
||||
bool update_win;
|
||||
|
@ -53,22 +53,17 @@ struct crc_window_param {
|
|||
int skip_frame_cnt;
|
||||
};
|
||||
|
||||
/* read_work for driver to call PSP to read */
|
||||
struct crc_rd_work {
|
||||
struct secure_display_context {
|
||||
/* work to notify PSP TA*/
|
||||
struct work_struct notify_ta_work;
|
||||
/* To protect crc_rd_work carried fields*/
|
||||
spinlock_t crc_rd_work_lock;
|
||||
struct drm_crtc *crtc;
|
||||
uint8_t phy_inst;
|
||||
};
|
||||
|
||||
/* forward_work for driver to forward ROI to dmu */
|
||||
struct crc_fw_work {
|
||||
/* work to forward ROI to dmcu/dmub */
|
||||
struct work_struct forward_roi_work;
|
||||
struct amdgpu_display_manager *dm;
|
||||
struct dc_stream_state *stream;
|
||||
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
/* Region of Interest (ROI) */
|
||||
struct rect rect;
|
||||
bool is_stop_cmd;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -100,11 +95,12 @@ void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc);
|
|||
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
|
||||
bool amdgpu_dm_crc_window_is_activated(struct drm_crtc *crtc);
|
||||
void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc);
|
||||
struct crc_rd_work *amdgpu_dm_crtc_secure_display_create_work(void);
|
||||
struct secure_display_context *amdgpu_dm_crtc_secure_display_create_contexts(
|
||||
struct amdgpu_device *adev);
|
||||
#else
|
||||
#define amdgpu_dm_crc_window_is_activated(x)
|
||||
#define amdgpu_dm_crtc_handle_crc_window_irq(x)
|
||||
#define amdgpu_dm_crtc_secure_display_create_work()
|
||||
#define amdgpu_dm_crtc_secure_display_create_contexts()
|
||||
#endif
|
||||
|
||||
#endif /* AMD_DAL_DEV_AMDGPU_DM_AMDGPU_DM_CRC_H_ */
|
||||
|
|
|
@ -1375,16 +1375,11 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
|
|||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream &&
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pipe_ctx) {
|
||||
kfree(rd_buf);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
dsc = pipe_ctx->stream_res.dsc;
|
||||
if (dsc)
|
||||
dsc->funcs->dsc_read_state(dsc, &dsc_state);
|
||||
|
@ -1481,12 +1476,12 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf,
|
|||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream &&
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pipe_ctx || !pipe_ctx->stream)
|
||||
if (!pipe_ctx->stream)
|
||||
goto done;
|
||||
|
||||
// Get CRTC state
|
||||
|
@ -1566,16 +1561,11 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
|
|||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream &&
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pipe_ctx) {
|
||||
kfree(rd_buf);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
dsc = pipe_ctx->stream_res.dsc;
|
||||
if (dsc)
|
||||
dsc->funcs->dsc_read_state(dsc, &dsc_state);
|
||||
|
@ -1670,12 +1660,12 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf,
|
|||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream &&
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pipe_ctx || !pipe_ctx->stream)
|
||||
if (!pipe_ctx->stream)
|
||||
goto done;
|
||||
|
||||
// Safely get CRTC state
|
||||
|
@ -1755,16 +1745,11 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
|
|||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream &&
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pipe_ctx) {
|
||||
kfree(rd_buf);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
dsc = pipe_ctx->stream_res.dsc;
|
||||
if (dsc)
|
||||
dsc->funcs->dsc_read_state(dsc, &dsc_state);
|
||||
|
@ -1859,12 +1844,12 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf,
|
|||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream &&
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pipe_ctx || !pipe_ctx->stream)
|
||||
if (!pipe_ctx->stream)
|
||||
goto done;
|
||||
|
||||
// Get CRTC state
|
||||
|
@ -1940,16 +1925,11 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
|
|||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream &&
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pipe_ctx) {
|
||||
kfree(rd_buf);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
dsc = pipe_ctx->stream_res.dsc;
|
||||
if (dsc)
|
||||
dsc->funcs->dsc_read_state(dsc, &dsc_state);
|
||||
|
@ -2041,12 +2021,12 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu
|
|||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream &&
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pipe_ctx || !pipe_ctx->stream)
|
||||
if (!pipe_ctx->stream)
|
||||
goto done;
|
||||
|
||||
// Get CRTC state
|
||||
|
@ -2120,16 +2100,11 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
|
|||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream &&
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pipe_ctx) {
|
||||
kfree(rd_buf);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
dsc = pipe_ctx->stream_res.dsc;
|
||||
if (dsc)
|
||||
dsc->funcs->dsc_read_state(dsc, &dsc_state);
|
||||
|
@ -2181,16 +2156,11 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
|
|||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream &&
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pipe_ctx) {
|
||||
kfree(rd_buf);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
dsc = pipe_ctx->stream_res.dsc;
|
||||
if (dsc)
|
||||
dsc->funcs->dsc_read_state(dsc, &dsc_state);
|
||||
|
@ -2257,16 +2227,11 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf,
|
|||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream &&
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pipe_ctx) {
|
||||
kfree(rd_buf);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
dsc = pipe_ctx->stream_res.dsc;
|
||||
if (dsc)
|
||||
dsc->funcs->dsc_read_state(dsc, &dsc_state);
|
||||
|
@ -2333,16 +2298,11 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
|
|||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream &&
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pipe_ctx) {
|
||||
kfree(rd_buf);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
dsc = pipe_ctx->stream_res.dsc;
|
||||
if (dsc)
|
||||
dsc->funcs->dsc_read_state(dsc, &dsc_state);
|
||||
|
@ -3245,46 +3205,24 @@ DEFINE_DEBUGFS_ATTRIBUTE(crc_win_y_end_fops, crc_win_y_end_get,
|
|||
*/
|
||||
static int crc_win_update_set(void *data, u64 val)
|
||||
{
|
||||
struct drm_crtc *new_crtc = data;
|
||||
struct drm_crtc *old_crtc = NULL;
|
||||
struct amdgpu_crtc *new_acrtc, *old_acrtc;
|
||||
struct amdgpu_device *adev = drm_to_adev(new_crtc->dev);
|
||||
struct crc_rd_work *crc_rd_wrk = adev->dm.crc_rd_wrk;
|
||||
|
||||
if (!crc_rd_wrk)
|
||||
return 0;
|
||||
struct drm_crtc *crtc = data;
|
||||
struct amdgpu_crtc *acrtc;
|
||||
struct amdgpu_device *adev = drm_to_adev(crtc->dev);
|
||||
|
||||
if (val) {
|
||||
new_acrtc = to_amdgpu_crtc(new_crtc);
|
||||
acrtc = to_amdgpu_crtc(crtc);
|
||||
mutex_lock(&adev->dm.dc_lock);
|
||||
/* PSR may write to OTG CRC window control register,
|
||||
* so close it before starting secure_display.
|
||||
*/
|
||||
amdgpu_dm_psr_disable(new_acrtc->dm_irq_params.stream);
|
||||
amdgpu_dm_psr_disable(acrtc->dm_irq_params.stream);
|
||||
|
||||
spin_lock_irq(&adev_to_drm(adev)->event_lock);
|
||||
spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
if (crc_rd_wrk->crtc) {
|
||||
old_crtc = crc_rd_wrk->crtc;
|
||||
old_acrtc = to_amdgpu_crtc(old_crtc);
|
||||
}
|
||||
|
||||
if (old_crtc && old_crtc != new_crtc) {
|
||||
old_acrtc->dm_irq_params.window_param.activated = false;
|
||||
old_acrtc->dm_irq_params.window_param.update_win = false;
|
||||
old_acrtc->dm_irq_params.window_param.skip_frame_cnt = 0;
|
||||
acrtc->dm_irq_params.window_param.activated = true;
|
||||
acrtc->dm_irq_params.window_param.update_win = true;
|
||||
acrtc->dm_irq_params.window_param.skip_frame_cnt = 0;
|
||||
|
||||
new_acrtc->dm_irq_params.window_param.activated = true;
|
||||
new_acrtc->dm_irq_params.window_param.update_win = true;
|
||||
new_acrtc->dm_irq_params.window_param.skip_frame_cnt = 0;
|
||||
crc_rd_wrk->crtc = new_crtc;
|
||||
} else {
|
||||
new_acrtc->dm_irq_params.window_param.activated = true;
|
||||
new_acrtc->dm_irq_params.window_param.update_win = true;
|
||||
new_acrtc->dm_irq_params.window_param.skip_frame_cnt = 0;
|
||||
crc_rd_wrk->crtc = new_crtc;
|
||||
}
|
||||
spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
spin_unlock_irq(&adev_to_drm(adev)->event_lock);
|
||||
mutex_unlock(&adev->dm.dc_lock);
|
||||
}
|
||||
|
|
|
@ -52,6 +52,20 @@ struct hdcp_workqueue {
|
|||
struct mod_hdcp_link link;
|
||||
|
||||
enum mod_hdcp_encryption_status encryption_status;
|
||||
|
||||
/* when display is unplugged from mst hub, connctor will be
|
||||
* destroyed within dm_dp_mst_connector_destroy. connector
|
||||
* hdcp perperties, like type, undesired, desired, enabled,
|
||||
* will be lost. So, save hdcp properties into hdcp_work within
|
||||
* amdgpu_dm_atomic_commit_tail. if the same display is
|
||||
* plugged back with same display index, its hdcp properties
|
||||
* will be retrieved from hdcp_work within dm_dp_mst_get_modes
|
||||
*/
|
||||
/* un-desired, desired, enabled */
|
||||
unsigned int content_protection[AMDGPU_DM_MAX_DISPLAY_INDEX];
|
||||
/* hdcp1.x, hdcp2.x */
|
||||
unsigned int hdcp_content_type[AMDGPU_DM_MAX_DISPLAY_INDEX];
|
||||
|
||||
uint8_t max_link;
|
||||
|
||||
uint8_t *srm;
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
#include "amdgpu_dm.h"
|
||||
#include "amdgpu_dm_mst_types.h"
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
#include "amdgpu_dm_hdcp.h"
|
||||
#endif
|
||||
|
||||
#include "dc.h"
|
||||
#include "dm_helpers.h"
|
||||
|
||||
|
@ -344,6 +348,28 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
|
|||
/* dc_link_add_remote_sink returns a new reference */
|
||||
aconnector->dc_sink = dc_sink;
|
||||
|
||||
/* when display is unplugged from mst hub, connctor will be
|
||||
* destroyed within dm_dp_mst_connector_destroy. connector
|
||||
* hdcp perperties, like type, undesired, desired, enabled,
|
||||
* will be lost. So, save hdcp properties into hdcp_work within
|
||||
* amdgpu_dm_atomic_commit_tail. if the same display is
|
||||
* plugged back with same display index, its hdcp properties
|
||||
* will be retrieved from hdcp_work within dm_dp_mst_get_modes
|
||||
*/
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
if (aconnector->dc_sink && connector->state) {
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue;
|
||||
struct hdcp_workqueue *hdcp_w = &hdcp_work[aconnector->dc_link->link_index];
|
||||
|
||||
connector->state->hdcp_content_type =
|
||||
hdcp_w->hdcp_content_type[connector->index];
|
||||
connector->state->content_protection =
|
||||
hdcp_w->content_protection[connector->index];
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aconnector->dc_sink) {
|
||||
amdgpu_dm_update_freesync_caps(
|
||||
connector, aconnector->edid);
|
||||
|
|
|
@ -382,16 +382,18 @@ static void dc_perf_trace_destroy(struct dc_perf_trace **perf_trace)
|
|||
}
|
||||
|
||||
/**
|
||||
* dc_stream_adjust_vmin_vmax:
|
||||
* dc_stream_adjust_vmin_vmax - look up pipe context & update parts of DRR
|
||||
* @dc: dc reference
|
||||
* @stream: Initial dc stream state
|
||||
* @adjust: Updated parameters for vertical_total_min and vertical_total_max
|
||||
*
|
||||
* Looks up the pipe context of dc_stream_state and updates the
|
||||
* vertical_total_min and vertical_total_max of the DRR, Dynamic Refresh
|
||||
* Rate, which is a power-saving feature that targets reducing panel
|
||||
* refresh rate while the screen is static
|
||||
*
|
||||
* @dc: dc reference
|
||||
* @stream: Initial dc stream state
|
||||
* @adjust: Updated parameters for vertical_total_min and vertical_total_max
|
||||
* Return: %true if the pipe context is found and adjusted;
|
||||
* %false if the pipe context is not found.
|
||||
*/
|
||||
bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
|
@ -419,14 +421,17 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
|||
}
|
||||
|
||||
/**
|
||||
* dc_stream_get_last_used_drr_vtotal - dc_stream_get_last_vrr_vtotal
|
||||
* dc_stream_get_last_used_drr_vtotal - Looks up the pipe context of
|
||||
* dc_stream_state and gets the last VTOTAL used by DRR (Dynamic Refresh Rate)
|
||||
*
|
||||
* @dc: [in] dc reference
|
||||
* @stream: [in] Initial dc stream state
|
||||
* @adjust: [in] Updated parameters for vertical_total_min and
|
||||
* @refresh_rate: [in] new refresh_rate
|
||||
*
|
||||
* Looks up the pipe context of dc_stream_state and gets the last VTOTAL used
|
||||
* by DRR (Dynamic Refresh Rate)
|
||||
* Return: %true if the pipe context is found and there is an associated
|
||||
* timing_generator for the DC;
|
||||
* %false if the pipe context is not found or there is no
|
||||
* timing_generator for the DC.
|
||||
*/
|
||||
bool dc_stream_get_last_used_drr_vtotal(struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
|
@ -518,14 +523,15 @@ dc_stream_forward_dmcu_crc_window(struct dmcu *dmcu,
|
|||
}
|
||||
|
||||
bool
|
||||
dc_stream_forward_crc_window(struct dc *dc,
|
||||
struct rect *rect, struct dc_stream_state *stream, bool is_stop)
|
||||
dc_stream_forward_crc_window(struct dc_stream_state *stream,
|
||||
struct rect *rect, bool is_stop)
|
||||
{
|
||||
struct dmcu *dmcu;
|
||||
struct dc_dmub_srv *dmub_srv;
|
||||
struct otg_phy_mux mux_mapping;
|
||||
struct pipe_ctx *pipe;
|
||||
int i;
|
||||
struct dc *dc = stream->ctx->dc;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
|
@ -566,7 +572,10 @@ dc_stream_forward_crc_window(struct dc *dc,
|
|||
* once.
|
||||
*
|
||||
* By default, only CRC0 is configured, and the entire frame is used to
|
||||
* calculate the crc.
|
||||
* calculate the CRC.
|
||||
*
|
||||
* Return: %false if the stream is not found or CRC capture is not supported;
|
||||
* %true if the stream has been configured.
|
||||
*/
|
||||
bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
|
||||
struct crc_params *crc_window, bool enable, bool continuous)
|
||||
|
@ -635,7 +644,7 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
|
|||
* dc_stream_configure_crc needs to be called beforehand to enable CRCs.
|
||||
*
|
||||
* Return:
|
||||
* false if stream is not found, or if CRCs are not enabled.
|
||||
* %false if stream is not found, or if CRCs are not enabled.
|
||||
*/
|
||||
bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream,
|
||||
uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
|
||||
|
@ -1740,6 +1749,8 @@ void dc_z10_save_init(struct dc *dc)
|
|||
*
|
||||
* Applies given context to the hardware and copy it into current context.
|
||||
* It's up to the user to release the src context afterwards.
|
||||
*
|
||||
* Return: an enum dc_status result code for the operation
|
||||
*/
|
||||
static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
|
@ -2007,8 +2018,9 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context)
|
|||
return result == DC_OK;
|
||||
}
|
||||
|
||||
if (!streams_changed(dc, context->streams, context->stream_count))
|
||||
if (!streams_changed(dc, context->streams, context->stream_count)) {
|
||||
return DC_OK;
|
||||
}
|
||||
|
||||
DC_LOG_DC("%s: %d streams\n",
|
||||
__func__, context->stream_count);
|
||||
|
@ -3325,6 +3337,7 @@ static void commit_planes_for_stream(struct dc *dc,
|
|||
struct pipe_ctx *top_pipe_to_program = NULL;
|
||||
bool should_lock_all_pipes = (update_type != UPDATE_TYPE_FAST);
|
||||
bool subvp_prev_use = false;
|
||||
bool subvp_curr_use = false;
|
||||
|
||||
// Once we apply the new subvp context to hardware it won't be in the
|
||||
// dc->current_state anymore, so we have to cache it before we apply
|
||||
|
@ -3381,6 +3394,15 @@ static void commit_planes_for_stream(struct dc *dc,
|
|||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
|
||||
subvp_curr_use = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE) {
|
||||
struct pipe_ctx *mpcc_pipe;
|
||||
struct pipe_ctx *odm_pipe;
|
||||
|
@ -3652,42 +3674,22 @@ static void commit_planes_for_stream(struct dc *dc,
|
|||
top_pipe_to_program->stream_res.tg);
|
||||
}
|
||||
|
||||
/* For phantom pipe OTG enable, it has to be done after any previous pipe
|
||||
* that was in use has already been programmed at gotten its double buffer
|
||||
* update for "disable".
|
||||
if (subvp_curr_use) {
|
||||
/* If enabling subvp or transitioning from subvp->subvp, enable the
|
||||
* phantom streams before we program front end for the phantom pipes.
|
||||
*/
|
||||
if (update_type != UPDATE_TYPE_FAST) {
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (dc->hwss.enable_phantom_streams)
|
||||
dc->hwss.enable_phantom_streams(dc, context);
|
||||
}
|
||||
}
|
||||
|
||||
/* If an active, non-phantom pipe is being transitioned into a phantom
|
||||
* pipe, wait for the double buffer update to complete first before we do
|
||||
* ANY phantom pipe programming.
|
||||
if (subvp_prev_use && !subvp_curr_use) {
|
||||
/* If disabling subvp, disable phantom streams after front end
|
||||
* programming has completed (we turn on phantom OTG in order
|
||||
* to complete the plane disable for phantom pipes).
|
||||
*/
|
||||
if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM &&
|
||||
old_pipe->stream && old_pipe->stream->mall_stream_config.type != SUBVP_PHANTOM) {
|
||||
old_pipe->stream_res.tg->funcs->wait_for_state(
|
||||
old_pipe->stream_res.tg,
|
||||
CRTC_STATE_VBLANK);
|
||||
old_pipe->stream_res.tg->funcs->wait_for_state(
|
||||
old_pipe->stream_res.tg,
|
||||
CRTC_STATE_VACTIVE);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if ((new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) ||
|
||||
subvp_prev_use) {
|
||||
// If old context or new context has phantom pipes, apply
|
||||
// the phantom timings now. We can't change the phantom
|
||||
// pipe configuration safely without driver acquiring
|
||||
// the DMCUB lock first.
|
||||
dc->hwss.apply_ctx_to_hw(dc, context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (update_type != UPDATE_TYPE_FAST)
|
||||
|
@ -4704,7 +4706,7 @@ bool dc_enable_dmub_notifications(struct dc *dc)
|
|||
/**
|
||||
* dc_enable_dmub_outbox - Enables DMUB unsolicited notification
|
||||
*
|
||||
* dc: [in] dc structure
|
||||
* @dc: [in] dc structure
|
||||
*
|
||||
* Enables DMUB unsolicited notifications to x86 via outbox.
|
||||
*/
|
||||
|
@ -4905,8 +4907,8 @@ enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc,
|
|||
/**
|
||||
* dc_process_dmub_dpia_hpd_int_enable - Submits DPIA DPD interruption
|
||||
*
|
||||
* @dc [in]: dc structure
|
||||
* @hpd_int_enable [in]: 1 for hpd int enable, 0 to disable
|
||||
* @dc: [in] dc structure
|
||||
* @hpd_int_enable: [in] 1 for hpd int enable, 0 to disable
|
||||
*
|
||||
* Submits dpia hpd int enable command to dmub via inbox message
|
||||
*/
|
||||
|
@ -4987,7 +4989,7 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bo
|
|||
}
|
||||
|
||||
/**
|
||||
* dc_extended_blank_supported 0 Decide whether extended blank is supported
|
||||
* dc_extended_blank_supported - Decide whether extended blank is supported
|
||||
*
|
||||
* @dc: [in] Current DC state
|
||||
*
|
||||
|
@ -4996,7 +4998,7 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bo
|
|||
* ability to enter z9/z10.
|
||||
*
|
||||
* Return:
|
||||
* Indicate whether extended blank is supported (true or false)
|
||||
* Indicate whether extended blank is supported (%true or %false)
|
||||
*/
|
||||
bool dc_extended_blank_supported(struct dc *dc)
|
||||
{
|
||||
|
|
|
@ -1916,12 +1916,6 @@ struct dc_link *link_create(const struct link_init_data *init_params)
|
|||
if (false == dc_link_construct(link, init_params))
|
||||
goto construct_fail;
|
||||
|
||||
/*
|
||||
* Must use preferred_link_setting, not reported_link_cap or verified_link_cap,
|
||||
* since struct preferred_link_setting won't be reset after S3.
|
||||
*/
|
||||
link->preferred_link_setting.dpcd_source_device_specific_field_support = true;
|
||||
|
||||
return link;
|
||||
|
||||
construct_fail:
|
||||
|
@ -4655,9 +4649,6 @@ void dc_link_set_preferred_training_settings(struct dc *dc,
|
|||
|
||||
if (link_setting != NULL) {
|
||||
link->preferred_link_setting = *link_setting;
|
||||
if (dp_get_link_encoding_format(link_setting) == DP_128b_132b_ENCODING)
|
||||
/* TODO: add dc update for acquiring link res */
|
||||
skip_immediate_retrain = true;
|
||||
} else {
|
||||
link->preferred_link_setting.lane_count = LANE_COUNT_UNKNOWN;
|
||||
link->preferred_link_setting.link_rate = LINK_RATE_UNKNOWN;
|
||||
|
|
|
@ -82,7 +82,6 @@ struct dp_hdmi_dongle_signature_data {
|
|||
#define HDMI_SCDC_STATUS_FLAGS 0x40
|
||||
#define HDMI_SCDC_ERR_DETECT 0x50
|
||||
#define HDMI_SCDC_TEST_CONFIG 0xC0
|
||||
#define HDMI_SCDC_DEVICE_ID 0xD3
|
||||
|
||||
union hdmi_scdc_update_read_data {
|
||||
uint8_t byte[2];
|
||||
|
|
|
@ -4094,6 +4094,12 @@ static void dp_test_send_link_training(struct dc_link *link)
|
|||
dp_retrain_link_dp_test(link, &link_settings, false);
|
||||
}
|
||||
|
||||
static bool is_dp_phy_sqaure_pattern(enum dp_test_pattern test_pattern)
|
||||
{
|
||||
return (DP_TEST_PATTERN_SQUARE_BEGIN <= test_pattern &&
|
||||
test_pattern <= DP_TEST_PATTERN_SQUARE_END);
|
||||
}
|
||||
|
||||
/* TODO Raven hbr2 compliance eye output is unstable
|
||||
* (toggling on and off) with debugger break
|
||||
* This caueses intermittent PHY automation failure
|
||||
|
@ -4111,6 +4117,8 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
|
|||
union lane_adjust dpcd_lane_adjust;
|
||||
unsigned int lane;
|
||||
struct link_training_settings link_training_settings;
|
||||
unsigned char no_preshoot = 0;
|
||||
unsigned char no_deemphasis = 0;
|
||||
|
||||
dpcd_test_pattern.raw = 0;
|
||||
memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment));
|
||||
|
@ -4204,8 +4212,21 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
|
|||
case PHY_TEST_PATTERN_264BIT_CUSTOM:
|
||||
test_pattern = DP_TEST_PATTERN_264BIT_CUSTOM;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_SQUARE_PULSE:
|
||||
test_pattern = DP_TEST_PATTERN_SQUARE_PULSE;
|
||||
case PHY_TEST_PATTERN_SQUARE:
|
||||
test_pattern = DP_TEST_PATTERN_SQUARE;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED:
|
||||
test_pattern = DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED;
|
||||
no_preshoot = 1;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED:
|
||||
test_pattern = DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED;
|
||||
no_deemphasis = 1;
|
||||
break;
|
||||
case PHY_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED:
|
||||
test_pattern = DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED;
|
||||
no_preshoot = 1;
|
||||
no_deemphasis = 1;
|
||||
break;
|
||||
default:
|
||||
test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
|
||||
|
@ -4222,7 +4243,7 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
|
|||
test_pattern_size);
|
||||
}
|
||||
|
||||
if (test_pattern == DP_TEST_PATTERN_SQUARE_PULSE) {
|
||||
if (is_dp_phy_sqaure_pattern(test_pattern)) {
|
||||
test_pattern_size = 1; // Square pattern data is 1 byte (DP spec)
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
|
@ -4259,8 +4280,10 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
|
|||
((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
|
||||
} else if (dp_get_link_encoding_format(&link->cur_link_settings) ==
|
||||
DP_128b_132b_ENCODING) {
|
||||
link_training_settings.hw_lane_settings[lane].FFE_PRESET.raw =
|
||||
link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.level =
|
||||
dpcd_lane_adjust.tx_ffe.PRESET_VALUE;
|
||||
link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.no_preshoot = no_preshoot;
|
||||
link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.no_deemphasis = no_deemphasis;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6114,7 +6137,7 @@ bool dc_link_dp_set_test_pattern(
|
|||
* MuteAudioEndpoint(pPathMode->pDisplayPath, true);
|
||||
*/
|
||||
/* Blank stream */
|
||||
pipes->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc);
|
||||
link->dc->hwss.blank_stream(pipe_ctx);
|
||||
}
|
||||
|
||||
dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern,
|
||||
|
@ -6178,8 +6201,17 @@ bool dc_link_dp_set_test_pattern(
|
|||
case DP_TEST_PATTERN_264BIT_CUSTOM:
|
||||
pattern = PHY_TEST_PATTERN_264BIT_CUSTOM;
|
||||
break;
|
||||
case DP_TEST_PATTERN_SQUARE_PULSE:
|
||||
pattern = PHY_TEST_PATTERN_SQUARE_PULSE;
|
||||
case DP_TEST_PATTERN_SQUARE:
|
||||
pattern = PHY_TEST_PATTERN_SQUARE;
|
||||
break;
|
||||
case DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED:
|
||||
pattern = PHY_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED;
|
||||
break;
|
||||
case DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED:
|
||||
pattern = PHY_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED;
|
||||
break;
|
||||
case DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED:
|
||||
pattern = PHY_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
@ -6190,14 +6222,12 @@ bool dc_link_dp_set_test_pattern(
|
|||
return false;
|
||||
|
||||
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (test_pattern == DP_TEST_PATTERN_SQUARE_PULSE)
|
||||
if (is_dp_phy_sqaure_pattern(test_pattern))
|
||||
core_link_write_dpcd(link,
|
||||
DP_LINK_SQUARE_PATTERN,
|
||||
p_custom_pattern,
|
||||
1);
|
||||
|
||||
#endif
|
||||
/* tell receiver that we are sending qualification
|
||||
* pattern DP 1.2 or later - DP receiver's link quality
|
||||
* pattern is set using DPCD LINK_QUAL_LANEx_SET
|
||||
|
@ -6554,18 +6584,10 @@ void dpcd_set_source_specific_data(struct dc_link *link)
|
|||
|
||||
uint8_t hblank_size = (uint8_t)link->dc->caps.min_horizontal_blanking_period;
|
||||
|
||||
if (link->preferred_link_setting.dpcd_source_device_specific_field_support) {
|
||||
result_write_min_hblank = core_link_write_dpcd(link,
|
||||
DP_SOURCE_MINIMUM_HBLANK_SUPPORTED, (uint8_t *)(&hblank_size),
|
||||
sizeof(hblank_size));
|
||||
|
||||
if (result_write_min_hblank == DC_ERROR_UNEXPECTED)
|
||||
link->preferred_link_setting.dpcd_source_device_specific_field_support = false;
|
||||
} else {
|
||||
DC_LOG_DC("Sink device does not support 00340h DPCD write. Skipping on purpose.\n");
|
||||
}
|
||||
}
|
||||
|
||||
DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION,
|
||||
WPP_BIT_FLAG_DC_DETECTION_DP_CAPS,
|
||||
"result=%u link_index=%u enum dce_version=%d DPCD=0x%04X min_hblank=%u branch_dev_id=0x%x branch_dev_name='%c%c%c%c%c%c'",
|
||||
|
@ -7254,59 +7276,35 @@ void dp_retrain_link_dp_test(struct dc_link *link,
|
|||
struct dc_link_settings *link_setting,
|
||||
bool skip_video_pattern)
|
||||
{
|
||||
struct pipe_ctx *pipes =
|
||||
&link->dc->current_state->res_ctx.pipe_ctx[0];
|
||||
struct pipe_ctx *pipe;
|
||||
unsigned int i;
|
||||
bool do_fallback = false;
|
||||
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
if (pipes[i].stream != NULL &&
|
||||
!pipes[i].top_pipe && !pipes[i].prev_odm_pipe &&
|
||||
pipes[i].stream->link != NULL &&
|
||||
pipes[i].stream_res.stream_enc != NULL &&
|
||||
pipes[i].stream->link == link) {
|
||||
udelay(100);
|
||||
|
||||
pipes[i].stream_res.stream_enc->funcs->dp_blank(link,
|
||||
pipes[i].stream_res.stream_enc);
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe->stream != NULL &&
|
||||
pipe->stream->link == link &&
|
||||
!pipe->stream->dpms_off &&
|
||||
!pipe->top_pipe && !pipe->prev_odm_pipe) {
|
||||
core_link_disable_stream(pipe);
|
||||
pipe->link_config.dp_link_settings = *link_setting;
|
||||
update_dp_encoder_resources_for_test_harness(
|
||||
link->dc,
|
||||
pipe->stream->ctx->dc->current_state,
|
||||
pipe);
|
||||
}
|
||||
}
|
||||
|
||||
/* disable any test pattern that might be active */
|
||||
dp_set_hw_test_pattern(link, &pipes[i].link_res,
|
||||
DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
|
||||
|
||||
dp_receiver_power_ctrl(link, false);
|
||||
|
||||
link->dc->hwss.disable_stream(&pipes[i]);
|
||||
if ((&pipes[i])->stream_res.audio && !link->dc->debug.az_endpoint_mute_only)
|
||||
(&pipes[i])->stream_res.audio->funcs->az_disable((&pipes[i])->stream_res.audio);
|
||||
|
||||
if (link->link_enc)
|
||||
link->link_enc->funcs->disable_output(
|
||||
link->link_enc,
|
||||
SIGNAL_TYPE_DISPLAY_PORT);
|
||||
|
||||
/* Clear current link setting. */
|
||||
memset(&link->cur_link_settings, 0,
|
||||
sizeof(link->cur_link_settings));
|
||||
|
||||
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
|
||||
do_fallback = true;
|
||||
|
||||
perform_link_training_with_retries(
|
||||
link_setting,
|
||||
skip_video_pattern,
|
||||
LINK_TRAINING_ATTEMPTS,
|
||||
&pipes[i],
|
||||
SIGNAL_TYPE_DISPLAY_PORT,
|
||||
do_fallback);
|
||||
|
||||
link->dc->hwss.enable_stream(&pipes[i]);
|
||||
|
||||
link->dc->hwss.unblank_stream(&pipes[i],
|
||||
link_setting);
|
||||
|
||||
link->dc->hwss.enable_audio_stream(&pipes[i]);
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe->stream != NULL &&
|
||||
pipe->stream->link == link &&
|
||||
!pipe->stream->dpms_off &&
|
||||
!pipe->top_pipe && !pipe->prev_odm_pipe) {
|
||||
core_link_enable_stream(
|
||||
pipe->stream->ctx->dc->current_state,
|
||||
pipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7496,7 +7494,6 @@ bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_u
|
|||
dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
|
||||
dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
|
||||
|
||||
DC_LOG_DSC(" ");
|
||||
dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]);
|
||||
memcpy(&stream->dsc_packed_pps[0], &dsc_packed_pps[0], sizeof(stream->dsc_packed_pps));
|
||||
if (dc_is_dp_signal(stream->signal)) {
|
||||
|
|
|
@ -3810,6 +3810,8 @@ void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc,
|
|||
int i;
|
||||
struct pipe_ctx *pipe_ctx, *pipe_ctx_check;
|
||||
|
||||
DC_LOGGER_INIT(dc->ctx->logger);
|
||||
|
||||
pipe_ctx = &context->res_ctx.pipe_ctx[disabled_master_pipe_idx];
|
||||
if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx) != disabled_master_pipe_idx) ||
|
||||
!IS_PIPE_SYNCD_VALID(pipe_ctx))
|
||||
|
@ -3820,10 +3822,17 @@ void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc,
|
|||
pipe_ctx_check = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx_check) == disabled_master_pipe_idx) &&
|
||||
IS_PIPE_SYNCD_VALID(pipe_ctx_check) && (i != disabled_master_pipe_idx))
|
||||
IS_PIPE_SYNCD_VALID(pipe_ctx_check) && (i != disabled_master_pipe_idx)) {
|
||||
/* On dcn32, this error isn't fatal since hw supports odm transition in fast update*/
|
||||
if (dc->ctx->dce_version == DCN_VERSION_3_2 ||
|
||||
dc->ctx->dce_version == DCN_VERSION_3_21)
|
||||
DC_LOG_DEBUG("DC: pipe_idx[%d] syncd with disabled master pipe_idx[%d]\n",
|
||||
i, disabled_master_pipe_idx);
|
||||
else
|
||||
DC_ERR("DC: Failure: pipe_idx[%d] syncd with disabled master pipe_idx[%d]\n",
|
||||
i, disabled_master_pipe_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void reset_sync_context_for_pipe(const struct dc *dc,
|
||||
|
@ -3981,3 +3990,42 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm(
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,
|
||||
struct dc_state *context,
|
||||
struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
if (dp_get_link_encoding_format(&pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) {
|
||||
if (pipe_ctx->stream_res.hpo_dp_stream_enc == NULL) {
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc =
|
||||
find_first_free_match_hpo_dp_stream_enc_for_link(
|
||||
&context->res_ctx, dc->res_pool, pipe_ctx->stream);
|
||||
|
||||
if (!pipe_ctx->stream_res.hpo_dp_stream_enc)
|
||||
return DC_NO_STREAM_ENC_RESOURCE;
|
||||
|
||||
update_hpo_dp_stream_engine_usage(
|
||||
&context->res_ctx, dc->res_pool,
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
true);
|
||||
}
|
||||
|
||||
if (pipe_ctx->link_res.hpo_dp_link_enc == NULL) {
|
||||
if (!add_hpo_dp_link_enc_to_ctx(&context->res_ctx, dc->res_pool, pipe_ctx, pipe_ctx->stream))
|
||||
return DC_NO_LINK_ENC_RESOURCE;
|
||||
}
|
||||
} else {
|
||||
if (pipe_ctx->stream_res.hpo_dp_stream_enc) {
|
||||
update_hpo_dp_stream_engine_usage(
|
||||
&context->res_ctx, dc->res_pool,
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
false);
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc = NULL;
|
||||
}
|
||||
if (pipe_ctx->link_res.hpo_dp_link_enc)
|
||||
remove_hpo_dp_link_enc_from_ctx(&context->res_ctx, pipe_ctx, pipe_ctx->stream);
|
||||
}
|
||||
|
||||
return DC_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification
|
|||
/* For HPD/HPD RX, convert dpia port index into link index */
|
||||
if (notify->type == DMUB_NOTIFICATION_HPD ||
|
||||
notify->type == DMUB_NOTIFICATION_HPD_IRQ ||
|
||||
notify->type == DMUB_NOTIFICATION_DPIA_NOTIFICATION ||
|
||||
notify->type == DMUB_NOTIFICATION_SET_CONFIG_REPLY) {
|
||||
notify->link_index =
|
||||
get_link_index_from_dpia_port_index(dc, notify->link_index);
|
||||
|
|
|
@ -481,6 +481,7 @@ bool dc_stream_add_writeback(struct dc *dc,
|
|||
}
|
||||
|
||||
if (!isDrc) {
|
||||
ASSERT(stream->num_wb_info + 1 <= MAX_DWB_PIPES);
|
||||
stream->writeback_info[stream->num_wb_info++] = *wb_info;
|
||||
}
|
||||
|
||||
|
@ -526,6 +527,11 @@ bool dc_stream_remove_writeback(struct dc *dc,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (stream->num_wb_info > MAX_DWB_PIPES) {
|
||||
dm_error("DC: num_wb_info is invalid!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// stream->writeback_info[dwb_pipe_inst].wb_enabled = false;
|
||||
for (i = 0; i < stream->num_wb_info; i++) {
|
||||
/*dynamic update*/
|
||||
|
@ -540,7 +546,8 @@ bool dc_stream_remove_writeback(struct dc *dc,
|
|||
if (stream->writeback_info[i].wb_enabled) {
|
||||
if (j < i)
|
||||
/* trim the array */
|
||||
stream->writeback_info[j] = stream->writeback_info[i];
|
||||
memcpy(&stream->writeback_info[j], &stream->writeback_info[i],
|
||||
sizeof(struct dc_writeback_info));
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ struct aux_payload;
|
|||
struct set_config_cmd_payload;
|
||||
struct dmub_notification;
|
||||
|
||||
#define DC_VER "3.2.215"
|
||||
#define DC_VER "3.2.217"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
|
@ -872,6 +872,7 @@ struct dc_debug_options {
|
|||
enum lttpr_mode lttpr_mode_override;
|
||||
unsigned int dsc_delay_factor_wa_x1000;
|
||||
unsigned int min_prefetch_in_strobe_ns;
|
||||
bool disable_unbounded_requesting;
|
||||
};
|
||||
|
||||
struct gpu_info_soc_bounding_box_v1_0;
|
||||
|
|
|
@ -149,7 +149,6 @@ struct dc_link_settings {
|
|||
enum dc_link_spread link_spread;
|
||||
bool use_link_rate_set;
|
||||
uint8_t link_rate_set;
|
||||
bool dpcd_source_device_specific_field_support;
|
||||
};
|
||||
|
||||
union dc_dp_ffe_preset {
|
||||
|
@ -926,6 +925,9 @@ struct dpcd_usb4_dp_tunneling_info {
|
|||
#ifndef DP_128b_132b_TRAINING_AUX_RD_INTERVAL
|
||||
#define DP_128b_132b_TRAINING_AUX_RD_INTERVAL 0x2216
|
||||
#endif
|
||||
#ifndef DP_LINK_SQUARE_PATTERN
|
||||
#define DP_LINK_SQUARE_PATTERN 0x10F
|
||||
#endif
|
||||
#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX
|
||||
#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX 0x2217
|
||||
#endif
|
||||
|
|
|
@ -335,15 +335,18 @@ static inline bool dc_get_edp_link_panel_inst(const struct dc *dc,
|
|||
unsigned int *inst_out)
|
||||
{
|
||||
struct dc_link *edp_links[MAX_NUM_EDP];
|
||||
int edp_num;
|
||||
int edp_num, i;
|
||||
|
||||
if (link->connector_signal != SIGNAL_TYPE_EDP)
|
||||
*inst_out = 0;
|
||||
if (link->connector_signal != SIGNAL_TYPE_EDP || !link->local_sink)
|
||||
return false;
|
||||
get_edp_links(dc, edp_links, &edp_num);
|
||||
if ((edp_num > 1) && (link->link_index > edp_links[0]->link_index))
|
||||
*inst_out = 1;
|
||||
else
|
||||
*inst_out = 0;
|
||||
for (i = 0; i < edp_num; i++) {
|
||||
if (link == edp_links[i])
|
||||
break;
|
||||
if (edp_links[i]->local_sink)
|
||||
(*inst_out)++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -543,9 +543,8 @@ bool dc_stream_get_crtc_position(struct dc *dc,
|
|||
unsigned int *nom_v_pos);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
bool dc_stream_forward_crc_window(struct dc *dc,
|
||||
bool dc_stream_forward_crc_window(struct dc_stream_state *stream,
|
||||
struct rect *rect,
|
||||
struct dc_stream_state *stream,
|
||||
bool is_stop);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1142,6 +1142,10 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
|
|||
struct dc_link *link = stream->link;
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
|
||||
struct dccg *dccg = dc->res_pool->dccg;
|
||||
struct timing_generator *tg = pipe_ctx->stream_res.tg;
|
||||
struct dtbclk_dto_params dto_params = {0};
|
||||
int dp_hpo_inst;
|
||||
|
||||
if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) {
|
||||
pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets(
|
||||
|
@ -1161,6 +1165,15 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
|
|||
|
||||
link_hwss->reset_stream_encoder(pipe_ctx);
|
||||
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
dto_params.otg_inst = tg->inst;
|
||||
dto_params.timing = &pipe_ctx->stream->timing;
|
||||
dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
|
||||
dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
|
||||
dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst);
|
||||
dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst);
|
||||
}
|
||||
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
/* TODO: This looks like a bug to me as we are disabling HPO IO when
|
||||
* we are just disabling a single HPO stream. Shouldn't we disable HPO
|
||||
|
|
|
@ -200,7 +200,6 @@ static void dsc2_set_config(struct display_stream_compressor *dsc, const struct
|
|||
bool is_config_ok;
|
||||
struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc);
|
||||
|
||||
DC_LOG_DSC(" ");
|
||||
DC_LOG_DSC("Setting DSC Config at DSC inst %d", dsc->inst);
|
||||
dsc_config_log(dsc, dsc_cfg);
|
||||
is_config_ok = dsc_prepare_config(dsc_cfg, &dsc20->reg_vals, dsc_optc_cfg);
|
||||
|
|
|
@ -582,6 +582,9 @@ void dcn20_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
|||
if (pipe_ctx->stream_res.gsl_group != 0)
|
||||
dcn20_setup_gsl_group_as_lock(dc, pipe_ctx, false);
|
||||
|
||||
if (hubp->funcs->hubp_update_mall_sel)
|
||||
hubp->funcs->hubp_update_mall_sel(hubp, 0, false);
|
||||
|
||||
dc->hwss.set_flip_control_gsl(pipe_ctx, false);
|
||||
|
||||
hubp->funcs->hubp_clk_cntl(hubp, false);
|
||||
|
@ -605,6 +608,9 @@ void dcn20_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
|||
|
||||
void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
bool is_phantom = pipe_ctx->plane_state && pipe_ctx->plane_state->is_phantom;
|
||||
struct timing_generator *tg = is_phantom ? pipe_ctx->stream_res.tg : NULL;
|
||||
|
||||
DC_LOGGER_INIT(dc->ctx->logger);
|
||||
|
||||
if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated)
|
||||
|
@ -612,6 +618,12 @@ void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
|||
|
||||
dcn20_plane_atomic_disable(dc, pipe_ctx);
|
||||
|
||||
/* Turn back off the phantom OTG after the phantom plane is fully disabled
|
||||
*/
|
||||
if (is_phantom)
|
||||
if (tg && tg->funcs->disable_phantom_crtc)
|
||||
tg->funcs->disable_phantom_crtc(tg);
|
||||
|
||||
DC_LOG_DC("Power down front end %d\n",
|
||||
pipe_ctx->pipe_idx);
|
||||
}
|
||||
|
@ -1803,6 +1815,18 @@ void dcn20_program_front_end_for_ctx(
|
|||
dcn20_detect_pipe_changes(&dc->current_state->res_ctx.pipe_ctx[i],
|
||||
&context->res_ctx.pipe_ctx[i]);
|
||||
|
||||
/* When disabling phantom pipes, turn on phantom OTG first (so we can get double
|
||||
* buffer updates properly)
|
||||
*/
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||
if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable
|
||||
&& dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) {
|
||||
struct timing_generator *tg = dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg;
|
||||
|
||||
if (tg->funcs->enable_crtc)
|
||||
tg->funcs->enable_crtc(tg);
|
||||
}
|
||||
|
||||
/* OTG blank before disabling all front ends */
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||
if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable
|
||||
|
@ -2615,6 +2639,37 @@ void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
|||
hubp->mpcc_id = mpcc_id;
|
||||
}
|
||||
|
||||
static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link)
|
||||
{
|
||||
switch (link->link_enc->transmitter) {
|
||||
case TRANSMITTER_UNIPHY_A:
|
||||
return PHYD32CLKA;
|
||||
case TRANSMITTER_UNIPHY_B:
|
||||
return PHYD32CLKB;
|
||||
case TRANSMITTER_UNIPHY_C:
|
||||
return PHYD32CLKC;
|
||||
case TRANSMITTER_UNIPHY_D:
|
||||
return PHYD32CLKD;
|
||||
case TRANSMITTER_UNIPHY_E:
|
||||
return PHYD32CLKE;
|
||||
default:
|
||||
return PHYD32CLKA;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_odm_segment_count(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
|
||||
int count = 1;
|
||||
|
||||
while (odm_pipe != NULL) {
|
||||
count++;
|
||||
odm_pipe = odm_pipe->next_odm_pipe;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
enum dc_lane_count lane_count =
|
||||
|
@ -2628,12 +2683,43 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
|
|||
struct timing_generator *tg = pipe_ctx->stream_res.tg;
|
||||
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
struct dtbclk_dto_params dto_params = {0};
|
||||
struct dccg *dccg = dc->res_pool->dccg;
|
||||
enum phyd32clk_clock_source phyd32clk;
|
||||
int dp_hpo_inst;
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
unsigned int k1_div = PIXEL_RATE_DIV_NA;
|
||||
unsigned int k2_div = PIXEL_RATE_DIV_NA;
|
||||
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
if (dc->hwseq->funcs.setup_hpo_hw_control)
|
||||
dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, true);
|
||||
}
|
||||
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
|
||||
dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, dp_hpo_inst);
|
||||
|
||||
phyd32clk = get_phyd32clk_src(link);
|
||||
dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
|
||||
|
||||
dto_params.otg_inst = tg->inst;
|
||||
dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10;
|
||||
dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx);
|
||||
dto_params.timing = &pipe_ctx->stream->timing;
|
||||
dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr);
|
||||
dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
|
||||
}
|
||||
|
||||
if (hws->funcs.calculate_dccg_k1_k2_values && dc->res_pool->dccg->funcs->set_pixel_rate_div) {
|
||||
hws->funcs.calculate_dccg_k1_k2_values(pipe_ctx, &k1_div, &k2_div);
|
||||
|
||||
dc->res_pool->dccg->funcs->set_pixel_rate_div(
|
||||
dc->res_pool->dccg,
|
||||
pipe_ctx->stream_res.tg->inst,
|
||||
k1_div, k2_div);
|
||||
}
|
||||
|
||||
link_hwss->setup_stream_encoder(pipe_ctx);
|
||||
|
||||
if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) {
|
||||
|
|
|
@ -1389,6 +1389,9 @@ enum dc_status dcn20_add_dsc_to_stream_resource(struct dc *dc,
|
|||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe_ctx = &dc_ctx->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (pipe_ctx->top_pipe)
|
||||
continue;
|
||||
|
||||
if (pipe_ctx->stream != dc_stream)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -1414,7 +1414,8 @@ static struct resource_funcs dcn301_res_pool_funcs = {
|
|||
.find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
|
||||
.acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut,
|
||||
.release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,
|
||||
.update_bw_bounding_box = dcn301_update_bw_bounding_box
|
||||
.update_bw_bounding_box = dcn301_update_bw_bounding_box,
|
||||
.patch_unknown_plane_state = dcn20_patch_unknown_plane_state
|
||||
};
|
||||
|
||||
static bool dcn301_resource_construct(
|
||||
|
|
|
@ -242,7 +242,10 @@ void dcn31_hpo_dp_link_enc_set_link_test_pattern(
|
|||
REG_UPDATE(DP_DPHY_SYM32_CONTROL,
|
||||
MODE, DP2_TEST_PATTERN);
|
||||
break;
|
||||
case DP_TEST_PATTERN_SQUARE_PULSE:
|
||||
case DP_TEST_PATTERN_SQUARE:
|
||||
case DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED:
|
||||
case DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED:
|
||||
case DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED:
|
||||
REG_SET(DP_DPHY_SYM32_TP_SQ_PULSE, 0,
|
||||
TP_SQ_PULSE_WIDTH, tp_params->custom_pattern[0]);
|
||||
|
||||
|
|
|
@ -623,43 +623,3 @@ void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable)
|
|||
if (hws->ctx->dc->debug.hpo_optimization)
|
||||
REG_UPDATE(HPO_TOP_HW_CONTROL, HPO_IO_EN, !!enable);
|
||||
}
|
||||
void dcn31_set_drr(struct pipe_ctx **pipe_ctx,
|
||||
int num_pipes, struct dc_crtc_timing_adjust adjust)
|
||||
{
|
||||
int i = 0;
|
||||
struct drr_params params = {0};
|
||||
unsigned int event_triggers = 0x2;/*Bit[1]: OTG_TRIG_A*/
|
||||
unsigned int num_frames = 2;
|
||||
params.vertical_total_max = adjust.v_total_max;
|
||||
params.vertical_total_min = adjust.v_total_min;
|
||||
params.vertical_total_mid = adjust.v_total_mid;
|
||||
params.vertical_total_mid_frame_num = adjust.v_total_mid_frame_num;
|
||||
for (i = 0; i < num_pipes; i++) {
|
||||
if ((pipe_ctx[i]->stream_res.tg != NULL) && pipe_ctx[i]->stream_res.tg->funcs) {
|
||||
if (pipe_ctx[i]->stream_res.tg->funcs->set_drr)
|
||||
pipe_ctx[i]->stream_res.tg->funcs->set_drr(
|
||||
pipe_ctx[i]->stream_res.tg, ¶ms);
|
||||
if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
|
||||
if (pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control)
|
||||
pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
|
||||
pipe_ctx[i]->stream_res.tg,
|
||||
event_triggers, num_frames);
|
||||
}
|
||||
}
|
||||
}
|
||||
void dcn31_set_static_screen_control(struct pipe_ctx **pipe_ctx,
|
||||
int num_pipes, const struct dc_static_screen_params *params)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int triggers = 0;
|
||||
if (params->triggers.surface_update)
|
||||
triggers |= 0x600;/*bit 9 and bit10 : 110 0000 0000*/
|
||||
if (params->triggers.cursor_update)
|
||||
triggers |= 0x10;/*bit4*/
|
||||
if (params->triggers.force_trigger)
|
||||
triggers |= 0x1;
|
||||
for (i = 0; i < num_pipes; i++)
|
||||
pipe_ctx[i]->stream_res.tg->funcs->
|
||||
set_static_screen_control(pipe_ctx[i]->stream_res.tg,
|
||||
triggers, params->num_frames);
|
||||
}
|
||||
|
|
|
@ -56,8 +56,4 @@ bool dcn31_is_abm_supported(struct dc *dc,
|
|||
void dcn31_init_pipes(struct dc *dc, struct dc_state *context);
|
||||
void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable);
|
||||
|
||||
void dcn31_set_static_screen_control(struct pipe_ctx **pipe_ctx,
|
||||
int num_pipes, const struct dc_static_screen_params *params);
|
||||
void dcn31_set_drr(struct pipe_ctx **pipe_ctx,
|
||||
int num_pipes, struct dc_crtc_timing_adjust adjust);
|
||||
#endif /* __DC_HWSS_DCN31_H__ */
|
||||
|
|
|
@ -64,9 +64,9 @@ static const struct hw_sequencer_funcs dcn31_funcs = {
|
|||
.prepare_bandwidth = dcn20_prepare_bandwidth,
|
||||
.optimize_bandwidth = dcn20_optimize_bandwidth,
|
||||
.update_bandwidth = dcn20_update_bandwidth,
|
||||
.set_drr = dcn31_set_drr,
|
||||
.set_drr = dcn10_set_drr,
|
||||
.get_position = dcn10_get_position,
|
||||
.set_static_screen_control = dcn31_set_static_screen_control,
|
||||
.set_static_screen_control = dcn10_set_static_screen_control,
|
||||
.setup_stereo = dcn10_setup_stereo,
|
||||
.set_avmute = dcn30_set_avmute,
|
||||
.log_hw_state = dcn10_log_hw_state,
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#define FN(reg_name, field_name) \
|
||||
optc1->tg_shift->field_name, optc1->tg_mask->field_name
|
||||
|
||||
#define STATIC_SCREEN_EVENT_MASK_DRR_DOUBLE_BUFFER_UPDATE_EN 0x2000 /*bit 13*/
|
||||
static void optc31_set_odm_combine(struct timing_generator *optc, int *opp_id, int opp_cnt,
|
||||
struct dc_crtc_timing *timing)
|
||||
{
|
||||
|
@ -232,32 +231,6 @@ void optc3_init_odm(struct timing_generator *optc)
|
|||
OPTC_MEM_SEL, 0);
|
||||
optc1->opp_count = 1;
|
||||
}
|
||||
void optc31_set_static_screen_control(
|
||||
struct timing_generator *optc,
|
||||
uint32_t event_triggers,
|
||||
uint32_t num_frames)
|
||||
{
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
uint32_t framecount;
|
||||
uint32_t events;
|
||||
|
||||
if (num_frames > 0xFF)
|
||||
num_frames = 0xFF;
|
||||
REG_GET_2(OTG_STATIC_SCREEN_CONTROL,
|
||||
OTG_STATIC_SCREEN_EVENT_MASK, &events,
|
||||
OTG_STATIC_SCREEN_FRAME_COUNT, &framecount);
|
||||
|
||||
if (events == event_triggers && num_frames == framecount)
|
||||
return;
|
||||
if ((event_triggers & STATIC_SCREEN_EVENT_MASK_DRR_DOUBLE_BUFFER_UPDATE_EN)
|
||||
!= 0)
|
||||
event_triggers = event_triggers &
|
||||
~STATIC_SCREEN_EVENT_MASK_DRR_DOUBLE_BUFFER_UPDATE_EN;
|
||||
|
||||
REG_UPDATE_2(OTG_STATIC_SCREEN_CONTROL,
|
||||
OTG_STATIC_SCREEN_EVENT_MASK, event_triggers,
|
||||
OTG_STATIC_SCREEN_FRAME_COUNT, num_frames);
|
||||
}
|
||||
|
||||
static struct timing_generator_funcs dcn31_tg_funcs = {
|
||||
.validate_timing = optc1_validate_timing,
|
||||
|
@ -293,7 +266,7 @@ static struct timing_generator_funcs dcn31_tg_funcs = {
|
|||
.set_drr = optc31_set_drr,
|
||||
.get_last_used_drr_vtotal = optc2_get_last_used_drr_vtotal,
|
||||
.set_vtotal_min_max = optc1_set_vtotal_min_max,
|
||||
.set_static_screen_control = optc31_set_static_screen_control,
|
||||
.set_static_screen_control = optc1_set_static_screen_control,
|
||||
.program_stereo = optc1_program_stereo,
|
||||
.is_stereo_left_eye = optc1_is_stereo_left_eye,
|
||||
.tg_init = optc3_tg_init,
|
||||
|
|
|
@ -263,8 +263,5 @@ bool optc31_immediate_disable_crtc(struct timing_generator *optc);
|
|||
void optc31_set_drr(struct timing_generator *optc, const struct drr_params *params);
|
||||
|
||||
void optc3_init_odm(struct timing_generator *optc);
|
||||
void optc31_set_static_screen_control(
|
||||
struct timing_generator *optc,
|
||||
uint32_t event_triggers,
|
||||
uint32_t num_frames);
|
||||
|
||||
#endif /* __DC_OPTC_DCN31_H__ */
|
||||
|
|
|
@ -278,10 +278,10 @@ static void enc314_stream_encoder_dp_blank(
|
|||
struct dc_link *link,
|
||||
struct stream_encoder *enc)
|
||||
{
|
||||
/* New to DCN314 - disable the FIFO before VID stream disable. */
|
||||
enc314_disable_fifo(enc);
|
||||
|
||||
enc1_stream_encoder_dp_blank(link, enc);
|
||||
|
||||
/* Disable FIFO after the DP vid stream is disabled to avoid corruption. */
|
||||
enc314_disable_fifo(enc);
|
||||
}
|
||||
|
||||
static void enc314_stream_encoder_dp_unblank(
|
||||
|
|
|
@ -66,9 +66,9 @@ static const struct hw_sequencer_funcs dcn314_funcs = {
|
|||
.prepare_bandwidth = dcn20_prepare_bandwidth,
|
||||
.optimize_bandwidth = dcn20_optimize_bandwidth,
|
||||
.update_bandwidth = dcn20_update_bandwidth,
|
||||
.set_drr = dcn31_set_drr,
|
||||
.set_drr = dcn10_set_drr,
|
||||
.get_position = dcn10_get_position,
|
||||
.set_static_screen_control = dcn31_set_static_screen_control,
|
||||
.set_static_screen_control = dcn10_set_static_screen_control,
|
||||
.setup_stereo = dcn10_setup_stereo,
|
||||
.set_avmute = dcn30_set_avmute,
|
||||
.log_hw_state = dcn10_log_hw_state,
|
||||
|
|
|
@ -228,7 +228,7 @@ static struct timing_generator_funcs dcn314_tg_funcs = {
|
|||
.set_drr = optc31_set_drr,
|
||||
.get_last_used_drr_vtotal = optc2_get_last_used_drr_vtotal,
|
||||
.set_vtotal_min_max = optc1_set_vtotal_min_max,
|
||||
.set_static_screen_control = optc31_set_static_screen_control,
|
||||
.set_static_screen_control = optc1_set_static_screen_control,
|
||||
.program_stereo = optc1_program_stereo,
|
||||
.is_stereo_left_eye = optc1_is_stereo_left_eye,
|
||||
.tg_init = optc3_tg_init,
|
||||
|
@ -241,7 +241,6 @@ static struct timing_generator_funcs dcn314_tg_funcs = {
|
|||
.set_dsc_config = optc3_set_dsc_config,
|
||||
.get_dsc_status = optc2_get_dsc_status,
|
||||
.set_dwb_source = NULL,
|
||||
.set_odm_combine = optc314_set_odm_combine,
|
||||
.get_optc_source = optc2_get_optc_source,
|
||||
.set_out_mux = optc3_set_out_mux,
|
||||
.set_drr_trigger_window = optc3_set_drr_trigger_window,
|
||||
|
|
|
@ -188,7 +188,8 @@ static bool dcn32_check_no_memory_request_for_cab(struct dc *dc)
|
|||
|
||||
/* First, check no-memory-request case */
|
||||
for (i = 0; i < dc->current_state->stream_count; i++) {
|
||||
if (dc->current_state->stream_status[i].plane_count)
|
||||
if ((dc->current_state->stream_status[i].plane_count) &&
|
||||
(dc->current_state->streams[i]->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED))
|
||||
/* Fail eligibility on a visible stream */
|
||||
break;
|
||||
}
|
||||
|
@ -1450,3 +1451,39 @@ void dcn32_update_dsc_pg(struct dc *dc,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
|
||||
/* If an active, non-phantom pipe is being transitioned into a phantom
|
||||
* pipe, wait for the double buffer update to complete first before we do
|
||||
* ANY phantom pipe programming.
|
||||
*/
|
||||
if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM &&
|
||||
old_pipe->stream && old_pipe->stream->mall_stream_config.type != SUBVP_PHANTOM) {
|
||||
old_pipe->stream_res.tg->funcs->wait_for_state(
|
||||
old_pipe->stream_res.tg,
|
||||
CRTC_STATE_VBLANK);
|
||||
old_pipe->stream_res.tg->funcs->wait_for_state(
|
||||
old_pipe->stream_res.tg,
|
||||
CRTC_STATE_VACTIVE);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
|
||||
// If old context or new context has phantom pipes, apply
|
||||
// the phantom timings now. We can't change the phantom
|
||||
// pipe configuration safely without driver acquiring
|
||||
// the DMCUB lock first.
|
||||
dc->hwss.apply_ctx_to_hw(dc, context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,4 +102,6 @@ void dcn32_update_dsc_pg(struct dc *dc,
|
|||
struct dc_state *context,
|
||||
bool safe_to_disable);
|
||||
|
||||
void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context);
|
||||
|
||||
#endif /* __DC_HWSS_DCN32_H__ */
|
||||
|
|
|
@ -106,6 +106,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = {
|
|||
.set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
|
||||
.get_dcc_en_bits = dcn10_get_dcc_en_bits,
|
||||
.commit_subvp_config = dcn32_commit_subvp_config,
|
||||
.enable_phantom_streams = dcn32_enable_phantom_streams,
|
||||
.subvp_pipe_control_lock = dcn32_subvp_pipe_control_lock,
|
||||
.update_visual_confirm_color = dcn20_update_visual_confirm_color,
|
||||
.update_phantom_vp_position = dcn32_update_phantom_vp_position,
|
||||
|
|
|
@ -726,6 +726,7 @@ static const struct dc_debug_options debug_defaults_drv = {
|
|||
.allow_sw_cursor_fallback = false, // Linux can't do SW cursor "fallback"
|
||||
.alloc_extra_way_for_cursor = true,
|
||||
.min_prefetch_in_strobe_ns = 60000, // 60us
|
||||
.disable_unbounded_requesting = false,
|
||||
};
|
||||
|
||||
static const struct dc_debug_options debug_defaults_diags = {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue