diff options
author | Tejal Kudav <tkudav@nvidia.com> | 2018-05-24 08:50:28 -0400 |
---|---|---|
committer | Tejal Kudav <tkudav@nvidia.com> | 2018-06-14 09:44:06 -0400 |
commit | 0b2f2f06a7d0424359d1b6e275789ceef1a8a8c3 (patch) | |
tree | 989279d942ba31d0d3bef7f2fbbb74f75dff2c41 | |
parent | 328a7bd3ffc9590c0c432724d45da9f25732c2a1 (diff) |
gpu: nvgpu: nvlink: Add HAL for RXDET
RXDET is supported only on nvlink 2.2 devices and forward.
Add HAL to run RXDET selectively based on chip. RXDET needs to be
done after the links are out of reset but before any other link
level initialization.
minion_send_cmd is also made non-static to support RXDET
functionality.
JIRA NVLINK-160
Change-Id: Ic65b8dbc7281743f62072089ff3c805521ac9b38
Signed-off-by: Tejal Kudav <tkudav@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1729525
GVS: Gerrit_Virtual_Submit
Reviewed-by: Vijayakumar Subbu <vsubbu@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 | 15 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gv100/nvlink_gv100.h | 15 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/nvlink.h | 16 |
5 files changed, 32 insertions, 16 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 48f0008a..9b72f1a7 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -1182,6 +1182,7 @@ struct gpu_ops { | |||
1182 | int (*discover_ioctrl)(struct gk20a *g); | 1182 | int (*discover_ioctrl)(struct gk20a *g); |
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 | /* API */ | 1186 | /* API */ |
1186 | int (*link_early_init)(struct gk20a *g, unsigned long mask); | 1187 | int (*link_early_init)(struct gk20a *g, unsigned long mask); |
1187 | u32 (*link_get_mode)(struct gk20a *g, u32 link_id); | 1188 | 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 9b38f881..3d47cc40 100644 --- a/drivers/gpu/nvgpu/gv100/hal_gv100.c +++ b/drivers/gpu/nvgpu/gv100/hal_gv100.c | |||
@@ -832,6 +832,7 @@ static const struct gpu_ops gv100_ops = { | |||
832 | .discover_link = gv100_nvlink_discover_link, | 832 | .discover_link = gv100_nvlink_discover_link, |
833 | .init = gv100_nvlink_init, | 833 | .init = gv100_nvlink_init, |
834 | .isr = gv100_nvlink_isr, | 834 | .isr = gv100_nvlink_isr, |
835 | .rxdet = NULL, | ||
835 | /* API */ | 836 | /* API */ |
836 | .link_early_init = gv100_nvlink_link_early_init, | 837 | .link_early_init = gv100_nvlink_link_early_init, |
837 | .link_get_state = gv100_nvlink_link_get_state, | 838 | .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 7258b9e9..098aae0e 100644 --- a/drivers/gpu/nvgpu/gv100/nvlink_gv100.c +++ b/drivers/gpu/nvgpu/gv100/nvlink_gv100.c | |||
@@ -735,10 +735,10 @@ static u32 gv100_nvlink_minion_command_complete(struct gk20a *g, u32 link_id) | |||
735 | /* | 735 | /* |
736 | * Send Minion command (can be async) | 736 | * Send Minion command (can be async) |
737 | */ | 737 | */ |
738 | static u32 gv100_nvlink_minion_send_command(struct gk20a *g, | 738 | int gv100_nvlink_minion_send_command(struct gk20a *g, u32 link_id, |
739 | u32 link_id, u32 command, u32 scratch_0, bool sync) | 739 | u32 command, u32 scratch_0, bool sync) |
740 | { | 740 | { |
741 | u32 err = 0; | 741 | int err = 0; |
742 | 742 | ||
743 | /* Check last command succeded */ | 743 | /* Check last command succeded */ |
744 | err = gv100_nvlink_minion_command_complete(g, link_id); | 744 | err = gv100_nvlink_minion_command_complete(g, link_id); |
@@ -1579,6 +1579,15 @@ static int gv100_nvlink_enable_links_pre_top(struct gk20a *g, u32 links) | |||
1579 | IOCTRL_REG_WR32(g, ioctrl_debug_reset_r(), reg); | 1579 | IOCTRL_REG_WR32(g, ioctrl_debug_reset_r(), reg); |
1580 | nvgpu_udelay(delay); | 1580 | nvgpu_udelay(delay); |
1581 | 1581 | ||
1582 | /* Before doing any link initialization, run RXDET to check | ||
1583 | * if link is connected on other end. | ||
1584 | */ | ||
1585 | if (g->ops.nvlink.rxdet) { | ||
1586 | err = g->ops.nvlink.rxdet(g, link_id); | ||
1587 | if (err) | ||
1588 | return err; | ||
1589 | } | ||
1590 | |||
1582 | /* Enable Link DLPL for AN0 */ | 1591 | /* Enable Link DLPL for AN0 */ |
1583 | reg = DLPL_REG_RD32(g, link_id, nvl_link_config_r()); | 1592 | reg = DLPL_REG_RD32(g, link_id, nvl_link_config_r()); |
1584 | reg = set_field(reg, nvl_link_config_link_en_m(), | 1593 | reg = set_field(reg, nvl_link_config_link_en_m(), |
diff --git a/drivers/gpu/nvgpu/gv100/nvlink_gv100.h b/drivers/gpu/nvgpu/gv100/nvlink_gv100.h index 4ac8b907..a583c576 100644 --- a/drivers/gpu/nvgpu/gv100/nvlink_gv100.h +++ b/drivers/gpu/nvgpu/gv100/nvlink_gv100.h | |||
@@ -25,23 +25,12 @@ | |||
25 | 25 | ||
26 | struct gk20a; | 26 | struct gk20a; |
27 | 27 | ||
28 | #define MINION_REG_RD32(g, off) gk20a_readl(g, g->nvlink.minion_base + (off)) | ||
29 | #define MINION_REG_WR32(g, off, v) gk20a_writel(g, g->nvlink.minion_base + (off), (v)) | ||
30 | #define IOCTRL_REG_RD32(g, off) gk20a_readl(g, g->nvlink.ioctrl_base + (off)) | ||
31 | #define IOCTRL_REG_WR32(g, off, v) gk20a_writel(g, g->nvlink.ioctrl_base + (off), (v)); | ||
32 | #define MIF_REG_RD32(g, id, off) gk20a_readl(g, g->nvlink.links[(id)].mif_base + (off)) | ||
33 | #define MIF_REG_WR32(g, id, off, v) gk20a_writel(g, g->nvlink.links[(id)].mif_base + (off), (v)) | ||
34 | #define IPT_REG_RD32(g, off) gk20a_readl(g, g->nvlink.ipt_base + (off)) | ||
35 | #define IPT_REG_WR32(g, off, v) gk20a_writel(g, g->nvlink.ipt_base + (off), (v)) | ||
36 | #define TLC_REG_RD32(g, id, off) gk20a_readl(g, g->nvlink.links[(id)].tl_base + (off)) | ||
37 | #define TLC_REG_WR32(g, id, off, v) gk20a_writel(g, g->nvlink.links[(id)].tl_base + (off), (v)) | ||
38 | #define DLPL_REG_RD32(g, id, off) gk20a_readl(g, g->nvlink.links[(id)].dlpl_base + (off)) | ||
39 | #define DLPL_REG_WR32(g, id, off, v) gk20a_writel(g, g->nvlink.links[(id)].dlpl_base + (off), (v)) | ||
40 | |||
41 | int gv100_nvlink_discover_ioctrl(struct gk20a *g); | 28 | int gv100_nvlink_discover_ioctrl(struct gk20a *g); |
42 | int gv100_nvlink_discover_link(struct gk20a *g); | 29 | int gv100_nvlink_discover_link(struct gk20a *g); |
43 | int gv100_nvlink_init(struct gk20a *g); | 30 | int gv100_nvlink_init(struct gk20a *g); |
44 | 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, | ||
33 | u32 scratch_0, bool sync); | ||
45 | /* API */ | 34 | /* API */ |
46 | int gv100_nvlink_link_early_init(struct gk20a *g, unsigned long mask); | 35 | int gv100_nvlink_link_early_init(struct gk20a *g, unsigned long mask); |
47 | u32 gv100_nvlink_link_get_mode(struct gk20a *g, u32 link_id); | 36 | u32 gv100_nvlink_link_get_mode(struct gk20a *g, u32 link_id); |
diff --git a/drivers/gpu/nvgpu/include/nvgpu/nvlink.h b/drivers/gpu/nvgpu/include/nvgpu/nvlink.h index 59e2009f..bb47537f 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/nvlink.h +++ b/drivers/gpu/nvgpu/include/nvgpu/nvlink.h | |||
@@ -33,6 +33,22 @@ | |||
33 | #include <nvgpu_rmos/include/nvlink.h> | 33 | #include <nvgpu_rmos/include/nvlink.h> |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | #define NV_NVLINK_REG_POLL_TIMEOUT_MS 3000 | ||
37 | #define NV_NVLINK_TIMEOUT_DELAY_US 5 | ||
38 | |||
39 | #define MINION_REG_RD32(g, off) gk20a_readl(g, g->nvlink.minion_base + (off)) | ||
40 | #define MINION_REG_WR32(g, off, v) gk20a_writel(g, g->nvlink.minion_base + (off), (v)) | ||
41 | #define IOCTRL_REG_RD32(g, off) gk20a_readl(g, g->nvlink.ioctrl_base + (off)) | ||
42 | #define IOCTRL_REG_WR32(g, off, v) gk20a_writel(g, g->nvlink.ioctrl_base + (off), (v)) | ||
43 | #define MIF_REG_RD32(g, id, off) gk20a_readl(g, g->nvlink.links[(id)].mif_base + (off)) | ||
44 | #define MIF_REG_WR32(g, id, off, v) gk20a_writel(g, g->nvlink.links[(id)].mif_base + (off), (v)) | ||
45 | #define IPT_REG_RD32(g, off) gk20a_readl(g, g->nvlink.ipt_base + (off)) | ||
46 | #define IPT_REG_WR32(g, off, v) gk20a_writel(g, g->nvlink.ipt_base + (off), (v)) | ||
47 | #define TLC_REG_RD32(g, id, off) gk20a_readl(g, g->nvlink.links[(id)].tl_base + (off)) | ||
48 | #define TLC_REG_WR32(g, id, off, v) gk20a_writel(g, g->nvlink.links[(id)].tl_base + (off), (v)) | ||
49 | #define DLPL_REG_RD32(g, id, off) gk20a_readl(g, g->nvlink.links[(id)].dlpl_base + (off)) | ||
50 | #define DLPL_REG_WR32(g, id, off, v) gk20a_writel(g, g->nvlink.links[(id)].dlpl_base + (off), (v)) | ||
51 | |||
36 | struct gk20a; | 52 | struct gk20a; |
37 | 53 | ||
38 | struct nvgpu_nvlink_ioctrl_list { | 54 | struct nvgpu_nvlink_ioctrl_list { |