mirror of
git://nv-tegra.nvidia.com/linux-hwpm.git
synced 2025-12-22 17:30:40 +03:00
tegra: hwpm: return error from read/write function
Currently, read/write functions validate aperture and mmio address pointers. However, the error cannot be returned to the parent resulting into undetected errors. Modify all read write functions to return error on failure. This will also allow HWPM driver to know about unavailable IP perfmuxes. Jira THWPM-41 Change-Id: I6cc4ba7a831d5058657d4f2536b1ce3ab20b30c6 Signed-off-by: Vedashree Vidwans <vvidwans@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2707446 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Vasuki Shankar <vasukis@nvidia.com> Reviewed-by: Seema Khowala <seemaj@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
mobile promotions
parent
8e27814e39
commit
c220f9f46f
@@ -64,7 +64,8 @@ static int tegra_hwpm_perfmon_reserve(struct tegra_soc_hwpm *hwpm,
|
||||
static int tegra_hwpm_perfmux_reserve(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_inst *ip_inst, struct hwpm_ip_aperture *perfmux)
|
||||
{
|
||||
u32 val = 0U;
|
||||
int ret = 0;
|
||||
u32 reg_val = 0U;
|
||||
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
@@ -89,10 +90,10 @@ static int tegra_hwpm_perfmux_reserve(struct tegra_soc_hwpm *hwpm,
|
||||
}
|
||||
|
||||
/* Validate perfmux availability by reading 1st alist offset */
|
||||
val = tegra_hwpm_regops_readl(hwpm,
|
||||
ret = tegra_hwpm_regops_readl(hwpm, ip_inst, perfmux,
|
||||
tegra_hwpm_safe_add_u64(perfmux->start_abs_pa,
|
||||
perfmux->alist[0U].reg_offset), ip_inst, perfmux);
|
||||
if (val < 0U) {
|
||||
perfmux->alist[0U].reg_offset), ®_val);
|
||||
if (ret != 0) {
|
||||
tegra_hwpm_dbg(hwpm, hwpm_info,
|
||||
"perfmux start_abs_pa 0x%llx unavailable",
|
||||
perfmux->start_abs_pa);
|
||||
|
||||
@@ -30,6 +30,7 @@ static int tegra_hwpm_exec_reg_ops(struct tegra_soc_hwpm *hwpm,
|
||||
u32 a_type = 0U;
|
||||
u32 reg_val = 0U;
|
||||
u64 addr_hi = 0ULL;
|
||||
int err = 0;
|
||||
enum tegra_hwpm_element_type element_type = HWPM_ELEMENT_INVALID;
|
||||
struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip;
|
||||
struct hwpm_ip *chip_ip = NULL;
|
||||
@@ -82,28 +83,48 @@ static int tegra_hwpm_exec_reg_ops(struct tegra_soc_hwpm *hwpm,
|
||||
|
||||
switch (reg_op->cmd) {
|
||||
case TEGRA_SOC_HWPM_REG_OP_CMD_RD32:
|
||||
reg_op->reg_val_lo = tegra_hwpm_regops_readl(hwpm,
|
||||
reg_op->phys_addr, ip_inst, element);
|
||||
err = tegra_hwpm_regops_readl(hwpm, ip_inst, element,
|
||||
reg_op->phys_addr, ®_op->reg_val_lo);
|
||||
if (err != 0) {
|
||||
reg_op->status = TEGRA_SOC_HWPM_REG_OP_STATUS_RD_FAILED;
|
||||
break;
|
||||
}
|
||||
reg_op->status = TEGRA_SOC_HWPM_REG_OP_STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case TEGRA_SOC_HWPM_REG_OP_CMD_RD64:
|
||||
addr_hi = tegra_hwpm_safe_add_u64(reg_op->phys_addr, 4ULL);
|
||||
reg_op->reg_val_lo = tegra_hwpm_regops_readl(hwpm,
|
||||
reg_op->phys_addr, ip_inst, element);
|
||||
reg_op->reg_val_hi = tegra_hwpm_regops_readl(hwpm,
|
||||
addr_hi, ip_inst, element);
|
||||
err = tegra_hwpm_regops_readl(hwpm, ip_inst, element,
|
||||
reg_op->phys_addr, ®_op->reg_val_lo);
|
||||
if (err != 0) {
|
||||
reg_op->status = TEGRA_SOC_HWPM_REG_OP_STATUS_RD_FAILED;
|
||||
break;
|
||||
}
|
||||
err = tegra_hwpm_regops_readl(hwpm, ip_inst, element,
|
||||
addr_hi, ®_op->reg_val_hi);
|
||||
if (err != 0) {
|
||||
reg_op->status = TEGRA_SOC_HWPM_REG_OP_STATUS_RD_FAILED;
|
||||
break;
|
||||
}
|
||||
reg_op->status = TEGRA_SOC_HWPM_REG_OP_STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
/* Read Modify Write operation */
|
||||
case TEGRA_SOC_HWPM_REG_OP_CMD_WR32:
|
||||
reg_val = tegra_hwpm_regops_readl(hwpm,
|
||||
reg_op->phys_addr, ip_inst, element);
|
||||
err = tegra_hwpm_regops_readl(hwpm, ip_inst, element,
|
||||
reg_op->phys_addr, ®_val);
|
||||
if (err != 0) {
|
||||
reg_op->status = TEGRA_SOC_HWPM_REG_OP_STATUS_RD_FAILED;
|
||||
break;
|
||||
}
|
||||
reg_val = set_field(reg_val, reg_op->mask_lo,
|
||||
reg_op->reg_val_lo);
|
||||
tegra_hwpm_regops_writel(hwpm,
|
||||
reg_op->phys_addr, reg_val, ip_inst, element);
|
||||
err = tegra_hwpm_regops_writel(hwpm, ip_inst, element,
|
||||
reg_op->phys_addr, reg_val);
|
||||
if (err != 0) {
|
||||
reg_op->status = TEGRA_SOC_HWPM_REG_OP_STATUS_WR_FAILED;
|
||||
break;
|
||||
}
|
||||
reg_op->status = TEGRA_SOC_HWPM_REG_OP_STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
@@ -112,20 +133,36 @@ static int tegra_hwpm_exec_reg_ops(struct tegra_soc_hwpm *hwpm,
|
||||
addr_hi = tegra_hwpm_safe_add_u64(reg_op->phys_addr, 4ULL);
|
||||
|
||||
/* Lower 32 bits */
|
||||
reg_val = tegra_hwpm_regops_readl(hwpm,
|
||||
reg_op->phys_addr, ip_inst, element);
|
||||
err = tegra_hwpm_regops_readl(hwpm, ip_inst, element,
|
||||
reg_op->phys_addr, ®_val);
|
||||
if (err != 0) {
|
||||
reg_op->status = TEGRA_SOC_HWPM_REG_OP_STATUS_RD_FAILED;
|
||||
break;
|
||||
}
|
||||
reg_val = set_field(reg_val, reg_op->mask_lo,
|
||||
reg_op->reg_val_lo);
|
||||
tegra_hwpm_regops_writel(hwpm,
|
||||
reg_op->phys_addr, reg_val, ip_inst, element);
|
||||
err = tegra_hwpm_regops_writel(hwpm, ip_inst, element,
|
||||
reg_op->phys_addr, reg_val);
|
||||
if (err != 0) {
|
||||
reg_op->status = TEGRA_SOC_HWPM_REG_OP_STATUS_WR_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Upper 32 bits */
|
||||
reg_val = tegra_hwpm_regops_readl(hwpm,
|
||||
addr_hi, ip_inst, element);
|
||||
err = tegra_hwpm_regops_readl(hwpm, ip_inst, element,
|
||||
addr_hi, ®_val);
|
||||
if (err != 0) {
|
||||
reg_op->status = TEGRA_SOC_HWPM_REG_OP_STATUS_RD_FAILED;
|
||||
break;
|
||||
}
|
||||
reg_val = set_field(reg_val, reg_op->mask_hi,
|
||||
reg_op->reg_val_hi);
|
||||
tegra_hwpm_regops_writel(hwpm,
|
||||
reg_op->phys_addr, reg_val, ip_inst, element);
|
||||
err = tegra_hwpm_regops_writel(hwpm, ip_inst, element,
|
||||
reg_op->phys_addr, reg_val);
|
||||
if (err != 0) {
|
||||
reg_op->status = TEGRA_SOC_HWPM_REG_OP_STATUS_WR_FAILED;
|
||||
break;
|
||||
}
|
||||
reg_op->status = TEGRA_SOC_HWPM_REG_OP_STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
|
||||
@@ -30,15 +30,20 @@ int t234_hwpm_zero_alist_regs(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_inst *ip_inst, struct hwpm_ip_aperture *aperture)
|
||||
{
|
||||
u32 alist_idx = 0U;
|
||||
int err = 0;
|
||||
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
for (alist_idx = 0; alist_idx < aperture->alist_size; alist_idx++) {
|
||||
if (aperture->alist[alist_idx].zero_at_init) {
|
||||
tegra_hwpm_regops_writel(hwpm,
|
||||
err = tegra_hwpm_regops_writel(hwpm, ip_inst, aperture,
|
||||
tegra_hwpm_safe_add_u64(aperture->start_abs_pa,
|
||||
aperture->alist[alist_idx].reg_offset),
|
||||
0U, ip_inst, aperture);
|
||||
0U);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "zero alist regs failed");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
int t234_hwpm_disable_triggers(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
int ret = 0;
|
||||
int err = 0;
|
||||
bool timeout = false;
|
||||
u32 reg_val = 0U;
|
||||
u32 field_mask = 0U;
|
||||
@@ -48,57 +48,97 @@ int t234_hwpm_disable_triggers(struct tegra_soc_hwpm *hwpm)
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
/* Disable PMA triggers */
|
||||
reg_val = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_trigger_config_user_r(0));
|
||||
err = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_trigger_config_user_r(0), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
reg_val = set_field(reg_val, pmasys_trigger_config_user_pma_pulse_m(),
|
||||
pmasys_trigger_config_user_pma_pulse_disable_f());
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_trigger_config_user_r(0), reg_val);
|
||||
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_sys_trigger_start_mask_r(), 0);
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_sys_trigger_start_maskb_r(), 0);
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_sys_trigger_stop_mask_r(), 0);
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_sys_trigger_stop_maskb_r(), 0);
|
||||
|
||||
/* Wait for PERFMONs, ROUTER, and PMA to idle */
|
||||
timeout = HWPM_TIMEOUT(pmmsys_sys0router_perfmonstatus_merged_v(
|
||||
tegra_hwpm_readl(hwpm, rtr_perfmux,
|
||||
pmmsys_sys0router_perfmonstatus_r())) == 0U,
|
||||
"NV_PERF_PMMSYS_SYS0ROUTER_PERFMONSTATUS_MERGED_EMPTY");
|
||||
if (timeout && ret == 0) {
|
||||
ret = -EIO;
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
timeout = HWPM_TIMEOUT(pmmsys_sys0router_enginestatus_status_v(
|
||||
tegra_hwpm_readl(hwpm, rtr_perfmux,
|
||||
pmmsys_sys0router_enginestatus_r())) ==
|
||||
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, ROUTER, and PMA to idle */
|
||||
err = tegra_hwpm_readl(hwpm, rtr_perfmux,
|
||||
pmmsys_sys0router_perfmonstatus_r(), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
timeout = HWPM_TIMEOUT(
|
||||
pmmsys_sys0router_perfmonstatus_merged_v(reg_val) == 0U,
|
||||
"NV_PERF_PMMSYS_SYS0ROUTER_PERFMONSTATUS_MERGED_EMPTY");
|
||||
if (timeout) {
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
err = tegra_hwpm_readl(hwpm, rtr_perfmux,
|
||||
pmmsys_sys0router_enginestatus_r(), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
timeout = HWPM_TIMEOUT(
|
||||
pmmsys_sys0router_enginestatus_status_v(reg_val) ==
|
||||
pmmsys_sys0router_enginestatus_status_empty_v(),
|
||||
"NV_PERF_PMMSYS_SYS0ROUTER_ENGINESTATUS_STATUS_EMPTY");
|
||||
if (timeout && ret == 0) {
|
||||
ret = -EIO;
|
||||
if (timeout) {
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
field_mask = pmasys_enginestatus_status_m() |
|
||||
pmasys_enginestatus_rbufempty_m();
|
||||
field_val = pmasys_enginestatus_status_empty_f() |
|
||||
pmasys_enginestatus_rbufempty_empty_f();
|
||||
timeout = HWPM_TIMEOUT((tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_enginestatus_r()) & field_mask) == field_val,
|
||||
err = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_enginestatus_r(), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
timeout = HWPM_TIMEOUT((reg_val & field_mask) == field_val,
|
||||
"NV_PERF_PMASYS_ENGINESTATUS");
|
||||
if (timeout && ret == 0) {
|
||||
ret = -EIO;
|
||||
if (timeout) {
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
|
||||
int t234_hwpm_init_prod_values(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
u32 reg_val = 0U;
|
||||
int err = 0;
|
||||
u32 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)];
|
||||
@@ -110,25 +150,41 @@ int t234_hwpm_init_prod_values(struct tegra_soc_hwpm *hwpm)
|
||||
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
reg_val = tegra_hwpm_readl(hwpm, pma_perfmux, pmasys_controlb_r());
|
||||
reg_val = set_field(reg_val,
|
||||
pmasys_controlb_coalesce_timeout_cycles_m(),
|
||||
err = tegra_hwpm_readl(hwpm, pma_perfmux, pmasys_controlb_r(), &val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
val = set_field(val, pmasys_controlb_coalesce_timeout_cycles_m(),
|
||||
pmasys_controlb_coalesce_timeout_cycles__prod_f());
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_controlb_r(), reg_val);
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_controlb_r(), val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
reg_val = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_channel_config_user_r(0));
|
||||
reg_val = set_field(reg_val,
|
||||
err = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_channel_config_user_r(0), &val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
val = set_field(val,
|
||||
pmasys_channel_config_user_coalesce_timeout_cycles_m(),
|
||||
pmasys_channel_config_user_coalesce_timeout_cycles__prod_f());
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_channel_config_user_r(0), reg_val);
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_channel_config_user_r(0), val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int t234_hwpm_disable_slcg(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
int err = 0;
|
||||
u32 field_mask = 0U;
|
||||
u32 field_val = 0U;
|
||||
u32 reg_val = 0U;
|
||||
@@ -146,10 +202,18 @@ int t234_hwpm_disable_slcg(struct tegra_soc_hwpm *hwpm)
|
||||
TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[
|
||||
T234_HWPM_IP_RTR_PERMUX_INDEX];
|
||||
|
||||
reg_val = tegra_hwpm_readl(hwpm, pma_perfmux, pmasys_cg2_r());
|
||||
err = tegra_hwpm_readl(hwpm, pma_perfmux, pmasys_cg2_r(), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
reg_val = set_field(reg_val, pmasys_cg2_slcg_m(),
|
||||
pmasys_cg2_slcg_disabled_f());
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_cg2_r(), reg_val);
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_cg2_r(), reg_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
field_mask = pmmsys_sys0router_cg2_slcg_perfmon_m() |
|
||||
pmmsys_sys0router_cg2_slcg_router_m() |
|
||||
@@ -157,17 +221,26 @@ int t234_hwpm_disable_slcg(struct tegra_soc_hwpm *hwpm)
|
||||
field_val = pmmsys_sys0router_cg2_slcg_perfmon_disabled_f() |
|
||||
pmmsys_sys0router_cg2_slcg_router_disabled_f() |
|
||||
pmmsys_sys0router_cg2_slcg_disabled_f();
|
||||
reg_val = tegra_hwpm_readl(hwpm, rtr_perfmux,
|
||||
pmmsys_sys0router_cg2_r());
|
||||
err = tegra_hwpm_readl(hwpm, rtr_perfmux,
|
||||
pmmsys_sys0router_cg2_r(), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
reg_val = set_field(reg_val, field_mask, field_val);
|
||||
tegra_hwpm_writel(hwpm, rtr_perfmux,
|
||||
err = tegra_hwpm_writel(hwpm, rtr_perfmux,
|
||||
pmmsys_sys0router_cg2_r(), reg_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int t234_hwpm_enable_slcg(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
int err = 0;
|
||||
u32 reg_val = 0U;
|
||||
u32 field_mask = 0U;
|
||||
u32 field_val = 0U;
|
||||
@@ -185,10 +258,18 @@ int t234_hwpm_enable_slcg(struct tegra_soc_hwpm *hwpm)
|
||||
TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[
|
||||
T234_HWPM_IP_RTR_PERMUX_INDEX];
|
||||
|
||||
reg_val = tegra_hwpm_readl(hwpm, pma_perfmux, pmasys_cg2_r());
|
||||
err = tegra_hwpm_readl(hwpm, pma_perfmux, pmasys_cg2_r(), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
reg_val = set_field(reg_val, pmasys_cg2_slcg_m(),
|
||||
pmasys_cg2_slcg_enabled_f());
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_cg2_r(), reg_val);
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_cg2_r(), reg_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
field_mask = pmmsys_sys0router_cg2_slcg_perfmon_m() |
|
||||
pmmsys_sys0router_cg2_slcg_router_m() |
|
||||
@@ -196,11 +277,19 @@ int t234_hwpm_enable_slcg(struct tegra_soc_hwpm *hwpm)
|
||||
field_val = pmmsys_sys0router_cg2_slcg_perfmon__prod_f() |
|
||||
pmmsys_sys0router_cg2_slcg_router__prod_f() |
|
||||
pmmsys_sys0router_cg2_slcg__prod_f();
|
||||
reg_val = tegra_hwpm_readl(hwpm, rtr_perfmux,
|
||||
pmmsys_sys0router_cg2_r());
|
||||
err = tegra_hwpm_readl(hwpm, rtr_perfmux,
|
||||
pmmsys_sys0router_cg2_r(), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
reg_val = set_field(reg_val, field_mask, field_val);
|
||||
tegra_hwpm_writel(hwpm, rtr_perfmux,
|
||||
err = tegra_hwpm_writel(hwpm, rtr_perfmux,
|
||||
pmmsys_sys0router_cg2_r(), reg_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
int t234_hwpm_disable_mem_mgmt(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
int err = 0;
|
||||
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)];
|
||||
@@ -36,12 +37,30 @@ int t234_hwpm_disable_mem_mgmt(struct tegra_soc_hwpm *hwpm)
|
||||
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_channel_outbase_r(0), 0);
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_channel_outbase_r(0), 0);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_channel_outbaseupper_r(0), 0);
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_channel_outsize_r(0), 0);
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_channel_outsize_r(0), 0);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_channel_mem_bytes_addr_r(0), 0);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -49,6 +68,7 @@ int t234_hwpm_disable_mem_mgmt(struct tegra_soc_hwpm *hwpm)
|
||||
int t234_hwpm_enable_mem_mgmt(struct tegra_soc_hwpm *hwpm,
|
||||
struct tegra_soc_hwpm_alloc_pma_stream *alloc_pma_stream)
|
||||
{
|
||||
int err = 0;
|
||||
u32 outbase_lo = 0;
|
||||
u32 outbase_hi = 0;
|
||||
u32 outsize = 0;
|
||||
@@ -66,38 +86,59 @@ int t234_hwpm_enable_mem_mgmt(struct tegra_soc_hwpm *hwpm,
|
||||
|
||||
outbase_lo = alloc_pma_stream->stream_buf_pma_va &
|
||||
pmasys_channel_outbase_ptr_m();
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_channel_outbase_r(0), outbase_lo);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
tegra_hwpm_dbg(hwpm, hwpm_verbose, "OUTBASE = 0x%x", outbase_lo);
|
||||
|
||||
outbase_hi = (alloc_pma_stream->stream_buf_pma_va >> 32) &
|
||||
pmasys_channel_outbaseupper_ptr_m();
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_channel_outbaseupper_r(0), outbase_hi);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
tegra_hwpm_dbg(hwpm, hwpm_verbose, "OUTBASEUPPER = 0x%x", outbase_hi);
|
||||
|
||||
outsize = alloc_pma_stream->stream_buf_size &
|
||||
pmasys_channel_outsize_numbytes_m();
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_channel_outsize_r(0), outsize);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
tegra_hwpm_dbg(hwpm, hwpm_verbose, "OUTSIZE = 0x%x", outsize);
|
||||
|
||||
mem_bytes_addr = sg_dma_address(hwpm->mem_bytes_sgt->sgl) &
|
||||
pmasys_channel_mem_bytes_addr_ptr_m();
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_channel_mem_bytes_addr_r(0), mem_bytes_addr);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
tegra_hwpm_dbg(hwpm, hwpm_verbose,
|
||||
"MEM_BYTES_ADDR = 0x%x", mem_bytes_addr);
|
||||
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_channel_mem_block_r(0),
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_channel_mem_block_r(0),
|
||||
pmasys_channel_mem_block_valid_f(
|
||||
pmasys_channel_mem_block_valid_true_v()));
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int t234_hwpm_invalidate_mem_config(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
int err = 0;
|
||||
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)];
|
||||
@@ -109,15 +150,20 @@ int t234_hwpm_invalidate_mem_config(struct tegra_soc_hwpm *hwpm)
|
||||
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_channel_mem_block_r(0),
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_channel_mem_block_r(0),
|
||||
pmasys_channel_mem_block_valid_f(
|
||||
pmasys_channel_mem_block_valid_false_v()));
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int t234_hwpm_stream_mem_bytes(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
int err = 0;
|
||||
u32 reg_val = 0U;
|
||||
u32 *mem_bytes_kernel_u32 = (u32 *)(hwpm->mem_bytes_kernel);
|
||||
struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip;
|
||||
@@ -133,19 +179,28 @@ int t234_hwpm_stream_mem_bytes(struct tegra_soc_hwpm *hwpm)
|
||||
|
||||
*mem_bytes_kernel_u32 = TEGRA_SOC_HWPM_MEM_BYTES_INVALID;
|
||||
|
||||
reg_val = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_channel_control_user_r(0));
|
||||
err = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_channel_control_user_r(0), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
reg_val = set_field(reg_val,
|
||||
pmasys_channel_control_user_update_bytes_m(),
|
||||
pmasys_channel_control_user_update_bytes_doit_f());
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_channel_control_user_r(0), reg_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int t234_hwpm_disable_pma_streaming(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
int err = 0;
|
||||
u32 reg_val = 0U;
|
||||
struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip;
|
||||
struct hwpm_ip *chip_ip = active_chip->chip_ips[
|
||||
@@ -159,21 +214,37 @@ int t234_hwpm_disable_pma_streaming(struct tegra_soc_hwpm *hwpm)
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
/* Disable PMA streaming */
|
||||
reg_val = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_trigger_config_user_r(0));
|
||||
err = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_trigger_config_user_r(0), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
reg_val = set_field(reg_val,
|
||||
pmasys_trigger_config_user_record_stream_m(),
|
||||
pmasys_trigger_config_user_record_stream_disable_f());
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_trigger_config_user_r(0), reg_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
reg_val = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_channel_control_user_r(0));
|
||||
err = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_channel_control_user_r(0), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
reg_val = set_field(reg_val,
|
||||
pmasys_channel_control_user_stream_m(),
|
||||
pmasys_channel_control_user_stream_disable_f());
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_channel_control_user_r(0), reg_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -181,6 +252,7 @@ int t234_hwpm_disable_pma_streaming(struct tegra_soc_hwpm *hwpm)
|
||||
int t234_hwpm_update_mem_bytes_get_ptr(struct tegra_soc_hwpm *hwpm,
|
||||
u64 mem_bump)
|
||||
{
|
||||
int err = 0;
|
||||
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)];
|
||||
@@ -197,14 +269,20 @@ int t234_hwpm_update_mem_bytes_get_ptr(struct tegra_soc_hwpm *hwpm,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
err = tegra_hwpm_writel(hwpm, pma_perfmux,
|
||||
pmasys_channel_mem_bump_r(0), mem_bump);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 t234_hwpm_get_mem_bytes_put_ptr(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
int err = 0;
|
||||
u32 reg_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)];
|
||||
@@ -216,12 +294,19 @@ u64 t234_hwpm_get_mem_bytes_put_ptr(struct tegra_soc_hwpm *hwpm)
|
||||
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
return (u64)tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_channel_mem_head_r(0));
|
||||
err = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_channel_mem_head_r(0), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
return (u64)reg_val;
|
||||
}
|
||||
|
||||
bool t234_hwpm_membuf_overflow_status(struct tegra_soc_hwpm *hwpm)
|
||||
{
|
||||
int err = 0;
|
||||
u32 reg_val, field_val;
|
||||
struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip;
|
||||
struct hwpm_ip *chip_ip = active_chip->chip_ips[
|
||||
@@ -234,8 +319,12 @@ bool t234_hwpm_membuf_overflow_status(struct tegra_soc_hwpm *hwpm)
|
||||
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
|
||||
reg_val = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_channel_status_secure_r(0));
|
||||
err = tegra_hwpm_readl(hwpm, pma_perfmux,
|
||||
pmasys_channel_status_secure_r(0), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
field_val = pmasys_channel_status_secure_membuf_status_v(
|
||||
reg_val);
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
int t234_hwpm_perfmon_enable(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *perfmon)
|
||||
{
|
||||
int err = 0;
|
||||
u32 reg_val;
|
||||
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
@@ -36,12 +37,20 @@ int t234_hwpm_perfmon_enable(struct tegra_soc_hwpm *hwpm,
|
||||
tegra_hwpm_dbg(hwpm, hwpm_verbose, "Enabling PERFMON(0x%llx - 0x%llx)",
|
||||
perfmon->start_abs_pa, perfmon->end_abs_pa);
|
||||
|
||||
reg_val = tegra_hwpm_readl(hwpm, perfmon,
|
||||
pmmsys_sys0_enginestatus_r(0));
|
||||
err = tegra_hwpm_readl(hwpm, perfmon,
|
||||
pmmsys_sys0_enginestatus_r(0), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
reg_val = set_field(reg_val, pmmsys_sys0_enginestatus_enable_m(),
|
||||
pmmsys_sys0_enginestatus_enable_out_f());
|
||||
tegra_hwpm_writel(hwpm, perfmon,
|
||||
err = tegra_hwpm_writel(hwpm, perfmon,
|
||||
pmmsys_sys0_enginestatus_r(0), reg_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -57,6 +66,7 @@ int t234_hwpm_perfmux_disable(struct tegra_soc_hwpm *hwpm,
|
||||
int t234_hwpm_perfmon_disable(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *perfmon)
|
||||
{
|
||||
int err = 0;
|
||||
u32 reg_val;
|
||||
|
||||
tegra_hwpm_fn(hwpm, " ");
|
||||
@@ -73,10 +83,18 @@ int t234_hwpm_perfmon_disable(struct tegra_soc_hwpm *hwpm,
|
||||
tegra_hwpm_dbg(hwpm, hwpm_verbose, "Disabling PERFMON(0x%llx - 0x%llx)",
|
||||
perfmon->start_abs_pa, perfmon->end_abs_pa);
|
||||
|
||||
reg_val = tegra_hwpm_readl(hwpm, perfmon, pmmsys_control_r(0));
|
||||
err = tegra_hwpm_readl(hwpm, perfmon, pmmsys_control_r(0), ®_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm read failed");
|
||||
return err;
|
||||
}
|
||||
reg_val = set_field(reg_val, pmmsys_control_mode_m(),
|
||||
pmmsys_control_mode_disable_f());
|
||||
tegra_hwpm_writel(hwpm, perfmon, pmmsys_control_r(0), reg_val);
|
||||
err = tegra_hwpm_writel(hwpm, perfmon, pmmsys_control_r(0), reg_val);
|
||||
if (err != 0) {
|
||||
tegra_hwpm_err(hwpm, "hwpm write failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -54,15 +54,15 @@ struct tegra_soc_hwpm;
|
||||
struct hwpm_ip_inst;
|
||||
struct hwpm_ip_aperture;
|
||||
|
||||
u32 tegra_hwpm_readl(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *aperture, u64 addr);
|
||||
void tegra_hwpm_writel(struct tegra_soc_hwpm *hwpm,
|
||||
int tegra_hwpm_readl(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *aperture, u64 addr, u32 *val);
|
||||
int tegra_hwpm_writel(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *aperture, u64 addr, u32 val);
|
||||
u32 tegra_hwpm_regops_readl(struct tegra_soc_hwpm *hwpm,
|
||||
u64 addr, struct hwpm_ip_inst *ip_inst,
|
||||
struct hwpm_ip_aperture *aperture);
|
||||
void tegra_hwpm_regops_writel(struct tegra_soc_hwpm *hwpm,
|
||||
u64 addr, u32 val, struct hwpm_ip_inst *ip_inst,
|
||||
struct hwpm_ip_aperture *aperture);
|
||||
int tegra_hwpm_regops_readl(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_inst *ip_inst, struct hwpm_ip_aperture *aperture,
|
||||
u64 addr, u32 *val);
|
||||
int tegra_hwpm_regops_writel(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_inst *ip_inst, struct hwpm_ip_aperture *aperture,
|
||||
u64 addr, u32 val);
|
||||
|
||||
#endif /* TEGRA_HWPM_IO_H */
|
||||
|
||||
@@ -23,59 +23,57 @@
|
||||
#include <tegra_hwpm_log.h>
|
||||
#include <tegra_hwpm_static_analysis.h>
|
||||
|
||||
static u32 fake_readl(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *aperture, u64 offset)
|
||||
static int fake_readl(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *aperture, u64 offset, u32 *val)
|
||||
{
|
||||
u32 reg_val = 0;
|
||||
|
||||
if (!hwpm->fake_registers_enabled) {
|
||||
tegra_hwpm_err(hwpm, "Fake registers are disabled!");
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
reg_val = aperture->fake_registers[offset];
|
||||
return reg_val;
|
||||
*val = aperture->fake_registers[offset];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fake_writel(struct tegra_soc_hwpm *hwpm,
|
||||
static int fake_writel(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *aperture, u64 offset, u32 val)
|
||||
{
|
||||
if (!hwpm->fake_registers_enabled) {
|
||||
tegra_hwpm_err(hwpm, "Fake registers are disabled!");
|
||||
return;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
aperture->fake_registers[offset] = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read IP domain registers
|
||||
* IP(except PMA and RTR) perfmux fall in this category
|
||||
*/
|
||||
static u32 ip_readl(struct tegra_soc_hwpm *hwpm, struct hwpm_ip_inst *ip_inst,
|
||||
struct hwpm_ip_aperture *aperture, u64 offset)
|
||||
static int ip_readl(struct tegra_soc_hwpm *hwpm, struct hwpm_ip_inst *ip_inst,
|
||||
struct hwpm_ip_aperture *aperture, u64 offset, u32 *val)
|
||||
{
|
||||
tegra_hwpm_dbg(hwpm, hwpm_register,
|
||||
"Aperture (0x%llx-0x%llx) offset(0x%llx)",
|
||||
aperture->start_abs_pa, aperture->end_abs_pa, offset);
|
||||
|
||||
if (hwpm->fake_registers_enabled) {
|
||||
return fake_readl(hwpm, aperture, offset);
|
||||
return fake_readl(hwpm, aperture, offset, val);
|
||||
} else {
|
||||
u32 reg_val = 0U;
|
||||
struct tegra_hwpm_ip_ops *ip_ops_ptr = &ip_inst->ip_ops;
|
||||
if (ip_ops_ptr->hwpm_ip_reg_op != NULL) {
|
||||
int err = 0;
|
||||
|
||||
err = (*ip_ops_ptr->hwpm_ip_reg_op)(ip_ops_ptr->ip_dev,
|
||||
TEGRA_SOC_HWPM_IP_REG_OP_READ,
|
||||
offset, ®_val);
|
||||
offset, val);
|
||||
if (err < 0) {
|
||||
tegra_hwpm_err(hwpm, "Aperture (0x%llx-0x%llx) "
|
||||
"read offset(0x%llx) failed",
|
||||
aperture->start_abs_pa,
|
||||
aperture->end_abs_pa, offset);
|
||||
return 0U;
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
/* Fall back to un-registered IP method */
|
||||
@@ -86,7 +84,7 @@ static u32 ip_readl(struct tegra_soc_hwpm *hwpm, struct hwpm_ip_inst *ip_inst,
|
||||
if (is_tegra_hypervisor_mode()) {
|
||||
tegra_hwpm_err(hwpm,
|
||||
"Fallback method not implemented on hypervisor config");
|
||||
return 0U;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ptr = ioremap(reg_addr, 0x4);
|
||||
@@ -94,20 +92,20 @@ static u32 ip_readl(struct tegra_soc_hwpm *hwpm, struct hwpm_ip_inst *ip_inst,
|
||||
tegra_hwpm_err(hwpm,
|
||||
"Failed to map register(0x%llx)",
|
||||
reg_addr);
|
||||
return 0U;
|
||||
return -ENODEV;
|
||||
}
|
||||
reg_val = __raw_readl(ptr);
|
||||
*val = __raw_readl(ptr);
|
||||
iounmap(ptr);
|
||||
}
|
||||
return reg_val;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to IP domain registers
|
||||
* IP(except PMA and RTR) perfmux fall in this category
|
||||
*/
|
||||
static void ip_writel(struct tegra_soc_hwpm *hwpm, struct hwpm_ip_inst *ip_inst,
|
||||
static int ip_writel(struct tegra_soc_hwpm *hwpm, struct hwpm_ip_inst *ip_inst,
|
||||
struct hwpm_ip_aperture *aperture, u64 offset, u32 val)
|
||||
{
|
||||
tegra_hwpm_dbg(hwpm, hwpm_register,
|
||||
@@ -115,7 +113,7 @@ static void ip_writel(struct tegra_soc_hwpm *hwpm, struct hwpm_ip_inst *ip_inst,
|
||||
aperture->start_abs_pa, aperture->end_abs_pa, offset, val);
|
||||
|
||||
if (hwpm->fake_registers_enabled) {
|
||||
fake_writel(hwpm, aperture, offset, val);
|
||||
return fake_writel(hwpm, aperture, offset, val);
|
||||
} else {
|
||||
struct tegra_hwpm_ip_ops *ip_ops_ptr = &ip_inst->ip_ops;
|
||||
if (ip_ops_ptr->hwpm_ip_reg_op != NULL) {
|
||||
@@ -129,7 +127,7 @@ static void ip_writel(struct tegra_soc_hwpm *hwpm, struct hwpm_ip_inst *ip_inst,
|
||||
"write offset(0x%llx) val 0x%x failed",
|
||||
aperture->start_abs_pa,
|
||||
aperture->end_abs_pa, offset, val);
|
||||
return;
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
/* Fall back to un-registered IP method */
|
||||
@@ -140,7 +138,7 @@ static void ip_writel(struct tegra_soc_hwpm *hwpm, struct hwpm_ip_inst *ip_inst,
|
||||
if (is_tegra_hypervisor_mode()) {
|
||||
tegra_hwpm_err(hwpm,
|
||||
"Fallback method not implemented on hypervisor config");
|
||||
return;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ptr = ioremap(reg_addr, 0x4);
|
||||
@@ -148,20 +146,21 @@ static void ip_writel(struct tegra_soc_hwpm *hwpm, struct hwpm_ip_inst *ip_inst,
|
||||
tegra_hwpm_err(hwpm,
|
||||
"Failed to map register(0x%llx)",
|
||||
reg_addr);
|
||||
return;
|
||||
return -ENODEV;
|
||||
}
|
||||
__raw_writel(val, ptr);
|
||||
iounmap(ptr);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read HWPM domain registers
|
||||
* PERFMONs, PMA and RTR registers fall in this category
|
||||
*/
|
||||
static u32 hwpm_readl(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *aperture, u64 offset)
|
||||
static int hwpm_readl(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *aperture, u64 offset, u32 *val)
|
||||
{
|
||||
tegra_hwpm_dbg(hwpm, hwpm_register,
|
||||
"Aperture (0x%llx-0x%llx) offset(0x%llx)",
|
||||
@@ -169,51 +168,55 @@ static u32 hwpm_readl(struct tegra_soc_hwpm *hwpm,
|
||||
|
||||
if (aperture->dt_mmio == NULL) {
|
||||
tegra_hwpm_err(hwpm, "aperture is not iomapped as expected");
|
||||
return 0U;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (hwpm->fake_registers_enabled) {
|
||||
return fake_readl(hwpm, aperture, offset);
|
||||
return fake_readl(hwpm, aperture, offset, val);
|
||||
} else {
|
||||
return readl(aperture->dt_mmio + offset);
|
||||
*val = readl(aperture->dt_mmio + offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to HWPM domain registers
|
||||
* PERFMONs, PMA and RTR registers fall in this category
|
||||
*/
|
||||
static void hwpm_writel(struct tegra_soc_hwpm *hwpm,
|
||||
static int hwpm_writel(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *aperture, u64 offset, u32 val)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
tegra_hwpm_dbg(hwpm, hwpm_register,
|
||||
"Aperture (0x%llx-0x%llx) offset(0x%llx) val(0x%x)",
|
||||
aperture->start_abs_pa, aperture->end_abs_pa, offset, val);
|
||||
|
||||
if (aperture->dt_mmio == NULL) {
|
||||
tegra_hwpm_err(hwpm, "aperture is not iomapped as expected");
|
||||
return;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (hwpm->fake_registers_enabled) {
|
||||
fake_writel(hwpm, aperture, offset, val);
|
||||
err = fake_writel(hwpm, aperture, offset, val);
|
||||
} else {
|
||||
writel(val, aperture->dt_mmio + offset);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a HWPM domain register. It is assumed that valid aperture
|
||||
* is passed to the function.
|
||||
*/
|
||||
u32 tegra_hwpm_readl(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *aperture, u64 addr)
|
||||
int tegra_hwpm_readl(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *aperture, u64 addr, u32 *val)
|
||||
{
|
||||
u32 reg_val = 0;
|
||||
|
||||
if (!aperture) {
|
||||
tegra_hwpm_err(hwpm, "aperture is NULL");
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if ((aperture->element_type == HWPM_ELEMENT_PERFMON) ||
|
||||
@@ -221,24 +224,24 @@ u32 tegra_hwpm_readl(struct tegra_soc_hwpm *hwpm,
|
||||
u64 reg_offset = tegra_hwpm_safe_sub_u64(
|
||||
addr, aperture->base_pa);
|
||||
/* HWPM domain registers */
|
||||
reg_val = hwpm_readl(hwpm, aperture, reg_offset);
|
||||
return hwpm_readl(hwpm, aperture, reg_offset, val);
|
||||
} else {
|
||||
tegra_hwpm_err(hwpm, "IP aperture read is not expected");
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
return reg_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to a HWPM domain register. It is assumed that valid aperture
|
||||
* is passed to the function.
|
||||
*/
|
||||
void tegra_hwpm_writel(struct tegra_soc_hwpm *hwpm,
|
||||
int tegra_hwpm_writel(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_aperture *aperture, u64 addr, u32 val)
|
||||
{
|
||||
if (!aperture) {
|
||||
tegra_hwpm_err(hwpm, "aperture is NULL");
|
||||
return;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if ((aperture->element_type == HWPM_ELEMENT_PERFMON) ||
|
||||
@@ -246,61 +249,64 @@ void tegra_hwpm_writel(struct tegra_soc_hwpm *hwpm,
|
||||
u64 reg_offset = tegra_hwpm_safe_sub_u64(
|
||||
addr, aperture->base_pa);
|
||||
/* HWPM domain internal registers */
|
||||
hwpm_writel(hwpm, aperture, reg_offset, val);
|
||||
return hwpm_writel(hwpm, aperture, reg_offset, val);
|
||||
} else {
|
||||
tegra_hwpm_err(hwpm, "IP aperture write is not expected");
|
||||
return;
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a register from the EXEC_REG_OPS IOCTL. It is assumed that the allowlist
|
||||
* check has been done before calling this function.
|
||||
*/
|
||||
u32 tegra_hwpm_regops_readl(struct tegra_soc_hwpm *hwpm,
|
||||
u64 addr, struct hwpm_ip_inst *ip_inst,
|
||||
struct hwpm_ip_aperture *aperture)
|
||||
int tegra_hwpm_regops_readl(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_inst *ip_inst, struct hwpm_ip_aperture *aperture,
|
||||
u64 addr, u32 *val)
|
||||
{
|
||||
u32 reg_val = 0;
|
||||
u64 reg_offset = 0ULL;
|
||||
int err = 0;
|
||||
|
||||
if (!aperture) {
|
||||
tegra_hwpm_err(hwpm, "aperture is NULL");
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
reg_offset = tegra_hwpm_safe_sub_u64(addr, aperture->start_abs_pa);
|
||||
|
||||
if ((aperture->element_type == HWPM_ELEMENT_PERFMON) ||
|
||||
(aperture->element_type == HWPM_ELEMENT_PERFMUX)) {
|
||||
reg_val = hwpm_readl(hwpm, aperture, reg_offset);
|
||||
err = hwpm_readl(hwpm, aperture, reg_offset, val);
|
||||
} else {
|
||||
reg_val = ip_readl(hwpm, ip_inst, aperture, reg_offset);
|
||||
err = ip_readl(hwpm, ip_inst, aperture, reg_offset, val);
|
||||
}
|
||||
return reg_val;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a register from the EXEC_REG_OPS IOCTL. It is assumed that the
|
||||
* allowlist check has been done before calling this function.
|
||||
*/
|
||||
void tegra_hwpm_regops_writel(struct tegra_soc_hwpm *hwpm,
|
||||
u64 addr, u32 val, struct hwpm_ip_inst *ip_inst,
|
||||
struct hwpm_ip_aperture *aperture)
|
||||
int tegra_hwpm_regops_writel(struct tegra_soc_hwpm *hwpm,
|
||||
struct hwpm_ip_inst *ip_inst, struct hwpm_ip_aperture *aperture,
|
||||
u64 addr, u32 val)
|
||||
{
|
||||
u64 reg_offset = 0ULL;
|
||||
int err = 0;
|
||||
|
||||
if (!aperture) {
|
||||
tegra_hwpm_err(hwpm, "aperture is NULL");
|
||||
return;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
reg_offset = tegra_hwpm_safe_sub_u64(addr, aperture->start_abs_pa);
|
||||
|
||||
if ((aperture->element_type == HWPM_ELEMENT_PERFMON) ||
|
||||
(aperture->element_type == HWPM_ELEMENT_PERFMUX)) {
|
||||
hwpm_writel(hwpm, aperture, reg_offset, val);
|
||||
err = hwpm_writel(hwpm, aperture, reg_offset, val);
|
||||
} else {
|
||||
ip_writel(hwpm, ip_inst, aperture, reg_offset, val);
|
||||
err = ip_writel(hwpm, ip_inst, aperture, reg_offset, val);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user