diff options
author | Tejal Kudav <tkudav@nvidia.com> | 2018-05-25 07:41:14 -0400 |
---|---|---|
committer | Tejal Kudav <tkudav@nvidia.com> | 2018-06-14 09:44:06 -0400 |
commit | 1e889871bc0ec3af05280f27497c0e7bd7a023b5 (patch) | |
tree | a992e96bcfe9d88bef49076a644fbb13703e519b | |
parent | 0b2f2f06a7d0424359d1b6e275789ceef1a8a8c3 (diff) |
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>
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gv100/hal_gv100.c | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gv100/nvlink_gv100.c | 13 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gv100/nvlink_gv100.h | 1 |
4 files changed, 9 insertions, 7 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 9b72f1a7..e29d7b07 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -1183,6 +1183,7 @@ struct gpu_ops { | |||
1183 | int (*discover_link)(struct gk20a *g); | 1183 | int (*discover_link)(struct gk20a *g); |
1184 | int (*isr)(struct gk20a *g); | 1184 | int (*isr)(struct gk20a *g); |
1185 | int (*rxdet)(struct gk20a *g, u32 link_id); | 1185 | int (*rxdet)(struct gk20a *g, u32 link_id); |
1186 | int (*setup_pll)(struct gk20a *g, unsigned long link_mask); | ||
1186 | /* API */ | 1187 | /* API */ |
1187 | int (*link_early_init)(struct gk20a *g, unsigned long mask); | 1188 | int (*link_early_init)(struct gk20a *g, unsigned long mask); |
1188 | u32 (*link_get_mode)(struct gk20a *g, u32 link_id); | 1189 | u32 (*link_get_mode)(struct gk20a *g, u32 link_id); |
diff --git a/drivers/gpu/nvgpu/gv100/hal_gv100.c b/drivers/gpu/nvgpu/gv100/hal_gv100.c index 3d47cc40..e1c44dd5 100644 --- a/drivers/gpu/nvgpu/gv100/hal_gv100.c +++ b/drivers/gpu/nvgpu/gv100/hal_gv100.c | |||
@@ -833,6 +833,7 @@ static const struct gpu_ops gv100_ops = { | |||
833 | .init = gv100_nvlink_init, | 833 | .init = gv100_nvlink_init, |
834 | .isr = gv100_nvlink_isr, | 834 | .isr = gv100_nvlink_isr, |
835 | .rxdet = NULL, | 835 | .rxdet = NULL, |
836 | .setup_pll = gv100_nvlink_setup_pll, | ||
836 | /* API */ | 837 | /* API */ |
837 | .link_early_init = gv100_nvlink_link_early_init, | 838 | .link_early_init = gv100_nvlink_link_early_init, |
838 | .link_get_state = gv100_nvlink_link_get_state, | 839 | .link_get_state = gv100_nvlink_link_get_state, |
diff --git a/drivers/gpu/nvgpu/gv100/nvlink_gv100.c b/drivers/gpu/nvgpu/gv100/nvlink_gv100.c index 098aae0e..7e25c946 100644 --- a/drivers/gpu/nvgpu/gv100/nvlink_gv100.c +++ b/drivers/gpu/nvgpu/gv100/nvlink_gv100.c | |||
@@ -219,7 +219,6 @@ static const char *__gv100_device_type_to_str(u32 type) | |||
219 | /* | 219 | /* |
220 | * Function prototypes | 220 | * Function prototypes |
221 | */ | 221 | */ |
222 | static int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long mask); | ||
223 | static u32 __gv100_nvlink_get_link_reset_mask(struct gk20a *g); | 222 | static u32 __gv100_nvlink_get_link_reset_mask(struct gk20a *g); |
224 | static u32 gv100_nvlink_rxcal_en(struct gk20a *g, unsigned long mask); | 223 | static u32 gv100_nvlink_rxcal_en(struct gk20a *g, unsigned long mask); |
225 | static u32 gv100_nvlink_minion_data_ready_en(struct gk20a *g, | 224 | 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, | |||
826 | } | 825 | } |
827 | } | 826 | } |
828 | 827 | ||
829 | err = gv100_nvlink_setup_pll(g, mask); | 828 | err = g->ops.nvlink.setup_pll(g, mask); |
830 | if (err) { | 829 | if (err) { |
831 | nvgpu_err(g, "Error setting up PLL"); | 830 | nvgpu_err(g, "Error setting up PLL"); |
832 | return err; | 831 | return err; |
@@ -1462,7 +1461,7 @@ static u32 __gv100_nvlink_state_load_hal(struct gk20a *g) | |||
1462 | #define TRIM_SYS_NVLINK_CTRL(i) (trim_sys_nvlink0_ctrl_r() + 16*i) | 1461 | #define TRIM_SYS_NVLINK_CTRL(i) (trim_sys_nvlink0_ctrl_r() + 16*i) |
1463 | #define TRIM_SYS_NVLINK_STATUS(i) (trim_sys_nvlink0_status_r() + 16*i) | 1462 | #define TRIM_SYS_NVLINK_STATUS(i) (trim_sys_nvlink0_status_r() + 16*i) |
1464 | 1463 | ||
1465 | static int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long mask) | 1464 | int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long link_mask) |
1466 | { | 1465 | { |
1467 | u32 reg; | 1466 | u32 reg; |
1468 | u32 i; | 1467 | u32 i; |
@@ -1481,7 +1480,7 @@ static int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long mask) | |||
1481 | pad_ctrl = top_nvhsclk_ctrl_e_clk_nvl_v(reg); | 1480 | pad_ctrl = top_nvhsclk_ctrl_e_clk_nvl_v(reg); |
1482 | swap_ctrl = top_nvhsclk_ctrl_swap_clk_nvl_v(reg); | 1481 | swap_ctrl = top_nvhsclk_ctrl_swap_clk_nvl_v(reg); |
1483 | 1482 | ||
1484 | for_each_set_bit(i, &mask, 32) { | 1483 | for_each_set_bit(i, &link_mask, 32) { |
1485 | /* There are 3 PLLs for 6 links. We have 3 bits for each PLL. | 1484 | /* There are 3 PLLs for 6 links. We have 3 bits for each PLL. |
1486 | * The PLL bit corresponding to a link is /2 of its master link. | 1485 | * The PLL bit corresponding to a link is /2 of its master link. |
1487 | */ | 1486 | */ |
@@ -1501,7 +1500,7 @@ static int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long mask) | |||
1501 | 1500 | ||
1502 | gk20a_writel(g, top_nvhsclk_ctrl_r(), reg); | 1501 | gk20a_writel(g, top_nvhsclk_ctrl_r(), reg); |
1503 | 1502 | ||
1504 | for_each_set_bit(i, &mask, 32) { | 1503 | for_each_set_bit(i, &link_mask, 32) { |
1505 | reg = gk20a_readl(g, TRIM_SYS_NVLINK_CTRL(i)); | 1504 | reg = gk20a_readl(g, TRIM_SYS_NVLINK_CTRL(i)); |
1506 | reg = set_field(reg, | 1505 | reg = set_field(reg, |
1507 | trim_sys_nvlink0_ctrl_unit2clks_pll_turn_off_m(), | 1506 | 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) | |||
1510 | } | 1509 | } |
1511 | 1510 | ||
1512 | /* Poll for links to go up */ | 1511 | /* Poll for links to go up */ |
1513 | links_off = mask; | 1512 | links_off = link_mask; |
1514 | 1513 | ||
1515 | nvgpu_timeout_init(g, &timeout, | 1514 | nvgpu_timeout_init(g, &timeout, |
1516 | NVLINK_PLL_ON_TIMEOUT_MS, NVGPU_TIMER_CPU_TIMER); | 1515 | NVLINK_PLL_ON_TIMEOUT_MS, NVGPU_TIMER_CPU_TIMER); |
1517 | do { | 1516 | do { |
1518 | for_each_set_bit(i, &mask, 32) { | 1517 | for_each_set_bit(i, &link_mask, 32) { |
1519 | reg = gk20a_readl(g, TRIM_SYS_NVLINK_STATUS(i)); | 1518 | reg = gk20a_readl(g, TRIM_SYS_NVLINK_STATUS(i)); |
1520 | if (trim_sys_nvlink0_status_pll_off_v(reg) == 0) | 1519 | if (trim_sys_nvlink0_status_pll_off_v(reg) == 0) |
1521 | links_off &= ~BIT(i); | 1520 | links_off &= ~BIT(i); |
diff --git a/drivers/gpu/nvgpu/gv100/nvlink_gv100.h b/drivers/gpu/nvgpu/gv100/nvlink_gv100.h index a583c576..0c58438c 100644 --- a/drivers/gpu/nvgpu/gv100/nvlink_gv100.h +++ b/drivers/gpu/nvgpu/gv100/nvlink_gv100.h | |||
@@ -31,6 +31,7 @@ int gv100_nvlink_init(struct gk20a *g); | |||
31 | int gv100_nvlink_isr(struct gk20a *g); | 31 | int gv100_nvlink_isr(struct gk20a *g); |
32 | int gv100_nvlink_minion_send_command(struct gk20a *g, u32 link_id, u32 command, | 32 | int gv100_nvlink_minion_send_command(struct gk20a *g, u32 link_id, u32 command, |
33 | u32 scratch_0, bool sync); | 33 | u32 scratch_0, bool sync); |
34 | int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long link_mask); | ||
34 | /* API */ | 35 | /* API */ |
35 | int gv100_nvlink_link_early_init(struct gk20a *g, unsigned long mask); | 36 | int gv100_nvlink_link_early_init(struct gk20a *g, unsigned long mask); |
36 | u32 gv100_nvlink_link_get_mode(struct gk20a *g, u32 link_id); | 37 | u32 gv100_nvlink_link_get_mode(struct gk20a *g, u32 link_id); |