platform: tegra: Check if MC channel is enabled

In MC-HWPM driver, check if MC channel is enabled before accessing its
registers.

Bug 5279654

Change-Id: I41e3d277a75d0a1045e47f148e2b9eb63f29b279
Signed-off-by: Ashish Mhetre <amhetre@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3369527
Reviewed-by: svcacv <svcacv@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
(cherry picked from commit e2b9c86688)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3370768
This commit is contained in:
Ashish Mhetre
2025-05-22 18:17:22 +00:00
committed by Jon Hunter
parent cb108984e1
commit b79129381b

View File

@@ -16,8 +16,11 @@
#include <uapi/linux/tegra-soc-hwpm-uapi.h> #include <uapi/linux/tegra-soc-hwpm-uapi.h>
#include <soc/tegra/fuse.h>
/* Broadcast Channel + 16 MC Channels */ /* Broadcast Channel + 16 MC Channels */
#define MAX_MC_CHANNELS 17 #define MAX_MC_CHANNELS 17
#define FUSE_EMC_DISABLE_OFFSET 0x8c0
static struct tegra_soc_hwpm_ip_ops hwpm_ip_ops; static struct tegra_soc_hwpm_ip_ops hwpm_ip_ops;
@@ -46,6 +49,23 @@ static void mc_writel(struct tegra_mc_hwpm *mc, u32 ch_no, u32 val, u32 reg)
writel(val, mc->ch_regs[ch_no] + reg); writel(val, mc->ch_regs[ch_no] + reg);
} }
static bool is_channel_enabled(u32 ch)
{
u32 fuse_val = 0U;
int err = 0;
err = tegra_fuse_readl(FUSE_EMC_DISABLE_OFFSET, &fuse_val);
if (err != 0) {
pr_err("Failed to read EMC FUSE\n");
return false;
}
if ((fuse_val & BIT(ch)) == 0)
return true;
return false;
}
static int tegra_mc_hwpm_reg_op(void *ip_dev, static int tegra_mc_hwpm_reg_op(void *ip_dev,
enum tegra_soc_hwpm_ip_reg_op reg_op, enum tegra_soc_hwpm_ip_reg_op reg_op,
u32 inst_element_index, u64 reg_offset, u32 *reg_data) u32 inst_element_index, u64 reg_offset, u32 *reg_data)
@@ -64,6 +84,12 @@ static int tegra_mc_hwpm_reg_op(void *ip_dev,
return -EINVAL; return -EINVAL;
} }
if (inst_element_index > 0) {
if (!is_channel_enabled(inst_element_index - 1)) {
dev_err(mc->dev, "MC Channel %u is not enabled\n", inst_element_index);
return -ENODEV;
}
}
if (reg_op == TEGRA_SOC_HWPM_IP_REG_OP_READ) { if (reg_op == TEGRA_SOC_HWPM_IP_REG_OP_READ) {
*reg_data = mc_readl(mc, inst_element_index, (u32)reg_offset); *reg_data = mc_readl(mc, inst_element_index, (u32)reg_offset);
} else if (reg_op == TEGRA_SOC_HWPM_IP_REG_OP_WRITE) { } else if (reg_op == TEGRA_SOC_HWPM_IP_REG_OP_WRITE) {