mirror of
git://nv-tegra.nvidia.com/linux-hwpm.git
synced 2025-12-22 09:12:05 +03:00
tegra: hwpm: add checks for PMA quiesce state
- Zeroing of PMA trigger registers is unnecessary. Remove corresponding logic from HWPM teardown function. - During device open, add a check for PMA/RTR status. This will ensure that PMA/RTR are ready to start new profiling session. Device open will fail if RTR and PMA enginestatus is not ready(idle). - SOC HWPM driver disables and releases all reserved IPs before teardown steps. Update teardown logic to zero out IP allowlist registers during teardown. Jira THWPM-41 Bug 3714516 Change-Id: Iede5a5ed9860e2a73c8e4a04aeedfc061458c793 Signed-off-by: Vedashree Vidwans <vvidwans@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2776229 Reviewed-by: Seema Khowala <seemaj@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-hwpm/+/2797444
This commit is contained in:
committed by
mobile promotions
parent
7c1ae11f78
commit
913f1b0697
@@ -57,7 +57,7 @@ fail:
|
||||
return err;
|
||||
}
|
||||
|
||||
int tegra_hwpm_element_release(struct tegra_soc_hwpm *hwpm,
|
||||
int tegra_hwpm_element_disable(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *element)
|
||||
{
|
||||
int err = 0;
|
||||
@@ -73,13 +73,6 @@ int tegra_hwpm_element_release(struct tegra_soc_hwpm *hwpm,
|
||||
element->element_index_mask);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = tegra_hwpm_perfmon_release(hwpm, element);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "Element mask 0x%x release failed",
|
||||
element->element_index_mask);
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case IP_ELEMENT_PERFMUX:
|
||||
case IP_ELEMENT_BROADCAST:
|
||||
@@ -89,7 +82,37 @@ int tegra_hwpm_element_release(struct tegra_soc_hwpm *hwpm,
|
||||
element->element_index_mask);
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case HWPM_ELEMENT_INVALID:
|
||||
default:
|
||||
tegra_hwpm_err(hwpm, "Invalid element type %d",
|
||||
element->element_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fail:
|
||||
return err;
|
||||
}
|
||||
|
||||
int tegra_hwpm_element_release(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *element)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
switch (element->element_type) {
|
||||
case HWPM_ELEMENT_PERFMON:
|
||||
case HWPM_ELEMENT_PERFMUX:
|
||||
err = tegra_hwpm_perfmon_release(hwpm, element);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "Element mask 0x%x release failed",
|
||||
element->element_index_mask);
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case IP_ELEMENT_PERFMUX:
|
||||
case IP_ELEMENT_BROADCAST:
|
||||
err = tegra_hwpm_perfmux_release(hwpm, element);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "Element mask 0x%x release failed",
|
||||
@@ -364,6 +387,34 @@ static int tegra_hwpm_func_single_element(struct tegra_soc_hwpm *hwpm,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TEGRA_HWPM_UNBIND_RESOURCES:
|
||||
if ((element->element_index_mask &
|
||||
ip_inst->element_fs_mask) == 0U) {
|
||||
tegra_hwpm_dbg(hwpm, hwpm_dbg_bind,
|
||||
"IP %d inst %d a_type %d element type %d"
|
||||
" start_addr 0x%llx not reserved",
|
||||
ip_idx, static_inst_idx, a_type,
|
||||
element->element_type, element->start_abs_pa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = tegra_hwpm_element_disable(hwpm, element);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "IP %d element"
|
||||
" type %d idx %d enable failed",
|
||||
ip_idx, a_type, static_aperture_idx);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = hwpm->active_chip->zero_alist_regs(
|
||||
hwpm, ip_inst, element);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "IP %d element"
|
||||
" type %d idx %d zero regs failed",
|
||||
ip_idx, a_type, static_aperture_idx);
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case TEGRA_HWPM_RELEASE_IP_STRUCTURES:
|
||||
if ((element->element_index_mask &
|
||||
ip_inst->element_fs_mask) == 0U) {
|
||||
@@ -660,6 +711,7 @@ int tegra_hwpm_func_single_ip(struct tegra_soc_hwpm *hwpm,
|
||||
case TEGRA_HWPM_GET_ALIST_SIZE:
|
||||
case TEGRA_HWPM_COMBINE_ALIST:
|
||||
case TEGRA_HWPM_BIND_RESOURCES:
|
||||
case TEGRA_HWPM_UNBIND_RESOURCES:
|
||||
/* Skip unavailable IPs */
|
||||
if (!chip_ip->reserved) {
|
||||
tegra_hwpm_dbg(hwpm, hwpm_dbg_allowlist | hwpm_dbg_bind,
|
||||
|
||||
@@ -161,6 +161,13 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tegra_hwpm_check_status(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
return hwpm->active_chip->check_status(hwpm);
|
||||
}
|
||||
|
||||
int tegra_hwpm_disable_triggers(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
@@ -110,6 +110,12 @@ int tegra_hwpm_release_resources(struct tegra_soc_hwpm *hwpm)
|
||||
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
ret = tegra_hwpm_func_all_ip(hwpm, NULL, TEGRA_HWPM_UNBIND_RESOURCES);
|
||||
if (ret != 0) {
|
||||
tegra_hwpm_err(hwpm, "failed to release resources");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = tegra_hwpm_func_all_ip(hwpm, NULL, TEGRA_HWPM_RELEASE_RESOURCES);
|
||||
if (ret != 0) {
|
||||
tegra_hwpm_err(hwpm, "failed to release resources");
|
||||
|
||||
@@ -163,8 +163,4 @@
|
||||
#define pmasys_enginestatus_mbu_status_idle_v() (0x00000000U)
|
||||
#define pmasys_enginestatus_mbu_status_busy_v() (0x00000001U)
|
||||
#define pmasys_enginestatus_mbu_status_pending_v() (0x00000002U)
|
||||
#define pmasys_sys_trigger_start_mask_r() (0x0f14a66cU)
|
||||
#define pmasys_sys_trigger_start_maskb_r() (0x0f14a670U)
|
||||
#define pmasys_sys_trigger_stop_mask_r() (0x0f14a684U)
|
||||
#define pmasys_sys_trigger_stop_maskb_r() (0x0f14a688U)
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,63 @@
|
||||
#include <hal/t234/hw/t234_pmasys_soc_hwpm.h>
|
||||
#include <hal/t234/hw/t234_pmmsys_soc_hwpm.h>
|
||||
|
||||
int t234_hwpm_check_status(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
int err = 0;
|
||||
u32 reg_val = 0U;
|
||||
u32 field_mask = 0U;
|
||||
u32 field_val = 0U;
|
||||
struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip;
|
||||
struct hwpm_ip *chip_ip = active_chip->chip_ips[
|
||||
active_chip->get_rtr_int_idx(hwpm)];
|
||||
struct hwpm_ip_inst *ip_inst_rtr = &chip_ip->ip_inst_static_array[
|
||||
T234_HWPM_IP_RTR_STATIC_RTR_INST];
|
||||
struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[
|
||||
T234_HWPM_IP_RTR_STATIC_PMA_INST];
|
||||
struct hwpm_ip_aperture *rtr_perfmux = &ip_inst_rtr->element_info[
|
||||
TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[
|
||||
T234_HWPM_IP_RTR_PERMUX_INDEX];
|
||||
struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[
|
||||
TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[
|
||||
T234_HWPM_IP_RTR_PERMUX_INDEX];
|
||||
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
/* Check ROUTER state */
|
||||
err = tegra_hwpm_readl(hwpm, rtr_perfmux,
|
||||
pmmsys_sys0router_enginestatus_r(), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (pmmsys_sys0router_enginestatus_status_v(reg_val) !=
|
||||
pmmsys_sys0router_enginestatus_status_empty_v()) {
|
||||
tegra_hwpm_err(hwpm, "Router not ready value 0x%x", reg_val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check PMA state */
|
||||
field_mask = pmasys_enginestatus_status_m() |
|
||||
pmasys_enginestatus_rbufempty_m();
|
||||
field_val = pmasys_enginestatus_status_empty_f() |
|
||||
pmasys_enginestatus_rbufempty_empty_f();
|
||||
|
||||
err = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_enginestatus_r(), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((reg_val & field_mask) != field_val) {
|
||||
tegra_hwpm_err(hwpm, "PMA not ready value 0x%x", reg_val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int t234_hwpm_disable_triggers(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
int err = 0;
|
||||
@@ -60,31 +117,6 @@ int t234_hwpm_disable_triggers(struct tegra_soc_hwpm *hwpm)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_sys_trigger_start_mask_r(), 0);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_sys_trigger_start_maskb_r(), 0);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_sys_trigger_stop_mask_r(), 0);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_sys_trigger_stop_maskb_r(), 0);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Wait for PERFMONs to idle */
|
||||
err = tegra_hwpm_timeout_init(hwpm, &timeout, 10U);
|
||||
if (err != 0) {
|
||||
|
||||
@@ -46,6 +46,7 @@ static struct tegra_soc_hwpm_chip t234_chip_info = {
|
||||
.perfmon_disable = t234_hwpm_perfmon_disable,
|
||||
.perfmux_disable = tegra_hwpm_perfmux_disable,
|
||||
.disable_triggers = t234_hwpm_disable_triggers,
|
||||
.check_status = t234_hwpm_check_status,
|
||||
|
||||
.disable_mem_mgmt = t234_hwpm_disable_mem_mgmt,
|
||||
.enable_mem_mgmt = t234_hwpm_enable_mem_mgmt,
|
||||
@@ -154,6 +155,11 @@ static bool t234_hwpm_validate_hals(struct tegra_soc_hwpm *hwpm)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hwpm->active_chip->check_status == NULL) {
|
||||
tegra_hwpm_err(hwpm, "check_status uninitialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hwpm->active_chip->disable_mem_mgmt == NULL) {
|
||||
tegra_hwpm_err(hwpm, "disable_mem_mgmt HAL uninitialized");
|
||||
return false;
|
||||
|
||||
@@ -86,6 +86,7 @@ int t234_hwpm_init_prod_values(struct tegra_soc_hwpm *hwpm);
|
||||
int t234_hwpm_disable_cg(struct tegra_soc_hwpm *hwpm);
|
||||
int t234_hwpm_enable_cg(struct tegra_soc_hwpm *hwpm);
|
||||
|
||||
int t234_hwpm_check_status(struct tegra_soc_hwpm *hwpm);
|
||||
int t234_hwpm_disable_triggers(struct tegra_soc_hwpm *hwpm);
|
||||
int t234_hwpm_perfmon_enable(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *perfmon);
|
||||
|
||||
@@ -162,12 +162,13 @@ enum tegra_hwpm_element_type {
|
||||
enum tegra_hwpm_funcs {
|
||||
TEGRA_HWPM_INIT_IP_STRUCTURES,
|
||||
TEGRA_HWPM_MATCH_BASE_ADDRESS,
|
||||
TEGRA_HWPM_FIND_GIVEN_ADDRESS,
|
||||
TEGRA_HWPM_UPDATE_IP_INST_MASK,
|
||||
TEGRA_HWPM_GET_ALIST_SIZE,
|
||||
TEGRA_HWPM_COMBINE_ALIST,
|
||||
TEGRA_HWPM_RESERVE_GIVEN_RESOURCE,
|
||||
TEGRA_HWPM_BIND_RESOURCES,
|
||||
TEGRA_HWPM_FIND_GIVEN_ADDRESS,
|
||||
TEGRA_HWPM_UNBIND_RESOURCES,
|
||||
TEGRA_HWPM_RELEASE_RESOURCES,
|
||||
TEGRA_HWPM_RELEASE_ROUTER,
|
||||
TEGRA_HWPM_RELEASE_IP_STRUCTURES
|
||||
@@ -396,6 +397,7 @@ struct tegra_soc_hwpm_chip {
|
||||
int (*reserve_rtr)(struct tegra_soc_hwpm *hwpm);
|
||||
int (*release_rtr)(struct tegra_soc_hwpm *hwpm);
|
||||
|
||||
int (*check_status)(struct tegra_soc_hwpm *hwpm);
|
||||
int (*disable_triggers)(struct tegra_soc_hwpm *hwpm);
|
||||
int (*perfmon_enable)(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *perfmon);
|
||||
|
||||
@@ -80,6 +80,7 @@ bool tegra_hwpm_check_alist(struct tegra_soc_hwpm *hwpm,
|
||||
int tegra_hwpm_setup_hw(struct tegra_soc_hwpm *hwpm);
|
||||
int tegra_hwpm_setup_sw(struct tegra_soc_hwpm *hwpm);
|
||||
int tegra_hwpm_disable_triggers(struct tegra_soc_hwpm *hwpm);
|
||||
int tegra_hwpm_check_status(struct tegra_soc_hwpm *hwpm);
|
||||
int tegra_hwpm_release_hw(struct tegra_soc_hwpm *hwpm);
|
||||
void tegra_hwpm_release_sw_setup(struct tegra_soc_hwpm *hwpm);
|
||||
|
||||
|
||||
@@ -412,6 +412,12 @@ static int tegra_hwpm_open(struct inode *inode, struct file *filp)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = tegra_hwpm_check_status(hwpm);
|
||||
if (ret < 0) {
|
||||
tegra_hwpm_err(hwpm, "HW not ready for profiling session");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = tegra_hwpm_setup_sw(hwpm);
|
||||
if (ret < 0) {
|
||||
tegra_hwpm_err(hwpm, "Failed to setup sw");
|
||||
|
||||
Reference in New Issue
Block a user