diff --git a/drivers/platform/tegra/mc-hwpm.c b/drivers/platform/tegra/mc-hwpm.c index 8a5722ce..7d0d5f85 100644 --- a/drivers/platform/tegra/mc-hwpm.c +++ b/drivers/platform/tegra/mc-hwpm.c @@ -14,8 +14,11 @@ #include +#include + /* Broadcast Channel + 16 MC Channels */ #define MAX_MC_CHANNELS 17 +#define FUSE_EMC_DISABLE_OFFSET 0x8c0 static struct tegra_soc_hwpm_ip_ops hwpm_ip_ops; @@ -44,6 +47,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); } +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, enum tegra_soc_hwpm_ip_reg_op reg_op, u32 inst_element_index, u64 reg_offset, u32 *reg_data) @@ -62,6 +82,12 @@ static int tegra_mc_hwpm_reg_op(void *ip_dev, 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) { *reg_data = mc_readl(mc, inst_element_index, (u32)reg_offset); } else if (reg_op == TEGRA_SOC_HWPM_IP_REG_OP_WRITE) {