From 2b05fccbd263fa75a6d07ffff3b6ef129292376f Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Fri, 31 Jul 2020 17:56:07 -0400 Subject: [PATCH 01/66] drm/amdkcl: Enable HDCP Build by default Add HDCP config flag to the makefile Signed-off-by: Bhawanpreet Lakha Signed-off-by: Yang Xiong Reviewed-by: Flora Cui --- drivers/gpu/drm/amd/dkms/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/dkms/Makefile b/drivers/gpu/drm/amd/dkms/Makefile index ae19820134308..d87c72d4a7eb7 100644 --- a/drivers/gpu/drm/amd/dkms/Makefile +++ b/drivers/gpu/drm/amd/dkms/Makefile @@ -197,6 +197,7 @@ export CONFIG_DRM_AMDGPU_USERPTR=y export CONFIG_DRM_AMD_DC=y export CONFIG_DRM_AMD_DC_DCN1_0=y export CONFIG_DRM_AMD_DC_DCN1_01=y +export CONFIG_DRM_AMD_DC_HDCP=y subdir-ccflags-y += -DCONFIG_HSA_AMD subdir-ccflags-y += -DCONFIG_DRM_TTM_DMA_PAGE_POOL @@ -206,6 +207,7 @@ subdir-ccflags-y += -DCONFIG_DRM_AMDGPU_USERPTR subdir-ccflags-y += -DCONFIG_DRM_AMD_DC subdir-ccflags-y += -DCONFIG_DRM_AMD_DC_DCN1_0 subdir-ccflags-y += -DCONFIG_DRM_AMD_DC_DCN1_01 +subdir-ccflags-y += -DCONFIG_DRM_AMD_DC_HDCP # Trying to enable DCN2/3 with core2 optimizations will result in From 2052943bd9d7fb9c72e94de1a85bc0666ad7c91c Mon Sep 17 00:00:00 2001 From: Yang Xiong Date: Thu, 20 Aug 2020 15:48:04 +0800 Subject: [PATCH 02/66] drm/amdkcl: test drm_hdcp.h for enabling hdcp This patch is caused by 'drm/amdkcl: Enable HDCP Build by default' Signed-off-by: Yang Xiong Reviewed-by: Flora Cui Acked-by: Bhawanpreet Lakha --- drivers/gpu/drm/amd/dkms/Makefile | 6 ++++-- drivers/gpu/drm/amd/dkms/config/config.h | 3 +++ drivers/gpu/drm/amd/dkms/m4/drm-headers.m4 | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/dkms/Makefile b/drivers/gpu/drm/amd/dkms/Makefile index d87c72d4a7eb7..ef44ccda9302f 100644 --- a/drivers/gpu/drm/amd/dkms/Makefile +++ b/drivers/gpu/drm/amd/dkms/Makefile @@ -197,7 +197,6 @@ export CONFIG_DRM_AMDGPU_USERPTR=y export CONFIG_DRM_AMD_DC=y export CONFIG_DRM_AMD_DC_DCN1_0=y export CONFIG_DRM_AMD_DC_DCN1_01=y -export CONFIG_DRM_AMD_DC_HDCP=y subdir-ccflags-y += -DCONFIG_HSA_AMD subdir-ccflags-y += -DCONFIG_DRM_TTM_DMA_PAGE_POOL @@ -207,8 +206,11 @@ subdir-ccflags-y += -DCONFIG_DRM_AMDGPU_USERPTR subdir-ccflags-y += -DCONFIG_DRM_AMD_DC subdir-ccflags-y += -DCONFIG_DRM_AMD_DC_DCN1_0 subdir-ccflags-y += -DCONFIG_DRM_AMD_DC_DCN1_01 -subdir-ccflags-y += -DCONFIG_DRM_AMD_DC_HDCP +ifeq ($(shell grep "HAVE_DRM_DRM_HDCP_H" $(src)/amd/dkms/config/config.h | grep -q "define" && echo "y" || echo "n"),y) +export CONFIG_DRM_AMD_DC_HDCP=y +subdir-ccflags-y += -DCONFIG_DRM_AMD_DC_HDCP +endif # Trying to enable DCN2/3 with core2 optimizations will result in # older versions of GCC hanging during building/installing. Check diff --git a/drivers/gpu/drm/amd/dkms/config/config.h b/drivers/gpu/drm/amd/dkms/config/config.h index 9cf299a3dfa9d..5f118658af3d7 100644 --- a/drivers/gpu/drm/amd/dkms/config/config.h +++ b/drivers/gpu/drm/amd/dkms/config/config.h @@ -351,6 +351,9 @@ */ #define HAVE_DRM_DRM_GEM_FRAMEBUFFER_HELPER_H 1 +/* Define to 1 if you have the header file. */ +#define HAVE_DRM_DRM_HDCP_H 1 + /* Define to 1 if you have the header file. */ #define HAVE_DRM_DRM_IOCTL_H 1 diff --git a/drivers/gpu/drm/amd/dkms/m4/drm-headers.m4 b/drivers/gpu/drm/amd/dkms/m4/drm-headers.m4 index 6fbcb305a9569..8ba3d8380c086 100644 --- a/drivers/gpu/drm/amd/dkms/m4/drm-headers.m4 +++ b/drivers/gpu/drm/amd/dkms/m4/drm-headers.m4 @@ -120,4 +120,10 @@ AC_DEFUN([AC_AMDGPU_DRM_HEADERS], [ dnl # RHEL 7.x wrapper dnl # AC_KERNEL_CHECK_HEADERS([drm/drm_backport.h]) + + dnl # + dnl # commit v4.15-rc4-1351-g495eb7f877ab + dnl # drm: Add some HDCP related #defines + dnl # + AC_KERNEL_CHECK_HEADERS([drm/drm_hdcp.h]) ]) From cbde586da17c4e14442eb9702f6537d98a9a77ab Mon Sep 17 00:00:00 2001 From: Yang Xiong Date: Fri, 21 Aug 2020 07:46:51 +0800 Subject: [PATCH 03/66] drm/amdkcl: add kcl/kcl_drm_hdcp.h Reference changes: v4.16-rc7-1717-gb8e47d87be65 drm: Fix HDCP downstream dev count read v4.19-rc2-1221-gaf5aad059885 drm: hdcp2.2 authentication msg definitions v4.19-rc2-1222-g8b44fefee694 drm: HDMI and DP specific HDCP2.2 defines v5.3-rc1-377-g7672dbba85d3 drm: Add Content protection type property This patch is caused by 'drm/amdkcl: Enable HDCP Build by default' Signed-off-by: Yang Xiong Reviewed-by: Flora Cui Acked-by: Bhawanpreet Lakha --- drivers/gpu/drm/amd/dkms/headers | 1 + include/kcl/kcl_drm_hdcp.h | 298 +++++++++++++++++++++++++++++++ 2 files changed, 299 insertions(+) create mode 100644 include/kcl/kcl_drm_hdcp.h diff --git a/drivers/gpu/drm/amd/dkms/headers b/drivers/gpu/drm/amd/dkms/headers index ecab3d0ee7a58..4616bff1060e4 100644 --- a/drivers/gpu/drm/amd/dkms/headers +++ b/drivers/gpu/drm/amd/dkms/headers @@ -29,4 +29,5 @@ linux/pfn_t.h kcl/kcl_mm_types.h linux/nospec.h kcl/kcl_nospec.h drm/task_barrier.h kcl/kcl_task_barrier.h linux/hashtable.h kcl/kcl_hashtable.h +drm/drm_hdcp.h kcl/kcl_drm_hdcp.h diff --git a/include/kcl/kcl_drm_hdcp.h b/include/kcl/kcl_drm_hdcp.h new file mode 100644 index 0000000000000..921fdd4440882 --- /dev/null +++ b/include/kcl/kcl_drm_hdcp.h @@ -0,0 +1,298 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef AMDKCL_DRM_HDCP_H +#define AMDKCL_DRM_HDCP_H + +#ifdef CONFIG_DRM_AMD_DC_HDCP +#include + +/* changed in v4.16-rc7-1717-gb8e47d87be65 + * drm: Fix HDCP downstream dev count read + */ +#ifdef DRM_HDCP_NUM_DOWNSTREAM +#undef DRM_HDCP_NUM_DOWNSTREAM +#define DRM_HDCP_NUM_DOWNSTREAM(x) (x & 0x7f) +#endif + +/* introduced in v5.3-rc1-377-g7672dbba85d3 + * drm: Add Content protection type property + */ +#ifndef DRM_MODE_HDCP_CONTENT_TYPE0 +#define DRM_MODE_HDCP_CONTENT_TYPE0 0 +#define DRM_MODE_HDCP_CONTENT_TYPE1 1 +#endif + +/* introduced in v4.19-rc2-1221-gaf5aad059885 + * drm: hdcp2.2 authentication msg definitions + */ +#ifndef DRM_HDCP_1_4_SRM_ID +#define DRM_HDCP_1_4_SRM_ID 0x8 +#define DRM_HDCP_1_4_VRL_LENGTH_SIZE 3 +#define DRM_HDCP_1_4_DCP_SIG_SIZE 40 + +/* Protocol message definition for HDCP2.2 specification */ +/* + * Protected content streams are classified into 2 types: + * - Type0: Can be transmitted with HDCP 1.4+ + * - Type1: Can be transmitted with HDCP 2.2+ + */ +#define HDCP_STREAM_TYPE0 0x00 +#define HDCP_STREAM_TYPE1 0x01 + +/* HDCP2.2 Msg IDs */ +#define HDCP_2_2_NULL_MSG 1 +#define HDCP_2_2_AKE_INIT 2 +#define HDCP_2_2_AKE_SEND_CERT 3 +#define HDCP_2_2_AKE_NO_STORED_KM 4 +#define HDCP_2_2_AKE_STORED_KM 5 +#define HDCP_2_2_AKE_SEND_HPRIME 7 +#define HDCP_2_2_AKE_SEND_PAIRING_INFO 8 +#define HDCP_2_2_LC_INIT 9 +#define HDCP_2_2_LC_SEND_LPRIME 10 +#define HDCP_2_2_SKE_SEND_EKS 11 +#define HDCP_2_2_REP_SEND_RECVID_LIST 12 +#define HDCP_2_2_REP_SEND_ACK 15 +#define HDCP_2_2_REP_STREAM_MANAGE 16 +#define HDCP_2_2_REP_STREAM_READY 17 +#define HDCP_2_2_ERRATA_DP_STREAM_TYPE 50 + +#define HDCP_2_2_RTX_LEN 8 +#define HDCP_2_2_RRX_LEN 8 + +#define HDCP_2_2_K_PUB_RX_MOD_N_LEN 128 +#define HDCP_2_2_K_PUB_RX_EXP_E_LEN 3 +#define HDCP_2_2_K_PUB_RX_LEN (HDCP_2_2_K_PUB_RX_MOD_N_LEN + \ + HDCP_2_2_K_PUB_RX_EXP_E_LEN) + +#define HDCP_2_2_DCP_LLC_SIG_LEN 384 + +#define HDCP_2_2_E_KPUB_KM_LEN 128 +#define HDCP_2_2_E_KH_KM_M_LEN (16 + 16) +#define HDCP_2_2_H_PRIME_LEN 32 +#define HDCP_2_2_E_KH_KM_LEN 16 +#define HDCP_2_2_RN_LEN 8 +#define HDCP_2_2_L_PRIME_LEN 32 +#define HDCP_2_2_E_DKEY_KS_LEN 16 +#define HDCP_2_2_RIV_LEN 8 +#define HDCP_2_2_SEQ_NUM_LEN 3 +#define HDCP_2_2_V_PRIME_HALF_LEN (HDCP_2_2_L_PRIME_LEN / 2) +#define HDCP_2_2_RECEIVER_ID_LEN DRM_HDCP_KSV_LEN +#define HDCP_2_2_MAX_DEVICE_COUNT 31 +#define HDCP_2_2_RECEIVER_IDS_MAX_LEN (HDCP_2_2_RECEIVER_ID_LEN * \ + HDCP_2_2_MAX_DEVICE_COUNT) +#define HDCP_2_2_MPRIME_LEN 32 + +/* Following Macros take a byte at a time for bit(s) masking */ +/* + * TODO: This has to be changed for DP MST, as multiple stream on + * same port is possible. + * For HDCP2.2 on HDMI and DP SST this value is always 1. + */ +#define HDCP_2_2_MAX_CONTENT_STREAMS_CNT 1 +#define HDCP_2_2_TXCAP_MASK_LEN 2 +#define HDCP_2_2_RXCAPS_LEN 3 +#define HDCP_2_2_RX_REPEATER(x) ((x) & BIT(0)) +#define HDCP_2_2_DP_HDCP_CAPABLE(x) ((x) & BIT(1)) +#define HDCP_2_2_RXINFO_LEN 2 + +/* HDCP1.x compliant device in downstream */ +#define HDCP_2_2_HDCP1_DEVICE_CONNECTED(x) ((x) & BIT(0)) + +/* HDCP2.0 Compliant repeater in downstream */ +#define HDCP_2_2_HDCP_2_0_REP_CONNECTED(x) ((x) & BIT(1)) +#define HDCP_2_2_MAX_CASCADE_EXCEEDED(x) ((x) & BIT(2)) +#define HDCP_2_2_MAX_DEVS_EXCEEDED(x) ((x) & BIT(3)) +#define HDCP_2_2_DEV_COUNT_LO(x) (((x) & (0xF << 4)) >> 4) +#define HDCP_2_2_DEV_COUNT_HI(x) ((x) & BIT(0)) +#define HDCP_2_2_DEPTH(x) (((x) & (0x7 << 1)) >> 1) + +struct hdcp2_cert_rx { + u8 receiver_id[HDCP_2_2_RECEIVER_ID_LEN]; + u8 kpub_rx[HDCP_2_2_K_PUB_RX_LEN]; + u8 reserved[2]; + u8 dcp_signature[HDCP_2_2_DCP_LLC_SIG_LEN]; +} __packed; + +struct hdcp2_streamid_type { + u8 stream_id; + u8 stream_type; +} __packed; + +/* + * The TxCaps field specified in the HDCP HDMI, DP specs + * This field is big endian as specified in the errata. + */ +struct hdcp2_tx_caps { + /* Transmitter must set this to 0x2 */ + u8 version; + + /* Reserved for HDCP and DP Spec. Read as Zero */ + u8 tx_cap_mask[HDCP_2_2_TXCAP_MASK_LEN]; +} __packed; + +/* Main structures for HDCP2.2 protocol communication */ +struct hdcp2_ake_init { + u8 msg_id; + u8 r_tx[HDCP_2_2_RTX_LEN]; + struct hdcp2_tx_caps tx_caps; +} __packed; + +struct hdcp2_ake_send_cert { + u8 msg_id; + struct hdcp2_cert_rx cert_rx; + u8 r_rx[HDCP_2_2_RRX_LEN]; + u8 rx_caps[HDCP_2_2_RXCAPS_LEN]; +} __packed; + +struct hdcp2_ake_no_stored_km { + u8 msg_id; + u8 e_kpub_km[HDCP_2_2_E_KPUB_KM_LEN]; +} __packed; + +struct hdcp2_ake_stored_km { + u8 msg_id; + u8 e_kh_km_m[HDCP_2_2_E_KH_KM_M_LEN]; +} __packed; + +struct hdcp2_ake_send_hprime { + u8 msg_id; + u8 h_prime[HDCP_2_2_H_PRIME_LEN]; +} __packed; + +struct hdcp2_ake_send_pairing_info { + u8 msg_id; + u8 e_kh_km[HDCP_2_2_E_KH_KM_LEN]; +} __packed; + +struct hdcp2_lc_init { + u8 msg_id; + u8 r_n[HDCP_2_2_RN_LEN]; +} __packed; + +struct hdcp2_lc_send_lprime { + u8 msg_id; + u8 l_prime[HDCP_2_2_L_PRIME_LEN]; +} __packed; + +struct hdcp2_ske_send_eks { + u8 msg_id; + u8 e_dkey_ks[HDCP_2_2_E_DKEY_KS_LEN]; + u8 riv[HDCP_2_2_RIV_LEN]; +} __packed; + +struct hdcp2_rep_send_receiverid_list { + u8 msg_id; + u8 rx_info[HDCP_2_2_RXINFO_LEN]; + u8 seq_num_v[HDCP_2_2_SEQ_NUM_LEN]; + u8 v_prime[HDCP_2_2_V_PRIME_HALF_LEN]; + u8 receiver_ids[HDCP_2_2_RECEIVER_IDS_MAX_LEN]; +} __packed; + +struct hdcp2_rep_send_ack { + u8 msg_id; + u8 v[HDCP_2_2_V_PRIME_HALF_LEN]; +} __packed; + +struct hdcp2_rep_stream_manage { + u8 msg_id; + u8 seq_num_m[HDCP_2_2_SEQ_NUM_LEN]; + __be16 k; + struct hdcp2_streamid_type streams[HDCP_2_2_MAX_CONTENT_STREAMS_CNT]; +} __packed; + +struct hdcp2_rep_stream_ready { + u8 msg_id; + u8 m_prime[HDCP_2_2_MPRIME_LEN]; +} __packed; + +struct hdcp2_dp_errata_stream_type { + u8 msg_id; + u8 stream_type; +} __packed; +#endif /* DRM_HDCP_1_4_SRM_ID */ + +/* introduced in v4.19-rc2-1222-g8b44fefee694 + * drm: HDMI and DP specific HDCP2.2 defines + */ +#ifndef HDCP_2_2_CERT_TIMEOUT_MS +/* HDCP2.2 TIMEOUTs in mSec */ +#define HDCP_2_2_CERT_TIMEOUT_MS 100 +#define HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS 1000 +#define HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS 200 +#define HDCP_2_2_PAIRING_TIMEOUT_MS 200 +#define HDCP_2_2_HDMI_LPRIME_TIMEOUT_MS 20 +#define HDCP_2_2_DP_LPRIME_TIMEOUT_MS 7 +#define HDCP_2_2_RECVID_LIST_TIMEOUT_MS 3000 +#define HDCP_2_2_STREAM_READY_TIMEOUT_MS 100 + +/* HDMI HDCP2.2 Register Offsets */ +#define HDCP_2_2_HDMI_REG_VER_OFFSET 0x50 +#define HDCP_2_2_HDMI_REG_WR_MSG_OFFSET 0x60 +#define HDCP_2_2_HDMI_REG_RXSTATUS_OFFSET 0x70 +#define HDCP_2_2_HDMI_REG_RD_MSG_OFFSET 0x80 +#define HDCP_2_2_HDMI_REG_DBG_OFFSET 0xC0 + +#define HDCP_2_2_HDMI_SUPPORT_MASK BIT(2) +#define HDCP_2_2_RX_CAPS_VERSION_VAL 0x02 +#define HDCP_2_2_SEQ_NUM_MAX 0xFFFFFF +#define HDCP_2_2_DELAY_BEFORE_ENCRYPTION_EN 200 + +/* Below macros take a byte at a time and mask the bit(s) */ +#define HDCP_2_2_HDMI_RXSTATUS_LEN 2 +#define HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(x) ((x) & 0x3) +#define HDCP_2_2_HDMI_RXSTATUS_READY(x) ((x) & BIT(2)) +#define HDCP_2_2_HDMI_RXSTATUS_REAUTH_REQ(x) ((x) & BIT(3)) +/* DP HDCP2.2 parameter offsets in DPCD address space */ +#define DP_HDCP_2_2_REG_RTX_OFFSET 0x69000 +#define DP_HDCP_2_2_REG_TXCAPS_OFFSET 0x69008 +#define DP_HDCP_2_2_REG_CERT_RX_OFFSET 0x6900B +#define DP_HDCP_2_2_REG_RRX_OFFSET 0x69215 +#define DP_HDCP_2_2_REG_RX_CAPS_OFFSET 0x6921D +#define DP_HDCP_2_2_REG_EKPUB_KM_OFFSET 0x69220 +#define DP_HDCP_2_2_REG_EKH_KM_WR_OFFSET 0x692A0 +#define DP_HDCP_2_2_REG_M_OFFSET 0x692B0 +#define DP_HDCP_2_2_REG_HPRIME_OFFSET 0x692C0 +#define DP_HDCP_2_2_REG_EKH_KM_RD_OFFSET 0x692E0 +#define DP_HDCP_2_2_REG_RN_OFFSET 0x692F0 +#define DP_HDCP_2_2_REG_LPRIME_OFFSET 0x692F8 +#define DP_HDCP_2_2_REG_EDKEY_KS_OFFSET 0x69318 +#define DP_HDCP_2_2_REG_RIV_OFFSET 0x69328 +#define DP_HDCP_2_2_REG_RXINFO_OFFSET 0x69330 +#define DP_HDCP_2_2_REG_SEQ_NUM_V_OFFSET 0x69332 +#define DP_HDCP_2_2_REG_VPRIME_OFFSET 0x69335 +#define DP_HDCP_2_2_REG_RECV_ID_LIST_OFFSET 0x69345 +#define DP_HDCP_2_2_REG_V_OFFSET 0x693E0 +#define DP_HDCP_2_2_REG_SEQ_NUM_M_OFFSET 0x693F0 +#define DP_HDCP_2_2_REG_K_OFFSET 0x693F3 +#define DP_HDCP_2_2_REG_STREAM_ID_TYPE_OFFSET 0x693F5 +#define DP_HDCP_2_2_REG_MPRIME_OFFSET 0x69473 +#define DP_HDCP_2_2_REG_RXSTATUS_OFFSET 0x69493 +#define DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET 0x69494 +#define DP_HDCP_2_2_REG_DBG_OFFSET 0x69518 + +/* DP HDCP message start offsets in DPCD address space */ +#define DP_HDCP_2_2_AKE_INIT_OFFSET DP_HDCP_2_2_REG_RTX_OFFSET +#define DP_HDCP_2_2_AKE_SEND_CERT_OFFSET DP_HDCP_2_2_REG_CERT_RX_OFFSET +#define DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET DP_HDCP_2_2_REG_EKPUB_KM_OFFSET +#define DP_HDCP_2_2_AKE_STORED_KM_OFFSET DP_HDCP_2_2_REG_EKH_KM_WR_OFFSET +#define DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET DP_HDCP_2_2_REG_HPRIME_OFFSET +#define DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET \ + DP_HDCP_2_2_REG_EKH_KM_RD_OFFSET +#define DP_HDCP_2_2_LC_INIT_OFFSET DP_HDCP_2_2_REG_RN_OFFSET +#define DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET DP_HDCP_2_2_REG_LPRIME_OFFSET +#define DP_HDCP_2_2_SKE_SEND_EKS_OFFSET DP_HDCP_2_2_REG_EDKEY_KS_OFFSET +#define DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET DP_HDCP_2_2_REG_RXINFO_OFFSET +#define DP_HDCP_2_2_REP_SEND_ACK_OFFSET DP_HDCP_2_2_REG_V_OFFSET +#define DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET DP_HDCP_2_2_REG_SEQ_NUM_M_OFFSET +#define DP_HDCP_2_2_REP_STREAM_READY_OFFSET DP_HDCP_2_2_REG_MPRIME_OFFSET + +#define HDCP_2_2_DP_RXSTATUS_LEN 1 +#define HDCP_2_2_DP_RXSTATUS_READY(x) ((x) & BIT(0)) +#define HDCP_2_2_DP_RXSTATUS_H_PRIME(x) ((x) & BIT(1)) +#define HDCP_2_2_DP_RXSTATUS_PAIRING(x) ((x) & BIT(2)) +#define HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(x) ((x) & BIT(3)) +#define HDCP_2_2_DP_RXSTATUS_LINK_FAILED(x) ((x) & BIT(4)) +#endif /* HDCP_2_2_CERT_TIMEOUT_MS */ + +#endif /* CONFIG_DRM_AMD_DC_HDCP */ + +#endif /* AMDKCL_DRM_HDCP_H */ From 888d4c5b52a93eb3d4fa87200b286eb3231858f8 Mon Sep 17 00:00:00 2001 From: Yang Xiong Date: Thu, 20 Aug 2020 21:18:45 +0800 Subject: [PATCH 04/66] drm/amdkcl: test whether struct drm_connector_state has hdcp_content_type This patch is caused by 'drm/amdkcl: Enable HDCP Build by default' Signed-off-by: Yang Xiong Reviewed-by: Flora Cui Acked-by: Bhawanpreet Lakha --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++++++++++ .../drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 4 ++++ drivers/gpu/drm/amd/dkms/config/config.h | 3 +++ .../m4/drm-connector-state-hdcp-content-type.m4 | 17 +++++++++++++++++ drivers/gpu/drm/amd/dkms/m4/kernel.m4 | 1 + 5 files changed, 35 insertions(+) create mode 100644 drivers/gpu/drm/amd/dkms/m4/drm-connector-state-hdcp-content-type.m4 diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index bb147cf658ebe..418785f28b969 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7065,7 +7065,11 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, #endif #ifdef CONFIG_DRM_AMD_DC_HDCP if (adev->dm.hdcp_workqueue) +#ifdef HAVE_DRM_CONNECTOR_STATE_HDCP_CONTENT_TYPE drm_connector_attach_content_protection_property(&aconnector->base, true); +#else + drm_connector_attach_content_protection_property(&aconnector->base); +#endif #endif drm_object_attach_property(&aconnector->base.base, adev->mode_info.freesync_property, 0); @@ -7329,11 +7333,13 @@ static bool is_content_protection_different(struct drm_connector_state *state, { struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); +#ifdef HAVE_DRM_CONNECTOR_STATE_HDCP_CONTENT_TYPE 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; return true; } +#endif /* CP is being re enabled, ignore this */ if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED && @@ -8384,7 +8390,11 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) if (is_content_protection_different(new_con_state, old_con_state, connector, adev->dm.hdcp_workqueue)) hdcp_update_display( adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector, +#ifdef HAVE_DRM_CONNECTOR_STATE_HDCP_CONTENT_TYPE new_con_state->hdcp_content_type, +#else + DRM_MODE_HDCP_CONTENT_TYPE0, +#endif new_con_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED ? true : false); } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index 694c5bc93665b..7b76840ad2777 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -299,12 +299,16 @@ static void event_property_update(struct work_struct *work) } if (hdcp_work->encryption_status != MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF) { +#ifdef HAVE_DRM_CONNECTOR_STATE_HDCP_CONTENT_TYPE if (aconnector->base.state->hdcp_content_type == DRM_MODE_HDCP_CONTENT_TYPE0 && hdcp_work->encryption_status <= MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE0_ON) drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_ENABLED); else if (aconnector->base.state->hdcp_content_type == DRM_MODE_HDCP_CONTENT_TYPE1 && hdcp_work->encryption_status == MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE1_ON) drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_ENABLED); +#else + drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_ENABLED); +#endif } else { drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_DESIRED); } diff --git a/drivers/gpu/drm/amd/dkms/config/config.h b/drivers/gpu/drm/amd/dkms/config/config.h index 5f118658af3d7..9f491e2b7ce2c 100644 --- a/drivers/gpu/drm/amd/dkms/config/config.h +++ b/drivers/gpu/drm/amd/dkms/config/config.h @@ -209,6 +209,9 @@ /* drm_connector_set_path_property() is available */ #define HAVE_DRM_CONNECTOR_SET_PATH_PROPERTY 1 +/* struct drm_connector_state has hdcp_content_type */ +#define HAVE_DRM_CONNECTOR_STATE_HDCP_CONTENT_TYPE 1 + /* drm_connector_unreference() is available */ /* #undef HAVE_DRM_CONNECTOR_UNREFERENCE */ diff --git a/drivers/gpu/drm/amd/dkms/m4/drm-connector-state-hdcp-content-type.m4 b/drivers/gpu/drm/amd/dkms/m4/drm-connector-state-hdcp-content-type.m4 new file mode 100644 index 0000000000000..6d852b75d9e05 --- /dev/null +++ b/drivers/gpu/drm/amd/dkms/m4/drm-connector-state-hdcp-content-type.m4 @@ -0,0 +1,17 @@ +dnl # +dnl # commit v5.3-rc1-377-g7672dbba85d3 +dnl # drm: Add Content protection type property +dnl # +AC_DEFUN([AC_AMDGPU_DRM_CONNECTOR_STATE_HDCP_CONTENT_TYPE], [ + AC_KERNEL_DO_BACKGROUND([ + AC_KERNEL_TRY_COMPILE([ + #include + ],[ + struct drm_connector_state *state = NULL; + state->hdcp_content_type = 0; + ],[ + AC_DEFINE(HAVE_DRM_CONNECTOR_STATE_HDCP_CONTENT_TYPE, 1, + [struct drm_connector_state has hdcp_content_type member]) + ]) + ]) +]) diff --git a/drivers/gpu/drm/amd/dkms/m4/kernel.m4 b/drivers/gpu/drm/amd/dkms/m4/kernel.m4 index 04edde19e74c1..c2e449f2bff9d 100644 --- a/drivers/gpu/drm/amd/dkms/m4/kernel.m4 +++ b/drivers/gpu/drm/amd/dkms/m4/kernel.m4 @@ -200,6 +200,7 @@ AC_DEFUN([AC_CONFIG_KERNEL], [ AC_AMDGPU_DRM_MODE_CONFIG_FUNCS AC_AMDGPU_DRM_MODE_CONFIG AC_AMDGPU_DRM_CRTC_ENABLE_COLOR_MGMT + AC_AMDGPU_DRM_CONNECTOR_STATE_HDCP_CONTENT_TYPE AC_KERNEL_WAIT AS_IF([test "$LINUX_OBJ" != "$LINUX"], [ From 56b2bf73a219b5f378359713420759895bc04903 Mon Sep 17 00:00:00 2001 From: Yang Xiong Date: Thu, 20 Aug 2020 22:14:03 +0800 Subject: [PATCH 05/66] drm/amdkcl: test whether drm_hdcp_update_content_protection is available This patch is caused by 'drm/amdkcl: Enable HDCP Build by default' Signed-off-by: Yang Xiong Reviewed-by: Flora Cui Acked-by: Bhawanpreet Lakha --- drivers/gpu/drm/amd/amdkcl/kcl_connector.c | 17 +++++++++++++++++ drivers/gpu/drm/amd/dkms/config/config.h | 3 +++ .../m4/drm-hdcp-update-content-protection.m4 | 16 ++++++++++++++++ drivers/gpu/drm/amd/dkms/m4/kernel.m4 | 1 + include/kcl/kcl_drm_connector.h | 13 +++++++++++++ 5 files changed, 50 insertions(+) create mode 100644 drivers/gpu/drm/amd/dkms/m4/drm-hdcp-update-content-protection.m4 diff --git a/drivers/gpu/drm/amd/amdkcl/kcl_connector.c b/drivers/gpu/drm/amd/amdkcl/kcl_connector.c index 3f9a9836c518d..d7ae3ae13b4a0 100644 --- a/drivers/gpu/drm/amd/amdkcl/kcl_connector.c +++ b/drivers/gpu/drm/amd/amdkcl/kcl_connector.c @@ -13,3 +13,20 @@ int _kcl_drm_connector_init_with_ddc(struct drm_device *dev, EXPORT_SYMBOL(_kcl_drm_connector_init_with_ddc); #endif +#ifdef CONFIG_DRM_AMD_DC_HDCP +#ifndef HAVE_DRM_HDCP_UPDATE_CONTENT_PROTECTION +void _kcl_drm_hdcp_update_content_protection(struct drm_connector *connector, + u64 val) +{ + struct drm_device *dev = connector->dev; + struct drm_connector_state *state = connector->state; + + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + if (state->content_protection == val) + return; + + state->content_protection = val; +} +EXPORT_SYMBOL(_kcl_drm_hdcp_update_content_protection); +#endif +#endif diff --git a/drivers/gpu/drm/amd/dkms/config/config.h b/drivers/gpu/drm/amd/dkms/config/config.h index 9f491e2b7ce2c..174fc6acf3aae 100644 --- a/drivers/gpu/drm/amd/dkms/config/config.h +++ b/drivers/gpu/drm/amd/dkms/config/config.h @@ -463,6 +463,9 @@ /* ddrm_get_max_iome() is available */ /* #undef HAVE_DRM_GET_MAX_IOMEM */ +/* drm_hdcp_update_content_protection is available */ +#define HAVE_DRM_HDCP_UPDATE_CONTENT_PROTECTION 1 + /* drm_hdmi_avi_infoframe_from_display_mode() has p,p,b interface */ /* #undef HAVE_DRM_HDMI_AVI_INFOFRAME_FROM_DISPLAY_MODE_P_P_B */ diff --git a/drivers/gpu/drm/amd/dkms/m4/drm-hdcp-update-content-protection.m4 b/drivers/gpu/drm/amd/dkms/m4/drm-hdcp-update-content-protection.m4 new file mode 100644 index 0000000000000..5b8c871002830 --- /dev/null +++ b/drivers/gpu/drm/amd/dkms/m4/drm-hdcp-update-content-protection.m4 @@ -0,0 +1,16 @@ +dnl # +dnl # commit v5.3-rc1-380-gbb5a45d40d50 +dnl # drm/hdcp: update content protection property with uevent +dnl # +AC_DEFUN([AC_AMDGPU_DRM_HDCP_UPDATE_CONTENT_PROTECTION], [ + AC_KERNEL_DO_BACKGROUND([ + AC_KERNEL_TRY_COMPILE([ + #include + ], [ + drm_hdcp_update_content_protection(NULL, 0); + ], [ + AC_DEFINE(HAVE_DRM_HDCP_UPDATE_CONTENT_PROTECTION, 1, + [drm_hdcp_update_content_protection is available]) + ]) + ]) +]) diff --git a/drivers/gpu/drm/amd/dkms/m4/kernel.m4 b/drivers/gpu/drm/amd/dkms/m4/kernel.m4 index c2e449f2bff9d..2d4958dfc4606 100644 --- a/drivers/gpu/drm/amd/dkms/m4/kernel.m4 +++ b/drivers/gpu/drm/amd/dkms/m4/kernel.m4 @@ -201,6 +201,7 @@ AC_DEFUN([AC_CONFIG_KERNEL], [ AC_AMDGPU_DRM_MODE_CONFIG AC_AMDGPU_DRM_CRTC_ENABLE_COLOR_MGMT AC_AMDGPU_DRM_CONNECTOR_STATE_HDCP_CONTENT_TYPE + AC_AMDGPU_DRM_HDCP_UPDATE_CONTENT_PROTECTION AC_KERNEL_WAIT AS_IF([test "$LINUX_OBJ" != "$LINUX"], [ diff --git a/include/kcl/kcl_drm_connector.h b/include/kcl/kcl_drm_connector.h index cc7c34f676031..73850d809eb4a 100755 --- a/include/kcl/kcl_drm_connector.h +++ b/include/kcl/kcl_drm_connector.h @@ -66,4 +66,17 @@ int drm_connector_init_with_ddc(struct drm_device *dev, return _kcl_drm_connector_init_with_ddc(dev, connector, funcs, connector_type, ddc); } #endif + +#ifdef CONFIG_DRM_AMD_DC_HDCP +#ifndef HAVE_DRM_HDCP_UPDATE_CONTENT_PROTECTION +void _kcl_drm_hdcp_update_content_protection(struct drm_connector *connector, + u64 val); +static inline +void drm_hdcp_update_content_protection(struct drm_connector *connector, + u64 val) +{ + _kcl_drm_hdcp_update_content_protection(connector, val); +} +#endif +#endif #endif /* AMDKCL_DRM_CONNECTOR_H */ From 6b7e0ce2763c1c8e3f78983022e0b252f95572d3 Mon Sep 17 00:00:00 2001 From: Flora Cui Date: Fri, 21 Aug 2020 14:18:24 +0800 Subject: [PATCH 06/66] drm/amdkcl: update kcl copy of compat.h Signed-off-by: Flora Cui Reviewed-by: Yang Xiong --- drivers/gpu/drm/amd/dkms/headers | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/dkms/headers b/drivers/gpu/drm/amd/dkms/headers index 4616bff1060e4..fd4033418de9b 100644 --- a/drivers/gpu/drm/amd/dkms/headers +++ b/drivers/gpu/drm/amd/dkms/headers @@ -29,5 +29,6 @@ linux/pfn_t.h kcl/kcl_mm_types.h linux/nospec.h kcl/kcl_nospec.h drm/task_barrier.h kcl/kcl_task_barrier.h linux/hashtable.h kcl/kcl_hashtable.h +linux/compat.h kcl/kcl_compat.h drm/drm_hdcp.h kcl/kcl_drm_hdcp.h From 197b3769528f3be92ef5bf09bbe6fc8a45d910e7 Mon Sep 17 00:00:00 2001 From: Flora Cui Date: Mon, 24 Aug 2020 16:32:22 +0800 Subject: [PATCH 07/66] drm/amdkcl: refactor kvfree/kvmalloc series Signed-off-by: Flora Cui Reviewed-by: Yang Xiong --- drivers/gpu/drm/amd/dkms/config/config.h | 9 ---- .../gpu/drm/amd/dkms/m4/drm-calloc-large.m4 | 25 ---------- drivers/gpu/drm/amd/dkms/m4/drm-free-large.m4 | 24 ---------- drivers/gpu/drm/amd/dkms/m4/drm-malloc-ab.m4 | 21 --------- drivers/gpu/drm/amd/dkms/m4/kernel.m4 | 3 -- include/kcl/kcl_mm.h | 47 +++++-------------- 6 files changed, 12 insertions(+), 117 deletions(-) delete mode 100644 drivers/gpu/drm/amd/dkms/m4/drm-calloc-large.m4 delete mode 100644 drivers/gpu/drm/amd/dkms/m4/drm-free-large.m4 delete mode 100644 drivers/gpu/drm/amd/dkms/m4/drm-malloc-ab.m4 diff --git a/drivers/gpu/drm/amd/dkms/config/config.h b/drivers/gpu/drm/amd/dkms/config/config.h index 174fc6acf3aae..d3f4a947a815e 100644 --- a/drivers/gpu/drm/amd/dkms/config/config.h +++ b/drivers/gpu/drm/amd/dkms/config/config.h @@ -172,9 +172,6 @@ /* drm_calc_vbltimestamp_from_scanoutpos() use ktime_t arg */ /* #undef HAVE_DRM_CALC_VBLTIMESTAMP_FROM_SCANOUTPOS_USE_KTIMER_T_ARG */ -/* drm_calloc_large() is available */ -/* #undef HAVE_DRM_CALLOC_LARGE */ - /* drm_color_lut_size() is available */ #define HAVE_DRM_COLOR_LUT_SIZE 1 @@ -439,9 +436,6 @@ /* whether struct drm_framebuffer have format */ #define HAVE_DRM_FRAMEBUFFER_FORMAT 1 -/* drm_free_large() is available */ -/* #undef HAVE_DRM_FREE_LARGE */ - /* drm_gem_map_attach() wants 2 arguments */ /* #undef HAVE_DRM_GEM_MAP_ATTACH_2ARGS */ @@ -487,9 +481,6 @@ /* drm_kms_helper_is_poll_worker() is available */ #define HAVE_DRM_KMS_HELPER_IS_POLL_WORKER 1 -/* drm_malloc_ab() is available */ -/* #undef HAVE_DRM_MALLOC_AB */ - /* whether drm_mm_insert_mode is available */ #define HAVE_DRM_MM_INSERT_MODE 1 diff --git a/drivers/gpu/drm/amd/dkms/m4/drm-calloc-large.m4 b/drivers/gpu/drm/amd/dkms/m4/drm-calloc-large.m4 deleted file mode 100644 index 6df190150e4b2..0000000000000 --- a/drivers/gpu/drm/amd/dkms/m4/drm-calloc-large.m4 +++ /dev/null @@ -1,25 +0,0 @@ -dnl # -dnl # commit 72e942dd846f98e2d35aad5436d77a878ef05c5e -dnl # Author: Dave Airlie -dnl # Date: Tue Mar 9 06:33:26 2010 +0000 -dnl # drm/ttm: use drm calloc large and free large -dnl # -AC_DEFUN([AC_AMDGPU_DRM_CALLOC_LARGE], [ - AC_KERNEL_DO_BACKGROUND([ - AC_KERNEL_TRY_COMPILE([ - #include - #ifndef SIZE_MAX - #define SIZE_MAX (~0UL) - #endif - #include - #include - #include - #include - ], [ - drm_calloc_large(8, 8); - ], [ - AC_DEFINE(HAVE_DRM_CALLOC_LARGE, 1, - [drm_calloc_large() is available]) - ]) - ]) -]) diff --git a/drivers/gpu/drm/amd/dkms/m4/drm-free-large.m4 b/drivers/gpu/drm/amd/dkms/m4/drm-free-large.m4 deleted file mode 100644 index 0db0dd4e4fbbb..0000000000000 --- a/drivers/gpu/drm/amd/dkms/m4/drm-free-large.m4 +++ /dev/null @@ -1,24 +0,0 @@ -dnl # -dnl # commit 72e942dd846f98e2d35aad5436d77a878ef05c5e -dnl # Author: Dave Airlie -dnl # Date: Tue Mar 9 06:33:26 2010 +0000 -dnl # drm/ttm: use drm calloc large and free large -dnl # -AC_DEFUN([AC_AMDGPU_DRM_FREE_LARGE], [ - AC_KERNEL_DO_BACKGROUND([ - AC_KERNEL_TRY_COMPILE([ - #include - #ifndef SIZE_MAX - #define SIZE_MAX (~0UL) - #endif - #include - #include - #include - ], [ - drm_free_large(NULL); - ], [ - AC_DEFINE(HAVE_DRM_FREE_LARGE, 1, - [drm_free_large() is available]) - ]) - ]) -]) diff --git a/drivers/gpu/drm/amd/dkms/m4/drm-malloc-ab.m4 b/drivers/gpu/drm/amd/dkms/m4/drm-malloc-ab.m4 deleted file mode 100644 index b71abec5d8a75..0000000000000 --- a/drivers/gpu/drm/amd/dkms/m4/drm-malloc-ab.m4 +++ /dev/null @@ -1,21 +0,0 @@ -dnl # -dnl # commit v2.6.32-rc6-131-gc8e0f93a381d -dnl # drm/i915: Replace a calloc followed by copying data over it with malloc. -dnl # -dnl # commit v4.12-rc1-110-gc4f51dc87296 -dnl # -dnl # -AC_DEFUN([AC_AMDGPU_DRM_MALLOC_AB], [ - AC_KERNEL_DO_BACKGROUND([ - AC_KERNEL_TEST_HEADER_FILE_EXIST([drm/drmP.h], [ - AC_KERNEL_TRY_COMPILE([ - #include - ], [ - drm_malloc_ab(0, 0); - ], [ - AC_DEFINE(HAVE_DRM_MALLOC_AB, 1, - [drm_malloc_ab() is available]) - ]) - ]) - ]) -]) diff --git a/drivers/gpu/drm/amd/dkms/m4/kernel.m4 b/drivers/gpu/drm/amd/dkms/m4/kernel.m4 index 2d4958dfc4606..4e792434b6739 100644 --- a/drivers/gpu/drm/amd/dkms/m4/kernel.m4 +++ b/drivers/gpu/drm/amd/dkms/m4/kernel.m4 @@ -77,9 +77,6 @@ AC_DEFUN([AC_CONFIG_KERNEL], [ AC_AMDGPU_LIST_BULK_MOVE_TAIL AC_AMDGPU_LIST_ROTATE_TO_FRONT AC_AMDGPU_LIST_IS_FIRST - AC_AMDGPU_DRM_CALLOC_LARGE - AC_AMDGPU_DRM_FREE_LARGE - AC_AMDGPU_DRM_MALLOC_AB AC_AMDGPU_KVCALLOC AC_AMDGPU_KVFREE AC_AMDGPU_KVMALLOC_ARRAY diff --git a/include/kcl/kcl_mm.h b/include/kcl/kcl_mm.h index c4f904398d344..63bc6f1575527 100644 --- a/include/kcl/kcl_mm.h +++ b/include/kcl/kcl_mm.h @@ -8,16 +8,22 @@ #include #include #include -#ifdef HAVE_DRM_MALLOC_AB -#include -#endif -#include #include #ifndef untagged_addr #define untagged_addr(addr) (addr) #endif +#ifndef HAVE_KVFREE +static inline void kvfree(const void *addr) +{ + if (is_vmalloc_addr(addr)) + vfree(addr); + else + kfree(addr); +} +#endif + #ifndef HAVE_KVZALLOC_KVMALLOC static inline void *kvmalloc(size_t size, gfp_t flags) { @@ -35,43 +41,14 @@ static inline void *kvzalloc(size_t size, gfp_t flags) } #endif /* HAVE_KVZALLOC_KVMALLOC */ -#ifndef HAVE_KVFREE -#ifdef HAVE_DRM_FREE_LARGE -static inline void kvfree(const void *addr) -{ - return drm_free_large(addr); -} -#else -static inline void kvfree(const void *addr) -{ - if (is_vmalloc_addr(addr)) - vfree(addr); - else - kfree(addr); -} -#endif /* HAVE_DRM_FREE_LARGE */ -#endif /* HAVE_KVFREE */ - #ifndef HAVE_KVMALLOC_ARRAY -#if defined(HAVE_DRM_MALLOC_AB) && defined(HAVE_DRM_CALLOC_LARGE) static inline void *kvmalloc_array(size_t n, size_t size, gfp_t flags) { - if (flags & __GFP_ZERO) - return drm_calloc_large(n, size); - else - return drm_malloc_ab(n, size); -} -#else -static inline void *kvmalloc_array(size_t n, size_t size, gfp_t flags) -{ - size_t bytes; - - if (unlikely(check_mul_overflow(n, size, &bytes))) + if (size != 0 && n > SIZE_MAX / size) return NULL; - return kvmalloc(bytes, flags); + return kvmalloc(n * size, flags); } -#endif /* HAVE_DRM_MALLOC_AB && HAVE_DRM_CALLOC_LARGE */ #endif /* HAVE_KVMALLOC_ARRAY */ #ifndef HAVE_KVCALLOC From ffe160872503c500787761e7a9ff284211462ab3 Mon Sep 17 00:00:00 2001 From: Flora Cui Date: Mon, 24 Aug 2020 17:43:22 +0800 Subject: [PATCH 08/66] drm/amdkcl: refactor test for dma_fence_set_error() Signed-off-by: Flora Cui Reviewed-by: Yang Xiong --- .../gpu/drm/amd/dkms/m4/dma-fence-headers.m4 | 40 +++++++------------ 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/amd/dkms/m4/dma-fence-headers.m4 b/drivers/gpu/drm/amd/dkms/m4/dma-fence-headers.m4 index b5fa26168e004..5fe61dcd9d23b 100644 --- a/drivers/gpu/drm/amd/dkms/m4/dma-fence-headers.m4 +++ b/drivers/gpu/drm/amd/dkms/m4/dma-fence-headers.m4 @@ -1,37 +1,25 @@ -dnl # commit a009e975da5c7d42a7f5eaadc54946eb5f76c9af +dnl # +dnl # commit v4.9-rc8-1783-ga009e975da5c dnl # dma-fence: Introduce drm_fence_set_error() helper -dnl # The dma_fence.error field (formerly known as dma_fence.status) is an -dnl # optional field that may be set by drivers before calling -dnl # dma_fence_signal(). The field can be used to indicate that the fence was -dnl # completed in err rather than with success, and is visible to other -dnl # consumers of the fence and to userspace via sync_file. -dnl # This patch renames the field from status to error so that its meaning is -dnl # hopefully more clear (and distinct from dma_fence_get_status() which is -dnl # a composite between the error state and signal state) and adds a helper -dnl # that validates the preconditions of when it is suitable to adjust the -dnl # error field. -AC_DEFUN([AC_AMDGPU_DMA_FENCE_SET_ERROR], [ - AC_KERNEL_TRY_COMPILE([ - #include - ], [ - dma_fence_set_error(NULL, 0); - ], [ - AC_DEFINE(HAVE_DMA_FENCE_SET_ERROR, 1, - [dma_fence_set_error() is available]) - ]) -]) - dnl # commit f5e0724e76c2c8efb4d3dc43c24228b409bbbfe9 dnl # dma-fence: Introduce drm_fence_set_error() helper -AC_DEFUN([AC_AMDGPU_FENCE_SET_ERROR], [ +dnl # +AC_DEFUN([AC_AMDGPU_DMA_FENCE_SET_ERROR], [ AC_KERNEL_TRY_COMPILE([ + #ifdef HAVE_LINUX_DMA_FENCE_H + #include + #else #include + #endif ], [ + #ifdef HAVE_LINUX_DMA_FENCE_H + dma_fence_set_error(NULL, 0); + #else fence_set_error(NULL, 0); + #endif ], [ AC_DEFINE(HAVE_DMA_FENCE_SET_ERROR, 1, - [fence_set_error() is available]) - + [dma_fence_set_error() is available]) ]) ]) @@ -67,7 +55,7 @@ AC_DEFUN([AC_AMDGPU_DMA_FENCE_HEADERS], [ dnl # AC_KERNEL_CHECK_HEADERS([linux/fence-array.h]) AC_KERNEL_DO_BACKGROUND([ - AC_AMDGPU_FENCE_SET_ERROR + AC_AMDGPU_DMA_FENCE_SET_ERROR ]) ]) ]) From 63d75a22e5b9a0f98c18b664da8b9c6ba63767db Mon Sep 17 00:00:00 2001 From: Flora Cui Date: Tue, 25 Aug 2020 10:42:15 +0800 Subject: [PATCH 09/66] drm/amdkcl: refactor dp related macros move to kcl_drm_dp_helper.h Signed-off-by: Flora Cui Reviewed-by: Yang Xiong --- include/kcl/kcl_drm.h | 66 --------------------------------- include/kcl/kcl_drm_dp_helper.h | 39 +++++++++++++++++++ 2 files changed, 39 insertions(+), 66 deletions(-) diff --git a/include/kcl/kcl_drm.h b/include/kcl/kcl_drm.h index 7904dba3b7cce..c0a61e92cd33e 100644 --- a/include/kcl/kcl_drm.h +++ b/include/kcl/kcl_drm.h @@ -24,72 +24,6 @@ #include #include -#ifndef DP_ADJUST_REQUEST_POST_CURSOR2 -#define DP_ADJUST_REQUEST_POST_CURSOR2 0x20c -#endif - -#ifndef DP_TEST_MISC0 -#define DP_TEST_MISC0 0x232 -#endif - -#ifndef DP_TEST_PHY_PATTERN -#define DP_TEST_PHY_PATTERN 0x248 -#endif -#ifndef DP_TEST_80BIT_CUSTOM_PATTERN_7_0 -#define DP_TEST_80BIT_CUSTOM_PATTERN_7_0 0x250 -#endif -#ifndef DP_TEST_80BIT_CUSTOM_PATTERN_15_8 -#define DP_TEST_80BIT_CUSTOM_PATTERN_15_8 0x251 -#endif -#ifndef DP_TEST_80BIT_CUSTOM_PATTERN_23_16 -#define DP_TEST_80BIT_CUSTOM_PATTERN_23_16 0x252 -#endif -#ifndef DP_TEST_80BIT_CUSTOM_PATTERN_31_24 -#define DP_TEST_80BIT_CUSTOM_PATTERN_31_24 0x253 -#endif -#ifndef DP_TEST_80BIT_CUSTOM_PATTERN_39_32 -#define DP_TEST_80BIT_CUSTOM_PATTERN_39_32 0x254 -#endif -#ifndef DP_TEST_80BIT_CUSTOM_PATTERN_47_40 -#define DP_TEST_80BIT_CUSTOM_PATTERN_47_40 0x255 -#endif -#ifndef DP_TEST_80BIT_CUSTOM_PATTERN_55_48 -#define DP_TEST_80BIT_CUSTOM_PATTERN_55_48 0x256 -#endif -#ifndef DP_TEST_80BIT_CUSTOM_PATTERN_63_56 -#define DP_TEST_80BIT_CUSTOM_PATTERN_63_56 0x257 -#endif -#ifndef DP_TEST_80BIT_CUSTOM_PATTERN_71_64 -#define DP_TEST_80BIT_CUSTOM_PATTERN_71_64 0x258 -#endif -#ifndef DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -#define DP_TEST_80BIT_CUSTOM_PATTERN_79_72 0x259 -#endif - -#ifndef DP_BRANCH_REVISION_START -#define DP_BRANCH_REVISION_START 0x509 -#endif - -#ifndef DP_DP13_DPCD_REV -#define DP_DP13_DPCD_REV 0x2200 -#endif -#ifndef DP_DP13_MAX_LINK_RATE -#define DP_DP13_MAX_LINK_RATE 0x2201 -#endif - -#ifndef DP_LANE0_1_STATUS_ESI -#define DP_LANE0_1_STATUS_ESI 0x200c /* status same as 0x202 */ -#endif -#ifndef DP_LANE2_3_STATUS_ESI -#define DP_LANE2_3_STATUS_ESI 0x200d /* status same as 0x203 */ -#endif -#ifndef DP_LANE_ALIGN_STATUS_UPDATED_ESI -#define DP_LANE_ALIGN_STATUS_UPDATED_ESI 0x200e /* status same as 0x204 */ -#endif -#ifndef DP_SINK_STATUS_ESI -#define DP_SINK_STATUS_ESI 0x200f /* status same as 0x205 */ -#endif - #ifndef DRM_MODE_ROTATE_0 #define DRM_MODE_ROTATE_0 (1<<0) #endif diff --git a/include/kcl/kcl_drm_dp_helper.h b/include/kcl/kcl_drm_dp_helper.h index 8363c29e477fb..029dc257556ea 100644 --- a/include/kcl/kcl_drm_dp_helper.h +++ b/include/kcl/kcl_drm_dp_helper.h @@ -32,6 +32,45 @@ #include #include +/* + * v4.13-rc5-840-gc673fe7f0cd5 + * drm/dp: DPCD register defines for link status within ESI field + */ +#ifndef DP_LANE0_1_STATUS_ESI +#define DP_LANE0_1_STATUS_ESI 0x200c /* status same as 0x202 */ +#define DP_LANE2_3_STATUS_ESI 0x200d /* status same as 0x203 */ +#define DP_LANE_ALIGN_STATUS_UPDATED_ESI 0x200e /* status same as 0x204 */ +#define DP_SINK_STATUS_ESI 0x200f /* status same as 0x205 */ +#endif + +/* + * v4.13-rc5-1383-gac58fff15516 + * drm/dp-helper: add missing defines needed by AMD display core. + */ +#ifndef DP_ADJUST_REQUEST_POST_CURSOR2 +#define DP_ADJUST_REQUEST_POST_CURSOR2 0x20c + +#define DP_TEST_MISC0 0x232 + +#define DP_TEST_PHY_PATTERN 0x248 +#define DP_TEST_80BIT_CUSTOM_PATTERN_7_0 0x250 +#define DP_TEST_80BIT_CUSTOM_PATTERN_15_8 0x251 +#define DP_TEST_80BIT_CUSTOM_PATTERN_23_16 0x252 +#define DP_TEST_80BIT_CUSTOM_PATTERN_31_24 0x253 +#define DP_TEST_80BIT_CUSTOM_PATTERN_39_32 0x254 +#define DP_TEST_80BIT_CUSTOM_PATTERN_47_40 0x255 +#define DP_TEST_80BIT_CUSTOM_PATTERN_55_48 0x256 +#define DP_TEST_80BIT_CUSTOM_PATTERN_63_56 0x257 +#define DP_TEST_80BIT_CUSTOM_PATTERN_71_64 0x258 +#define DP_TEST_80BIT_CUSTOM_PATTERN_79_72 0x259 + +#define DP_BRANCH_REVISION_START 0x509 + +#define DP_DP13_DPCD_REV 0x2200 +#define DP_DP13_MAX_LINK_RATE 0x2201 +#endif + + #if !defined(DP_DPRX_FEATURE_ENUMERATION_LIST) #define DP_DPRX_FEATURE_ENUMERATION_LIST 0x2210 /* DP 1.3 */ #endif From a5c94245cf091a65a5362bc8e97809362b499fdb Mon Sep 17 00:00:00 2001 From: Jiansong Chen Date: Fri, 21 Aug 2020 11:30:19 +0800 Subject: [PATCH 10/66] drm/amd/pm: enable run_btc callback for sienna_cichlid DC BTC support for sienna_cichlid is added, it provides the DC tolerance and aging measurements. Signed-off-by: Jiansong Chen Reviewed-by: Kenneth Feng Change-Id: I93b439b99c1bf365194d61385eb0fe0251f27041 --- drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index 8ffa8b71b75fe..d2320ce7ef0db 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -95,6 +95,7 @@ static struct cmn2asic_msg_mapping sienna_cichlid_message_map[SMU_MSG_MAX_COUNT] MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 0), MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 0), MSG_MAP(UseDefaultPPTable, PPSMC_MSG_UseDefaultPPTable, 0), + MSG_MAP(RunDcBtc, PPSMC_MSG_RunDcBtc, 0), MSG_MAP(EnterBaco, PPSMC_MSG_EnterBaco, 0), MSG_MAP(SetSoftMinByFreq, PPSMC_MSG_SetSoftMinByFreq, 0), MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq, 0), @@ -1735,6 +1736,11 @@ static int sienna_cichlid_get_dpm_ultimate_freq(struct smu_context *smu, return ret; } +static int sienna_cichlid_run_btc(struct smu_context *smu) +{ + return smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL); +} + static bool sienna_cichlid_is_baco_supported(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; @@ -2792,6 +2798,7 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = { .mode1_reset = smu_v11_0_mode1_reset, .get_dpm_ultimate_freq = sienna_cichlid_get_dpm_ultimate_freq, .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range, + .run_btc = sienna_cichlid_run_btc, .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, .set_pp_feature_mask = smu_cmn_set_pp_feature_mask, .get_gpu_metrics = sienna_cichlid_get_gpu_metrics, From 0a9569acf9698dbd18541888779af0f1d3ac1f12 Mon Sep 17 00:00:00 2001 From: Jiansong Chen Date: Fri, 21 Aug 2020 16:20:47 +0800 Subject: [PATCH 11/66] drm/amd/pm: set VCN pg per instances When deciding whether to set pg for vcn1, instances number is more generic than chip name. Signed-off-by: Jiansong Chen Change-Id: I5bf3f024ac499c347e3ea72563ae75e4a540f321 --- drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index d2320ce7ef0db..66d655958a789 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -783,7 +783,7 @@ static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enabl ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0, NULL); if (ret) return ret; - if (adev->asic_type == CHIP_SIENNA_CICHLID) { + if (adev->vcn.num_vcn_inst > 1) { ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0x10000, NULL); if (ret) @@ -795,7 +795,7 @@ static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enabl ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, 0, NULL); if (ret) return ret; - if (adev->asic_type == CHIP_SIENNA_CICHLID) { + if (adev->vcn.num_vcn_inst > 1) { ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, 0x10000, NULL); if (ret) From 3f49b0266b482d333d210ab3db73a03985735b7d Mon Sep 17 00:00:00 2001 From: Dennis Li Date: Thu, 20 Aug 2020 10:06:32 +0800 Subject: [PATCH 12/66] drm/amdgpu: change reset lock from mutex to rw_semaphore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit clients don't need reset-lock for synchronization when no GPU recovery. v2: change to return the return value of down_read_killable. v3: if GPU recovery begin, VF ignore FLR notification. Reviewed-by: Monk Liu Acked-by: Christian König Signed-off-by: Dennis Li --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 23 ++++++++++++++------- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 +++--- drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c | 18 ++++++---------- drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c | 18 ++++++---------- 5 files changed, 32 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 45c3da6fbc993..70a944d79cac9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1002,7 +1002,7 @@ struct amdgpu_device { atomic_t in_gpu_reset; enum pp_mp1_state mp1_state; - struct mutex lock_reset; + struct rw_semaphore reset_sem; struct amdgpu_doorbell_index doorbell_index; #ifdef HAVE_AMDKCL_HMM_MIRROR_ENABLED diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index 1374d93b837ee..ca389879b1c2d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -122,14 +122,18 @@ static int amdgpu_debugfs_autodump_open(struct inode *inode, struct file *file) file->private_data = adev; - mutex_lock(&adev->lock_reset); + ret = down_read_killable(&adev->reset_sem); + if (ret) + return ret; + if (adev->autodump.dumping.done) { reinit_completion(&adev->autodump.dumping); ret = 0; } else { ret = -EBUSY; } - mutex_unlock(&adev->lock_reset); + + up_read(&adev->reset_sem); return ret; } @@ -1263,7 +1267,9 @@ static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data) } /* Avoid accidently unparking the sched thread during GPU reset */ - mutex_lock(&adev->lock_reset); + r = down_read_killable(&adev->reset_sem); + if (r) + return r; /* hold on the scheduler */ for (i = 0; i < AMDGPU_MAX_RINGS; i++) { @@ -1290,7 +1296,7 @@ static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data) kthread_unpark(ring->sched.thread); } - mutex_unlock(&adev->lock_reset); + up_read(&adev->reset_sem); pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); @@ -1480,7 +1486,9 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val) return -ENOMEM; /* Avoid accidently unparking the sched thread during GPU reset */ - mutex_lock(&adev->lock_reset); + r = down_read_killable(&adev->reset_sem); + if (r) + goto pro_end; /* stop the scheduler */ kthread_park(ring->sched.thread); @@ -1521,13 +1529,14 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val) /* restart the scheduler */ kthread_unpark(ring->sched.thread); - mutex_unlock(&adev->lock_reset); + up_read(&adev->reset_sem); ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched); +pro_end: kfree(fences); - return 0; + return r; } static int amdgpu_debugfs_sclk_set(void *data, u64 val) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 9bd5ea44c8820..05f7bf90a0813 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3068,7 +3068,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, mutex_init(&adev->virt.vf_errors.lock); hash_init(adev->mn_hash); atomic_set(&adev->in_gpu_reset, 0); - mutex_init(&adev->lock_reset); + init_rwsem(&adev->reset_sem); mutex_init(&adev->psp.mutex); #ifdef HAVE_AMDKCL_HMM_MIRROR_ENABLED mutex_init(&adev->notifier_lock); @@ -4242,7 +4242,7 @@ static bool amdgpu_device_lock_adev(struct amdgpu_device *adev) if (atomic_cmpxchg(&adev->in_gpu_reset, 0, 1) != 0) return false; - mutex_lock(&adev->lock_reset); + down_write(&adev->reset_sem); atomic_inc(&adev->gpu_reset_counter); switch (amdgpu_asic_reset_method(adev)) { @@ -4265,7 +4265,7 @@ static void amdgpu_device_unlock_adev(struct amdgpu_device *adev) amdgpu_vf_error_trans_all(adev); adev->mp1_state = PP_MP1_STATE_NONE; atomic_set(&adev->in_gpu_reset, 0); - mutex_unlock(&adev->lock_reset); + up_write(&adev->reset_sem); } static void amdgpu_device_resume_display_audio(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c index f27d83f2de789..9c07014d9bd6c 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c @@ -238,19 +238,15 @@ static void xgpu_ai_mailbox_flr_work(struct work_struct *work) struct amdgpu_virt *virt = container_of(work, struct amdgpu_virt, flr_work); struct amdgpu_device *adev = container_of(virt, struct amdgpu_device, virt); int timeout = AI_MAILBOX_POLL_FLR_TIMEDOUT; - int locked; /* block amdgpu_gpu_recover till msg FLR COMPLETE received, * otherwise the mailbox msg will be ruined/reseted by * the VF FLR. - * - * we can unlock the lock_reset to allow "amdgpu_job_timedout" - * to run gpu_recover() after FLR_NOTIFICATION_CMPL received - * which means host side had finished this VF's FLR. */ - locked = mutex_trylock(&adev->lock_reset); - if (locked) - atomic_set(&adev->in_gpu_reset, 1); + if (!down_read_trylock(&adev->reset_sem)) + return; + + atomic_set(&adev->in_gpu_reset, 1); do { if (xgpu_ai_mailbox_peek_msg(adev) == IDH_FLR_NOTIFICATION_CMPL) @@ -261,10 +257,8 @@ static void xgpu_ai_mailbox_flr_work(struct work_struct *work) } while (timeout > 1); flr_done: - if (locked) { - atomic_set(&adev->in_gpu_reset, 0); - mutex_unlock(&adev->lock_reset); - } + atomic_set(&adev->in_gpu_reset, 0); + up_read(&adev->reset_sem); /* Trigger recovery for world switch failure if no TDR */ if (amdgpu_device_should_recover_gpu(adev) diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c index 3cb10ab943a66..9c23abf9b140d 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c @@ -259,19 +259,15 @@ static void xgpu_nv_mailbox_flr_work(struct work_struct *work) struct amdgpu_virt *virt = container_of(work, struct amdgpu_virt, flr_work); struct amdgpu_device *adev = container_of(virt, struct amdgpu_device, virt); int timeout = NV_MAILBOX_POLL_FLR_TIMEDOUT; - int locked; /* block amdgpu_gpu_recover till msg FLR COMPLETE received, * otherwise the mailbox msg will be ruined/reseted by * the VF FLR. - * - * we can unlock the lock_reset to allow "amdgpu_job_timedout" - * to run gpu_recover() after FLR_NOTIFICATION_CMPL received - * which means host side had finished this VF's FLR. */ - locked = mutex_trylock(&adev->lock_reset); - if (locked) - atomic_set(&adev->in_gpu_reset, 1); + if (!down_read_trylock(&adev->reset_sem)) + return; + + atomic_set(&adev->in_gpu_reset, 1); do { if (xgpu_nv_mailbox_peek_msg(adev) == IDH_FLR_NOTIFICATION_CMPL) @@ -282,10 +278,8 @@ static void xgpu_nv_mailbox_flr_work(struct work_struct *work) } while (timeout > 1); flr_done: - if (locked) { - atomic_set(&adev->in_gpu_reset, 0); - mutex_unlock(&adev->lock_reset); - } + atomic_set(&adev->in_gpu_reset, 0); + up_read(&adev->reset_sem); /* Trigger recovery for world switch failure if no TDR */ if (amdgpu_device_should_recover_gpu(adev) From 40d4aaeecaf02f25898b51d770cbc68b3215c19f Mon Sep 17 00:00:00 2001 From: Yang Xiong Date: Tue, 25 Aug 2020 12:24:13 +0800 Subject: [PATCH 13/66] drm/amdkcl: test whether down_read_killable is available introduced by v4.14-rc4-65-g76f8507f7a64 This patch is caused by 'drm/amdgpu: change reset lock from mutex to rw_semaphore' Change-Id: Id9bb8634318333302388fe43366f25763304d687 Signed-off-by: Yang Xiong Reviewed-by: Dennis Li --- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 12 ++++++++++++ drivers/gpu/drm/amd/dkms/config/config.h | 3 +++ drivers/gpu/drm/amd/dkms/m4/down-read-killable.m4 | 14 ++++++++++++++ drivers/gpu/drm/amd/dkms/m4/kernel.m4 | 1 + 4 files changed, 30 insertions(+) create mode 100644 drivers/gpu/drm/amd/dkms/m4/down-read-killable.m4 diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index ca389879b1c2d..02dbc4700d11d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -122,9 +122,13 @@ static int amdgpu_debugfs_autodump_open(struct inode *inode, struct file *file) file->private_data = adev; +#ifdef HAVE_DOWN_READ_KILLABLE ret = down_read_killable(&adev->reset_sem); if (ret) return ret; +#else + down_read(&adev->reset_sem); +#endif if (adev->autodump.dumping.done) { reinit_completion(&adev->autodump.dumping); @@ -1267,9 +1271,13 @@ static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data) } /* Avoid accidently unparking the sched thread during GPU reset */ +#ifdef HAVE_DOWN_READ_KILLABLE r = down_read_killable(&adev->reset_sem); if (r) return r; +#else + down_read(&adev->reset_sem); +#endif /* hold on the scheduler */ for (i = 0; i < AMDGPU_MAX_RINGS; i++) { @@ -1486,9 +1494,13 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val) return -ENOMEM; /* Avoid accidently unparking the sched thread during GPU reset */ +#ifdef HAVE_DOWN_READ_KILLABLE r = down_read_killable(&adev->reset_sem); if (r) goto pro_end; +#else + down_read(&adev->reset_sem); +#endif /* stop the scheduler */ kthread_park(ring->sched.thread); diff --git a/drivers/gpu/drm/amd/dkms/config/config.h b/drivers/gpu/drm/amd/dkms/config/config.h index d3f4a947a815e..f91370cd5a538 100644 --- a/drivers/gpu/drm/amd/dkms/config/config.h +++ b/drivers/gpu/drm/amd/dkms/config/config.h @@ -82,6 +82,9 @@ /* dma_resv->seq is available */ #define HAVE_DMA_RESV_SEQ 1 +/* down_read_killable() is available */ +#define HAVE_DOWN_READ_KILLABLE 1 + /* down_write_killable() is available */ #define HAVE_DOWN_WRITE_KILLABLE 1 diff --git a/drivers/gpu/drm/amd/dkms/m4/down-read-killable.m4 b/drivers/gpu/drm/amd/dkms/m4/down-read-killable.m4 new file mode 100644 index 0000000000000..6de71b3c0a40d --- /dev/null +++ b/drivers/gpu/drm/amd/dkms/m4/down-read-killable.m4 @@ -0,0 +1,14 @@ +#dnl +#dnl commit v4.14-rc4-65-g76f8507f7a64 +#dnl locking/rwsem: Add down_read_killable() +#dnl +AC_DEFUN([AC_AMDGPU_DOWN_READ_KILLABLE], [ + AC_KERNEL_DO_BACKGROUND([ + AC_KERNEL_CHECK_SYMBOL_EXPORT( + [down_read_killable], + [kernel/locking/rwsem.c], + [AC_DEFINE(HAVE_DOWN_READ_KILLABLE, 1, + [down_read_killable() is available])] + ) + ]) +]) diff --git a/drivers/gpu/drm/amd/dkms/m4/kernel.m4 b/drivers/gpu/drm/amd/dkms/m4/kernel.m4 index 4e792434b6739..229fbc5137e6f 100644 --- a/drivers/gpu/drm/amd/dkms/m4/kernel.m4 +++ b/drivers/gpu/drm/amd/dkms/m4/kernel.m4 @@ -199,6 +199,7 @@ AC_DEFUN([AC_CONFIG_KERNEL], [ AC_AMDGPU_DRM_CRTC_ENABLE_COLOR_MGMT AC_AMDGPU_DRM_CONNECTOR_STATE_HDCP_CONTENT_TYPE AC_AMDGPU_DRM_HDCP_UPDATE_CONTENT_PROTECTION + AC_AMDGPU_DOWN_READ_KILLABLE AC_KERNEL_WAIT AS_IF([test "$LINUX_OBJ" != "$LINUX"], [ From 47f40f8a972ee491c292c3896e0b80f5b2bb5ec2 Mon Sep 17 00:00:00 2001 From: Dennis Li Date: Thu, 20 Aug 2020 10:17:39 +0800 Subject: [PATCH 14/66] drm/amdgpu: fix the nullptr issue when reenter GPU recovery in single gpu system, if driver reenter gpu recovery, amdgpu_device_lock_adev will return false, but hive is nullptr now. Reviewed-by: Hawking Zhang Signed-off-by: Dennis Li --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 05f7bf90a0813..f9c8e62f331ef 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4407,8 +4407,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, if (!amdgpu_device_lock_adev(tmp_adev)) { DRM_INFO("Bailing on TDR for s_job:%llx, as another already in progress", job ? job->base.id : -1); - mutex_unlock(&hive->hive_lock); - return 0; + r = 0; + goto skip_recovery; } /* @@ -4541,6 +4541,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, amdgpu_device_unlock_adev(tmp_adev); } +skip_recovery: if (hive) { atomic_set(&hive->in_reset, 0); mutex_unlock(&hive->hive_lock); From 54a5f4bd702fa2ae4b3607f3bce9cbc7cd64c7a3 Mon Sep 17 00:00:00 2001 From: Dennis Li Date: Thu, 20 Aug 2020 10:40:53 +0800 Subject: [PATCH 15/66] drm/amdgpu: refine message print for devices of hive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using dev_xxx instead of DRM_xxx/pr_xxx to indicate which device of a hive is the message for. Reviewed-by: Christian König Signed-off-by: Dennis Li --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 32 +++++++++++----------- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 4 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 2 +- drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index f9c8e62f331ef..694a3f3299b9a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3388,7 +3388,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) { int r; - DRM_INFO("amdgpu: finishing device.\n"); + dev_info(adev->dev, "amdgpu: finishing device.\n"); flush_delayed_work(&adev->delayed_init_work); adev->shutdown = true; @@ -3585,12 +3585,12 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon) if (amdgpu_device_need_post(adev)) { r = amdgpu_atom_asic_init(adev->mode_info.atom_context); if (r) - DRM_ERROR("amdgpu asic init failed\n"); + dev_err(adev->dev, "amdgpu asic init failed\n"); } r = amdgpu_device_ip_resume(adev); if (r) { - DRM_ERROR("amdgpu_device_ip_resume failed (%d).\n", r); + dev_err(adev->dev, "amdgpu_device_ip_resume failed (%d).\n", r); return r; } amdgpu_fence_driver_resume(adev); @@ -3614,7 +3614,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon) if (r == 0) { r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM); if (r != 0) - DRM_ERROR("Failed to pin cursor BO (%d)\n", r); + dev_err(adev->dev, "Failed to pin cursor BO (%d)\n", r); amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj); amdgpu_bo_unreserve(aobj); } @@ -3710,7 +3710,7 @@ static bool amdgpu_device_ip_check_soft_reset(struct amdgpu_device *adev) adev->ip_blocks[i].status.hang = adev->ip_blocks[i].version->funcs->check_soft_reset(adev); if (adev->ip_blocks[i].status.hang) { - DRM_INFO("IP block:%s is hung!\n", adev->ip_blocks[i].version->funcs->name); + dev_info(adev->dev, "IP block:%s is hung!\n", adev->ip_blocks[i].version->funcs->name); asic_hang = true; } } @@ -3771,7 +3771,7 @@ static bool amdgpu_device_ip_need_full_reset(struct amdgpu_device *adev) (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE) || adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP) { if (adev->ip_blocks[i].status.hang) { - DRM_INFO("Some block need full reset!\n"); + dev_info(adev->dev, "Some block need full reset!\n"); return true; } } @@ -3859,7 +3859,7 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev) else tmo = msecs_to_jiffies(100); - DRM_INFO("recover vram bo from shadow start\n"); + dev_info(adev->dev, "recover vram bo from shadow start\n"); mutex_lock(&adev->shadow_list_lock); list_for_each_entry(shadow, &adev->shadow_list, shadow_list) { @@ -3895,11 +3895,11 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev) dma_fence_put(fence); if (r < 0 || tmo <= 0) { - DRM_ERROR("recover vram bo from shadow failed, r is %ld, tmo is %ld\n", r, tmo); + dev_err(adev->dev, "recover vram bo from shadow failed, r is %ld, tmo is %ld\n", r, tmo); return -EIO; } - DRM_INFO("recover vram bo from shadow done\n"); + dev_info(adev->dev, "recover vram bo from shadow done\n"); return 0; } @@ -3998,7 +3998,7 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev) bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev) { if (!amdgpu_device_ip_check_soft_reset(adev)) { - DRM_INFO("Timeout, but no hardware hang detected.\n"); + dev_info(adev->dev, "Timeout, but no hardware hang detected.\n"); return false; } @@ -4038,7 +4038,7 @@ bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev) return true; disabled: - DRM_INFO("GPU recovery disabled.\n"); + dev_info(adev->dev, "GPU recovery disabled.\n"); return false; } @@ -4077,7 +4077,7 @@ static int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, r = amdgpu_device_ip_soft_reset(adev); amdgpu_device_ip_post_soft_reset(adev); if (r || amdgpu_device_ip_check_soft_reset(adev)) { - DRM_INFO("soft reset failed, will fallback to full reset!\n"); + dev_info(adev->dev, "soft reset failed, will fallback to full reset!\n"); need_full_reset = true; } } @@ -4113,7 +4113,7 @@ static int amdgpu_do_asic_reset(struct amdgpu_hive_info *hive, r = amdgpu_asic_reset(tmp_adev); if (r) { - DRM_ERROR("ASIC reset failed with error, %d for drm dev, %s", + dev_err(tmp_adev->dev, "ASIC reset failed with error, %d for drm dev, %s", r, tmp_adev->ddev->unique); break; } @@ -4147,7 +4147,7 @@ static int amdgpu_do_asic_reset(struct amdgpu_hive_info *hive, if (need_full_reset) { /* post card */ if (amdgpu_atom_asic_init(tmp_adev->mode_info.atom_context)) - DRM_WARN("asic atom init failed!"); + dev_warn(tmp_adev->dev, "asic atom init failed!"); if (!r) { dev_info(tmp_adev->dev, "GPU reset succeeded, trying to resume\n"); @@ -4405,7 +4405,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, /* block all schedulers and reset given job's ring */ list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) { if (!amdgpu_device_lock_adev(tmp_adev)) { - DRM_INFO("Bailing on TDR for s_job:%llx, as another already in progress", + dev_info(tmp_adev->dev, "Bailing on TDR for s_job:%llx, as another already in progress", job ? job->base.id : -1); r = 0; goto skip_recovery; @@ -4480,7 +4480,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, &need_full_reset); /*TODO Should we stop ?*/ if (r) { - DRM_ERROR("GPU pre asic reset failed with err, %d for drm dev, %s ", + dev_err(tmp_adev->dev, "GPU pre asic reset failed with err, %d for drm dev, %s ", r, tmp_adev->ddev->unique); tmp_adev->asic_reset_res = r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index ebea3f6558268..d6981425ec510 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -743,7 +743,7 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg) failed_kiq_read: if (reg_val_offs) amdgpu_device_wb_free(adev, reg_val_offs); - pr_err("failed to read reg:%x\n", reg); + dev_err(adev->dev, "failed to read reg:%x\n", reg); return ~0; } @@ -796,5 +796,5 @@ void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v) amdgpu_ring_undo(ring); spin_unlock_irqrestore(&kiq->ring_lock, flags); failed_kiq_write: - pr_err("failed to write reg:%x\n", reg); + dev_err(adev->dev, "failed to write reg:%x\n", reg); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index ae720a6dc5a0a..d84649b4d51a0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -93,7 +93,7 @@ void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev, amdgpu_ring_undo(ring); spin_unlock_irqrestore(&kiq->ring_lock, flags); failed_kiq: - pr_err("failed to write reg %x wait reg %x\n", reg0, reg1); + dev_err(adev->dev, "failed to write reg %x wait reg %x\n", reg0, reg1); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c index 73285355c6195..8e9fb8afc646c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c @@ -391,7 +391,7 @@ static int gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev, spin_unlock(&adev->gfx.kiq.ring_lock); r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout); if (r < 1) { - DRM_ERROR("wait for kiq fence error: %ld.\n", r); + dev_err(adev->dev, "wait for kiq fence error: %ld.\n", r); return -ETIME; } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 86f20426c4afb..e1a0ae327cf5a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -633,7 +633,7 @@ static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev, spin_unlock(&adev->gfx.kiq.ring_lock); r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout); if (r < 1) { - DRM_ERROR("wait for kiq fence error: %ld.\n", r); + dev_err(adev->dev, "wait for kiq fence error: %ld.\n", r); return -ETIME; } From e84f03e4b8183d795e7b6412cf93cce41debdb7e Mon Sep 17 00:00:00 2001 From: Dennis Li Date: Tue, 18 Aug 2020 18:44:17 +0800 Subject: [PATCH 16/66] drm/amdgpu: refine create and release logic of hive info Change to dynamically create and release hive info object, which help driver support more hives in the future. v2: Change to save hive object pointer in adev, to avoid locking xgmi_mutex every time when calling amdgpu_get_xgmi_hive. v3: 1. Change type of hive object pointer in adev from void* to amdgpu_hive_info*. 2. remove unnecessary variable initialization. Reviewed-by: Hawking Zhang Signed-off-by: Dennis Li --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 208 +++++++++++---------- drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h | 14 +- 5 files changed, 131 insertions(+), 106 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 70a944d79cac9..128e1dd5d7476 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -254,6 +254,7 @@ struct amdgpu_fpriv; struct amdgpu_bo_va_mapping; struct amdgpu_atif; struct kfd_vm_fault_info; +struct amdgpu_hive_info; enum amdgpu_cp_irq { AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP = 0, @@ -773,7 +774,7 @@ struct amdgpu_device { #ifdef CONFIG_DRM_AMD_ACP struct amdgpu_acp acp; #endif - + struct amdgpu_hive_info *hive; /* ASIC */ enum amd_asic_type asic_type; uint32_t family; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 694a3f3299b9a..bb3fd53950dda 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2871,7 +2871,7 @@ static void amdgpu_device_xgmi_reset_func(struct work_struct *__work) { struct amdgpu_device *adev = container_of(__work, struct amdgpu_device, xgmi_reset_work); - struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev, 0); + struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev); /* It's a bug to not have a hive within this function */ if (WARN_ON(!hive)) @@ -2909,6 +2909,7 @@ static void amdgpu_device_xgmi_reset_func(struct work_struct *__work) if (adev->asic_reset_res) DRM_WARN("ASIC reset failed with error, %d for drm dev, %s", adev->asic_reset_res, adev->ddev->unique); + amdgpu_put_xgmi_hive(hive); } static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev) @@ -4375,11 +4376,12 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, * We always reset all schedulers for device and all devices for XGMI * hive so that should take care of them too. */ - hive = amdgpu_get_xgmi_hive(adev, false); + hive = amdgpu_get_xgmi_hive(adev); if (hive) { if (atomic_cmpxchg(&hive->in_reset, 0, 1) != 0) { DRM_INFO("Bailing on TDR for s_job:%llx, hive: %llx as another already in progress", job ? job->base.id : -1, hive->hive_id); + amdgpu_put_xgmi_hive(hive); return 0; } mutex_lock(&hive->hive_lock); @@ -4545,6 +4547,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, if (hive) { atomic_set(&hive->in_reset, 0); mutex_unlock(&hive->hive_lock); + amdgpu_put_xgmi_hive(hive); } if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index fa2c28ae97854..ec377a8147a21 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -1554,9 +1554,10 @@ static void amdgpu_ras_do_recovery(struct work_struct *work) struct amdgpu_device *remote_adev = NULL; struct amdgpu_device *adev = ras->adev; struct list_head device_list, *device_list_handle = NULL; - struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev, false); if (!ras->disable_ras_err_cnt_harvest) { + struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev); + /* Build list of devices to query RAS related errors */ if (hive && adev->gmc.xgmi.num_physical_nodes > 1) { device_list_handle = &hive->device_list; @@ -1569,6 +1570,8 @@ static void amdgpu_ras_do_recovery(struct work_struct *work) list_for_each_entry(remote_adev, device_list_handle, gmc.xgmi.head) amdgpu_ras_log_on_err_counter(remote_adev); + + amdgpu_put_xgmi_hive(hive); } if (amdgpu_device_should_recover_gpu(ras->adev)) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index a15e35243ea59..192dfc6e3e7d0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -35,11 +35,9 @@ static DEFINE_MUTEX(xgmi_mutex); -#define AMDGPU_MAX_XGMI_HIVE 8 #define AMDGPU_MAX_XGMI_DEVICE_PER_HIVE 4 -static struct amdgpu_hive_info xgmi_hives[AMDGPU_MAX_XGMI_HIVE]; -static unsigned hive_count = 0; +static LIST_HEAD(xgmi_hive_list); static const int xgmi_pcs_err_status_reg_vg20[] = { smnXGMI0_PCS_GOPX16_PCS_ERROR_STATUS, @@ -171,59 +169,47 @@ static const struct amdgpu_pcs_ras_field wafl_pcs_ras_fields[] = { * */ +static struct attribute amdgpu_xgmi_hive_id = { + .name = "xgmi_hive_id", + .mode = S_IRUGO +}; -static ssize_t amdgpu_xgmi_show_hive_id(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct amdgpu_hive_info *hive = - container_of(attr, struct amdgpu_hive_info, dev_attr); - - return snprintf(buf, PAGE_SIZE, "%llu\n", hive->hive_id); -} +static struct attribute *amdgpu_xgmi_hive_attrs[] = { + &amdgpu_xgmi_hive_id, + NULL +}; -static int amdgpu_xgmi_sysfs_create(struct amdgpu_device *adev, - struct amdgpu_hive_info *hive) +static ssize_t amdgpu_xgmi_show_attrs(struct kobject *kobj, + struct attribute *attr, char *buf) { - int ret = 0; - - if (WARN_ON(hive->kobj)) - return -EINVAL; - - hive->kobj = kobject_create_and_add("xgmi_hive_info", &adev->dev->kobj); - if (!hive->kobj) { - dev_err(adev->dev, "XGMI: Failed to allocate sysfs entry!\n"); - return -EINVAL; - } - - hive->dev_attr = (struct device_attribute) { - .attr = { - .name = "xgmi_hive_id", - .mode = S_IRUGO, + struct amdgpu_hive_info *hive = container_of( + kobj, struct amdgpu_hive_info, kobj); - }, - .show = amdgpu_xgmi_show_hive_id, - }; - - ret = sysfs_create_file(hive->kobj, &hive->dev_attr.attr); - if (ret) { - dev_err(adev->dev, "XGMI: Failed to create device file xgmi_hive_id\n"); - kobject_del(hive->kobj); - kobject_put(hive->kobj); - hive->kobj = NULL; - } + if (attr == &amdgpu_xgmi_hive_id) + return snprintf(buf, PAGE_SIZE, "%llu\n", hive->hive_id); - return ret; + return 0; } -static void amdgpu_xgmi_sysfs_destroy(struct amdgpu_device *adev, - struct amdgpu_hive_info *hive) +static void amdgpu_xgmi_hive_release(struct kobject *kobj) { - sysfs_remove_file(hive->kobj, &hive->dev_attr.attr); - kobject_del(hive->kobj); - kobject_put(hive->kobj); - hive->kobj = NULL; + struct amdgpu_hive_info *hive = container_of( + kobj, struct amdgpu_hive_info, kobj); + + mutex_destroy(&hive->hive_lock); + kfree(hive); } +static const struct sysfs_ops amdgpu_xgmi_hive_ops = { + .show = amdgpu_xgmi_show_attrs, +}; + +struct kobj_type amdgpu_xgmi_hive_type = { + .release = amdgpu_xgmi_hive_release, + .sysfs_ops = &amdgpu_xgmi_hive_ops, + .default_attrs = amdgpu_xgmi_hive_attrs, +}; + static ssize_t amdgpu_xgmi_show_device_id(struct device *dev, struct device_attribute *attr, char *buf) @@ -287,8 +273,8 @@ static int amdgpu_xgmi_sysfs_add_dev_info(struct amdgpu_device *adev, /* Create sysfs link to hive info folder on the first device */ - if (adev != hive->adev) { - ret = sysfs_create_link(&adev->dev->kobj, hive->kobj, + if (hive->kobj.parent != (&adev->dev->kobj)) { + ret = sysfs_create_link(&adev->dev->kobj, &hive->kobj, "xgmi_hive_info"); if (ret) { dev_err(adev->dev, "XGMI: Failed to create link to hive info"); @@ -296,9 +282,9 @@ static int amdgpu_xgmi_sysfs_add_dev_info(struct amdgpu_device *adev, } } - sprintf(node, "node%d", hive->number_devices); + sprintf(node, "node%d", atomic_read(&hive->number_devices)); /* Create sysfs link form the hive folder to yourself */ - ret = sysfs_create_link(hive->kobj, &adev->dev->kobj, node); + ret = sysfs_create_link(&hive->kobj, &adev->dev->kobj, node); if (ret) { dev_err(adev->dev, "XGMI: Failed to create link from hive info"); goto remove_link; @@ -326,78 +312,96 @@ static void amdgpu_xgmi_sysfs_rem_dev_info(struct amdgpu_device *adev, device_remove_file(adev->dev, &dev_attr_xgmi_device_id); device_remove_file(adev->dev, &dev_attr_xgmi_error); - if (adev != hive->adev) + if (hive->kobj.parent != (&adev->dev->kobj)) sysfs_remove_link(&adev->dev->kobj,"xgmi_hive_info"); - sprintf(node, "node%d", hive->number_devices); - sysfs_remove_link(hive->kobj, node); + sprintf(node, "node%d", atomic_read(&hive->number_devices)); + sysfs_remove_link(&hive->kobj, node); } -struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev, int lock) +struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev) { - int i; - struct amdgpu_hive_info *tmp; + struct amdgpu_hive_info *hive = NULL, *tmp = NULL; + int ret; if (!adev->gmc.xgmi.hive_id) return NULL; + if (adev->hive) { + kobject_get(&adev->hive->kobj); + return adev->hive; + } + mutex_lock(&xgmi_mutex); - for (i = 0 ; i < hive_count; ++i) { - tmp = &xgmi_hives[i]; - if (tmp->hive_id == adev->gmc.xgmi.hive_id) { - if (lock) - mutex_lock(&tmp->hive_lock); - mutex_unlock(&xgmi_mutex); - return tmp; + if (!list_empty(&xgmi_hive_list)) { + list_for_each_entry_safe(hive, tmp, &xgmi_hive_list, node) { + if (hive->hive_id == adev->gmc.xgmi.hive_id) + goto pro_end; } } - if (i >= AMDGPU_MAX_XGMI_HIVE) { - mutex_unlock(&xgmi_mutex); - return NULL; + + hive = kzalloc(sizeof(*hive), GFP_KERNEL); + if (!hive) { + dev_err(adev->dev, "XGMI: allocation failed\n"); + hive = NULL; + goto pro_end; } /* initialize new hive if not exist */ - tmp = &xgmi_hives[hive_count++]; - - if (amdgpu_xgmi_sysfs_create(adev, tmp)) { - mutex_unlock(&xgmi_mutex); - return NULL; + ret = kobject_init_and_add(&hive->kobj, + &amdgpu_xgmi_hive_type, + &adev->dev->kobj, + "%s", "xgmi_hive_info"); + if (ret) { + dev_err(adev->dev, "XGMI: failed initializing kobject for xgmi hive\n"); + kfree(hive); + hive = NULL; + goto pro_end; } - tmp->adev = adev; - tmp->hive_id = adev->gmc.xgmi.hive_id; - INIT_LIST_HEAD(&tmp->device_list); - mutex_init(&tmp->hive_lock); - atomic_set(&tmp->in_reset, 0); - task_barrier_init(&tmp->tb); - - if (lock) - mutex_lock(&tmp->hive_lock); - tmp->pstate = AMDGPU_XGMI_PSTATE_UNKNOWN; - tmp->hi_req_gpu = NULL; + hive->hive_id = adev->gmc.xgmi.hive_id; + INIT_LIST_HEAD(&hive->device_list); + INIT_LIST_HEAD(&hive->node); + mutex_init(&hive->hive_lock); + atomic_set(&hive->in_reset, 0); + atomic_set(&hive->number_devices, 0); + task_barrier_init(&hive->tb); + hive->pstate = AMDGPU_XGMI_PSTATE_UNKNOWN; + hive->hi_req_gpu = NULL; /* * hive pstate on boot is high in vega20 so we have to go to low * pstate on after boot. */ - tmp->hi_req_count = AMDGPU_MAX_XGMI_DEVICE_PER_HIVE; + hive->hi_req_count = AMDGPU_MAX_XGMI_DEVICE_PER_HIVE; + list_add_tail(&hive->node, &xgmi_hive_list); + +pro_end: + if (hive) + kobject_get(&hive->kobj); mutex_unlock(&xgmi_mutex); + return hive; +} - return tmp; +void amdgpu_put_xgmi_hive(struct amdgpu_hive_info *hive) +{ + if (hive) + kobject_put(&hive->kobj); } int amdgpu_xgmi_set_pstate(struct amdgpu_device *adev, int pstate) { int ret = 0; - struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev, 0); + struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev); struct amdgpu_device *request_adev = hive->hi_req_gpu ? hive->hi_req_gpu : adev; bool is_hi_req = pstate == AMDGPU_XGMI_PSTATE_MAX_VEGA20; bool init_low = hive->pstate == AMDGPU_XGMI_PSTATE_UNKNOWN; + amdgpu_put_xgmi_hive(hive); /* fw bug so temporarily disable pstate switching */ return 0; @@ -449,7 +453,7 @@ int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_dev /* Each psp need to set the latest topology */ ret = psp_xgmi_set_topology_info(&adev->psp, - hive->number_devices, + atomic_read(&hive->number_devices), &adev->psp.xgmi_context.top_info); if (ret) dev_err(adev->dev, @@ -511,7 +515,7 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev) adev->gmc.xgmi.node_id = adev->gmc.xgmi.physical_node_id + 16; } - hive = amdgpu_get_xgmi_hive(adev, 1); + hive = amdgpu_get_xgmi_hive(adev); if (!hive) { ret = -EINVAL; dev_err(adev->dev, @@ -519,6 +523,7 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev) adev->gmc.xgmi.node_id, adev->gmc.xgmi.hive_id); goto exit; } + mutex_lock(&hive->hive_lock); top_info = &adev->psp.xgmi_context.top_info; @@ -526,7 +531,7 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev) list_for_each_entry(entry, &hive->device_list, head) top_info->nodes[count++].node_id = entry->node_id; top_info->num_nodes = count; - hive->number_devices = count; + atomic_set(&hive->number_devices, count); task_barrier_add_task(&hive->tb); @@ -565,35 +570,48 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev) exit_unlock: mutex_unlock(&hive->hive_lock); exit: - if (!ret) + if (!ret) { + adev->hive = hive; dev_info(adev->dev, "XGMI: Add node %d, hive 0x%llx.\n", adev->gmc.xgmi.physical_node_id, adev->gmc.xgmi.hive_id); - else + } else { + amdgpu_put_xgmi_hive(hive); dev_err(adev->dev, "XGMI: Failed to add node %d, hive 0x%llx ret: %d\n", adev->gmc.xgmi.physical_node_id, adev->gmc.xgmi.hive_id, ret); + } return ret; } int amdgpu_xgmi_remove_device(struct amdgpu_device *adev) { - struct amdgpu_hive_info *hive; + struct amdgpu_hive_info *hive = adev->hive; if (!adev->gmc.xgmi.supported) return -EINVAL; - hive = amdgpu_get_xgmi_hive(adev, 1); if (!hive) return -EINVAL; + mutex_lock(&hive->hive_lock); task_barrier_rem_task(&hive->tb); amdgpu_xgmi_sysfs_rem_dev_info(adev, hive); + if (hive->hi_req_gpu == adev) + hive->hi_req_gpu = NULL; + list_del(&adev->gmc.xgmi.head); mutex_unlock(&hive->hive_lock); - if(!(--hive->number_devices)){ - amdgpu_xgmi_sysfs_destroy(adev, hive); - mutex_destroy(&hive->hive_lock); + amdgpu_put_xgmi_hive(hive); + adev->hive = NULL; + + if (atomic_dec_return(&hive->number_devices) == 0) { + /* Remove the hive from global hive list */ + mutex_lock(&xgmi_mutex); + list_del(&hive->node); + mutex_unlock(&xgmi_mutex); + + amdgpu_put_xgmi_hive(hive); } return psp_xgmi_terminate(&adev->psp); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h index 453336ca96757..148560d635543 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h @@ -27,13 +27,12 @@ struct amdgpu_hive_info { - uint64_t hive_id; - struct list_head device_list; - int number_devices; + struct kobject kobj; + uint64_t hive_id; + struct list_head device_list; + struct list_head node; + atomic_t number_devices; struct mutex hive_lock; - struct kobject *kobj; - struct device_attribute dev_attr; - struct amdgpu_device *adev; atomic_t in_reset; int hi_req_count; struct amdgpu_device *hi_req_gpu; @@ -51,7 +50,8 @@ struct amdgpu_pcs_ras_field { uint32_t pcs_err_shift; }; -struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev, int lock); +struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev); +void amdgpu_put_xgmi_hive(struct amdgpu_hive_info *hive); int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_device *adev); int amdgpu_xgmi_add_device(struct amdgpu_device *adev); int amdgpu_xgmi_remove_device(struct amdgpu_device *adev); From 0e941d0a68330e0157b9f1f496cec26c27329ad9 Mon Sep 17 00:00:00 2001 From: Dennis Li Date: Thu, 6 Aug 2020 14:48:15 +0800 Subject: [PATCH 17/66] drm/amdgpu: annotate a false positive recursive locking Re-apply commit 4fe159da08343cf2340593894d14cab896cf4c43 [ 584.110304] ============================================ [ 584.110590] WARNING: possible recursive locking detected [ 584.110876] 5.6.0-deli-v5.6-2848-g3f3109b0e75f #1 Tainted: G OE [ 584.111164] -------------------------------------------- [ 584.111456] kworker/38:1/553 is trying to acquire lock: [ 584.111721] ffff9b15ff0a47a0 (&adev->reset_sem){++++}, at: amdgpu_device_gpu_recover+0x262/0x1030 [amdgpu] [ 584.112112] but task is already holding lock: [ 584.112673] ffff9b1603d247a0 (&adev->reset_sem){++++}, at: amdgpu_device_gpu_recover+0x262/0x1030 [amdgpu] [ 584.113068] other info that might help us debug this: [ 584.113689] Possible unsafe locking scenario: [ 584.114350] CPU0 [ 584.114685] ---- [ 584.115014] lock(&adev->reset_sem); [ 584.115349] lock(&adev->reset_sem); [ 584.115678] *** DEADLOCK *** [ 584.116624] May be due to missing lock nesting notation [ 584.117284] 4 locks held by kworker/38:1/553: [ 584.117616] #0: ffff9ad635c1d348 ((wq_completion)events){+.+.}, at: process_one_work+0x21f/0x630 [ 584.117967] #1: ffffac708e1c3e58 ((work_completion)(&con->recovery_work)){+.+.}, at: process_one_work+0x21f/0x630 [ 584.118358] #2: ffffffffc1c2a5d0 (&tmp->hive_lock){+.+.}, at: amdgpu_device_gpu_recover+0xae/0x1030 [amdgpu] [ 584.118786] #3: ffff9b1603d247a0 (&adev->reset_sem){++++}, at: amdgpu_device_gpu_recover+0x262/0x1030 [amdgpu] [ 584.119222] stack backtrace: [ 584.119990] CPU: 38 PID: 553 Comm: kworker/38:1 Kdump: loaded Tainted: G OE 5.6.0-deli-v5.6-2848-g3f3109b0e75f #1 [ 584.120782] Hardware name: Supermicro SYS-7049GP-TRT/X11DPG-QT, BIOS 3.1 05/23/2019 [ 584.121223] Workqueue: events amdgpu_ras_do_recovery [amdgpu] [ 584.121638] Call Trace: [ 584.122050] dump_stack+0x98/0xd5 [ 584.122499] __lock_acquire+0x1139/0x16e0 [ 584.122931] ? trace_hardirqs_on+0x3b/0xf0 [ 584.123358] ? cancel_delayed_work+0xa6/0xc0 [ 584.123771] lock_acquire+0xb8/0x1c0 [ 584.124197] ? amdgpu_device_gpu_recover+0x262/0x1030 [amdgpu] [ 584.124599] down_write+0x49/0x120 [ 584.125032] ? amdgpu_device_gpu_recover+0x262/0x1030 [amdgpu] [ 584.125472] amdgpu_device_gpu_recover+0x262/0x1030 [amdgpu] [ 584.125910] ? amdgpu_ras_error_query+0x1b8/0x2a0 [amdgpu] [ 584.126367] amdgpu_ras_do_recovery+0x159/0x190 [amdgpu] [ 584.126789] process_one_work+0x29e/0x630 [ 584.127208] worker_thread+0x3c/0x3f0 [ 584.127621] ? __kthread_parkme+0x61/0x90 [ 584.128014] kthread+0x12f/0x150 [ 584.128402] ? process_one_work+0x630/0x630 [ 584.128790] ? kthread_park+0x90/0x90 [ 584.129174] ret_from_fork+0x3a/0x50 Each adev has owned lock_class_key to avoid false positive recursive locking. v2: 1. register adev->lock_key into lockdep, otherwise lockdep will report the below warning [ 1216.705820] BUG: key ffff890183b647d0 has not been registered! [ 1216.705924] ------------[ cut here ]------------ [ 1216.705972] DEBUG_LOCKS_WARN_ON(1) [ 1216.705997] WARNING: CPU: 20 PID: 541 at kernel/locking/lockdep.c:3743 lockdep_init_map+0x150/0x210 v3: change to use down_write_nest_lock to annotate the false dead-lock warning. Reviewed-by: Daniel Vetter Signed-off-by: Dennis Li --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index bb3fd53950dda..ac134d4c0531e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4238,12 +4238,17 @@ static int amdgpu_do_asic_reset(struct amdgpu_hive_info *hive, return r; } -static bool amdgpu_device_lock_adev(struct amdgpu_device *adev) +static bool amdgpu_device_lock_adev(struct amdgpu_device *adev, + struct amdgpu_hive_info *hive) { if (atomic_cmpxchg(&adev->in_gpu_reset, 0, 1) != 0) return false; - down_write(&adev->reset_sem); + if (hive) { + down_write_nest_lock(&adev->reset_sem, &hive->hive_lock); + } else { + down_write(&adev->reset_sem); + } atomic_inc(&adev->gpu_reset_counter); switch (amdgpu_asic_reset_method(adev)) { @@ -4406,7 +4411,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, /* block all schedulers and reset given job's ring */ list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) { - if (!amdgpu_device_lock_adev(tmp_adev)) { + if (!amdgpu_device_lock_adev(tmp_adev, hive)) { dev_info(tmp_adev->dev, "Bailing on TDR for s_job:%llx, as another already in progress", job ? job->base.id : -1); r = 0; From 62f698e01ec881dc8d69824934817135644c16a7 Mon Sep 17 00:00:00 2001 From: "Prike.Liang" Date: Mon, 1 Jun 2020 14:07:13 +0800 Subject: [PATCH 18/66] drm/amdgpu: enable ATHUB clock gatting Enable ATHUB clock gatting set in Renoir series. Signed-off-by: Prike.Liang Reviewed-by: Evan Quan Reviewed-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/athub_v1_0.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/athub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/athub_v1_0.c index 847ca9b3ce4ea..3ea5578643200 100644 --- a/drivers/gpu/drm/amd/amdgpu/athub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/athub_v1_0.c @@ -73,6 +73,7 @@ int athub_v1_0_set_clockgating(struct amdgpu_device *adev, case CHIP_VEGA12: case CHIP_VEGA20: case CHIP_RAVEN: + case CHIP_RENOIR: athub_update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE); athub_update_medium_grain_light_sleep(adev, From e4f2f7c7b8b50621ef32e07767d1107bad964ce5 Mon Sep 17 00:00:00 2001 From: "Prike.Liang" Date: Mon, 1 Jun 2020 14:10:54 +0800 Subject: [PATCH 19/66] drm/amdgpu: enable HDP clock gatting Enabe HDP SD/DS clock gatting in Renoir series. Signed-off-by: Prike.Liang Reviewed-by: Evan Quan Reviewed-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc15.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 3cd98c144bc65..3c3a7adad0249 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -1452,7 +1452,8 @@ static void soc15_update_hdp_light_sleep(struct amdgpu_device *adev, bool enable uint32_t def, data; if (adev->asic_type == CHIP_VEGA20 || - adev->asic_type == CHIP_ARCTURUS) { + adev->asic_type == CHIP_ARCTURUS || + adev->asic_type == CHIP_RENOIR) { def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_CTRL)); if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS)) From 6c7d82a3a52c624700e6540db7c0f22f1b58626f Mon Sep 17 00:00:00 2001 From: Sung Lee Date: Tue, 11 Aug 2020 17:23:20 -0400 Subject: [PATCH 20/66] drm/amd/display: Send DISPLAY_OFF after power down on boot [WHY] update_clocks might not be called on headless adapters. This means DISPLAY_OFF may not be sent in headless cases. [HOW] If hardware is powered down on boot because it is headless (mode set does not happen on that adapter) also send DISPLAY_OFF notification. Signed-off-by: Sung Lee Reviewed-by: Yongqiang Sun Acked-by: Eryk Brol --- .../amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 10 ++++ .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 53 +++++++++++-------- .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h | 2 + 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c index c664404a75d4f..543afa34d87aa 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c @@ -94,6 +94,15 @@ int rn_get_active_display_cnt_wa( return display_count; } +void rn_set_low_power_state(struct clk_mgr *clk_mgr_base) +{ + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); + + rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_LOW_POWER); + /* update power state */ + clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER; +} + void rn_update_clocks(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool safe_to_lower) @@ -516,6 +525,7 @@ static struct clk_mgr_funcs dcn21_funcs = { .init_clocks = rn_init_clocks, .enable_pme_wa = rn_enable_pme_wa, .are_clock_states_equal = rn_are_clock_states_equal, + .set_low_power_state = rn_set_low_power_state, .notify_wm_ranges = rn_notify_wm_ranges, .notify_link_rate_change = rn_notify_link_rate_change, }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 7bc5004ef973e..3d2a5a1905d21 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1461,33 +1461,42 @@ void dcn10_init_hw(struct dc *dc) void dcn10_power_down_on_boot(struct dc *dc) { int i = 0; + struct dc_link *edp_link; - if (dc->config.power_down_display_on_boot) { - struct dc_link *edp_link = get_edp_link(dc); - - if (edp_link && - edp_link->link_enc->funcs->is_dig_enabled && - edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) && - dc->hwseq->funcs.edp_backlight_control && - dc->hwss.power_down && - dc->hwss.edp_power_control) { - dc->hwseq->funcs.edp_backlight_control(edp_link, false); - dc->hwss.power_down(dc); - dc->hwss.edp_power_control(edp_link, false); - } else { - for (i = 0; i < dc->link_count; i++) { - struct dc_link *link = dc->links[i]; - - if (link->link_enc->funcs->is_dig_enabled && - link->link_enc->funcs->is_dig_enabled(link->link_enc) && - dc->hwss.power_down) { - dc->hwss.power_down(dc); - break; - } + if (!dc->config.power_down_display_on_boot) + return; + + edp_link = get_edp_link(dc); + if (edp_link && + edp_link->link_enc->funcs->is_dig_enabled && + edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) && + dc->hwseq->funcs.edp_backlight_control && + dc->hwss.power_down && + dc->hwss.edp_power_control) { + dc->hwseq->funcs.edp_backlight_control(edp_link, false); + dc->hwss.power_down(dc); + dc->hwss.edp_power_control(edp_link, false); + } else { + for (i = 0; i < dc->link_count; i++) { + struct dc_link *link = dc->links[i]; + if (link->link_enc->funcs->is_dig_enabled && + link->link_enc->funcs->is_dig_enabled(link->link_enc) && + dc->hwss.power_down) { + dc->hwss.power_down(dc); + break; } + } } + + /* + * Call update_clocks with empty context + * to send DISPLAY_OFF + * Otherwise DISPLAY_OFF may not be asserted + */ + if (dc->clk_mgr->funcs->set_low_power_state) + dc->clk_mgr->funcs->set_low_power_state(dc->clk_mgr); } void dcn10_reset_hw_ctx_wrap( diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h index 7ed1170e814cf..3b1bbbf2cebf6 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h @@ -235,6 +235,8 @@ struct clk_mgr_funcs { int (*get_dp_ref_clk_frequency)(struct clk_mgr *clk_mgr); + void (*set_low_power_state)(struct clk_mgr *clk_mgr); + void (*init_clocks)(struct clk_mgr *clk_mgr); void (*enable_pme_wa) (struct clk_mgr *clk_mgr); From 09ec4f7c7c4e23940d0bc96f2de58124b0201c5d Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Mon, 10 Aug 2020 10:19:04 -0400 Subject: [PATCH 21/66] drm/amd/display: 3.2.99 Signed-off-by: Aric Cyr Reviewed-by: Aric Cyr Acked-by: Eryk Brol --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 8d8241bdbd049..fea8ea83fa015 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -42,7 +42,7 @@ #include "inc/hw/dmcu.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.2.98" +#define DC_VER "3.2.99" #define MAX_SURFACES 3 #define MAX_PLANES 6 From dd24f28a4567f48c9c5b2a5ac312464594572e43 Mon Sep 17 00:00:00 2001 From: Chris Park Date: Mon, 10 Aug 2020 14:20:16 -0400 Subject: [PATCH 22/66] drm/amd/display: Call DMUB for eDP power control [Why] If DMUB is used, LVTMA VBIOS call can be used to control eDP instead of tranditional transmitter control. Interface is agreed with VBIOS for eDP to use this new path to program LVTMA registers. [How] Expose DAL interface to send DMUB command for LVTMA control that VBIOS currently uses. Signed-off-by: Chris Park Reviewed-by: Nicholas Kazlauskas Acked-by: Eryk Brol --- .../drm/amd/display/dc/bios/command_table2.c | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c index a91d7be5d86e0..25bdf1c38e0ad 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c @@ -920,11 +920,39 @@ static void init_enable_lvtma_control(struct bios_parser *bp) } +static void enable_lvtma_control_dmcub( + struct dc_dmub_srv *dmcub, + uint8_t uc_pwr_on) +{ + + union dmub_rb_cmd cmd; + + memset(&cmd, 0, sizeof(cmd)); + + cmd.cmd_common.header.type = DMUB_CMD__VBIOS; + cmd.cmd_common.header.sub_type = + DMUB_CMD__VBIOS_LVTMA_CONTROL; + cmd.cmd_common.cmd_buffer[0] = + uc_pwr_on; + + dc_dmub_srv_cmd_queue(dmcub, &cmd); + dc_dmub_srv_cmd_execute(dmcub); + dc_dmub_srv_wait_idle(dmcub); + +} + static enum bp_result enable_lvtma_control( struct bios_parser *bp, uint8_t uc_pwr_on) { enum bp_result result = BP_RESULT_FAILURE; + + if (bp->base.ctx->dc->ctx->dmub_srv && + bp->base.ctx->dc->debug.dmub_command_table) { + enable_lvtma_control_dmcub(bp->base.ctx->dmub_srv, + uc_pwr_on); + return BP_RESULT_OK; + } return result; } From c8e65545c53c10917ef536a0120feb71e1b60cdb Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Wed, 15 Jul 2020 16:45:09 +0800 Subject: [PATCH 23/66] drm/amd/display: Send H14b-VSIF specified in HDMI [Why] Current function excludes the logic to generate H14b-VSIF. Now it constructs HF-VSIF only and causes HDMI compliace test fail. [How] According to HDMI spec, source devices shall utilize the H14b-VSIF whenever the signaling capabilities of the H14b-VSIF allow this. Here keep the logic for HF-VSIF and add H14b-VSIF construction part. Signed-off-by: Wayne Lin Reviewed-by: Roman Li Acked-by: Eryk Brol --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- .../amd/display/modules/inc/mod_info_packet.h | 2 +- .../display/modules/info_packet/info_packet.c | 16 ++-------------- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 418785f28b969..f23f20e65e5e9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5094,7 +5094,8 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, update_stream_signal(stream, sink); if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) - mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket, false, false); + mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket); + if (stream->link->psr_settings.psr_feature_enabled) { // // should decide stream support vsc sdp colorimetry capability diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h index 13c57ff2abdce..1ab813b4fd14f 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h @@ -37,6 +37,6 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream, struct dc_info_packet *info_packet); void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream, - struct dc_info_packet *info_packet, int ALLMEnabled, int ALLMValue); + struct dc_info_packet *info_packet); #endif diff --git a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c index 7cd8a43d18896..0fdf7a3e96dea 100644 --- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c +++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c @@ -421,15 +421,13 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream, ***************************************************************************** */ void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream, - struct dc_info_packet *info_packet, int ALLMEnabled, int ALLMValue) + struct dc_info_packet *info_packet) { unsigned int length = 5; bool hdmi_vic_mode = false; uint8_t checksum = 0; uint32_t i = 0; enum dc_timing_3d_format format; - bool bALLM = (bool)ALLMEnabled; - bool bALLMVal = (bool)ALLMValue; info_packet->valid = false; format = stream->timing.timing_3d_format; @@ -442,20 +440,13 @@ void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream, && format == TIMING_3D_FORMAT_NONE) hdmi_vic_mode = true; - if ((format == TIMING_3D_FORMAT_NONE) && !hdmi_vic_mode && !bALLM) + if ((format == TIMING_3D_FORMAT_NONE) && !hdmi_vic_mode) return; info_packet->sb[1] = 0x03; info_packet->sb[2] = 0x0C; info_packet->sb[3] = 0x00; - if (bALLM) { - info_packet->sb[1] = 0xD8; - info_packet->sb[2] = 0x5D; - info_packet->sb[3] = 0xC4; - info_packet->sb[4] = HF_VSIF_VERSION; - } - if (format != TIMING_3D_FORMAT_NONE) info_packet->sb[4] = (2 << 5); @@ -490,9 +481,6 @@ void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream, info_packet->hb1 = 0x01; info_packet->hb2 = (uint8_t) (length); - if (bALLM) - info_packet->sb[5] = (info_packet->sb[5] & ~0x02) | (bALLMVal << 1); - checksum += info_packet->hb0; checksum += info_packet->hb1; checksum += info_packet->hb2; From dc03052d617d6779d53f88dd128f1619a95fbb81 Mon Sep 17 00:00:00 2001 From: Jaehyun Chung Date: Mon, 10 Aug 2020 16:02:47 -0400 Subject: [PATCH 24/66] drm/amd/display: Revert HDCP disable sequence change [Why] Revert HDCP disable sequence change that blanks stream before disabling HDCP. PSP and HW teams are currently investigating the root cause of why HDCP cannot be disabled before stream blank, which is expected to work without issues. Signed-off-by: Jaehyun Chung Reviewed-by: Wenjing Liu Acked-by: Eryk Brol --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 20d072d3f76f1..a35b1e735a2da 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -3300,10 +3300,10 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx) core_link_set_avmute(pipe_ctx, true); } - dc->hwss.blank_stream(pipe_ctx); #if defined(CONFIG_DRM_AMD_DC_HDCP) update_psp_stream_config(pipe_ctx, true); #endif + dc->hwss.blank_stream(pipe_ctx); if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) deallocate_mst_payload(pipe_ctx); From b31e68d56b318778516b599c7b183de30c32f23d Mon Sep 17 00:00:00 2001 From: Eryk Brol Date: Mon, 10 Aug 2020 14:02:55 -0400 Subject: [PATCH 25/66] drm/amd/display: Add debugfs for connector's FEC & DSC capabilities [why & how] Useful entry to understand if link has DSC or FEC capabilities, implemented to read DPCD caps stored on the link. Better than manually reading the registers with aux dpcd helper. Signed-off-by: Eryk Brol Signed-off-by: Mikita Lipski Reviewed-by: Mikita Lipski Acked-by: Eryk Brol Change-Id: I7f1cf444de70ffbce0ba0a72f57b0e34b2c565c4 --- .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 75 ++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 6883ed7c12415..c079755f2067b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -49,6 +49,10 @@ struct dmub_debugfs_trace_entry { uint32_t param1; }; +static inline const char *yesno(bool v) +{ + return v ? "yes" : "no"; +} /* parse_write_buffer_into_params - Helper function to parse debugfs write buffer into an array * @@ -999,6 +1003,71 @@ static ssize_t dp_dpcd_data_read(struct file *f, char __user *buf, } #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT +/* function: Read link's DSC & FEC capabilities + * + * + * Access it with the following command (you need to specify + * connector like DP-1): + * + * cat /sys/kernel/debug/dri/0/DP-X/dp_dsc_fec_support + * + */ +static int dp_dsc_fec_support_show(struct seq_file *m, void *data) +{ + struct drm_connector *connector = m->private; + struct drm_modeset_acquire_ctx ctx; + struct drm_device *dev = connector->dev; + struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); + int ret = 0; + bool try_again = false; + bool is_fec_supported = false; + bool is_dsc_supported = false; + struct dpcd_caps dpcd_caps; + + drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); + do { + try_again = false; + ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx); + if (ret) { + if (ret == -EDEADLK) { + ret = drm_modeset_backoff(&ctx); + if (!ret) { + try_again = true; + continue; + } + } + break; + } + if (connector->status != connector_status_connected) { + ret = -ENODEV; + break; + } + dpcd_caps = aconnector->dc_link->dpcd_caps; + if (aconnector->port) { + /* aconnector sets dsc_aux during get_modes call + * if MST connector has it means it can either + * enable DSC on the sink device or on MST branch + * its connected to. + */ + if (aconnector->dsc_aux) { + is_fec_supported = true; + is_dsc_supported = true; + } + } else { + is_fec_supported = dpcd_caps.fec_cap.raw & 0x1; + is_dsc_supported = dpcd_caps.dsc_caps.dsc_basic_caps.raw[0] & 0x1; + } + } while (try_again); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); + + seq_printf(m, "FEC_Sink_Support: %s\n", yesno(is_fec_supported)); + seq_printf(m, "DSC_Sink_Support: %s\n", yesno(is_dsc_supported)); + + return ret; +} + /* function: read DSC status on the connector * * The read function: dp_dsc_clock_en_read @@ -1859,6 +1928,9 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf, #endif #ifdef DEFINE_SHOW_ATTRIBUTE +#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT +DEFINE_SHOW_ATTRIBUTE(dp_dsc_fec_support); +#endif DEFINE_SHOW_ATTRIBUTE(dmub_fw_state); DEFINE_SHOW_ATTRIBUTE(dmub_tracebuffer); DEFINE_SHOW_ATTRIBUTE(output_bpc); @@ -1992,7 +2064,8 @@ static const struct { {"dsc_pic_width", &dp_dsc_pic_width_debugfs_fops}, {"dsc_pic_height", &dp_dsc_pic_height_debugfs_fops}, {"dsc_chunk_size", &dp_dsc_chunk_size_debugfs_fops}, - {"dsc_slice_bpg", &dp_dsc_slice_bpg_offset_debugfs_fops} + {"dsc_slice_bpg", &dp_dsc_slice_bpg_offset_debugfs_fops}, + {"dp_dsc_fec_support", &dp_dsc_fec_support_fops} #endif }; From 999284f05f5a3f758bb2a79fb68cc75a42a72be8 Mon Sep 17 00:00:00 2001 From: Eryk Brol Date: Mon, 10 Aug 2020 14:08:11 -0400 Subject: [PATCH 26/66] drm/amd/display: Add connector HPD trigger debugfs entry [why] Need a tool to retrigger a virtual hotplug for testing purposes with force redetection in both DC and DM. [how] Emulate handle_hpd_irq for connector as if usermode would trigger a hotplug. Perform DC link discovery, DM connector update, and DM force atomic commit. In order to trigger HPD on the connector user needs to echo 1 into "trigger_hotplug" debugfs entry on its respective connector. Signed-off-by: Eryk Brol Signed-off-by: Mikita Lipski Reviewed-by: Mikita Lipski Acked-by: Eryk Brol --- .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index c079755f2067b..90296c8a9c67e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -1067,7 +1067,84 @@ static int dp_dsc_fec_support_show(struct seq_file *m, void *data) return ret; } +#endif + +/* function: Trigger virtual HPD redetection on connector + * + * This function will perform link rediscovery, link disable + * and enable, and dm connector state update. + * + * Retrigger HPD on an existing connector by echoing 1 into + * its respectful "trigger_hotplug" debugfs entry: + * + * echo 1 > /sys/kernel/debug/dri/0/DP-X/trigger_hotplug + * + */ +static ssize_t dp_trigger_hotplug(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; + struct drm_connector *connector = &aconnector->base; + struct drm_device *dev = connector->dev; + enum dc_connection_type new_connection_type = dc_connection_none; + char *wr_buf = NULL; + uint32_t wr_buf_size = 42; + int max_param_num = 1; + long param[1] = {0}; + uint8_t param_nums = 0; + + if (!aconnector || !aconnector->dc_link) + return -EINVAL; + + if (size == 0) + return -EINVAL; + + wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL); + + if (!wr_buf) { + DRM_DEBUG_DRIVER("no memory to allocate write buffer\n"); + return -ENOSPC; + } + if (parse_write_buffer_into_params(wr_buf, wr_buf_size, + (long *)param, buf, + max_param_num, + ¶m_nums)) + return -EINVAL; + + if (param_nums <= 0) { + DRM_DEBUG_DRIVER("user data not be read\n"); + kfree(wr_buf); + return -EINVAL; + } + + if (param[0] == 1) { + mutex_lock(&aconnector->hpd_lock); + + if (!dc_link_detect_sink(aconnector->dc_link, &new_connection_type) && + new_connection_type != dc_connection_none) + goto unlock; + + if (!dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) + goto unlock; + + amdgpu_dm_update_connector_after_detect(aconnector); + + drm_modeset_lock_all(dev); + dm_restore_drm_connector_state(dev, connector); + drm_modeset_unlock_all(dev); + + drm_kms_helper_hotplug_event(dev); + +unlock: + mutex_unlock(&aconnector->hpd_lock); + } + + kfree(wr_buf); + return size; +} + +#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT /* function: read DSC status on the connector * * The read function: dp_dsc_clock_en_read @@ -1994,6 +2071,12 @@ static const struct file_operations dp_dsc_slice_bpg_offset_debugfs_fops = { }; #endif +static const struct file_operations dp_trigger_hotplug_debugfs_fops = { + .owner = THIS_MODULE, + .write = dp_trigger_hotplug, + .llseek = default_llseek +}; + static const struct file_operations dp_link_settings_debugfs_fops = { .owner = THIS_MODULE, .read = dp_link_settings_read, From 86897c12b8f593b0a954fefc6f3d8f9594f68b94 Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Thu, 13 Aug 2020 10:50:21 -0400 Subject: [PATCH 27/66] drm/amd/display: Fix passive dongle mistaken as active dongle in EDID emulation [Why] dongle_type is set during dongle connection but for passive dongles, dongle_type is not set. If user starts with an active dongle and then switches to a passive dongle, it will still report as an active dongle. Trying to emulate the wrong connecter type results in display not lighting up. [How] Set dpcd_caps.dongle_type for passive dongles in detect_dp(). Signed-off-by: Samson Tam Reviewed-by: Joshua Aberback Acked-by: Eryk Brol --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index a35b1e735a2da..18f807f4d53a2 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -763,6 +763,7 @@ static bool detect_dp(struct dc_link *link, sink_caps->signal = dp_passive_dongle_detection(link->ddc, sink_caps, audio_support); + link->dpcd_caps.dongle_type = sink_caps->dongle_type; } return true; From d88e45fa3fa97198550c468b22a8314d926055a3 Mon Sep 17 00:00:00 2001 From: Brandon Syu Date: Wed, 10 Jun 2020 16:44:33 +0800 Subject: [PATCH 28/66] drm/amd/display: Keep current gain when ABM disable immediately [Why] When system enters s3/s0i3, backlight PWM would set user level. [How] ABM disable function add keep current gain to avoid it. Signed-off-by: Brandon Syu Reviewed-by: Josip Pavic Acked-by: Eryk Brol --- drivers/gpu/drm/amd/display/dc/dc_stream.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 5251073a30f91..fd30325426fa4 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -243,7 +243,7 @@ struct dc_stream_state { union stream_update_flags update_flags; }; -#define ABM_LEVEL_IMMEDIATE_DISABLE 0xFFFFFFFF +#define ABM_LEVEL_IMMEDIATE_DISABLE 255 struct dc_stream_update { struct dc_stream_state *stream; From ec8fa2f3e741f54f1a37475c64eff78e1cbc6f24 Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Fri, 21 Aug 2020 11:57:15 -0400 Subject: [PATCH 29/66] drm/amd/display: Add DPCS regs for dcn3 link encoder dpcs reg are missing for dcn3 link encoder regs list, so add them. Also remove DPCSTX_DEBUG_CONFIG and RDPCSTX_DEBUG_CONFIG as they are unused and cause compile errors for dcn3 Signed-off-by: Bhawanpreet Lakha Reviewed-by: Nicholas Kazlauskas --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h | 2 -- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h index 52259436688b4..8e0301ad87577 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.h @@ -231,8 +231,6 @@ SRI(RDPCSTX_PHY_FUSE3, RDPCSTX, id), \ SRI(DPCSTX_TX_CLOCK_CNTL, DPCSTX, id), \ SRI(DPCSTX_TX_CNTL, DPCSTX, id), \ - SRI(DPCSTX_DEBUG_CONFIG, DPCSTX, id), \ - SRI(RDPCSTX_DEBUG_CONFIG, RDPCSTX, id), \ SR(RDPCSTX0_RDPCSTX_SCRATCH) diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 8bcf6bc0c4816..bccca69bc32a4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -493,6 +493,7 @@ static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = { [id] = {\ LE_DCN3_REG_LIST(id), \ UNIPHY_DCN2_REG_LIST(phyid), \ + DPCS_DCN2_REG_LIST(id), \ SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \ } From 9577e07dc3f7a72099855197cf6843398bbfec0a Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Tue, 18 Aug 2020 11:19:42 +0800 Subject: [PATCH 30/66] drm/amd/display: Retry AUX write when fail occurs [Why] In dm_dp_aux_transfer() now, we forget to handle AUX_WR fail cases. We suppose every write wil get done successfully and hence some AUX commands might not sent out indeed. [How] Check if AUX_WR success. If not, retry it. Signed-off-by: Wayne Lin Reviewed-by: Hersen Wu Acked-by: Rodrigo Siqueira --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 3fc7eeef90a8a..42b529ca26733 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -69,7 +69,7 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload, &operation_result); - if (payload.write) + if (payload.write && result >= 0) result = msg->size; if (result < 0) From e72c202745f80222a1a2c08a5b2c7a96ca719435 Mon Sep 17 00:00:00 2001 From: Dinghao Liu Date: Wed, 26 Aug 2020 21:24:58 +0800 Subject: [PATCH 31/66] drm/amd/display: Fix memleak in amdgpu_dm_mode_config_init When amdgpu_display_modeset_create_props() fails, state and state->context should be freed to prevent memleak. It's the same when amdgpu_dm_audio_init() fails. Signed-off-by: Dinghao Liu Signed-off-by: Alex Deucher Change-Id: Ic59118f8e5e32bf99d134e6602435ca5efe348fd --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index f23f20e65e5e9..6e704c929586e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3068,13 +3068,19 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) #endif #endif r = amdgpu_display_modeset_create_props(adev); - if (r) + if (r) { + dc_release_state(state->context); + kfree(state); return r; + } #if defined(HAVE_DRM_AUDIO_COMPONENT_HEADER) r = amdgpu_dm_audio_init(adev); - if (r) + if (r) { + dc_release_state(state->context); + kfree(state); return r; + } #endif return 0; From bf77fb16c44913359f15ab411b127d4212353166 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Fri, 21 Aug 2020 12:05:03 +0800 Subject: [PATCH 32/66] drm/amd/pm: correct Vega10 swctf limit setting Correct the Vega10 thermal swctf limit. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1267 Change-Id: I220c18bcb0772bfb8cb674337bac6dccafbd7698 Signed-off-by: Evan Quan Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c index 468bdd6f66973..ce9514c881ec2 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c @@ -363,6 +363,9 @@ int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr) static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *range) { + struct phm_ppt_v2_information *pp_table_info = + (struct phm_ppt_v2_information *)(hwmgr->pptable); + struct phm_tdp_table *tdp_table = pp_table_info->tdp_table; struct amdgpu_device *adev = hwmgr->adev; int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP * PP_TEMPERATURE_UNITS_PER_CENTIGRADES; @@ -372,8 +375,8 @@ static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, if (low < range->min) low = range->min; - if (high > range->max) - high = range->max; + if (high > tdp_table->usSoftwareShutdownTemp) + high = tdp_table->usSoftwareShutdownTemp; if (low > high) return -EINVAL; From e5fba622da32327b94df8ac4947f0331878a7c59 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Fri, 21 Aug 2020 12:18:58 +0800 Subject: [PATCH 33/66] drm/amd/pm: correct Vega12 swctf limit setting Correct the Vega12 thermal swctf limit. Change-Id: I369e1adf9f177a8d9558282db9aa908b5a25bbb3 Signed-off-by: Evan Quan Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c index c15b9756025d9..e755fc0c98860 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c @@ -170,6 +170,8 @@ int vega12_thermal_get_temperature(struct pp_hwmgr *hwmgr) static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *range) { + struct phm_ppt_v3_information *pptable_information = + (struct phm_ppt_v3_information *)hwmgr->pptable; struct amdgpu_device *adev = hwmgr->adev; int low = VEGA12_THERMAL_MINIMUM_ALERT_TEMP * PP_TEMPERATURE_UNITS_PER_CENTIGRADES; @@ -179,8 +181,8 @@ static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, if (low < range->min) low = range->min; - if (high > range->max) - high = range->max; + if (high > pptable_information->us_software_shutdown_temp) + high = pptable_information->us_software_shutdown_temp; if (low > high) return -EINVAL; From 5ad871ceea692827ec33c910aafb616e55201790 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Fri, 21 Aug 2020 12:21:30 +0800 Subject: [PATCH 34/66] drm/amd/pm: correct Vega20 swctf limit setting Correct the Vega20 thermal swctf limit. Change-Id: I6cec41152b5ac377177b1a9fda92d7b6cd982e9e Signed-off-by: Evan Quan Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c index 7add2f60f49c4..a9bc9d16641a2 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c @@ -240,6 +240,8 @@ int vega20_thermal_get_temperature(struct pp_hwmgr *hwmgr) static int vega20_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *range) { + struct phm_ppt_v3_information *pptable_information = + (struct phm_ppt_v3_information *)hwmgr->pptable; struct amdgpu_device *adev = hwmgr->adev; int low = VEGA20_THERMAL_MINIMUM_ALERT_TEMP * PP_TEMPERATURE_UNITS_PER_CENTIGRADES; @@ -249,8 +251,8 @@ static int vega20_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, if (low < range->min) low = range->min; - if (high > range->max) - high = range->max; + if (high > pptable_information->us_software_shutdown_temp) + high = pptable_information->us_software_shutdown_temp; if (low > high) return -EINVAL; From cd426ad9ec8e01010646b6207fb23ade55649862 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Tue, 25 Aug 2020 10:35:11 +0800 Subject: [PATCH 35/66] drm/amd/pm: correct the thermal alert temperature limit settings Do the maths in celsius degree. This can fix the issues caused by the changes below: drm/amd/pm: correct Vega20 swctf limit setting drm/amd/pm: correct Vega12 swctf limit setting drm/amd/pm: correct Vega10 swctf limit setting Change-Id: Ia49936240106a3172d10ffc44e51d3c9ba00763d Signed-off-by: Evan Quan Reviewed-by: Kenneth Feng --- .../drm/amd/pm/powerplay/hwmgr/vega10_thermal.c | 15 +++++++-------- .../drm/amd/pm/powerplay/hwmgr/vega12_thermal.c | 15 +++++++-------- .../drm/amd/pm/powerplay/hwmgr/vega20_thermal.c | 15 +++++++-------- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c index ce9514c881ec2..d572ba4ec9b16 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c @@ -367,14 +367,13 @@ static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, (struct phm_ppt_v2_information *)(hwmgr->pptable); struct phm_tdp_table *tdp_table = pp_table_info->tdp_table; struct amdgpu_device *adev = hwmgr->adev; - int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP * - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - int high = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP * - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; + int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP; + int high = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP; uint32_t val; - if (low < range->min) - low = range->min; + /* compare them in unit celsius degree */ + if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) + low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; if (high > tdp_table->usSoftwareShutdownTemp) high = tdp_table->usSoftwareShutdownTemp; @@ -385,8 +384,8 @@ static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5); val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); - val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); - val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); + val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high); + val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low); val &= (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK) & (~THM_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK) & (~THM_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c index e755fc0c98860..7ace439dcde7a 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c @@ -173,14 +173,13 @@ static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, struct phm_ppt_v3_information *pptable_information = (struct phm_ppt_v3_information *)hwmgr->pptable; struct amdgpu_device *adev = hwmgr->adev; - int low = VEGA12_THERMAL_MINIMUM_ALERT_TEMP * - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - int high = VEGA12_THERMAL_MAXIMUM_ALERT_TEMP * - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; + int low = VEGA12_THERMAL_MINIMUM_ALERT_TEMP; + int high = VEGA12_THERMAL_MAXIMUM_ALERT_TEMP; uint32_t val; - if (low < range->min) - low = range->min; + /* compare them in unit celsius degree */ + if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) + low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; if (high > pptable_information->us_software_shutdown_temp) high = pptable_information->us_software_shutdown_temp; @@ -191,8 +190,8 @@ static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5); val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); - val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); - val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); + val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high); + val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low); val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK); WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c index a9bc9d16641a2..364162ddaa9c6 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c @@ -243,14 +243,13 @@ static int vega20_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, struct phm_ppt_v3_information *pptable_information = (struct phm_ppt_v3_information *)hwmgr->pptable; struct amdgpu_device *adev = hwmgr->adev; - int low = VEGA20_THERMAL_MINIMUM_ALERT_TEMP * - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - int high = VEGA20_THERMAL_MAXIMUM_ALERT_TEMP * - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; + int low = VEGA20_THERMAL_MINIMUM_ALERT_TEMP; + int high = VEGA20_THERMAL_MAXIMUM_ALERT_TEMP; uint32_t val; - if (low < range->min) - low = range->min; + /* compare them in unit celsius degree */ + if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) + low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; if (high > pptable_information->us_software_shutdown_temp) high = pptable_information->us_software_shutdown_temp; @@ -261,8 +260,8 @@ static int vega20_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5); val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); - val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); - val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); + val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high); + val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low); val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK); WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val); From e0cd9de79a0ba9875eeb02318fa14c2427db3a51 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Tue, 25 Aug 2020 13:51:29 +0800 Subject: [PATCH 36/66] drm/amd/pm: avoid false alarm due to confusing softwareshutdowntemp setting Normally softwareshutdowntemp should be greater than Thotspotlimit. However, on some VEGA10 ASIC, the softwareshutdowntemp is 91C while Thotspotlimit is 105C. This seems not right and may trigger some false alarms. Change-Id: I940cc6e450eebccd93ccdc3428187f6b7c09dcda Signed-off-by: Evan Quan Acked-by: Alex Deucher --- .../drm/amd/pm/powerplay/hwmgr/vega10_thermal.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c index d572ba4ec9b16..952cd3d7240e3 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c @@ -374,8 +374,18 @@ static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, /* compare them in unit celsius degree */ if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - if (high > tdp_table->usSoftwareShutdownTemp) - high = tdp_table->usSoftwareShutdownTemp; + + /* + * As a common sense, usSoftwareShutdownTemp should be bigger + * than ThotspotLimit. For any invalid usSoftwareShutdownTemp, + * we will just use the max possible setting VEGA10_THERMAL_MAXIMUM_ALERT_TEMP + * to avoid false alarms. + */ + if ((tdp_table->usSoftwareShutdownTemp > + range->hotspot_crit_max / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)) { + if (high > tdp_table->usSoftwareShutdownTemp) + high = tdp_table->usSoftwareShutdownTemp; + } if (low > high) return -EINVAL; From 2040422b233c1fb4d81580c432e5f9b4fae43428 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 18 Aug 2020 14:54:23 +0800 Subject: [PATCH 37/66] drm/amdkfd: implement the dGPU fallback path for apu (v6) We still have a few iommu issues which need to address, so force raven as "dgpu" path for the moment. This is to add the fallback path to bypass IOMMU if IOMMU v2 is disabled or ACPI CRAT table not correct. v2: Use ignore_crat parameter to decide whether it will go with IOMMUv2. v3: Align with existed thunk, don't change the way of raven, only renoir will use "dgpu" path by default. v4: don't update global ignore_crat in the driver, and revise fallback function if CRAT is broken. v5: refine acpi crat good but no iommu support case, and rename the title. v6: fix the issue of dGPU initialized firstly, just modify the report value in the node_show(). Signed-off-by: Huang Rui Reviewed-by: Felix Kuehling --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 5 +++- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 18 +++++++++++- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 5 +++- .../amd/amdkfd/kfd_device_queue_manager_v9.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c | 4 +-- drivers/gpu/drm/amd/amdkfd/kfd_iommu.c | 10 +++---- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 4 +++ drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 29 +++++++++++++++++-- 9 files changed, 64 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index db14eb22fa579..62e3411ed5e77 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -691,11 +691,14 @@ MODULE_PARM_DESC(debug_largebar, * Ignore CRAT table during KFD initialization. By default, KFD uses the ACPI CRAT * table to get information about AMD APUs. This option can serve as a workaround on * systems with a broken CRAT table. + * + * Default is auto (according to asic type, iommu_v2, and crat table, to decide + * whehter use CRAT) */ int ignore_crat; module_param(ignore_crat, int, 0444); MODULE_PARM_DESC(ignore_crat, - "Ignore CRAT table during KFD initialization (0 = use CRAT (default), 1 = ignore CRAT)"); + "Ignore CRAT table during KFD initialization (0 = auto (default), 1 = ignore CRAT)"); /** * DOC: halt_if_hws_hang (int) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 0be3b3f107b9c..e298b31ba5e03 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -1258,7 +1258,7 @@ bool kfd_dev_is_large_bar(struct kfd_dev *dev) return true; } - if (dev->device_info->needs_iommu_device) + if (dev->use_iommu_v2) return false; amdgpu_amdkfd_get_local_mem_info(dev->kgd, &mem_info); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c index 8334dc72b3a28..7c361869be3d4 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c @@ -742,6 +742,22 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev, return 0; } +static bool kfd_ignore_crat(void) +{ + bool ret; + + if (ignore_crat) + return true; + +#ifndef KFD_SUPPORT_IOMMU_V2 + ret = true; +#else + ret = false; +#endif + + return ret; +} + /* * kfd_create_crat_image_acpi - Allocates memory for CRAT image and * copies CRAT from ACPI (if available). @@ -777,7 +793,7 @@ int kfd_create_crat_image_acpi(void **crat_image, size_t *size) return -EINVAL; } - if (ignore_crat) { + if (kfd_ignore_crat()) { pr_info("CRAT table disabled by module option\n"); return -ENODATA; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 92e0d3240b2ef..e027ed67b8b9a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -116,6 +116,7 @@ static const struct kfd_device_info carrizo_device_info = { .num_xgmi_sdma_engines = 0, .num_sdma_queues_per_engine = 2, }; +#endif static const struct kfd_device_info raven_device_info = { .asic_family = CHIP_RAVEN, @@ -134,7 +135,6 @@ static const struct kfd_device_info raven_device_info = { .num_xgmi_sdma_engines = 0, .num_sdma_queues_per_engine = 2, }; -#endif static const struct kfd_device_info hawaii_device_info = { .asic_family = CHIP_HAWAII, @@ -747,6 +747,9 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, goto gws_error; } + /* If CRAT is broken, won't set iommu enabled */ + kfd_double_confirm_iommu_support(kfd); + if (kfd_iommu_device_init(kfd)) { dev_err(kfd_device, "Error initializing iommuv2\n"); goto device_iommu_error; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c index 95a82ac455f2b..309f63a0b34a1 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c @@ -62,7 +62,7 @@ static int update_qpd_v9(struct device_queue_manager *dqm, SH_MEM_ALIGNMENT_MODE_UNALIGNED << SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT; if (amdgpu_noretry && - !dqm->dev->device_info->needs_iommu_device) + !dqm->dev->use_iommu_v2) qpd->sh_mem_config |= 1 << SH_MEM_CONFIG__RETRY_DISABLE__SHIFT; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c index c1166c40ac15e..3c22909470f20 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c @@ -321,7 +321,7 @@ static void kfd_init_apertures_vi(struct kfd_process_device *pdd, uint8_t id) pdd->lds_base = MAKE_LDS_APP_BASE_VI(); pdd->lds_limit = MAKE_LDS_APP_LIMIT(pdd->lds_base); - if (!pdd->dev->device_info->needs_iommu_device) { + if (!pdd->dev->use_iommu_v2) { /* dGPUs: SVM aperture starting at 0 * with small reserved space for kernel. * Set them to CANONICAL addresses. @@ -425,7 +425,7 @@ int kfd_init_apertures(struct kfd_process *process) return -EINVAL; } - if (!dev->device_info->needs_iommu_device) { + if (!dev->use_iommu_v2) { /* dGPUs: the reserved space for kernel * before SVM */ diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c index 395ebfdcf2c56..242cb0119addc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c @@ -41,7 +41,7 @@ int kfd_iommu_check_device(struct kfd_dev *kfd) struct amd_iommu_device_info iommu_info; int err; - if (!kfd->device_info->needs_iommu_device) + if (!kfd->use_iommu_v2) return -ENODEV; iommu_info.flags = 0; @@ -63,7 +63,7 @@ int kfd_iommu_device_init(struct kfd_dev *kfd) unsigned int pasid_limit; int err; - if (!kfd->device_info->needs_iommu_device) + if (!kfd->use_iommu_v2) return 0; iommu_info.flags = 0; @@ -109,7 +109,7 @@ int kfd_iommu_bind_process_to_device(struct kfd_process_device *pdd) struct kfd_process *p = pdd->process; int err; - if (!dev->device_info->needs_iommu_device || pdd->bound == PDD_BOUND) + if (!dev->use_iommu_v2 || pdd->bound == PDD_BOUND) return 0; if (unlikely(pdd->bound == PDD_BOUND_SUSPENDED)) { @@ -284,7 +284,7 @@ static void kfd_unbind_processes_from_device(struct kfd_dev *kfd) */ void kfd_iommu_suspend(struct kfd_dev *kfd) { - if (!kfd->device_info->needs_iommu_device) + if (!kfd->use_iommu_v2) return; kfd_unbind_processes_from_device(kfd); @@ -304,7 +304,7 @@ int kfd_iommu_resume(struct kfd_dev *kfd) unsigned int pasid_limit; int err; - if (!kfd->device_info->needs_iommu_device) + if (!kfd->use_iommu_v2) return 0; pasid_limit = kfd_get_pasid_limit(); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 085c9c8394c87..9fc610d6b0ca0 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -310,6 +310,9 @@ struct kfd_dev { bool pci_atomic_requested; + /* Use IOMMU v2 flag */ + bool use_iommu_v2; + /* SRAM ECC flag */ atomic_t sram_ecc_flag; @@ -1024,6 +1027,7 @@ struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev); struct kfd_dev *kfd_device_by_kgd(const struct kgd_dev *kgd); int kfd_topology_enum_kfd_devices(uint8_t idx, struct kfd_dev **kdev); int kfd_numa_node_to_apic_id(int numa_node_id); +void kfd_double_confirm_iommu_support(struct kfd_dev *gpu); /* Interrupts */ int kfd_interrupt_init(struct kfd_dev *dev); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index fc8852a0beaf4..917c32061efe4 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -471,7 +471,7 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, sysfs_show_32bit_prop(buffer, offs, "cpu_cores_count", dev->node_props.cpu_cores_count); sysfs_show_32bit_prop(buffer, offs, "simd_count", - dev->node_props.simd_count); + dev->gpu ? dev->node_props.simd_count : 0); sysfs_show_32bit_prop(buffer, offs, "mem_banks_count", dev->node_props.mem_banks_count); sysfs_show_32bit_prop(buffer, offs, "caches_count", @@ -1213,7 +1213,7 @@ static struct kfd_topology_device *kfd_assign_gpu(struct kfd_dev *gpu) /* Discrete GPUs need their own topology device list * entries. Don't assign them to CPU/APU nodes. */ - if (!gpu->device_info->needs_iommu_device && + if (!gpu->use_iommu_v2 && dev->node_props.cpu_cores_count) continue; @@ -1472,7 +1472,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu) * Overwrite ATS capability according to needs_iommu_device to fix * potential missing corresponding bit in CRAT of BIOS. */ - if (dev->gpu->device_info->needs_iommu_device) + if (dev->gpu->use_iommu_v2) dev->node_props.capability |= HSA_CAP_ATS_PRESENT; else dev->node_props.capability &= ~HSA_CAP_ATS_PRESENT; @@ -1599,6 +1599,29 @@ int kfd_numa_node_to_apic_id(int numa_node_id) return kfd_cpumask_to_apic_id(cpumask_of_node(numa_node_id)); } +void kfd_double_confirm_iommu_support(struct kfd_dev *gpu) +{ + struct kfd_topology_device *dev; + + gpu->use_iommu_v2 = false; + + if (!gpu->device_info->needs_iommu_device) + return; + + down_read(&topology_lock); + + /* Only use IOMMUv2 if there is an APU topology node with no GPU + * assigned yet. This GPU will be assigned to it. + */ + list_for_each_entry(dev, &topology_device_list, list) + if (dev->node_props.cpu_cores_count && + dev->node_props.simd_count && + !dev->gpu) + gpu->use_iommu_v2 = true; + + up_read(&topology_lock); +} + #if defined(CONFIG_DEBUG_FS) int kfd_debugfs_hqds_by_device(struct seq_file *m, void *data) From 4a78879c175a5c325adf58ef259166f45e610ca1 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Mon, 24 Aug 2020 09:55:16 -0400 Subject: [PATCH 38/66] drm/amdkfd: call amdgpu_amdkfd_get_unique_id directly No need to use a function pointer because the implementation is not ASIC-specific. This fixes missing support due to a missing function pointer on Arcturus. Signed-off-by: Felix Kuehling Reviewed-by: Alex Deucher Change-Id: Ia48e62404ac0cacc27f0b9da8430d89716ede2c8 --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c | 1 - drivers/gpu/drm/amd/amdkfd/kfd_device.c | 3 +-- drivers/gpu/drm/amd/include/kgd_kfd_interface.h | 3 --- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c index 0291025792f4e..19c3e0b19a759 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c @@ -1095,5 +1095,4 @@ const struct kfd2kgd_calls gfx_v10_kfd2kgd = { .clear_address_watch = kgd_gfx_v10_clear_address_watch, .get_iq_wait_times = kgd_gfx_v10_get_iq_wait_times, .build_grace_period_packet_info = kgd_gfx_v10_build_grace_period_packet_info, - .get_unique_id = amdgpu_amdkfd_get_unique_id, }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c index f9f8c37201534..3f68931c428fa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c @@ -1079,5 +1079,4 @@ const struct kfd2kgd_calls gfx_v9_kfd2kgd = { .clear_address_watch = kgd_gfx_v9_clear_address_watch, .get_iq_wait_times = kgd_gfx_v9_get_iq_wait_times, .build_grace_period_packet_info = kgd_gfx_v9_build_grace_period_packet_info, - .get_unique_id = amdgpu_amdkfd_get_unique_id, }; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index e027ed67b8b9a..32773afdb8a87 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -724,8 +724,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, if (kfd->kfd2kgd->get_hive_id) kfd->hive_id = kfd->kfd2kgd->get_hive_id(kfd->kgd); - if (kfd->kfd2kgd->get_unique_id) - kfd->unique_id = kfd->kfd2kgd->get_unique_id(kfd->kgd); + kfd->unique_id = amdgpu_amdkfd_get_unique_id(kfd->kgd); if (kfd_interrupt_init(kfd)) { dev_err(kfd_device, "Error initializing interrupts\n"); diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index 44d8888869218..20afcc7d573f7 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h @@ -223,8 +223,6 @@ struct tile_config { * @build_grace_period_packet_info: build a IQ_WAUT_TIME2 reg value with an * updated grace period value. * - * @get_unique_id: Returns uuid id of current device - * * This structure contains function pointers to services that the kgd driver * provides to amdkfd driver. * @@ -300,7 +298,6 @@ struct kfd2kgd_calls { uint32_t vmid, uint64_t page_table_base); uint32_t (*read_vmid_from_vmfault_reg)(struct kgd_dev *kgd); uint64_t (*get_hive_id)(struct kgd_dev *kgd); - uint64_t (*get_unique_id)(struct kgd_dev *kgd); void (*enable_debug_trap)(struct kgd_dev *kgd, uint32_t trap_debug_wave_launch_mode, From 31afcbfce74709ce11aec712c03f2af4663a9a95 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Mon, 24 Aug 2020 10:18:37 -0400 Subject: [PATCH 39/66] drm/amdkfd: call amdgpu_amdkfd_get_hive_id directly No need to use a function pointer because the implementation is not ASIC-specific. Signed-off-by: Felix Kuehling Reviewed-by: Alex Deucher Change-Id: I90e9f173a7ccb0a978b4e402cf38be9c836c387f --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c | 2 -- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c | 1 - drivers/gpu/drm/amd/amdkfd/kfd_device.c | 3 +-- drivers/gpu/drm/amd/include/kgd_kfd_interface.h | 3 --- 6 files changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c index 2b281cad9a16c..efebb0522b565 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c @@ -305,7 +305,6 @@ const struct kfd2kgd_calls arcturus_kfd2kgd = { kgd_gfx_v9_get_atc_vmid_pasid_mapping_info, .set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base, - .get_hive_id = amdgpu_amdkfd_get_hive_id, .enable_debug_trap = kgd_gfx_v9_enable_debug_trap, .disable_debug_trap = kgd_gfx_v9_disable_debug_trap, .set_wave_launch_trap_override = kgd_gfx_v9_set_wave_launch_trap_override, @@ -314,5 +313,4 @@ const struct kfd2kgd_calls arcturus_kfd2kgd = { .clear_address_watch = kgd_gfx_v9_clear_address_watch, .get_iq_wait_times = kgd_gfx_v9_get_iq_wait_times, .build_grace_period_packet_info = kgd_gfx_v9_build_grace_period_packet_info, - }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c index 19c3e0b19a759..a22c432a937d3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c @@ -1086,7 +1086,6 @@ const struct kfd2kgd_calls gfx_v10_kfd2kgd = { .get_atc_vmid_pasid_mapping_info = get_atc_vmid_pasid_mapping_info, .set_vm_context_page_table_base = set_vm_context_page_table_base, - .get_hive_id = amdgpu_amdkfd_get_hive_id, .enable_debug_trap = kgd_gfx_v10_enable_debug_trap, .disable_debug_trap = kgd_gfx_v10_disable_debug_trap, .set_wave_launch_trap_override = kgd_gfx_v10_set_wave_launch_trap_override, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c index 7e59e473a1901..e12623a9f7c2d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c @@ -822,7 +822,6 @@ const struct kfd2kgd_calls gfx_v10_3_kfd2kgd = { .address_watch_get_offset = address_watch_get_offset_v10_3, .get_atc_vmid_pasid_mapping_info = NULL, .set_vm_context_page_table_base = set_vm_context_page_table_base_v10_3, - .get_hive_id = amdgpu_amdkfd_get_hive_id, #if 0 .enable_debug_trap = enable_debug_trap_v10_3, .disable_debug_trap = disable_debug_trap_v10_3, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c index 3f68931c428fa..311566fcba057 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c @@ -1070,7 +1070,6 @@ const struct kfd2kgd_calls gfx_v9_kfd2kgd = { .get_atc_vmid_pasid_mapping_info = kgd_gfx_v9_get_atc_vmid_pasid_mapping_info, .set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base, - .get_hive_id = amdgpu_amdkfd_get_hive_id, .enable_debug_trap = kgd_gfx_v9_enable_debug_trap, .disable_debug_trap = kgd_gfx_v9_disable_debug_trap, .set_wave_launch_trap_override = kgd_gfx_v9_set_wave_launch_trap_override, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 32773afdb8a87..12ce918165dce 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -721,8 +721,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, goto kfd_doorbell_error; } - if (kfd->kfd2kgd->get_hive_id) - kfd->hive_id = kfd->kfd2kgd->get_hive_id(kfd->kgd); + kfd->hive_id = amdgpu_amdkfd_get_hive_id(kfd->kgd); kfd->unique_id = amdgpu_amdkfd_get_unique_id(kfd->kgd); diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index 20afcc7d573f7..552ba5ef9f6f4 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h @@ -216,8 +216,6 @@ struct tile_config { * IH ring entry. This function allows the KFD ISR to get the VMID * from the fault status register as early as possible. * - * @get_hive_id: Returns hive id of current device, 0 if xgmi is not enabled - * * @get_iq_wait_times: Returns the mmCP_IQ_WAIT_TIME1/2 values * * @build_grace_period_packet_info: build a IQ_WAUT_TIME2 reg value with an @@ -297,7 +295,6 @@ struct kfd2kgd_calls { void (*set_vm_context_page_table_base)(struct kgd_dev *kgd, uint32_t vmid, uint64_t page_table_base); uint32_t (*read_vmid_from_vmfault_reg)(struct kgd_dev *kgd); - uint64_t (*get_hive_id)(struct kgd_dev *kgd); void (*enable_debug_trap)(struct kgd_dev *kgd, uint32_t trap_debug_wave_launch_mode, From c56d0ef755693596d4dfbc3ed123233c1540d0be Mon Sep 17 00:00:00 2001 From: "Stanley.Yang" Date: Mon, 17 Aug 2020 15:48:21 +0800 Subject: [PATCH 40/66] drm/amdkfd: fix set kfd node ras properties value The ctx->features are new RAS implementation which is only available for Vega20 and onwards, it is not available for vega10, vega10 should follow legacy ECC implementation. Changed from V1: wrap function to initialize kfd node properties Changed from V2: remove wrap function and SDMA SRAM ECC check Change-Id: I1e3ff899bf066611fe5775e67104ce2e0bf8b7d0 Signed-off-by: Stanley.Yang Reviewed-by: Guchun Chen --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 28 +++++++++++++++-------- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 24 +++++++++---------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 128e1dd5d7476..fa1c6c9ff447b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1037,6 +1037,7 @@ struct amdgpu_device { atomic_t throttling_logging_enabled; struct ratelimit_state throttling_logging_rs; + uint32_t ras_features; }; static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index ec377a8147a21..2378df18e7303 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -1963,6 +1963,17 @@ int amdgpu_ras_request_reset_on_boot(struct amdgpu_device *adev, return 0; } +static int amdgpu_ras_check_asic_type(struct amdgpu_device *adev) +{ + if (adev->asic_type != CHIP_VEGA10 && + adev->asic_type != CHIP_VEGA20 && + adev->asic_type != CHIP_ARCTURUS && + adev->asic_type != CHIP_SIENNA_CICHLID) + return 1; + else + return 0; +} + /* * check hardware's ras ability which will be saved in hw_supported. * if hardware does not support ras, we can skip some ras initializtion and @@ -1979,9 +1990,7 @@ static void amdgpu_ras_check_supported(struct amdgpu_device *adev, *supported = 0; if (amdgpu_sriov_vf(adev) || !adev->is_atom_fw || - (adev->asic_type != CHIP_VEGA20 && - adev->asic_type != CHIP_ARCTURUS && - adev->asic_type != CHIP_SIENNA_CICHLID)) + amdgpu_ras_check_asic_type(adev)) return; if (amdgpu_atomfirmware_mem_ecc_supported(adev)) { @@ -2003,6 +2012,7 @@ static void amdgpu_ras_check_supported(struct amdgpu_device *adev, *supported = amdgpu_ras_enable == 0 ? 0 : *hw_supported & amdgpu_ras_mask; + adev->ras_features = *supported; } int amdgpu_ras_init(struct amdgpu_device *adev) @@ -2025,9 +2035,9 @@ int amdgpu_ras_init(struct amdgpu_device *adev) amdgpu_ras_check_supported(adev, &con->hw_supported, &con->supported); - if (!con->hw_supported) { + if (!con->hw_supported || (adev->asic_type == CHIP_VEGA10)) { r = 0; - goto err_out; + goto release_con; } con->features = 0; @@ -2038,25 +2048,25 @@ int amdgpu_ras_init(struct amdgpu_device *adev) if (adev->nbio.funcs->init_ras_controller_interrupt) { r = adev->nbio.funcs->init_ras_controller_interrupt(adev); if (r) - goto err_out; + goto release_con; } if (adev->nbio.funcs->init_ras_err_event_athub_interrupt) { r = adev->nbio.funcs->init_ras_err_event_athub_interrupt(adev); if (r) - goto err_out; + goto release_con; } if (amdgpu_ras_fs_init(adev)) { r = -EINVAL; - goto err_out; + goto release_con; } dev_info(adev->dev, "RAS INFO: ras initialized successfully, " "hardware ability[%x] ras_mask[%x]\n", con->hw_supported, con->supported); return 0; -err_out: +release_con: amdgpu_ras_set_context(adev, NULL); kfree(con); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 917c32061efe4..fa5d32488c276 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -1314,7 +1314,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu) void *crat_image = NULL; size_t image_size = 0; int proximity_domain; - struct amdgpu_ras *ctx; + struct amdgpu_device *adev; INIT_LIST_HEAD(&temp_topology_device_list); @@ -1488,19 +1488,17 @@ int kfd_topology_add_device(struct kfd_dev *gpu) dev->node_props.max_waves_per_simd = 10; } - ctx = amdgpu_ras_get_context((struct amdgpu_device *)(dev->gpu->kgd)); - if (ctx) { - /* kfd only concerns sram ecc on GFX/SDMA and HBM ecc on UMC */ - dev->node_props.capability |= - (((ctx->features & BIT(AMDGPU_RAS_BLOCK__SDMA)) != 0) || - ((ctx->features & BIT(AMDGPU_RAS_BLOCK__GFX)) != 0)) ? - HSA_CAP_SRAM_EDCSUPPORTED : 0; - dev->node_props.capability |= ((ctx->features & BIT(AMDGPU_RAS_BLOCK__UMC)) != 0) ? - HSA_CAP_MEM_EDCSUPPORTED : 0; - - dev->node_props.capability |= (ctx->features != 0) ? + adev = (struct amdgpu_device *)(dev->gpu->kgd); + /* kfd only concerns sram ecc on GFX and HBM ecc on UMC */ + dev->node_props.capability |= + ((adev->ras_features & BIT(AMDGPU_RAS_BLOCK__GFX)) != 0) ? + HSA_CAP_SRAM_EDCSUPPORTED : 0; + dev->node_props.capability |= ((adev->ras_features & BIT(AMDGPU_RAS_BLOCK__UMC)) != 0) ? + HSA_CAP_MEM_EDCSUPPORTED : 0; + + if (adev->asic_type != CHIP_VEGA10) + dev->node_props.capability |= (adev->ras_features != 0) ? HSA_CAP_RASEVENTNOTIFY : 0; - } kfd_debug_print_topology(); From d0f6ce51d14d1e44289ee68d6587666b3d1643a3 Mon Sep 17 00:00:00 2001 From: Youling Tang Date: Sat, 22 Aug 2020 16:27:23 +0800 Subject: [PATCH 41/66] gpu: amd: Remove duplicate semicolons at the end of line Remove duplicate semicolons at the end of line. Signed-off-by: Youling Tang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 2 +- drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c index 2719ef9de3bd9..139fac0d8e76e 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c @@ -1103,7 +1103,7 @@ static int vcn_v2_5_mmsch_start(struct amdgpu_device *adev, { uint32_t data = 0, loop = 0, size = 0; uint64_t addr = table->gpu_addr; - struct mmsch_v1_1_init_header *header = NULL;; + struct mmsch_v1_1_init_header *header = NULL; header = (struct mmsch_v1_1_init_header *)table->cpu_addr; size = header->total_size; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index fa25866c41383..c632e52ad7f9f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -468,7 +468,7 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) mode_lib->vba.AudioSampleLayout[mode_lib->vba.NumberOfActivePlanes] = 1; mode_lib->vba.DRAMClockChangeLatencyOverride = 0.0; - mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;; + mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable; mode_lib->vba.DSCEnable[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable; mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_slices; From 5001ab38736244ac218acdcc03190dc0e6c61ceb Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 23 Aug 2020 15:35:36 -0700 Subject: [PATCH 42/66] amdgpu: fix Documentation builds for pm/ file movement Fix Documentation errors for amdgpu.rst due to file rename (moved to another subdirectory). Error: Cannot open file ../drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c WARNING: kernel-doc '../scripts/kernel-doc -rst -enable-lineno -function hwmon ../drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c' failed with return code 1 Fixes: e098bc9612c2 ("drm/amd/pm: optimize the power related source code layout") Signed-off-by: Randy Dunlap Cc: Evan Quan Cc: Alex Deucher Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- Documentation/gpu/amdgpu.rst | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Documentation/gpu/amdgpu.rst b/Documentation/gpu/amdgpu.rst index 0f7679a7cf542..29ca5f5feb35d 100644 --- a/Documentation/gpu/amdgpu.rst +++ b/Documentation/gpu/amdgpu.rst @@ -153,7 +153,7 @@ This section covers hwmon and power/thermal controls. HWMON Interfaces ---------------- -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c :doc: hwmon GPU sysfs Power State Interfaces @@ -164,52 +164,52 @@ GPU power controls are exposed via sysfs files. power_dpm_state ~~~~~~~~~~~~~~~ -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c :doc: power_dpm_state power_dpm_force_performance_level ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c :doc: power_dpm_force_performance_level pp_table ~~~~~~~~ -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c :doc: pp_table pp_od_clk_voltage ~~~~~~~~~~~~~~~~~ -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c :doc: pp_od_clk_voltage pp_dpm_* ~~~~~~~~ -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c :doc: pp_dpm_sclk pp_dpm_mclk pp_dpm_socclk pp_dpm_fclk pp_dpm_dcefclk pp_dpm_pcie pp_power_profile_mode ~~~~~~~~~~~~~~~~~~~~~ -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c :doc: pp_power_profile_mode *_busy_percent ~~~~~~~~~~~~~~ -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c :doc: gpu_busy_percent -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c :doc: mem_busy_percent gpu_metrics ~~~~~~~~~~~~~~~~~~~~~ -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c :doc: gpu_metrics GPU Product Information @@ -239,7 +239,7 @@ serial_number unique_id --------- -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c :doc: unique_id GPU Memory Usage Information @@ -289,7 +289,7 @@ PCIe Accounting Information pcie_bw ------- -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c :doc: pcie_bw pcie_replay_count From 51fb958f545925a21fb092d75cf107c1800e5a58 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 18 Aug 2020 19:24:03 -0400 Subject: [PATCH 43/66] drm/amdgpu: fix up DCHUBBUB_SDPIF_MMIO_CNTRL_0 handling Properly define this register using a relative offset rather than an absolute offset and use the proper SOC15 macros to access it. It's also DCN, not DCE, so remove it from the DCE12 header. No functional change. Acked-by: Nirmoy Das Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 7 +++++-- drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h | 2 -- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index e1a0ae327cf5a..a858912eb0942 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -67,6 +67,9 @@ #define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_HEIGHT__SHIFT 0x10 #define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_WIDTH_MASK 0x00003FFFL #define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_HEIGHT_MASK 0x3FFF0000L +#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0 0x049d +#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0_BASE_IDX 2 + static const u32 golden_settings_vega10_hdp[] = { @@ -1282,7 +1285,7 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) static void gmc_v9_0_restore_registers(struct amdgpu_device *adev) { if (adev->asic_type == CHIP_RAVEN) - WREG32(mmDCHUBBUB_SDPIF_MMIO_CNTRL_0, adev->gmc.sdpif_register); + WREG32_SOC15(DCE, 0, mmDCHUBBUB_SDPIF_MMIO_CNTRL_0, adev->gmc.sdpif_register); } /** @@ -1394,7 +1397,7 @@ static int gmc_v9_0_hw_init(void *handle) static void gmc_v9_0_save_registers(struct amdgpu_device *adev) { if (adev->asic_type == CHIP_RAVEN) - adev->gmc.sdpif_register = RREG32(mmDCHUBBUB_SDPIF_MMIO_CNTRL_0); + adev->gmc.sdpif_register = RREG32_SOC15(DCE, 0, mmDCHUBBUB_SDPIF_MMIO_CNTRL_0); } /** diff --git a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h index 27bb8c1ab8587..b6f74bf4af023 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h @@ -7376,8 +7376,6 @@ #define mmCRTC4_CRTC_DRR_CONTROL 0x0f3e #define mmCRTC4_CRTC_DRR_CONTROL_BASE_IDX 2 -#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0 0x395d -#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0_BASE_IDX 2 // addressBlock: dce_dc_fmt4_dispdec // base address: 0x2000 From edd4f4d9316e34c700370b43f7a15627642c5ee2 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 19 Aug 2020 13:40:56 -0400 Subject: [PATCH 44/66] drm/amdgpu: add an asic callback for pre asic init This callback can be used by asics that need to do something special prior to calling atom asic init. Acked-by: Nirmoy Das Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index fa1c6c9ff447b..040c6f580b936 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -632,6 +632,8 @@ struct amdgpu_asic_funcs { uint64_t (*get_pcie_replay_count)(struct amdgpu_device *adev); /* device supports BACO */ bool (*supports_baco)(struct amdgpu_device *adev); + /* pre asic_init quirks */ + void (*pre_asic_init)(struct amdgpu_device *adev); }; /* @@ -1184,6 +1186,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev); #define amdgpu_asic_need_reset_on_init(adev) (adev)->asic_funcs->need_reset_on_init((adev)) #define amdgpu_asic_get_pcie_replay_count(adev) ((adev)->asic_funcs->get_pcie_replay_count((adev))) #define amdgpu_asic_supports_baco(adev) (adev)->asic_funcs->supports_baco((adev)) +#define amdgpu_asic_pre_asic_init(adev) (adev)->asic_funcs->pre_asic_init((adev)) #define amdgpu_inc_vram_lost(adev) atomic_inc(&((adev)->vram_lost_counter)); From 5f68d75bdcb0011e445743aa97d67b712626b952 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 19 Aug 2020 17:02:41 -0400 Subject: [PATCH 45/66] drm/amdgpu: add pre_asic_init callback for SI Nothing to do for this family. Acked-by: Nirmoy Das Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/si.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c index eaa2f071b1394..455d5e366c690 100644 --- a/drivers/gpu/drm/amd/amdgpu/si.c +++ b/drivers/gpu/drm/amd/amdgpu/si.c @@ -1871,6 +1871,10 @@ static int si_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk) return 0; } +static void si_pre_asic_init(struct amdgpu_device *adev) +{ +} + static const struct amdgpu_asic_funcs si_asic_funcs = { .read_disabled_bios = &si_read_disabled_bios, @@ -1892,6 +1896,7 @@ static const struct amdgpu_asic_funcs si_asic_funcs = .need_reset_on_init = &si_need_reset_on_init, .get_pcie_replay_count = &si_get_pcie_replay_count, .supports_baco = &si_asic_supports_baco, + .pre_asic_init = &si_pre_asic_init, }; static uint32_t si_get_rev_id(struct amdgpu_device *adev) From c91c1479401c4bac9a0ac8c4c7c6a86316cdc663 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 19 Aug 2020 17:03:39 -0400 Subject: [PATCH 46/66] drm/amdgpu: add pre_asic_init callback for CIK Nothing to do for this family. Acked-by: Nirmoy Das Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/cik.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 7e71ffbca93d8..03ff8bd1fee84 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c @@ -1921,6 +1921,10 @@ static uint64_t cik_get_pcie_replay_count(struct amdgpu_device *adev) return (nak_r + nak_g); } +static void cik_pre_asic_init(struct amdgpu_device *adev) +{ +} + static const struct amdgpu_asic_funcs cik_asic_funcs = { .read_disabled_bios = &cik_read_disabled_bios, @@ -1941,6 +1945,7 @@ static const struct amdgpu_asic_funcs cik_asic_funcs = .need_reset_on_init = &cik_need_reset_on_init, .get_pcie_replay_count = &cik_get_pcie_replay_count, .supports_baco = &cik_asic_supports_baco, + .pre_asic_init = &cik_pre_asic_init, }; static int cik_common_early_init(void *handle) From c4f893fb2de4cbe791912a175b55bde784394d03 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 19 Aug 2020 17:04:31 -0400 Subject: [PATCH 47/66] drm/amdgpu: add pre_asic_init callback for VI Nothing to do for this family. Acked-by: Nirmoy Das Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index a92880c678410..9bcd0eebc6d7e 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -1068,6 +1068,10 @@ static bool vi_need_reset_on_init(struct amdgpu_device *adev) return false; } +static void vi_pre_asic_init(struct amdgpu_device *adev) +{ +} + static const struct amdgpu_asic_funcs vi_asic_funcs = { .read_disabled_bios = &vi_read_disabled_bios, @@ -1088,6 +1092,7 @@ static const struct amdgpu_asic_funcs vi_asic_funcs = .need_reset_on_init = &vi_need_reset_on_init, .get_pcie_replay_count = &vi_get_pcie_replay_count, .supports_baco = &vi_asic_supports_baco, + .pre_asic_init = &vi_pre_asic_init, }; #define CZ_REV_BRISTOL(rev) \ From 401c7dd363b0551d55241ba7a618bc346031c063 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 19 Aug 2020 16:48:17 -0400 Subject: [PATCH 48/66] drm/amdgpu: add pre_asic_init callback for SOC15 We need to restore some registers prior to running asic init to work around a firmware bug. Acked-by: Nirmoy Das Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 35 +++++++++++++-------------- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h | 2 ++ drivers/gpu/drm/amd/amdgpu/soc15.c | 7 ++++++ 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index a858912eb0942..1ca79030e95eb 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -1075,6 +1075,20 @@ static int gmc_v9_0_gart_init(struct amdgpu_device *adev) return amdgpu_gart_table_vram_alloc(adev); } +/** + * gmc_v9_0_save_registers - saves regs + * + * @adev: amdgpu_device pointer + * + * This saves potential register values that should be + * restored upon resume + */ +static void gmc_v9_0_save_registers(struct amdgpu_device *adev) +{ + if (adev->asic_type == CHIP_RAVEN) + adev->gmc.sdpif_register = RREG32_SOC15(DCE, 0, mmDCHUBBUB_SDPIF_MMIO_CNTRL_0); +} + static int gmc_v9_0_sw_init(void *handle) { int r, vram_width = 0, vram_type = 0, vram_vendor = 0; @@ -1229,6 +1243,8 @@ static int gmc_v9_0_sw_init(void *handle) amdgpu_vm_manager_init(adev); + gmc_v9_0_save_registers(adev); + return 0; } @@ -1282,7 +1298,7 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) * * This restores register values, saved at suspend. */ -static void gmc_v9_0_restore_registers(struct amdgpu_device *adev) +void gmc_v9_0_restore_registers(struct amdgpu_device *adev) { if (adev->asic_type == CHIP_RAVEN) WREG32_SOC15(DCE, 0, mmDCHUBBUB_SDPIF_MMIO_CNTRL_0, adev->gmc.sdpif_register); @@ -1386,20 +1402,6 @@ static int gmc_v9_0_hw_init(void *handle) return r; } -/** - * gmc_v9_0_save_registers - saves regs - * - * @adev: amdgpu_device pointer - * - * This saves potential register values that should be - * restored upon resume - */ -static void gmc_v9_0_save_registers(struct amdgpu_device *adev) -{ - if (adev->asic_type == CHIP_RAVEN) - adev->gmc.sdpif_register = RREG32_SOC15(DCE, 0, mmDCHUBBUB_SDPIF_MMIO_CNTRL_0); -} - /** * gmc_v9_0_gart_disable - gart disable * @@ -1440,8 +1442,6 @@ static int gmc_v9_0_suspend(void *handle) if (r) return r; - gmc_v9_0_save_registers(adev); - return 0; } @@ -1450,7 +1450,6 @@ static int gmc_v9_0_resume(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - gmc_v9_0_restore_registers(adev); r = gmc_v9_0_hw_init(adev); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h index e0585e8c6c1b7..c415c439f6905 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.h @@ -26,4 +26,6 @@ extern const struct amd_ip_funcs gmc_v9_0_ip_funcs; extern const struct amdgpu_ip_block_version gmc_v9_0_ip_block; + +void gmc_v9_0_restore_registers(struct amdgpu_device *adev); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 3c3a7adad0249..2f93c475d6d86 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -1029,6 +1029,11 @@ static uint64_t soc15_get_pcie_replay_count(struct amdgpu_device *adev) return (nak_r + nak_g); } +static void soc15_pre_asic_init(struct amdgpu_device *adev) +{ + gmc_v9_0_restore_registers(adev); +} + static const struct amdgpu_asic_funcs soc15_asic_funcs = { .read_disabled_bios = &soc15_read_disabled_bios, @@ -1049,6 +1054,7 @@ static const struct amdgpu_asic_funcs soc15_asic_funcs = .need_reset_on_init = &soc15_need_reset_on_init, .get_pcie_replay_count = &soc15_get_pcie_replay_count, .supports_baco = &soc15_supports_baco, + .pre_asic_init = &soc15_pre_asic_init, }; static const struct amdgpu_asic_funcs vega20_asic_funcs = @@ -1072,6 +1078,7 @@ static const struct amdgpu_asic_funcs vega20_asic_funcs = .need_reset_on_init = &soc15_need_reset_on_init, .get_pcie_replay_count = &soc15_get_pcie_replay_count, .supports_baco = &soc15_supports_baco, + .pre_asic_init = &soc15_pre_asic_init, }; static int soc15_common_early_init(void *handle) From 015c3a9749bd7aa8df18568534145d263c3f161a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 19 Aug 2020 17:04:47 -0400 Subject: [PATCH 49/66] drm/amdgpu: add pre_asic_init callback for navi Nothing to do for this family. Acked-by: Nirmoy Das Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/nv.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c index 54e941e0db608..33a6d2d5fc16c 100644 --- a/drivers/gpu/drm/amd/amdgpu/nv.c +++ b/drivers/gpu/drm/amd/amdgpu/nv.c @@ -691,6 +691,10 @@ static void nv_init_doorbell_index(struct amdgpu_device *adev) adev->doorbell_index.sdma_doorbell_range = 20; } +static void nv_pre_asic_init(struct amdgpu_device *adev) +{ +} + static const struct amdgpu_asic_funcs nv_asic_funcs = { .read_disabled_bios = &nv_read_disabled_bios, @@ -710,6 +714,7 @@ static const struct amdgpu_asic_funcs nv_asic_funcs = .need_reset_on_init = &nv_need_reset_on_init, .get_pcie_replay_count = &nv_get_pcie_replay_count, .supports_baco = &nv_asic_supports_baco, + .pre_asic_init = &nv_pre_asic_init, }; static int nv_common_early_init(void *handle) From f4b77b184ac7e8f9f6fde5f3be9211cf35c7fb70 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 24 Aug 2020 12:34:10 -0400 Subject: [PATCH 50/66] drm/amdgpu: add a wrapper for atom asic_init This allows us to add asic specific workarounds for atom asic init while keeping the adev specifics out of the atombios parser code. Acked-by: Nirmoy Das Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index ac134d4c0531e..249a6bf47b47c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -654,6 +654,20 @@ static void amdgpu_block_invalid_wreg(struct amdgpu_device *adev, BUG(); } +/** + * amdgpu_device_asic_init - Wrapper for atom asic_init + * + * @dev: drm_device pointer + * + * Does any asic specific work and then calls atom asic init. + */ +static int amdgpu_device_asic_init(struct amdgpu_device *adev) +{ + amdgpu_asic_pre_asic_init(adev); + + return amdgpu_atom_asic_init(adev->mode_info.atom_context); +} + /** * amdgpu_device_vram_scratch_init - allocate the VRAM scratch page * @@ -3223,7 +3237,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, goto failed; } DRM_INFO("GPU posting now...\n"); - r = amdgpu_atom_asic_init(adev->mode_info.atom_context); + r = amdgpu_device_asic_init(adev); if (r) { dev_err(adev->dev, "gpu post error!\n"); goto failed; @@ -3584,7 +3598,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon) /* post card */ if (amdgpu_device_need_post(adev)) { - r = amdgpu_atom_asic_init(adev->mode_info.atom_context); + r = amdgpu_device_asic_init(adev); if (r) dev_err(adev->dev, "amdgpu asic init failed\n"); } @@ -4147,7 +4161,7 @@ static int amdgpu_do_asic_reset(struct amdgpu_hive_info *hive, list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) { if (need_full_reset) { /* post card */ - if (amdgpu_atom_asic_init(tmp_adev->mode_info.atom_context)) + if (amdgpu_device_asic_init(tmp_adev)) dev_warn(tmp_adev->dev, "asic atom init failed!"); if (!r) { From 2e3700e399c924a552e31e3c47c2d11a23d067f8 Mon Sep 17 00:00:00 2001 From: Tao Zhou Date: Tue, 28 Jul 2020 12:44:59 +0800 Subject: [PATCH 51/66] drm/amdgpu: add asd fw check before loading asd asd is not ready for some ASICs in early stage, and psp->asd_fw is more generic than ASIC name in the check. Signed-off-by: Tao Zhou Reviewed-by: Hawking Zhang Reviewed-by: Jiansong Chen --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index f15c8782756d9..2675b3ea71dbe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -523,8 +523,7 @@ static int psp_asd_load(struct psp_context *psp) * add workaround to bypass it for sriov now. * TODO: add version check to make it common */ - if (amdgpu_sriov_vf(psp->adev) || - (psp->adev->asic_type == CHIP_NAVY_FLOUNDER)) + if (amdgpu_sriov_vf(psp->adev) || !psp->asd_fw) return 0; cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); From b001c326cbf6e9a6579fa2b4d0ed10400371f5b8 Mon Sep 17 00:00:00 2001 From: Jiansong Chen Date: Tue, 25 Aug 2020 15:39:57 +0800 Subject: [PATCH 52/66] drm/amdgpu: use MODE1 reset for navy_flounder by default Switch default gpu reset method to MODE1 for navy_flounder. Signed-off-by: Jiansong Chen Reviewed-by: Tao Zhou Change-Id: I99b2d3ac04352142e288877f3b6c3138d0efd4bc --- drivers/gpu/drm/amd/amdgpu/nv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c index 33a6d2d5fc16c..4d14023562627 100644 --- a/drivers/gpu/drm/amd/amdgpu/nv.c +++ b/drivers/gpu/drm/amd/amdgpu/nv.c @@ -364,6 +364,7 @@ nv_asic_reset_method(struct amdgpu_device *adev) switch (adev->asic_type) { case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: return AMD_RESET_METHOD_MODE1; default: if (smu_baco_is_support(smu)) From 8c9381044d92b0f3986bdbfedad2fcb5e05ee6da Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 25 Aug 2020 11:43:45 -0400 Subject: [PATCH 53/66] drm/amdgpu: Fix buffer overflow in INFO ioctl The values for "se_num" and "sh_num" come from the user in the ioctl. They can be in the 0-255 range but if they're more than AMDGPU_GFX_MAX_SE (4) or AMDGPU_GFX_MAX_SH_PER_SE (2) then it results in an out of bounds read. Reported-by: Dan Carpenter Acked-by: Dan Carpenter Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 0158bad1a1fa2..7a5840d89b73a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -696,8 +696,12 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file * in the bitfields */ if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK) se_num = 0xffffffff; + else if (se_num >= AMDGPU_GFX_MAX_SE) + return -EINVAL; if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK) sh_num = 0xffffffff; + else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE) + return -EINVAL; if (info->read_mmr_reg.count > 128) return -EINVAL; From 089352abc6750ade61df3444c6f1f6c76a03472c Mon Sep 17 00:00:00 2001 From: Jiansong Chen Date: Wed, 26 Aug 2020 14:11:52 +0800 Subject: [PATCH 54/66] drm/amdgpu: disable runtime pm for navy_flounder Disable runtime pm for navy_flounder temporarily. Signed-off-by: Jiansong Chen Reviewed-by: Tao Zhou Change-Id: Ie1b03f09ab70e79b6dd67ede5547afa23c063eee --- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 7a5840d89b73a..dbfd407046e5d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -179,6 +179,7 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags) case CHIP_VEGA20: case CHIP_ARCTURUS: case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: /* enable runpm if runpm=1 */ if (amdgpu_runtime_pm > 0) adev->runpm = true; From f9a15142f47f3d9d7053d01f92ee411800e02749 Mon Sep 17 00:00:00 2001 From: Guchun Chen Date: Wed, 26 Aug 2020 15:43:42 +0800 Subject: [PATCH 55/66] drm/amdgpu: correct SE number for arcturus gfx ras Arcturus GFX has 8 SEs and 16 CUs per SE, so when resetting EDC related register, all CUs needs to be visited, otherwise, garbage data from EDC register of missed SEs would present. Signed-off-by: Guchun Chen Reviewed-by: Dennis Li --- drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c index 46351db369226..bd85aed3523a2 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c @@ -57,10 +57,10 @@ static const struct soc15_reg_entry gfx_v9_4_edc_counter_regs[] = { /* SPI */ { SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT), 0, 4, 1 }, /* SQ */ - { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 0, 4, 16 }, - { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_DED_CNT), 0, 4, 16 }, - { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_INFO), 0, 4, 16 }, - { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_SEC_CNT), 0, 4, 16 }, + { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 0, 8, 16 }, + { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_DED_CNT), 0, 8, 16 }, + { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_INFO), 0, 8, 16 }, + { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_SEC_CNT), 0, 8, 16 }, /* SQC */ { SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 0, 4, 6 }, { SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 0, 4, 6 }, From 07a90d770622dba3fda4da6c73392f7ac195f6a9 Mon Sep 17 00:00:00 2001 From: Yang Xiong Date: Thu, 27 Aug 2020 13:43:03 +0800 Subject: [PATCH 56/66] Revert "drm/amdgpu: [hybrid] disable DC when virtual display is enabled" This reverts commit d8e77debfeaddf39dd2af9c2589643d833306238. To apply the following patch, revert this hybrid patch first. b004c0712361 drm/amdgpu: report DC not supported if virtual display is enabled (v2) Signed-off-by: Yang Xiong Reviewed-by: Yu, Qiang --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 249a6bf47b47c..8f6a964038956 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2874,7 +2874,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) */ bool amdgpu_device_has_dc_support(struct amdgpu_device *adev) { - if (adev->enable_virtual_display) + if (amdgpu_sriov_vf(adev)) return false; return amdgpu_device_asic_has_dc_support(adev->asic_type); From dfe878e3ce794212deae8f37fdd8c3c2d23955c3 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 24 Aug 2020 20:17:30 -0400 Subject: [PATCH 57/66] drm/amdgpu: report DC not supported if virtual display is enabled (v2) Virtual display is non-atomic so report false to avoid checking atomic state and other atomic things at runtime. v2: squash into the sr-iov check Acked-by: Nirmoy Das Acked-by: Guchun Chen Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 8f6a964038956..ac04caa1675c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2874,7 +2874,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) */ bool amdgpu_device_has_dc_support(struct amdgpu_device *adev) { - if (amdgpu_sriov_vf(adev)) + if (amdgpu_sriov_vf(adev) || adev->enable_virtual_display) return false; return amdgpu_device_asic_has_dc_support(adev->asic_type); From 8b605cdf684dc45e66fab413d9865bf9c97e5d70 Mon Sep 17 00:00:00 2001 From: Alex Dewar Date: Mon, 24 Aug 2020 22:15:25 +0100 Subject: [PATCH 58/66] drm/amd/pm: use kmemdup() rather than kmalloc+memcpy Issue identified with Coccinelle. Signed-off-by: Alex Dewar Signed-off-by: Alex Deucher --- .../drm/amd/pm/powerplay/hwmgr/vega20_processpptables.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_processpptables.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_processpptables.c index f56a3cbdfa3b3..1f90825394575 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_processpptables.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_processpptables.c @@ -890,14 +890,12 @@ static int init_powerplay_table_information( power_saving_clock_count); } - pptable_information->smc_pptable = kmalloc(sizeof(PPTable_t), GFP_KERNEL); + pptable_information->smc_pptable = kmemdup(&(powerplay_table->smcPPTable), + sizeof(PPTable_t), + GFP_KERNEL); if (pptable_information->smc_pptable == NULL) return -ENOMEM; - memcpy(pptable_information->smc_pptable, - &(powerplay_table->smcPPTable), - sizeof(PPTable_t)); - result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable)); if (result) From 960b24755d6edadcaa6bc9cfcbc26e74c1470a8d Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 24 Aug 2020 16:50:12 +0800 Subject: [PATCH 59/66] drm/amd/pm: fix is_dpm_running() run error on 32bit system v1: the C type "unsigned long" size is 32bit on 32bit system, it will cause code logic error, so replace it with "uint64_t". v2: remove duplicate cast operation. Signed-off-by: Kevin Suggest-by: Jiansong Chen Reviewed-by: Jiansong Chen --- drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 10 +++++++--- drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 10 +++++++--- .../gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 10 +++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index 8347b1f2509fb..59b245c6c4d7b 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -1844,10 +1844,14 @@ static bool arcturus_is_dpm_running(struct smu_context *smu) { int ret = 0; uint32_t feature_mask[2]; - unsigned long feature_enabled; + uint64_t feature_enabled; + ret = smu_cmn_get_enabled_mask(smu, feature_mask, 2); - feature_enabled = (unsigned long)((uint64_t)feature_mask[0] | - ((uint64_t)feature_mask[1] << 32)); + if (ret) + return false; + + feature_enabled = (uint64_t)feature_mask[1] << 32 | feature_mask[0]; + return !!(feature_enabled & SMC_DPM_FEATURE); } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c index 72f3d68691d8d..cc67d5c60f3d0 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -1345,10 +1345,14 @@ static bool navi10_is_dpm_running(struct smu_context *smu) { int ret = 0; uint32_t feature_mask[2]; - unsigned long feature_enabled; + uint64_t feature_enabled; + ret = smu_cmn_get_enabled_mask(smu, feature_mask, 2); - feature_enabled = (unsigned long)((uint64_t)feature_mask[0] | - ((uint64_t)feature_mask[1] << 32)); + if (ret) + return false; + + feature_enabled = (uint64_t)feature_mask[1] << 32 | feature_mask[0]; + return !!(feature_enabled & SMC_DPM_FEATURE); } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index 66d655958a789..b48ac591db8b2 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -1150,10 +1150,14 @@ static bool sienna_cichlid_is_dpm_running(struct smu_context *smu) { int ret = 0; uint32_t feature_mask[2]; - unsigned long feature_enabled; + uint64_t feature_enabled; + ret = smu_cmn_get_enabled_mask(smu, feature_mask, 2); - feature_enabled = (unsigned long)((uint64_t)feature_mask[0] | - ((uint64_t)feature_mask[1] << 32)); + if (ret) + return false; + + feature_enabled = (uint64_t)feature_mask[1] << 32 | feature_mask[0]; + return !!(feature_enabled & SMC_DPM_FEATURE); } From cadf1f724e01c326958d509b94b92bfe238844c8 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Wed, 26 Aug 2020 11:28:19 +0800 Subject: [PATCH 60/66] drm/amd/pm: suppress static checker warning Suppress the warning below: drivers/gpu/drm/amd/amdgpu/../pm/powerplay/hwmgr/hardwaremanager.c:274 phm_check_smc_update_required_for_display_configuration() warn: signedness bug returning '(-22)' Change-Id: If50e39fe401c16d981d917ef7d8d5ea81d6538df Reported-by: Dan Carpenter Signed-off-by: Evan Quan Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c index 9454ab50f9a12..1f9b9facdf1f4 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c @@ -271,7 +271,10 @@ int phm_start_thermal_controller(struct pp_hwmgr *hwmgr) bool phm_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr) { - PHM_FUNC_CHECK(hwmgr); + if (hwmgr == NULL || + hwmgr->hwmgr_func == NULL) + return false; + if (hwmgr->pp_one_vf) return false; From 9c967a16bb21114265951261e14e387b4e8df5ac Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 14 Aug 2020 11:49:13 -0400 Subject: [PATCH 61/66] drm/amd/powerplay: Fix hardmins not being sent to SMU for RV [Why] DC uses these to raise the voltage as needed for higher dispclk/dppclk and to ensure that we have enough bandwidth to drive the displays. There's a bug preventing these from actuially sending messages since it's checking the actual clock (which is 0) instead of the incoming clock (which shouldn't be 0) when deciding to send the hardmin. [How] Check the clocks != 0 instead of the actual clocks. Fixes: 9ed9203c3ee7 ("drm/amd/powerplay: rv dal-pplib interface refactor powerplay part") Signed-off-by: Nicholas Kazlauskas Reviewed-by: Alex Deucher Reviewed-by: Evan Quan --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c index c9cfe90a29471..9ee8cf8267c88 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c @@ -204,8 +204,7 @@ static int smu10_set_min_deep_sleep_dcefclk(struct pp_hwmgr *hwmgr, uint32_t clo { struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); - if (smu10_data->need_min_deep_sleep_dcefclk && - smu10_data->deep_sleep_dcefclk != clock) { + if (clock && smu10_data->deep_sleep_dcefclk != clock) { smu10_data->deep_sleep_dcefclk = clock; smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetMinDeepSleepDcefclk, @@ -219,8 +218,7 @@ static int smu10_set_hard_min_dcefclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t c { struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); - if (smu10_data->dcf_actual_hard_min_freq && - smu10_data->dcf_actual_hard_min_freq != clock) { + if (clock && smu10_data->dcf_actual_hard_min_freq != clock) { smu10_data->dcf_actual_hard_min_freq = clock; smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetHardMinDcefclkByFreq, @@ -234,8 +232,7 @@ static int smu10_set_hard_min_fclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t cloc { struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); - if (smu10_data->f_actual_hard_min_freq && - smu10_data->f_actual_hard_min_freq != clock) { + if (clock && smu10_data->f_actual_hard_min_freq != clock) { smu10_data->f_actual_hard_min_freq = clock; smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetHardMinFclkByFreq, From 8735d38db0ff628f1aa2e36b80ce634478eb4282 Mon Sep 17 00:00:00 2001 From: Jiansong Chen Date: Thu, 27 Aug 2020 14:31:20 +0800 Subject: [PATCH 62/66] drm/amd/pm: enable MP0 DPM for sienna_cichlid Enable MP0 clock DPM for sienna_cichlid. Signed-off-by: Jiansong Chen Reviewed-by: Tao Zhou Change-Id: Iee6a05a634c200f9bbb895b963365bb001a451bc --- drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index b48ac591db8b2..b67931fd64b4a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -68,7 +68,8 @@ FEATURE_MASK(FEATURE_DPM_LINK_BIT) | \ FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT) | \ FEATURE_MASK(FEATURE_DPM_FCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT)) + FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT) | \ + FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT)) #define SMU_11_0_7_GFX_BUSY_THRESHOLD 15 @@ -230,6 +231,7 @@ sienna_cichlid_get_allowed_feature_mask(struct smu_context *smu, *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT) | FEATURE_MASK(FEATURE_DPM_FCLK_BIT) + | FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT) | FEATURE_MASK(FEATURE_DS_SOCCLK_BIT) | FEATURE_MASK(FEATURE_DS_DCEFCLK_BIT) | FEATURE_MASK(FEATURE_DS_FCLK_BIT) From f184f459709b5631ae6a2dd27c2c7a8ec1d38577 Mon Sep 17 00:00:00 2001 From: Jiawei Date: Thu, 27 Aug 2020 10:07:52 +0800 Subject: [PATCH 63/66] drm/amdgpu: simplify hw status clear/set logic Optimize code to iterate less loops in amdgpu_device_ip_reinit_early_sriov() Signed-off-by: Jiawei Reviewed-by: Emily.Deng --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index ac04caa1675c2..e1c48ba8f8276 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2607,17 +2607,16 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev) AMD_IP_BLOCK_TYPE_IH, }; - for (i = 0; i < adev->num_ip_blocks; i++) - adev->ip_blocks[i].status.hw = false; - - for (i = 0; i < ARRAY_SIZE(ip_order); i++) { + for (i = 0; i < adev->num_ip_blocks; i++) { int j; struct amdgpu_ip_block *block; - for (j = 0; j < adev->num_ip_blocks; j++) { - block = &adev->ip_blocks[j]; + block = &adev->ip_blocks[i]; + block->status.hw = false; - if (block->version->type != ip_order[i] || + for (j = 0; j < ARRAY_SIZE(ip_order); j++) { + + if (block->version->type != ip_order[j] || !block->status.valid) continue; From b435f6e03f067131c24abba5b82bd1e8d8dad296 Mon Sep 17 00:00:00 2001 From: Sandeep Raghuraman Date: Thu, 27 Aug 2020 17:07:33 +0530 Subject: [PATCH 64/66] drm/amdgpu: Specify get_argument function for ci_smu_funcs Starting in Linux 5.8, the graphics and memory clock frequency were not being reported for CIK cards. This is a regression, since they were reported correctly in Linux 5.7. This was due to changes in commit a0ec225633d9f681e393a1827f29f02c837deb84. After investigation, I discovered that the smum_send_msg_to_smc() function, attempts to call the corresponding get_argument() function of ci_smu_funcs. However, the get_argument() function is not defined in ci_smu_funcs. This patch fixes the bug by specifying the correct get_argument() function. Signed-off-by: Sandeep Raghuraman Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c index 02159ca29fa29..e772e2dc98ccb 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c @@ -37,6 +37,7 @@ #include "cgs_common.h" #include "atombios.h" #include "pppcielanes.h" +#include "smu7_smumgr.h" #include "smu/smu_7_0_1_d.h" #include "smu/smu_7_0_1_sh_mask.h" @@ -2945,6 +2946,7 @@ const struct pp_smumgr_func ci_smu_funcs = { .request_smu_load_specific_fw = NULL, .send_msg_to_smc = ci_send_msg_to_smc, .send_msg_to_smc_with_parameter = ci_send_msg_to_smc_with_parameter, + .get_argument = smu7_get_argument, .download_pptable_settings = NULL, .upload_pptable_settings = NULL, .get_offsetof = ci_get_offsetof, From 09b8be9d4cb3910204246779e5cae41120843112 Mon Sep 17 00:00:00 2001 From: Sandeep Raghuraman Date: Thu, 27 Aug 2020 18:43:37 +0530 Subject: [PATCH 65/66] drm/amdgpu: Fix bug in reporting voltage for CIK On my R9 390, the voltage was reported as a constant 1000 mV. This was due to a bug in smu7_hwmgr.c, in the smu7_read_sensor() function, where some magic constants were used in a condition, to determine whether the voltage should be read from PLANE2_VID or PLANE1_VID. The VDDC mask was incorrectly used, instead of the VDDGFX mask. This patch changes the code to use the correct defined constants (and apply the correct bitshift), thus resulting in correct voltage reporting. Signed-off-by: Sandeep Raghuraman Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c index ffe05b7cc1f0a..4a3b64aa21ceb 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c @@ -3581,7 +3581,8 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx, case AMDGPU_PP_SENSOR_GPU_POWER: return smu7_get_gpu_power(hwmgr, (uint32_t *)value); case AMDGPU_PP_SENSOR_VDDGFX: - if ((data->vr_config & 0xff) == 0x2) + if ((data->vr_config & VRCONF_VDDGFX_MASK) == + (VR_SVI2_PLANE_2 << VRCONF_VDDGFX_SHIFT)) val_vid = PHM_READ_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_SVI2_STATUS, PLANE2_VID); else From 570ea696a9f176d4107bc92973999f5f77c45c5f Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Thu, 27 Aug 2020 17:50:36 +0200 Subject: [PATCH 66/66] drm/amdgpu: fix compiler warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes below compiler warnings: CC [M] drivers/gpu/drm/amd/amdgpu/amdgpu_device.o drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:381:1: warning: ‘static’ is not at beginning of declaration [-Wold-style-declaration] 381 | void static inline amdgpu_mm_wreg_mmio(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint32_t acc_flags) | ^~~~ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:381:1: warning: ‘inline’ is not at beginning of declaration [-Wold-style-declaration] drivers/gpu/drm/amd/amdgpu/amdgpu_device.c: In function ‘amdgpu_device_fini’: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:3381:6: warning: variable ‘r’ set but not used [-Wunused-but-set-variable] 3381 | int r; | ^ Signed-off-by: Nirmoy Das Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index e1c48ba8f8276..39407c701007c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -379,7 +379,9 @@ void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value) BUG(); } -void static inline amdgpu_mm_wreg_mmio(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint32_t acc_flags) +static inline void amdgpu_mm_wreg_mmio(struct amdgpu_device *adev, + uint32_t reg, uint32_t v, + uint32_t acc_flags) { trace_amdgpu_mm_wreg(adev->pdev->device, reg, v); @@ -3400,8 +3402,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, */ void amdgpu_device_fini(struct amdgpu_device *adev) { - int r; - dev_info(adev->dev, "amdgpu: finishing device.\n"); flush_delayed_work(&adev->delayed_init_work); adev->shutdown = true; @@ -3426,7 +3426,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) if (adev->pm_sysfs_en) amdgpu_pm_sysfs_fini(adev); amdgpu_fbdev_fini(adev); - r = amdgpu_device_ip_fini(adev); + amdgpu_device_ip_fini(adev); release_firmware(adev->firmware.gpu_info_fw); adev->firmware.gpu_info_fw = NULL; adev->accel_working = false;