mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 10:34:43 +03:00
gpu: nvgpu: nvlink: Add HAL for pll setup
Before nvlink 2.2, driver was responsible for setting the NVLink clocks during NVLink initialization. For the purpose of security, NVLink PLL handling is moved to Minion in nvlink 2.2 and driver should stop writing to these registers. JIRA NVLINK-167 Change-Id: I18392a29c322da55053037bfde62c8f74ee75288 Signed-off-by: Tejal Kudav <tkudav@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1730597 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
@@ -1183,6 +1183,7 @@ struct gpu_ops {
|
||||
int (*discover_link)(struct gk20a *g);
|
||||
int (*isr)(struct gk20a *g);
|
||||
int (*rxdet)(struct gk20a *g, u32 link_id);
|
||||
int (*setup_pll)(struct gk20a *g, unsigned long link_mask);
|
||||
/* API */
|
||||
int (*link_early_init)(struct gk20a *g, unsigned long mask);
|
||||
u32 (*link_get_mode)(struct gk20a *g, u32 link_id);
|
||||
|
||||
@@ -833,6 +833,7 @@ static const struct gpu_ops gv100_ops = {
|
||||
.init = gv100_nvlink_init,
|
||||
.isr = gv100_nvlink_isr,
|
||||
.rxdet = NULL,
|
||||
.setup_pll = gv100_nvlink_setup_pll,
|
||||
/* API */
|
||||
.link_early_init = gv100_nvlink_link_early_init,
|
||||
.link_get_state = gv100_nvlink_link_get_state,
|
||||
|
||||
@@ -219,7 +219,6 @@ static const char *__gv100_device_type_to_str(u32 type)
|
||||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
static int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long mask);
|
||||
static u32 __gv100_nvlink_get_link_reset_mask(struct gk20a *g);
|
||||
static u32 gv100_nvlink_rxcal_en(struct gk20a *g, unsigned long mask);
|
||||
static u32 gv100_nvlink_minion_data_ready_en(struct gk20a *g,
|
||||
@@ -826,7 +825,7 @@ static u32 gv100_nvlink_minion_init_uphy(struct gk20a *g, unsigned long mask,
|
||||
}
|
||||
}
|
||||
|
||||
err = gv100_nvlink_setup_pll(g, mask);
|
||||
err = g->ops.nvlink.setup_pll(g, mask);
|
||||
if (err) {
|
||||
nvgpu_err(g, "Error setting up PLL");
|
||||
return err;
|
||||
@@ -1462,7 +1461,7 @@ static u32 __gv100_nvlink_state_load_hal(struct gk20a *g)
|
||||
#define TRIM_SYS_NVLINK_CTRL(i) (trim_sys_nvlink0_ctrl_r() + 16*i)
|
||||
#define TRIM_SYS_NVLINK_STATUS(i) (trim_sys_nvlink0_status_r() + 16*i)
|
||||
|
||||
static int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long mask)
|
||||
int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long link_mask)
|
||||
{
|
||||
u32 reg;
|
||||
u32 i;
|
||||
@@ -1481,7 +1480,7 @@ static int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long mask)
|
||||
pad_ctrl = top_nvhsclk_ctrl_e_clk_nvl_v(reg);
|
||||
swap_ctrl = top_nvhsclk_ctrl_swap_clk_nvl_v(reg);
|
||||
|
||||
for_each_set_bit(i, &mask, 32) {
|
||||
for_each_set_bit(i, &link_mask, 32) {
|
||||
/* There are 3 PLLs for 6 links. We have 3 bits for each PLL.
|
||||
* The PLL bit corresponding to a link is /2 of its master link.
|
||||
*/
|
||||
@@ -1501,7 +1500,7 @@ static int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long mask)
|
||||
|
||||
gk20a_writel(g, top_nvhsclk_ctrl_r(), reg);
|
||||
|
||||
for_each_set_bit(i, &mask, 32) {
|
||||
for_each_set_bit(i, &link_mask, 32) {
|
||||
reg = gk20a_readl(g, TRIM_SYS_NVLINK_CTRL(i));
|
||||
reg = set_field(reg,
|
||||
trim_sys_nvlink0_ctrl_unit2clks_pll_turn_off_m(),
|
||||
@@ -1510,12 +1509,12 @@ static int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long mask)
|
||||
}
|
||||
|
||||
/* Poll for links to go up */
|
||||
links_off = mask;
|
||||
links_off = link_mask;
|
||||
|
||||
nvgpu_timeout_init(g, &timeout,
|
||||
NVLINK_PLL_ON_TIMEOUT_MS, NVGPU_TIMER_CPU_TIMER);
|
||||
do {
|
||||
for_each_set_bit(i, &mask, 32) {
|
||||
for_each_set_bit(i, &link_mask, 32) {
|
||||
reg = gk20a_readl(g, TRIM_SYS_NVLINK_STATUS(i));
|
||||
if (trim_sys_nvlink0_status_pll_off_v(reg) == 0)
|
||||
links_off &= ~BIT(i);
|
||||
|
||||
@@ -31,6 +31,7 @@ int gv100_nvlink_init(struct gk20a *g);
|
||||
int gv100_nvlink_isr(struct gk20a *g);
|
||||
int gv100_nvlink_minion_send_command(struct gk20a *g, u32 link_id, u32 command,
|
||||
u32 scratch_0, bool sync);
|
||||
int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long link_mask);
|
||||
/* API */
|
||||
int gv100_nvlink_link_early_init(struct gk20a *g, unsigned long mask);
|
||||
u32 gv100_nvlink_link_get_mode(struct gk20a *g, u32 link_id);
|
||||
|
||||
Reference in New Issue
Block a user