summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorThomas Fleury <tfleury@nvidia.com>2018-03-07 12:30:21 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2018-03-13 03:04:31 -0400
commitc6e8257c445ad7cd3924673ac2e36f9dde796f0f (patch)
tree178b26121bbb297c5316e618614a57653fab450a /drivers/gpu
parent6c33a010d8e3983cc3504e073cd552f952440aa1 (diff)
gpu: nvgpu: gv100: add IPA to PA translation
Add IPA to PA translation for GV100 nvlink / pass-through mode - define platform->phys_addr(g, ipa) method - call nvgpu_init_soc_vars from nvgpu_tegra_pci_probe - in nvgpu_init_soc_vars, define set platform->phys_addr to nvgpu_tegra_hv_ipa_pa, if hypervisor is present. - in __nvgpu_sgl_phys, use sg_phys, then apply platform->phys_addr if defined. - implement IPA to PA translation in nvgpu_tegra_hv_ipa_pa Bug 200392719 Change-Id: I622049ddc62c2a57a665dd259c1bb4ed3843a537 Signed-off-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1673582 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: Richard Zhao <rizhao@nvidia.com> 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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/nvgpu/common/linux/nvgpu_mem.c12
-rw-r--r--drivers/gpu/nvgpu/common/linux/pci.c3
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gk20a.h9
-rw-r--r--drivers/gpu/nvgpu/common/linux/soc.c59
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/soc.h1
5 files changed, 81 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c b/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c
index 63a14f40..3cac13ba 100644
--- a/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c
+++ b/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c
@@ -33,10 +33,18 @@
33 33
34#include "gk20a/gk20a.h" 34#include "gk20a/gk20a.h"
35#include "gk20a/mm_gk20a.h" 35#include "gk20a/mm_gk20a.h"
36#include "platform_gk20a.h"
36 37
37static inline u64 __nvgpu_sgl_phys(struct gk20a *g, struct nvgpu_sgl *sgl) 38static u64 __nvgpu_sgl_phys(struct gk20a *g, struct nvgpu_sgl *sgl)
38{ 39{
39 return sg_phys((struct scatterlist *)sgl); 40 struct device *dev = dev_from_gk20a(g);
41 struct gk20a_platform *platform = gk20a_get_platform(dev);
42 u64 ipa = sg_phys((struct scatterlist *)sgl);
43
44 if (platform->phys_addr)
45 return platform->phys_addr(g, ipa);
46
47 return ipa;
40} 48}
41 49
42int nvgpu_mem_begin(struct gk20a *g, struct nvgpu_mem *mem) 50int nvgpu_mem_begin(struct gk20a *g, struct nvgpu_mem *mem)
diff --git a/drivers/gpu/nvgpu/common/linux/pci.c b/drivers/gpu/nvgpu/common/linux/pci.c
index 973da9ca..922792d7 100644
--- a/drivers/gpu/nvgpu/common/linux/pci.c
+++ b/drivers/gpu/nvgpu/common/linux/pci.c
@@ -24,6 +24,7 @@
24#include <nvgpu/kmem.h> 24#include <nvgpu/kmem.h>
25#include <nvgpu/enabled.h> 25#include <nvgpu/enabled.h>
26#include <nvgpu/nvlink.h> 26#include <nvgpu/nvlink.h>
27#include <nvgpu/soc.h>
27 28
28#include "gk20a/gk20a.h" 29#include "gk20a/gk20a.h"
29#include "clk/clk.h" 30#include "clk/clk.h"
@@ -44,7 +45,7 @@
44 45
45static int nvgpu_pci_tegra_probe(struct device *dev) 46static int nvgpu_pci_tegra_probe(struct device *dev)
46{ 47{
47 return 0; 48 return nvgpu_init_soc_vars(get_gk20a(dev));
48} 49}
49 50
50static int nvgpu_pci_tegra_remove(struct device *dev) 51static int nvgpu_pci_tegra_remove(struct device *dev)
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gk20a.h b/drivers/gpu/nvgpu/common/linux/platform_gk20a.h
index 927a2cee..aed50ed7 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gk20a.h
+++ b/drivers/gpu/nvgpu/common/linux/platform_gk20a.h
@@ -121,6 +121,9 @@ struct gk20a_platform {
121 */ 121 */
122 u32 default_pri_timeout; 122 u32 default_pri_timeout;
123 123
124 /* guest/vm id, needed for IPA to PA transation */
125 int vmid;
126
124 /* Initialize the platform interface of the gk20a driver. 127 /* Initialize the platform interface of the gk20a driver.
125 * 128 *
126 * The platform implementation of this function must 129 * The platform implementation of this function must
@@ -204,6 +207,12 @@ struct gk20a_platform {
204 */ 207 */
205 void (*dump_platform_dependencies)(struct device *dev); 208 void (*dump_platform_dependencies)(struct device *dev);
206 209
210 /* Defined when SMMU stage-2 is enabled, and we need to use physical
211 * addresses (not IPA). This is the case for GV100 nvlink in HV+L
212 * configuration, when dGPU is in pass-through mode.
213 */
214 u64 (*phys_addr)(struct gk20a *g, u64 ipa);
215
207 /* Callbacks to assert/deassert GPU reset */ 216 /* Callbacks to assert/deassert GPU reset */
208 int (*reset_assert)(struct device *dev); 217 int (*reset_assert)(struct device *dev);
209 int (*reset_deassert)(struct device *dev); 218 int (*reset_deassert)(struct device *dev);
diff --git a/drivers/gpu/nvgpu/common/linux/soc.c b/drivers/gpu/nvgpu/common/linux/soc.c
index 6a2bc7c0..22645381 100644
--- a/drivers/gpu/nvgpu/common/linux/soc.c
+++ b/drivers/gpu/nvgpu/common/linux/soc.c
@@ -13,8 +13,13 @@
13 13
14#include <soc/tegra/chip-id.h> 14#include <soc/tegra/chip-id.h>
15#include <soc/tegra/tegra_bpmp.h> 15#include <soc/tegra/tegra_bpmp.h>
16#ifdef CONFIG_TEGRA_HV_MANAGER
17#include <soc/tegra/virt/syscalls.h>
18#endif
16 19
17#include <nvgpu/soc.h> 20#include <nvgpu/soc.h>
21#include "os_linux.h"
22#include "platform_gk20a.h"
18 23
19bool nvgpu_platform_is_silicon(struct gk20a *g) 24bool nvgpu_platform_is_silicon(struct gk20a *g)
20{ 25{
@@ -40,3 +45,57 @@ bool nvgpu_is_bpmp_running(struct gk20a *g)
40{ 45{
41 return tegra_bpmp_running(); 46 return tegra_bpmp_running();
42} 47}
48
49#ifdef CONFIG_TEGRA_HV_MANAGER
50/* When nvlink is enabled on dGPU, we need to use physical memory addresses.
51 * There is no SMMU translation. However, the device initially enumerates as a
52 * PCIe device. As such, when allocation memory for this PCIe device, the DMA
53 * framework ends up allocating memory using SMMU (if enabled in device tree).
54 * As a result, when we switch to nvlink, we need to use underlying physical
55 * addresses, even if memory mappings exist in SMMU.
56 * In addition, when stage-2 SMMU translation is enabled (for instance when HV
57 * is enabled), the addresses we get from dma_alloc are IPAs. We need to
58 * convert them to PA.
59 */
60static u64 nvgpu_tegra_hv_ipa_pa(struct gk20a *g, u64 ipa)
61{
62 struct device *dev = dev_from_gk20a(g);
63 struct gk20a_platform *platform = gk20a_get_platform(dev);
64 struct hyp_ipa_pa_info info;
65 int err;
66 u64 pa = 0ULL;
67
68 err = hyp_read_ipa_pa_info(&info, platform->vmid, ipa);
69 if (err < 0) {
70 nvgpu_err(g, "ipa=%llx translation failed vmid=%u err=%d",
71 ipa, platform->vmid, err);
72 } else {
73 pa = info.base + info.offset;
74 nvgpu_log(g, gpu_dbg_map_v,
75 "ipa=%llx vmid=%d -> pa=%llx "
76 "base=%llx offset=%llx size=%llx\n",
77 ipa, platform->vmid, pa, info.base,
78 info.offset, info.size);
79 }
80 return pa;
81}
82#endif
83
84int nvgpu_init_soc_vars(struct gk20a *g)
85{
86#ifdef CONFIG_TEGRA_HV_MANAGER
87 struct device *dev = dev_from_gk20a(g);
88 struct gk20a_platform *platform = gk20a_get_platform(dev);
89 int err;
90
91 if (nvgpu_is_hypervisor_mode(g)) {
92 err = hyp_read_gid(&platform->vmid);
93 if (err) {
94 nvgpu_err(g, "failed to read vmid");
95 return err;
96 }
97 platform->phys_addr = nvgpu_tegra_hv_ipa_pa;
98 }
99#endif
100 return 0;
101}
diff --git a/drivers/gpu/nvgpu/include/nvgpu/soc.h b/drivers/gpu/nvgpu/include/nvgpu/soc.h
index 5001f27f..f1b4f862 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/soc.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/soc.h
@@ -29,5 +29,6 @@ bool nvgpu_platform_is_simulation(struct gk20a *g);
29bool nvgpu_platform_is_fpga(struct gk20a *g); 29bool nvgpu_platform_is_fpga(struct gk20a *g);
30bool nvgpu_is_hypervisor_mode(struct gk20a *g); 30bool nvgpu_is_hypervisor_mode(struct gk20a *g);
31bool nvgpu_is_bpmp_running(struct gk20a *g); 31bool nvgpu_is_bpmp_running(struct gk20a *g);
32int nvgpu_init_soc_vars(struct gk20a *g);
32 33
33#endif 34#endif