Add a new kernel module parameter 'amdgpu.ptl' to allow
users to enable or disable PTL feature at driver loading time.

Parameter values:
  *) 0 or -1: disable PTL (default)
  *) 1: enable PTL
  *) 2: permanently disable PTL

Signed-off-by: Perry Yuan <[email protected]>
Reviewed-by: Yifan Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h     |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 13 ++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 18 ++++++++++++----
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h |  1 +
 drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 28 ++++++++++++++++++++++++-
 5 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index af4042387f3b..23c58361b4d8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -268,6 +268,7 @@ extern int amdgpu_rebar;
 
 extern int amdgpu_wbrf;
 extern int amdgpu_user_queue;
+extern int amdgpu_ptl;
 
 extern uint amdgpu_hdmi_hpd_debounce_delay_ms;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 95d26f086d54..482fa222292e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -248,6 +248,7 @@ int amdgpu_umsch_mm_fwlog;
 int amdgpu_rebar = -1; /* auto */
 int amdgpu_user_queue = -1;
 uint amdgpu_hdmi_hpd_debounce_delay_ms;
+int amdgpu_ptl = -1; /* auto */
 
 DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
                        "DRM_UT_CORE",
@@ -1134,6 +1135,18 @@ module_param_named(user_queue, amdgpu_user_queue, int, 
0444);
 MODULE_PARM_DESC(hdmi_hpd_debounce_delay_ms, "HDMI HPD disconnect debounce 
delay in milliseconds (0 to disable (by default), 1500 is common)");
 module_param_named(hdmi_hpd_debounce_delay_ms, 
amdgpu_hdmi_hpd_debounce_delay_ms, uint, 0644);
 
+/**
+ * DOC: ptl (int)
+ * Enable PTL feature at boot time. Possible values:
+ *
+ * - -1 = auto (ASIC specific default)
+ * -  0 = disable PTL (default)
+ * -  1 = enable PTL
+ * -  2 = permanently disable PTL (cannot be re-enabled at runtime)
+ */
+MODULE_PARM_DESC(ptl, "Enable PTL (-1 = auto, 0 = disable (default), 1 = 
enable, 2 = permanently disable)");
+module_param_named(ptl, amdgpu_ptl, int, 0444);
+
 /* These devices are not supported by amdgpu.
  * They are supported by the mach64, r128, radeon drivers
  */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index 3d7c1a788cf6..dfda694aefe4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -1296,6 +1296,9 @@ int amdgpu_ptl_perf_monitor_ctrl(struct amdgpu_device 
*adev, u32 req_code,
        psp = &adev->psp;
        ptl = &psp->ptl;
 
+       if (ptl->permanently_disabled && *ptl_state == 1)
+               return 0;
+
        if (amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(9, 4, 4) ||
                        psp->sos.fw_version < 0x0036081a)
                return -EOPNOTSUPP;
@@ -1364,7 +1367,6 @@ static ssize_t ptl_enable_store(struct device *dev,
 {
        struct drm_device *ddev = dev_get_drvdata(dev);
        struct amdgpu_device *adev = drm_to_adev(ddev);
-       struct psp_context *psp = &adev->psp;
        struct amdgpu_ptl *ptl = &adev->psp.ptl;
        uint32_t ptl_state, fmt1, fmt2;
        int ret;
@@ -1381,6 +1383,12 @@ static ssize_t ptl_enable_store(struct device *dev,
                return -EINVAL;
        }
 
+       /* Block enable when permanently disabled */
+       if (ptl->permanently_disabled) {
+               mutex_unlock(&ptl->mutex);
+               return -EPERM;
+       }
+
        fmt1 = ptl->fmt1;
        fmt2 = ptl->fmt2;
        ptl_state = enable ? 1 : 0;
@@ -1410,9 +1418,12 @@ static ssize_t ptl_enable_show(struct device *dev, 
struct device_attribute *attr
 {
        struct drm_device *ddev = dev_get_drvdata(dev);
        struct amdgpu_device *adev = drm_to_adev(ddev);
-       struct psp_context *psp = &adev->psp;
+       struct amdgpu_ptl *ptl = &adev->psp.ptl;
 
-       return sysfs_emit(buf, "%s\n", psp->ptl.enabled ? "enabled" : 
"disabled");
+       if (ptl->permanently_disabled)
+               return sysfs_emit(buf, "permanently disabled\n");
+
+       return sysfs_emit(buf, "%s\n", ptl->enabled ? "enabled" : "disabled");
 }
 
 static ssize_t ptl_format_store(struct device *dev,
@@ -1421,7 +1432,6 @@ static ssize_t ptl_format_store(struct device *dev,
 {
        struct drm_device *ddev = dev_get_drvdata(dev);
        struct amdgpu_device *adev = drm_to_adev(ddev);
-       struct psp_context *psp = &adev->psp;
        char fmt1_str[8], fmt2_str[8];
        enum amdgpu_ptl_fmt fmt1_enum, fmt2_enum;
        struct amdgpu_ptl *ptl = &adev->psp.ptl;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
index 2de7815c7516..1d4e53ddd38b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
@@ -394,6 +394,7 @@ struct amdgpu_ptl {
        enum amdgpu_ptl_fmt             fmt2;
        bool                            enabled;
        bool                            hw_supported;
+       bool                            permanently_disabled;
        /* PTL disable reference counting */
        atomic_t                        disable_ref;
        struct mutex                    mutex;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
index 13933e3ee096..e0782ed149e2 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
@@ -2401,6 +2401,32 @@ static int gfx_v9_4_3_perf_monitor_ptl_init(struct 
amdgpu_device *adev, bool sta
        return 0;
 }
 
+static int gfx_v9_4_3_ptl_hw_init(struct amdgpu_device *adev)
+{
+       struct amdgpu_ptl *ptl = &adev->psp.ptl;
+       bool enable;
+
+       switch (amdgpu_ptl) {
+       case 1:
+               enable = true;
+               break;
+       case 2:
+               /* Permanently disabled - cannot be re-enabled */
+               enable = false;
+               ptl->permanently_disabled = true;
+               break;
+       case -1:
+       case 0:
+       default:
+               enable = false;
+               break;
+       }
+
+       gfx_v9_4_3_perf_monitor_ptl_init(adev, enable ? 1 : 0);
+
+       return 0;
+}
+
 static int gfx_v9_4_3_hw_fini(struct amdgpu_ip_block *ip_block)
 {
        struct amdgpu_device *adev = ip_block->adev;
@@ -2583,7 +2609,7 @@ static int gfx_v9_4_3_late_init(struct amdgpu_ip_block 
*ip_block)
            adev->gfx.ras->enable_watchdog_timer)
                adev->gfx.ras->enable_watchdog_timer(adev);
 
-       gfx_v9_4_3_perf_monitor_ptl_init(adev, 1);
+       gfx_v9_4_3_ptl_hw_init(adev);
 
        return 0;
 }
-- 
2.34.1

Reply via email to