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:
Abdul Salam
2020-01-10 17:35:18 +05:30
committed by Alex Waterman
parent 977cc73230
commit 1481fe54e9
7 changed files with 134 additions and 183 deletions

View File

@@ -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;
}

View File

@@ -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, &reg_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, &reg_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,
&reg_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;
}
}
}
}

View File

@@ -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 */

View File

@@ -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 = {

View File

@@ -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 {

View File

@@ -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 */

View File

@@ -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) \