From 7a504c16337df8ad9c39dcbe1b18038e3d39dc6c Mon Sep 17 00:00:00 2001 From: Ashish Mhetre Date: Wed, 25 Jan 2023 12:56:30 +0530 Subject: [PATCH] platform: tegra: Remove EMC register access for HV EMC registers are currently accessed to get DRAM parameters. As these are platform specific and static, DRAM parameters are added in device-tree. In case of hypervisor environment, read DRAM properties from device-tree instead of accessing EMC registers. Also, MC and EMC register access by kernel is going to be blocked from hypervisor. So, remove access to these registers. Bug 3938091 Change-Id: I8a85bef7c34a919a48b3f0999f631f264540585a Signed-off-by: Ashish Mhetre Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2848653 Reviewed-by: svcacv Reviewed-by: Sachin Nikam GVS: Gerrit_Virtual_Submit --- drivers/platform/tegra/mc-utils/mc-utils.c | 81 ++++++++++++++-------- 1 file changed, 53 insertions(+), 28 deletions(-) diff --git a/drivers/platform/tegra/mc-utils/mc-utils.c b/drivers/platform/tegra/mc-utils/mc-utils.c index 5a74eeaa..7e5df39c 100644 --- a/drivers/platform/tegra/mc-utils/mc-utils.c +++ b/drivers/platform/tegra/mc-utils/mc-utils.c @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -21,6 +21,9 @@ #include #include #include +#include + +#include #define BYTES_PER_CLK_PER_CH 4 #define CH_16 16 @@ -80,7 +83,6 @@ struct emc_params { u32 rank; u32 ecc; - u32 ch; u32 dram; }; @@ -292,40 +294,63 @@ static void tegra_mc_utils_debugfs_init(void) } #endif +static u32 get_dram_dt_prop(struct device_node *np, const char *prop) +{ + u32 val; + int ret; + + ret = of_property_read_u32(np, prop, &val); + if (ret) { + pr_err("failed to read %s\n", prop); + return ~0U; + } + + return val; +} + static int __init tegra_mc_utils_init(void) { u32 dram, ch, ecc, rank; void __iomem *emc_base; void __iomem *mcb_base; - emc_base = ioremap(EMC_BASE, 0x00010000); - dram = readl(emc_base + EMC_FBIO_CFG5_0) & DRAM_MASK; - mcb_base = ioremap(MCB_BASE, MCB_SIZE); - if (!mcb_base) { - pr_err("Failed to ioremap\n"); - return -ENOMEM; + if (!is_tegra_hypervisor_mode()) { + emc_base = ioremap(EMC_BASE, 0x00010000); + dram = readl(emc_base + EMC_FBIO_CFG5_0) & DRAM_MASK; + mcb_base = ioremap(MCB_BASE, MCB_SIZE); + if (!mcb_base) { + pr_err("Failed to ioremap\n"); + return -ENOMEM; + } + + ch = readl(mcb_base + MC_EMEM_ADR_CFG_CHANNEL_ENABLE_0); + ch &= CH_MASK; + ecc = readl(mcb_base + MC_ECC_CONTROL_0) & ECC_MASK; + + rank = readl(mcb_base + MC_EMEM_ADR_CFG_0) & RANK_MASK; + + iounmap(emc_base); + iounmap(mcb_base); + + while (ch) { + if (ch & 1) + ch_num++; + ch >>= 1; + } + } else { + struct device_node *np = of_find_compatible_node(NULL, NULL, "nvidia,tegra234-mc"); + + if (!np) { + pr_err("mc-utils: Not able to find MC DT node\n"); + return -ENODEV; + } + + ecc = get_dram_dt_prop(np, "dram_ecc"); + rank = get_dram_dt_prop(np, "dram_rank"); + dram = get_dram_dt_prop(np, "dram_lpddr"); + ch_num = get_dram_dt_prop(np, "dram_channels"); } - ch = readl(mcb_base + MC_EMEM_ADR_CFG_CHANNEL_ENABLE_0); - ch &= CH_MASK; - /* - * TODO: For non orin chips MC_ECC_CONTROL_0 is not present, hence set - * ecc to 0 and cleanup this once we have chip specific mc_utils driver. - */ - ecc = readl(mcb_base + MC_ECC_CONTROL_0) & ECC_MASK; - - rank = readl(mcb_base + MC_EMEM_ADR_CFG_0) & RANK_MASK; - - iounmap(emc_base); - iounmap(mcb_base); - - while (ch) { - if (ch & 1) - ch_num++; - ch >>= 1; - } - - emc_param.ch = ch; emc_param.ecc = ecc; emc_param.rank = rank; emc_param.dram = dram;