mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 10:34:43 +03:00
gpu: nvgpu: Remove dependency in FMON
This patch removes dependency between pmu.clk and hal.clk. Below is the implementation. *Init the clk domains inside pmu.clk unit. *Set this in a member variable and send it to hal.clk unit *Use this to determine the valid clock domains and read the monitor registers for each valid domains. *Return the domain with error code. *With this all the clk domain data is removed from hal.clk and only pmu.clk uses it as it owns it. JIRA NVGPU-4491 Change-Id: Ie57b2472cfaacfd2ce43ac7f95702bd95fb8bbaa Signed-off-by: Abdul Salam <absalam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2272416 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Alex Waterman
parent
977cc73230
commit
1481fe54e9
@@ -93,3 +93,22 @@ void nvgpu_clk_free_pmupstate(struct gk20a *g)
|
||||
nvgpu_kfree(g, g->pmu->clk_pmu);
|
||||
g->pmu->clk_pmu = NULL;
|
||||
}
|
||||
|
||||
u32 nvgpu_clk_mon_init_domains(struct gk20a *g)
|
||||
{
|
||||
u32 domain_mask;
|
||||
|
||||
domain_mask = (CTRL_CLK_DOMAIN_MCLK |
|
||||
CTRL_CLK_DOMAIN_XBARCLK |
|
||||
CTRL_CLK_DOMAIN_SYSCLK |
|
||||
CTRL_CLK_DOMAIN_HUBCLK |
|
||||
CTRL_CLK_DOMAIN_GPCCLK |
|
||||
CTRL_CLK_DOMAIN_HOSTCLK |
|
||||
CTRL_CLK_DOMAIN_UTILSCLK |
|
||||
CTRL_CLK_DOMAIN_PWRCLK |
|
||||
CTRL_CLK_DOMAIN_NVDCLK |
|
||||
CTRL_CLK_DOMAIN_XCLK |
|
||||
CTRL_CLK_DOMAIN_NVL_COMMON |
|
||||
CTRL_CLK_DOMAIN_PEX_REFCLK );
|
||||
return domain_mask;
|
||||
}
|
||||
|
||||
@@ -60,159 +60,92 @@
|
||||
#define BOOT_GPCCLK_MHZ 645U
|
||||
|
||||
/**
|
||||
* FMON register types
|
||||
* Mapping between the clk domain and the various clock monitor registers
|
||||
* The rows represent clock domains starting from index 0 and column represent
|
||||
* the various registers each domain has, non available domains are set to 0
|
||||
* for easy accessing, refer nvgpu_clk_mon_init_domains() for valid domains.
|
||||
*/
|
||||
#define FMON_THRESHOLD_HIGH 0x0U
|
||||
#define FMON_THRESHOLD_LOW 0x1U
|
||||
#define FMON_FAULT_STATUS 0x2U
|
||||
#define FMON_FAULT_STATUS_PRIV_MASK 0x3U
|
||||
|
||||
|
||||
/**
|
||||
* Mapping between the clk api domain and the various clock monitor registers
|
||||
*/
|
||||
static struct clk_mon_address_map clock_mon_map_tu104[] = {
|
||||
static u32 clock_mon_map_tu104[CLK_CLOCK_MON_DOMAIN_COUNT]
|
||||
[CLK_CLOCK_MON_REG_TYPE_COUNT] = {
|
||||
{
|
||||
CTRL_CLK_DOMAIN_GPCCLK,
|
||||
{
|
||||
trim_gpcclk_fault_threshold_high_r(),
|
||||
trim_gpcclk_fault_threshold_low_r(),
|
||||
trim_gpcclk_fault_status_r(),
|
||||
trim_gpcclk_fault_priv_level_mask_r(),
|
||||
}
|
||||
trim_gpcclk_fault_threshold_high_r(),
|
||||
trim_gpcclk_fault_threshold_low_r(),
|
||||
trim_gpcclk_fault_status_r(),
|
||||
trim_gpcclk_fault_priv_level_mask_r(),
|
||||
},
|
||||
{
|
||||
CTRL_CLK_DOMAIN_SYSCLK,
|
||||
{
|
||||
trim_sysclk_fault_threshold_high_r(),
|
||||
trim_sysclk_fault_threshold_low_r(),
|
||||
trim_sysclk_fault_status_r(),
|
||||
trim_sysclk_fault_priv_level_mask_r(),
|
||||
}
|
||||
trim_xbarclk_fault_threshold_high_r(),
|
||||
trim_xbarclk_fault_threshold_low_r(),
|
||||
trim_xbarclk_fault_status_r(),
|
||||
trim_xbarclk_fault_priv_level_mask_r(),
|
||||
},
|
||||
{
|
||||
CTRL_CLK_DOMAIN_HUBCLK,
|
||||
{
|
||||
trim_hubclk_fault_threshold_high_r(),
|
||||
trim_hubclk_fault_threshold_low_r(),
|
||||
trim_hubclk_fault_status_r(),
|
||||
trim_hubclk_fault_priv_level_mask_r(),
|
||||
}
|
||||
trim_sysclk_fault_threshold_high_r(),
|
||||
trim_sysclk_fault_threshold_low_r(),
|
||||
trim_sysclk_fault_status_r(),
|
||||
trim_sysclk_fault_priv_level_mask_r(),
|
||||
},
|
||||
{
|
||||
CTRL_CLK_DOMAIN_HOSTCLK,
|
||||
{
|
||||
trim_hostclk_fault_threshold_high_r(),
|
||||
trim_hostclk_fault_threshold_low_r(),
|
||||
trim_hostclk_fault_status_r(),
|
||||
trim_hostclk_fault_priv_level_mask_r(),
|
||||
}
|
||||
trim_hubclk_fault_threshold_high_r(),
|
||||
trim_hubclk_fault_threshold_low_r(),
|
||||
trim_hubclk_fault_status_r(),
|
||||
trim_hubclk_fault_priv_level_mask_r(),
|
||||
},
|
||||
{
|
||||
CTRL_CLK_DOMAIN_XBARCLK,
|
||||
{
|
||||
trim_xbarclk_fault_threshold_high_r(),
|
||||
trim_xbarclk_fault_threshold_low_r(),
|
||||
trim_xbarclk_fault_status_r(),
|
||||
trim_xbarclk_fault_priv_level_mask_r(),
|
||||
}
|
||||
trim_dramclk_fault_threshold_high_r(),
|
||||
trim_dramclk_fault_threshold_low_r(),
|
||||
trim_dramclk_fault_status_r(),
|
||||
trim_dramclk_fault_priv_level_mask_r(),
|
||||
},
|
||||
{
|
||||
CTRL_CLK_DOMAIN_NVDCLK,
|
||||
{
|
||||
trim_nvdclk_fault_threshold_high_r(),
|
||||
trim_nvdclk_fault_threshold_low_r(),
|
||||
trim_nvdclk_fault_status_r(),
|
||||
trim_nvdclk_fault_priv_level_mask_r(),
|
||||
}
|
||||
trim_hostclk_fault_threshold_high_r(),
|
||||
trim_hostclk_fault_threshold_low_r(),
|
||||
trim_hostclk_fault_status_r(),
|
||||
trim_hostclk_fault_priv_level_mask_r(),
|
||||
},
|
||||
{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0},
|
||||
{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0},
|
||||
{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0},
|
||||
{
|
||||
trim_utilsclk_fault_threshold_high_r(),
|
||||
trim_utilsclk_fault_threshold_low_r(),
|
||||
trim_utilsclk_fault_status_r(),
|
||||
trim_utilsclk_fault_priv_level_mask_r(),
|
||||
},
|
||||
{
|
||||
CTRL_CLK_DOMAIN_MCLK,
|
||||
{
|
||||
trim_dramclk_fault_threshold_high_r(),
|
||||
trim_dramclk_fault_threshold_low_r(),
|
||||
trim_dramclk_fault_status_r(),
|
||||
trim_dramclk_fault_priv_level_mask_r(),
|
||||
}
|
||||
trim_pwrclk_fault_threshold_high_r(),
|
||||
trim_pwrclk_fault_threshold_low_r(),
|
||||
trim_pwrclk_fault_status_r(),
|
||||
trim_pwrclk_fault_priv_level_mask_r(),
|
||||
},
|
||||
{
|
||||
CTRL_CLK_DOMAIN_PWRCLK,
|
||||
{
|
||||
trim_pwrclk_fault_threshold_high_r(),
|
||||
trim_pwrclk_fault_threshold_low_r(),
|
||||
trim_pwrclk_fault_status_r(),
|
||||
trim_pwrclk_fault_priv_level_mask_r(),
|
||||
}
|
||||
trim_nvdclk_fault_threshold_high_r(),
|
||||
trim_nvdclk_fault_threshold_low_r(),
|
||||
trim_nvdclk_fault_status_r(),
|
||||
trim_nvdclk_fault_priv_level_mask_r(),
|
||||
},
|
||||
{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0},
|
||||
{
|
||||
trim_xclk_fault_threshold_high_r(),
|
||||
trim_xclk_fault_threshold_low_r(),
|
||||
trim_xclk_fault_status_r(),
|
||||
trim_xclk_fault_priv_level_mask_r(),
|
||||
},
|
||||
{
|
||||
CTRL_CLK_DOMAIN_UTILSCLK,
|
||||
{
|
||||
trim_utilsclk_fault_threshold_high_r(),
|
||||
trim_utilsclk_fault_threshold_low_r(),
|
||||
trim_utilsclk_fault_status_r(),
|
||||
trim_utilsclk_fault_priv_level_mask_r(),
|
||||
}
|
||||
trim_nvl_commonclk_fault_threshold_high_r(),
|
||||
trim_nvl_commonclk_fault_threshold_low_r(),
|
||||
trim_nvl_commonclk_fault_status_r(),
|
||||
trim_nvl_commonclk_fault_priv_level_mask_r(),
|
||||
},
|
||||
{
|
||||
CTRL_CLK_DOMAIN_PEX_REFCLK,
|
||||
{
|
||||
trim_pex_refclk_fault_threshold_high_r(),
|
||||
trim_pex_refclk_fault_threshold_low_r(),
|
||||
trim_pex_refclk_fault_status_r(),
|
||||
trim_pex_refclk_fault_priv_level_mask_r(),
|
||||
}
|
||||
},
|
||||
{
|
||||
CTRL_CLK_DOMAIN_NVL_COMMON,
|
||||
{
|
||||
trim_nvl_commonclk_fault_threshold_high_r(),
|
||||
trim_nvl_commonclk_fault_threshold_low_r(),
|
||||
trim_nvl_commonclk_fault_status_r(),
|
||||
trim_nvl_commonclk_fault_priv_level_mask_r(),
|
||||
}
|
||||
},
|
||||
{
|
||||
CTRL_CLK_DOMAIN_XCLK,
|
||||
{
|
||||
trim_xclk_fault_threshold_high_r(),
|
||||
trim_xclk_fault_threshold_low_r(),
|
||||
trim_xclk_fault_status_r(),
|
||||
trim_xclk_fault_priv_level_mask_r(),
|
||||
}
|
||||
trim_pex_refclk_fault_threshold_high_r(),
|
||||
trim_pex_refclk_fault_threshold_low_r(),
|
||||
trim_pex_refclk_fault_status_r(),
|
||||
trim_pex_refclk_fault_priv_level_mask_r(),
|
||||
},
|
||||
{0,0,0,0}, {0,0,0,0}, {0,0,0,0}
|
||||
};
|
||||
|
||||
static int nvgpu_clk_mon_idx_get(struct gk20a *g, u32 clk_api_domain, u8 *idx)
|
||||
{
|
||||
u8 index;
|
||||
|
||||
for (index = 0; index < CTRL_CLK_CLK_DOMAIN_ARCH_MAX_DOMAINS; index++) {
|
||||
if (clock_mon_map_tu104[index].clk_api_domain ==
|
||||
clk_api_domain) {
|
||||
*idx = index;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int nvgpu_clk_mon_reg_get(struct gk20a *g, u32 clk_api_domain,
|
||||
u32 *reg_address, u32 reg_type)
|
||||
{
|
||||
u8 index = 0;
|
||||
int status;
|
||||
|
||||
status = nvgpu_clk_mon_idx_get(g, clk_api_domain, &index);
|
||||
if (status != 0) {
|
||||
nvgpu_err(g, "Failed to get clk_domain index");
|
||||
return -EINVAL;
|
||||
}
|
||||
*reg_address = clock_mon_map_tu104[index].reg_add[reg_type];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 nvgpu_check_for_dc_fault(u32 data)
|
||||
{
|
||||
return (trim_fault_status_dc_v(data) ==
|
||||
@@ -257,28 +190,15 @@ static int nvgpu_clk_mon_get_fault(struct gk20a *g, u32 i, u32 data,
|
||||
clk_mon_status->clk_mon_list[i].clk_api_domain,
|
||||
clk_mon_status->clk_mon_list[i].
|
||||
clk_domain_fault_status);
|
||||
/* Get the low threshold limit */
|
||||
status = nvgpu_clk_mon_reg_get(g, clock_mon_map_tu104[i].
|
||||
clk_api_domain, ®_address,
|
||||
FMON_THRESHOLD_LOW);
|
||||
if (status != 0) {
|
||||
nvgpu_err(g, "Failed to get register address");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get the low threshold limit */
|
||||
reg_address = clock_mon_map_tu104[i][FMON_THRESHOLD_LOW];
|
||||
data = nvgpu_readl(g, reg_address);
|
||||
clk_mon_status->clk_mon_list[i].low_threshold =
|
||||
trim_fault_threshold_low_count_v(data);
|
||||
|
||||
/* Get the high threshold limit */
|
||||
status = nvgpu_clk_mon_reg_get(g, clock_mon_map_tu104[i].
|
||||
clk_api_domain, ®_address,
|
||||
FMON_THRESHOLD_HIGH);
|
||||
if (status != 0) {
|
||||
nvgpu_err(g, "Failed to get register address");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
reg_address = clock_mon_map_tu104[i][FMON_THRESHOLD_HIGH];
|
||||
data = nvgpu_readl(g, reg_address);
|
||||
clk_mon_status->clk_mon_list[i].high_threshold =
|
||||
trim_fault_threshold_high_count_v(data);
|
||||
@@ -298,36 +218,39 @@ bool nvgpu_clk_mon_check_master_fault_status(struct gk20a *g)
|
||||
}
|
||||
|
||||
int nvgpu_clk_mon_check_status(struct gk20a *g,
|
||||
struct clk_domains_mon_status_params *clk_mon_status)
|
||||
struct clk_domains_mon_status_params *clk_mon_status,
|
||||
u32 domain_mask)
|
||||
{
|
||||
u32 reg_address;
|
||||
u32 data, i;
|
||||
u32 reg_address, bit_pos;
|
||||
u32 data;
|
||||
int status;
|
||||
|
||||
clk_mon_status->clk_mon_list_size =
|
||||
CTRL_CLK_CLK_DOMAIN_ARCH_MAX_DOMAINS;
|
||||
clk_mon_status->clk_mon_domain_mask = domain_mask;
|
||||
/*
|
||||
* Parse through each domain and check for faults, each bit set
|
||||
* represents a domain here
|
||||
*/
|
||||
for (bit_pos = 0U; bit_pos < (sizeof(domain_mask) * BITS_PER_BYTE);
|
||||
bit_pos++) {
|
||||
if (nvgpu_test_bit(bit_pos, (void *)&domain_mask)) {
|
||||
clk_mon_status->clk_mon_list[bit_pos].clk_api_domain =
|
||||
BIT(bit_pos);
|
||||
|
||||
for (i = 0; i < clk_mon_status->clk_mon_list_size; i++) {
|
||||
clk_mon_status->clk_mon_list[i].clk_api_domain =
|
||||
clock_mon_map_tu104[i].clk_api_domain;
|
||||
status = nvgpu_clk_mon_reg_get(g,
|
||||
clk_mon_status->clk_mon_list[i].clk_api_domain,
|
||||
®_address, FMON_FAULT_STATUS);
|
||||
if (status != 0) {
|
||||
nvgpu_err(g, "Failed to get register address");
|
||||
return -EINVAL;
|
||||
}
|
||||
data = nvgpu_readl(g, reg_address);
|
||||
reg_address = clock_mon_map_tu104[bit_pos]
|
||||
[FMON_FAULT_STATUS];
|
||||
data = nvgpu_readl(g, reg_address);
|
||||
|
||||
clk_mon_status->clk_mon_list[i].clk_domain_fault_status = 0U;
|
||||
/* Check FMON fault status, fault_out field is same for all */
|
||||
if (trim_fault_status_fault_out_v(data) ==
|
||||
clk_mon_status->clk_mon_list[bit_pos].
|
||||
clk_domain_fault_status = 0U;
|
||||
/* Check FMON fault status, field is same for all */
|
||||
if (trim_fault_status_fault_out_v(data) ==
|
||||
trim_fault_status_fault_out_true_v()) {
|
||||
status = nvgpu_clk_mon_get_fault(g, i, data,
|
||||
clk_mon_status);
|
||||
if (status != 0) {
|
||||
nvgpu_err(g, "Failed to get fault status");
|
||||
return -EINVAL;
|
||||
status = nvgpu_clk_mon_get_fault(g, bit_pos,
|
||||
data, clk_mon_status);
|
||||
if (status != 0) {
|
||||
nvgpu_err(g, "Failed to get status");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,16 @@
|
||||
#include <nvgpu/lock.h>
|
||||
#include <nvgpu/gk20a.h>
|
||||
|
||||
/**
|
||||
* FMON register types
|
||||
*/
|
||||
#define FMON_THRESHOLD_HIGH 0x0U
|
||||
#define FMON_THRESHOLD_LOW 0x1U
|
||||
#define FMON_FAULT_STATUS 0x2U
|
||||
#define FMON_FAULT_STATUS_PRIV_MASK 0x3U
|
||||
#define CLK_CLOCK_MON_REG_TYPE_COUNT 0x4U
|
||||
#define CLK_MON_BITS_PER_BYTE 0x8U
|
||||
|
||||
u32 tu104_get_rate_cntr(struct gk20a *g, struct namemap_cfg *c);
|
||||
int tu104_init_clk_support(struct gk20a *g);
|
||||
u32 tu104_crystal_clk_hz(struct gk20a *g);
|
||||
@@ -40,6 +50,6 @@ void tu104_get_change_seq_time(struct gk20a *g, s64 *change_time);
|
||||
void tu104_change_host_clk_source(struct gk20a *g);
|
||||
bool nvgpu_clk_mon_check_master_fault_status(struct gk20a *g);
|
||||
int nvgpu_clk_mon_check_status(struct gk20a *g, struct
|
||||
clk_domains_mon_status_params *clk_mon_status);
|
||||
|
||||
clk_domains_mon_status_params *clk_mon_status,
|
||||
u32 domain_mask);
|
||||
#endif /* CLK_TU104_H */
|
||||
|
||||
@@ -217,6 +217,7 @@
|
||||
#include <nvgpu/gr/gr_intr.h>
|
||||
#include <nvgpu/pmu/pmu_perfmon.h>
|
||||
#include <nvgpu/nvgpu_init.h>
|
||||
#include <nvgpu/pmu/clk/clk.h>
|
||||
|
||||
#include <nvgpu/hw/tu104/hw_pwr_tu104.h>
|
||||
|
||||
@@ -1260,6 +1261,7 @@ static const struct gpu_ops tu104_ops = {
|
||||
.clk_mon_check_master_fault_status =
|
||||
nvgpu_clk_mon_check_master_fault_status,
|
||||
.clk_mon_check_status = nvgpu_clk_mon_check_status,
|
||||
.clk_mon_init_domains = nvgpu_clk_mon_init_domains,
|
||||
},
|
||||
#ifdef CONFIG_NVGPU_CLK_ARB
|
||||
.clk_arb = {
|
||||
|
||||
@@ -367,7 +367,9 @@ struct gpu_ops {
|
||||
u8 lut_num_entries;
|
||||
bool (*clk_mon_check_master_fault_status)(struct gk20a *g);
|
||||
int (*clk_mon_check_status)(struct gk20a *g,
|
||||
struct clk_domains_mon_status_params *clk_mon_status);
|
||||
struct clk_domains_mon_status_params *clk_mon_status,
|
||||
u32 domain_mask);
|
||||
u32 (*clk_mon_init_domains)(struct gk20a *g);
|
||||
} clk;
|
||||
#ifdef CONFIG_NVGPU_CLK_ARB
|
||||
struct {
|
||||
|
||||
@@ -104,5 +104,6 @@ int nvgpu_clk_get_fll_clks(struct gk20a *g,
|
||||
int nvgpu_clk_domain_freq_to_volt(struct gk20a *g, u8 clkdomain_idx,
|
||||
u32 *pclkmhz, u32 *pvoltuv, u8 railidx);
|
||||
int nvgpu_clk_domain_get_from_index(struct gk20a *g, u32 *domain, u32 index);
|
||||
u32 nvgpu_clk_mon_init_domains(struct gk20a *g);
|
||||
|
||||
#endif /* NVGPU_PMU_CLK_H */
|
||||
|
||||
@@ -97,9 +97,8 @@
|
||||
#define CTRL_CLK_CLK_VF_POINT_TYPE_35_VOLT_SEC 0x06U
|
||||
#define CTRL_CLK_CLK_VF_POINT_TYPE_UNKNOWN 255U
|
||||
|
||||
#define CTRL_CLK_CLK_DOMAIN_CLIENT_MAX_DOMAINS 16
|
||||
#define CTRL_CLK_CLK_DOMAIN_ARCH_MAX_DOMAINS 12U
|
||||
#define CLK_CLOCK_MON_REG_TYPE_COUNT 4U
|
||||
#define CTRL_CLK_CLK_DOMAIN_CLIENT_MAX_DOMAINS 16
|
||||
#define CLK_CLOCK_MON_DOMAIN_COUNT 0x32U
|
||||
|
||||
struct ctrl_clk_domain_control_35_prog_clk_mon {
|
||||
u32 flags;
|
||||
@@ -290,15 +289,10 @@ struct clk_domain_mon_status {
|
||||
u32 clk_domain_fault_status;
|
||||
};
|
||||
|
||||
struct clk_mon_address_map {
|
||||
u32 clk_api_domain;
|
||||
u32 reg_add[CLK_CLOCK_MON_REG_TYPE_COUNT];
|
||||
};
|
||||
|
||||
struct clk_domains_mon_status_params {
|
||||
u32 clk_mon_list_size;
|
||||
u32 clk_mon_domain_mask;
|
||||
struct clk_domain_mon_status
|
||||
clk_mon_list[CTRL_CLK_CLK_DOMAIN_ARCH_MAX_DOMAINS];
|
||||
clk_mon_list[CLK_CLOCK_MON_DOMAIN_COUNT];
|
||||
};
|
||||
|
||||
#define CTRL_CLK_VF_PAIR_FREQ_MHZ_GET(pvfpair) \
|
||||
|
||||
Reference in New Issue
Block a user