aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1046-drm-amdgpu-psp-make-get_fw_type-and-prep_cmd_buf-to-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1046-drm-amdgpu-psp-make-get_fw_type-and-prep_cmd_buf-to-.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1046-drm-amdgpu-psp-make-get_fw_type-and-prep_cmd_buf-to-.patch468
1 files changed, 468 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1046-drm-amdgpu-psp-make-get_fw_type-and-prep_cmd_buf-to-.patch b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1046-drm-amdgpu-psp-make-get_fw_type-and-prep_cmd_buf-to-.patch
new file mode 100644
index 00000000..a74c6896
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1046-drm-amdgpu-psp-make-get_fw_type-and-prep_cmd_buf-to-.patch
@@ -0,0 +1,468 @@
+From 52e29bfa1e533a075fccfe7b5ff40001ab661d61 Mon Sep 17 00:00:00 2001
+From: Hawking Zhang <Hawking.Zhang@amd.com>
+Date: Thu, 3 Jan 2019 21:38:41 +0800
+Subject: [PATCH 1046/2940] drm/amdgpu/psp: make get_fw_type and prep_cmd_buf
+ to be common interfaces
+
+get_fw_type and prep_cmd_buf should be common interface
+instead of IP specific ones
+
+Signed-off-by: Hawking Zhang <Hawking.Zhang@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 94 ++++++++++++++++++++++++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 3 -
+ drivers/gpu/drm/amd/amdgpu/psp_v10_0.c | 90 -----------------------
+ drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 75 --------------------
+ drivers/gpu/drm/amd/amdgpu/psp_v3_1.c | 72 -------------------
+ 5 files changed, 93 insertions(+), 241 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+index 122b7ba843c5..624308d788a0 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+@@ -510,6 +510,98 @@ static int psp_hw_start(struct psp_context *psp)
+ return 0;
+ }
+
++static int psp_get_fw_type(struct amdgpu_firmware_info *ucode,
++ enum psp_gfx_fw_type *type)
++{
++ switch (ucode->ucode_id) {
++ case AMDGPU_UCODE_ID_SDMA0:
++ *type = GFX_FW_TYPE_SDMA0;
++ break;
++ case AMDGPU_UCODE_ID_SDMA1:
++ *type = GFX_FW_TYPE_SDMA1;
++ break;
++ case AMDGPU_UCODE_ID_CP_CE:
++ *type = GFX_FW_TYPE_CP_CE;
++ break;
++ case AMDGPU_UCODE_ID_CP_PFP:
++ *type = GFX_FW_TYPE_CP_PFP;
++ break;
++ case AMDGPU_UCODE_ID_CP_ME:
++ *type = GFX_FW_TYPE_CP_ME;
++ break;
++ case AMDGPU_UCODE_ID_CP_MEC1:
++ *type = GFX_FW_TYPE_CP_MEC;
++ break;
++ case AMDGPU_UCODE_ID_CP_MEC1_JT:
++ *type = GFX_FW_TYPE_CP_MEC_ME1;
++ break;
++ case AMDGPU_UCODE_ID_CP_MEC2:
++ *type = GFX_FW_TYPE_CP_MEC;
++ break;
++ case AMDGPU_UCODE_ID_CP_MEC2_JT:
++ *type = GFX_FW_TYPE_CP_MEC_ME2;
++ break;
++ case AMDGPU_UCODE_ID_RLC_G:
++ *type = GFX_FW_TYPE_RLC_G;
++ break;
++ case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL:
++ *type = GFX_FW_TYPE_RLC_RESTORE_LIST_SRM_CNTL;
++ break;
++ case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM:
++ *type = GFX_FW_TYPE_RLC_RESTORE_LIST_GPM_MEM;
++ break;
++ case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM:
++ *type = GFX_FW_TYPE_RLC_RESTORE_LIST_SRM_MEM;
++ break;
++ case AMDGPU_UCODE_ID_SMC:
++ *type = GFX_FW_TYPE_SMU;
++ break;
++ case AMDGPU_UCODE_ID_UVD:
++ *type = GFX_FW_TYPE_UVD;
++ break;
++ case AMDGPU_UCODE_ID_UVD1:
++ *type = GFX_FW_TYPE_UVD1;
++ break;
++ case AMDGPU_UCODE_ID_VCE:
++ *type = GFX_FW_TYPE_VCE;
++ break;
++ case AMDGPU_UCODE_ID_VCN:
++ *type = GFX_FW_TYPE_VCN;
++ break;
++ case AMDGPU_UCODE_ID_DMCU_ERAM:
++ *type = GFX_FW_TYPE_DMCU_ERAM;
++ break;
++ case AMDGPU_UCODE_ID_DMCU_INTV:
++ *type = GFX_FW_TYPE_DMCU_ISR;
++ break;
++ case AMDGPU_UCODE_ID_MAXIMUM:
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int psp_prep_load_ip_fw_cmd_buf(struct amdgpu_firmware_info *ucode,
++ struct psp_gfx_cmd_resp *cmd)
++{
++ int ret;
++ uint64_t fw_mem_mc_addr = ucode->mc_addr;
++
++ memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp));
++
++ cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW;
++ cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = lower_32_bits(fw_mem_mc_addr);
++ cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(fw_mem_mc_addr);
++ cmd->cmd.cmd_load_ip_fw.fw_size = ucode->ucode_size;
++
++ ret = psp_get_fw_type(ucode, &cmd->cmd.cmd_load_ip_fw.fw_type);
++ if (ret)
++ DRM_ERROR("Unknown firmware type\n");
++
++ return ret;
++}
++
+ static int psp_np_fw_load(struct psp_context *psp)
+ {
+ int i, ret;
+@@ -531,7 +623,7 @@ static int psp_np_fw_load(struct psp_context *psp)
+ /*skip ucode loading in SRIOV VF */
+ continue;
+
+- ret = psp_prep_cmd_buf(ucode, psp->cmd);
++ ret = psp_prep_load_ip_fw_cmd_buf(ucode, psp->cmd);
+ if (ret)
+ return ret;
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+index 3ee573b4016e..2ef98cc755d6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+@@ -65,8 +65,6 @@ struct psp_funcs
+ int (*init_microcode)(struct psp_context *psp);
+ int (*bootloader_load_sysdrv)(struct psp_context *psp);
+ int (*bootloader_load_sos)(struct psp_context *psp);
+- int (*prep_cmd_buf)(struct amdgpu_firmware_info *ucode,
+- struct psp_gfx_cmd_resp *cmd);
+ int (*ring_init)(struct psp_context *psp, enum psp_ring_type ring_type);
+ int (*ring_create)(struct psp_context *psp,
+ enum psp_ring_type ring_type);
+@@ -176,7 +174,6 @@ struct psp_xgmi_topology_info {
+ struct psp_xgmi_node_info nodes[AMDGPU_XGMI_MAX_CONNECTED_NODES];
+ };
+
+-#define psp_prep_cmd_buf(ucode, type) (psp)->funcs->prep_cmd_buf((ucode), (type))
+ #define psp_ring_init(psp, type) (psp)->funcs->ring_init((psp), (type))
+ #define psp_ring_create(psp, type) (psp)->funcs->ring_create((psp), (type))
+ #define psp_ring_stop(psp, type) (psp)->funcs->ring_stop((psp), (type))
+diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
+index 2b03378b9d88..70a5a9eaf037 100644
+--- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
+@@ -38,75 +38,6 @@ MODULE_FIRMWARE("amdgpu/raven_asd.bin");
+ MODULE_FIRMWARE("amdgpu/picasso_asd.bin");
+ MODULE_FIRMWARE("amdgpu/raven2_asd.bin");
+
+-static int
+-psp_v10_0_get_fw_type(struct amdgpu_firmware_info *ucode, enum psp_gfx_fw_type *type)
+-{
+- switch(ucode->ucode_id) {
+- case AMDGPU_UCODE_ID_SDMA0:
+- *type = GFX_FW_TYPE_SDMA0;
+- break;
+- case AMDGPU_UCODE_ID_SDMA1:
+- *type = GFX_FW_TYPE_SDMA1;
+- break;
+- case AMDGPU_UCODE_ID_CP_CE:
+- *type = GFX_FW_TYPE_CP_CE;
+- break;
+- case AMDGPU_UCODE_ID_CP_PFP:
+- *type = GFX_FW_TYPE_CP_PFP;
+- break;
+- case AMDGPU_UCODE_ID_CP_ME:
+- *type = GFX_FW_TYPE_CP_ME;
+- break;
+- case AMDGPU_UCODE_ID_CP_MEC1:
+- *type = GFX_FW_TYPE_CP_MEC;
+- break;
+- case AMDGPU_UCODE_ID_CP_MEC1_JT:
+- *type = GFX_FW_TYPE_CP_MEC_ME1;
+- break;
+- case AMDGPU_UCODE_ID_CP_MEC2:
+- *type = GFX_FW_TYPE_CP_MEC;
+- break;
+- case AMDGPU_UCODE_ID_CP_MEC2_JT:
+- *type = GFX_FW_TYPE_CP_MEC_ME2;
+- break;
+- case AMDGPU_UCODE_ID_RLC_G:
+- *type = GFX_FW_TYPE_RLC_G;
+- break;
+- case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL:
+- *type = GFX_FW_TYPE_RLC_RESTORE_LIST_SRM_CNTL;
+- break;
+- case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM:
+- *type = GFX_FW_TYPE_RLC_RESTORE_LIST_GPM_MEM;
+- break;
+- case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM:
+- *type = GFX_FW_TYPE_RLC_RESTORE_LIST_SRM_MEM;
+- break;
+- case AMDGPU_UCODE_ID_SMC:
+- *type = GFX_FW_TYPE_SMU;
+- break;
+- case AMDGPU_UCODE_ID_UVD:
+- *type = GFX_FW_TYPE_UVD;
+- break;
+- case AMDGPU_UCODE_ID_VCE:
+- *type = GFX_FW_TYPE_VCE;
+- break;
+- case AMDGPU_UCODE_ID_VCN:
+- *type = GFX_FW_TYPE_VCN;
+- break;
+- case AMDGPU_UCODE_ID_DMCU_ERAM:
+- *type = GFX_FW_TYPE_DMCU_ERAM;
+- break;
+- case AMDGPU_UCODE_ID_DMCU_INTV:
+- *type = GFX_FW_TYPE_DMCU_ISR;
+- break;
+- case AMDGPU_UCODE_ID_MAXIMUM:
+- default:
+- return -EINVAL;
+- }
+-
+- return 0;
+-}
+-
+ static int psp_v10_0_init_microcode(struct psp_context *psp)
+ {
+ struct amdgpu_device *adev = psp->adev;
+@@ -161,26 +92,6 @@ static int psp_v10_0_init_microcode(struct psp_context *psp)
+ return err;
+ }
+
+-static int psp_v10_0_prep_cmd_buf(struct amdgpu_firmware_info *ucode,
+- struct psp_gfx_cmd_resp *cmd)
+-{
+- int ret;
+- uint64_t fw_mem_mc_addr = ucode->mc_addr;
+-
+- memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp));
+-
+- cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW;
+- cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = lower_32_bits(fw_mem_mc_addr);
+- cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(fw_mem_mc_addr);
+- cmd->cmd.cmd_load_ip_fw.fw_size = ucode->ucode_size;
+-
+- ret = psp_v10_0_get_fw_type(ucode, &cmd->cmd.cmd_load_ip_fw.fw_type);
+- if (ret)
+- DRM_ERROR("Unknown firmware type\n");
+-
+- return ret;
+-}
+-
+ static int psp_v10_0_ring_init(struct psp_context *psp,
+ enum psp_ring_type ring_type)
+ {
+@@ -457,7 +368,6 @@ static int psp_v10_0_mode1_reset(struct psp_context *psp)
+
+ static const struct psp_funcs psp_v10_0_funcs = {
+ .init_microcode = psp_v10_0_init_microcode,
+- .prep_cmd_buf = psp_v10_0_prep_cmd_buf,
+ .ring_init = psp_v10_0_ring_init,
+ .ring_create = psp_v10_0_ring_create,
+ .ring_stop = psp_v10_0_ring_stop,
+diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
+index ed7a8c59170d..7c68b9c6e546 100644
+--- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
+@@ -43,60 +43,6 @@ MODULE_FIRMWARE("amdgpu/vega20_sos_old.bin");
+
+ #define VEGA20_BL_VERSION_VAR_NEW 0xA1
+
+-static int
+-psp_v11_0_get_fw_type(struct amdgpu_firmware_info *ucode, enum psp_gfx_fw_type *type)
+-{
+- switch (ucode->ucode_id) {
+- case AMDGPU_UCODE_ID_SDMA0:
+- *type = GFX_FW_TYPE_SDMA0;
+- break;
+- case AMDGPU_UCODE_ID_SDMA1:
+- *type = GFX_FW_TYPE_SDMA1;
+- break;
+- case AMDGPU_UCODE_ID_CP_CE:
+- *type = GFX_FW_TYPE_CP_CE;
+- break;
+- case AMDGPU_UCODE_ID_CP_PFP:
+- *type = GFX_FW_TYPE_CP_PFP;
+- break;
+- case AMDGPU_UCODE_ID_CP_ME:
+- *type = GFX_FW_TYPE_CP_ME;
+- break;
+- case AMDGPU_UCODE_ID_CP_MEC1:
+- *type = GFX_FW_TYPE_CP_MEC;
+- break;
+- case AMDGPU_UCODE_ID_CP_MEC1_JT:
+- *type = GFX_FW_TYPE_CP_MEC_ME1;
+- break;
+- case AMDGPU_UCODE_ID_CP_MEC2:
+- *type = GFX_FW_TYPE_CP_MEC;
+- break;
+- case AMDGPU_UCODE_ID_CP_MEC2_JT:
+- *type = GFX_FW_TYPE_CP_MEC_ME2;
+- break;
+- case AMDGPU_UCODE_ID_RLC_G:
+- *type = GFX_FW_TYPE_RLC_G;
+- break;
+- case AMDGPU_UCODE_ID_SMC:
+- *type = GFX_FW_TYPE_SMU;
+- break;
+- case AMDGPU_UCODE_ID_UVD:
+- *type = GFX_FW_TYPE_UVD;
+- break;
+- case AMDGPU_UCODE_ID_VCE:
+- *type = GFX_FW_TYPE_VCE;
+- break;
+- case AMDGPU_UCODE_ID_UVD1:
+- *type = GFX_FW_TYPE_UVD1;
+- break;
+- case AMDGPU_UCODE_ID_MAXIMUM:
+- default:
+- return -EINVAL;
+- }
+-
+- return 0;
+-}
+-
+ static int psp_v11_0_init_microcode(struct psp_context *psp)
+ {
+ struct amdgpu_device *adev = psp->adev;
+@@ -277,26 +223,6 @@ static int psp_v11_0_bootloader_load_sos(struct psp_context *psp)
+ return ret;
+ }
+
+-static int psp_v11_0_prep_cmd_buf(struct amdgpu_firmware_info *ucode,
+- struct psp_gfx_cmd_resp *cmd)
+-{
+- int ret;
+- uint64_t fw_mem_mc_addr = ucode->mc_addr;
+-
+- memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp));
+-
+- cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW;
+- cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = lower_32_bits(fw_mem_mc_addr);
+- cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(fw_mem_mc_addr);
+- cmd->cmd.cmd_load_ip_fw.fw_size = ucode->ucode_size;
+-
+- ret = psp_v11_0_get_fw_type(ucode, &cmd->cmd.cmd_load_ip_fw.fw_type);
+- if (ret)
+- DRM_ERROR("Unknown firmware type\n");
+-
+- return ret;
+-}
+-
+ static int psp_v11_0_ring_init(struct psp_context *psp,
+ enum psp_ring_type ring_type)
+ {
+@@ -763,7 +689,6 @@ static const struct psp_funcs psp_v11_0_funcs = {
+ .init_microcode = psp_v11_0_init_microcode,
+ .bootloader_load_sysdrv = psp_v11_0_bootloader_load_sysdrv,
+ .bootloader_load_sos = psp_v11_0_bootloader_load_sos,
+- .prep_cmd_buf = psp_v11_0_prep_cmd_buf,
+ .ring_init = psp_v11_0_ring_init,
+ .ring_create = psp_v11_0_ring_create,
+ .ring_stop = psp_v11_0_ring_stop,
+diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
+index 79694ff16969..c63de945c021 100644
+--- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
++++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
+@@ -47,57 +47,6 @@ MODULE_FIRMWARE("amdgpu/vega12_asd.bin");
+
+ static uint32_t sos_old_versions[] = {1517616, 1510592, 1448594, 1446554};
+
+-static int
+-psp_v3_1_get_fw_type(struct amdgpu_firmware_info *ucode, enum psp_gfx_fw_type *type)
+-{
+- switch(ucode->ucode_id) {
+- case AMDGPU_UCODE_ID_SDMA0:
+- *type = GFX_FW_TYPE_SDMA0;
+- break;
+- case AMDGPU_UCODE_ID_SDMA1:
+- *type = GFX_FW_TYPE_SDMA1;
+- break;
+- case AMDGPU_UCODE_ID_CP_CE:
+- *type = GFX_FW_TYPE_CP_CE;
+- break;
+- case AMDGPU_UCODE_ID_CP_PFP:
+- *type = GFX_FW_TYPE_CP_PFP;
+- break;
+- case AMDGPU_UCODE_ID_CP_ME:
+- *type = GFX_FW_TYPE_CP_ME;
+- break;
+- case AMDGPU_UCODE_ID_CP_MEC1:
+- *type = GFX_FW_TYPE_CP_MEC;
+- break;
+- case AMDGPU_UCODE_ID_CP_MEC1_JT:
+- *type = GFX_FW_TYPE_CP_MEC_ME1;
+- break;
+- case AMDGPU_UCODE_ID_CP_MEC2:
+- *type = GFX_FW_TYPE_CP_MEC;
+- break;
+- case AMDGPU_UCODE_ID_CP_MEC2_JT:
+- *type = GFX_FW_TYPE_CP_MEC_ME2;
+- break;
+- case AMDGPU_UCODE_ID_RLC_G:
+- *type = GFX_FW_TYPE_RLC_G;
+- break;
+- case AMDGPU_UCODE_ID_SMC:
+- *type = GFX_FW_TYPE_SMU;
+- break;
+- case AMDGPU_UCODE_ID_UVD:
+- *type = GFX_FW_TYPE_UVD;
+- break;
+- case AMDGPU_UCODE_ID_VCE:
+- *type = GFX_FW_TYPE_VCE;
+- break;
+- case AMDGPU_UCODE_ID_MAXIMUM:
+- default:
+- return -EINVAL;
+- }
+-
+- return 0;
+-}
+-
+ static int psp_v3_1_init_microcode(struct psp_context *psp)
+ {
+ struct amdgpu_device *adev = psp->adev;
+@@ -277,26 +226,6 @@ static int psp_v3_1_bootloader_load_sos(struct psp_context *psp)
+ return ret;
+ }
+
+-static int psp_v3_1_prep_cmd_buf(struct amdgpu_firmware_info *ucode,
+- struct psp_gfx_cmd_resp *cmd)
+-{
+- int ret;
+- uint64_t fw_mem_mc_addr = ucode->mc_addr;
+-
+- memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp));
+-
+- cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW;
+- cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = lower_32_bits(fw_mem_mc_addr);
+- cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(fw_mem_mc_addr);
+- cmd->cmd.cmd_load_ip_fw.fw_size = ucode->ucode_size;
+-
+- ret = psp_v3_1_get_fw_type(ucode, &cmd->cmd.cmd_load_ip_fw.fw_type);
+- if (ret)
+- DRM_ERROR("Unknown firmware type\n");
+-
+- return ret;
+-}
+-
+ static int psp_v3_1_ring_init(struct psp_context *psp,
+ enum psp_ring_type ring_type)
+ {
+@@ -615,7 +544,6 @@ static const struct psp_funcs psp_v3_1_funcs = {
+ .init_microcode = psp_v3_1_init_microcode,
+ .bootloader_load_sysdrv = psp_v3_1_bootloader_load_sysdrv,
+ .bootloader_load_sos = psp_v3_1_bootloader_load_sos,
+- .prep_cmd_buf = psp_v3_1_prep_cmd_buf,
+ .ring_init = psp_v3_1_ring_init,
+ .ring_create = psp_v3_1_ring_create,
+ .ring_stop = psp_v3_1_ring_stop,
+--
+2.17.1
+