From 0e423669a4ff3f00b06d86f8ca251ef99f3671ce Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Mon, 11 Apr 2016 13:01:59 -0700 Subject: gpu: nvgpu: Wait for BAR1 bind Wait for BAR1 bind to complete before continuing. The register to wait exists Maxwell onwards. Change-Id: Ie3736033fdb748c5da8d7a6085ad6d63acaf41f5 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/1123941 --- drivers/gpu/nvgpu/gk20a/gk20a.h | 1 + drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 26 +++++++++++------ drivers/gpu/nvgpu/gm20b/hw_bus_gm20b.h | 52 ++++++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/gm20b/mm_gm20b.c | 29 +++++++++++++++++++ 4 files changed, 99 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index e17392d0..61e8e641 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -475,6 +475,7 @@ struct gpu_ops { void (*init_pdb)(struct gk20a *g, void *inst_ptr, u64 pdb_addr); u64 (*get_iova_addr)(struct gk20a *g, struct scatterlist *sgl, u32 flags); + int (*bar1_bind)(struct gk20a *g, u64 bar1_iova); } mm; struct { int (*init_therm_setup_hw)(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index 5c3f83a6..b5ec5e25 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c @@ -493,15 +493,7 @@ int gk20a_init_mm_setup_hw(struct gk20a *g) g->ops.fb.set_use_full_comp_tag_line(g); - inst_pa = (u32)(inst_pa >> bar1_instance_block_shift_gk20a()); - gk20a_dbg_info("bar1 inst block ptr: 0x%08x", (u32)inst_pa); - - gk20a_writel(g, bus_bar1_block_r(), - (g->mm.vidmem_is_vidmem ? - bus_bar1_block_target_sys_mem_ncoh_f() : - bus_bar1_block_target_vid_mem_f()) | - bus_bar1_block_mode_virtual_f() | - bus_bar1_block_ptr_f(inst_pa)); + g->ops.mm.bar1_bind(g, inst_pa); if (g->ops.mm.init_bar2_mm_hw_setup) { err = g->ops.mm.init_bar2_mm_hw_setup(g); @@ -516,6 +508,21 @@ int gk20a_init_mm_setup_hw(struct gk20a *g) return 0; } +static int gk20a_mm_bar1_bind(struct gk20a *g, u64 bar1_iova) +{ + u64 inst_pa = (u32)(bar1_iova >> bar1_instance_block_shift_gk20a()); + gk20a_dbg_info("bar1 inst block ptr: 0x%08x", (u32)inst_pa); + + gk20a_writel(g, bus_bar1_block_r(), + (g->mm.vidmem_is_vidmem ? + bus_bar1_block_target_sys_mem_ncoh_f() : + bus_bar1_block_target_vid_mem_f()) | + bus_bar1_block_mode_virtual_f() | + bus_bar1_block_ptr_f(inst_pa)); + + return 0; +} + int gk20a_init_mm_support(struct gk20a *g) { u32 err; @@ -3919,4 +3926,5 @@ void gk20a_init_mm(struct gpu_ops *gops) gops->mm.get_mmu_levels = gk20a_mm_get_mmu_levels; gops->mm.init_pdb = gk20a_mm_init_pdb; gops->mm.init_mm_setup_hw = gk20a_init_mm_setup_hw; + gops->mm.bar1_bind = gk20a_mm_bar1_bind; } diff --git a/drivers/gpu/nvgpu/gm20b/hw_bus_gm20b.h b/drivers/gpu/nvgpu/gm20b/hw_bus_gm20b.h index 6e412e17..e69275e0 100644 --- a/drivers/gpu/nvgpu/gm20b/hw_bus_gm20b.h +++ b/drivers/gpu/nvgpu/gm20b/hw_bus_gm20b.h @@ -106,6 +106,58 @@ static inline u32 bus_bar2_block_ptr_shift_v(void) { return 0x0000000c; } +static inline u32 bus_bind_status_r(void) +{ + return 0x00001710; +} +static inline u32 bus_bind_status_bar1_pending_v(u32 r) +{ + return (r >> 0) & 0x1; +} +static inline u32 bus_bind_status_bar1_pending_empty_f(void) +{ + return 0x0; +} +static inline u32 bus_bind_status_bar1_pending_busy_f(void) +{ + return 0x1; +} +static inline u32 bus_bind_status_bar1_outstanding_v(u32 r) +{ + return (r >> 1) & 0x1; +} +static inline u32 bus_bind_status_bar1_outstanding_false_f(void) +{ + return 0x0; +} +static inline u32 bus_bind_status_bar1_outstanding_true_f(void) +{ + return 0x2; +} +static inline u32 bus_bind_status_bar2_pending_v(u32 r) +{ + return (r >> 2) & 0x1; +} +static inline u32 bus_bind_status_bar2_pending_empty_f(void) +{ + return 0x0; +} +static inline u32 bus_bind_status_bar2_pending_busy_f(void) +{ + return 0x4; +} +static inline u32 bus_bind_status_bar2_outstanding_v(u32 r) +{ + return (r >> 3) & 0x1; +} +static inline u32 bus_bind_status_bar2_outstanding_false_f(void) +{ + return 0x0; +} +static inline u32 bus_bind_status_bar2_outstanding_true_f(void) +{ + return 0x8; +} static inline u32 bus_intr_0_r(void) { return 0x00001100; diff --git a/drivers/gpu/nvgpu/gm20b/mm_gm20b.c b/drivers/gpu/nvgpu/gm20b/mm_gm20b.c index 7bc19972..ac73b5c8 100644 --- a/drivers/gpu/nvgpu/gm20b/mm_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/mm_gm20b.c @@ -14,12 +14,14 @@ */ #include +#include #include "gk20a/gk20a.h" #include "mm_gm20b.h" #include "hw_gmmu_gm20b.h" #include "hw_fb_gm20b.h" #include "hw_gr_gm20b.h" #include "hw_ram_gm20b.h" +#include "hw_bus_gm20b.h" static int gm20b_mm_mmu_vpr_info_fetch_wait(struct gk20a *g, const unsigned int msec) @@ -133,6 +135,32 @@ static bool gm20b_mm_support_sparse(struct gk20a *g) return true; } +static int gm20b_mm_bar1_bind(struct gk20a *g, u64 bar1_iova) +{ + int retry = 1000; + u64 inst_pa = (u32)(bar1_iova >> bar1_instance_block_shift_gk20a()); + gk20a_dbg_info("bar1 inst block ptr: 0x%08x", (u32)inst_pa); + + gk20a_writel(g, bus_bar1_block_r(), + (g->mm.vidmem_is_vidmem ? + bus_bar1_block_target_sys_mem_ncoh_f() : + bus_bar1_block_target_vid_mem_f()) | + bus_bar1_block_mode_virtual_f() | + bus_bar1_block_ptr_f(inst_pa)); + do { + u32 val = gk20a_readl(g, bus_bind_status_r()); + u32 pending = bus_bind_status_bar1_pending_v(val); + u32 outstanding = bus_bind_status_bar1_outstanding_v(val); + if (!pending && !outstanding) + break; + + udelay(5); + retry--; + } while (retry >= 0 || !tegra_platform_is_silicon()); + + return retry ? -EINVAL : 0; +} + void gm20b_init_mm(struct gpu_ops *gops) { gops->mm.support_sparse = gm20b_mm_support_sparse; @@ -155,4 +183,5 @@ void gm20b_init_mm(struct gpu_ops *gops) gops->mm.get_mmu_levels = gk20a_mm_get_mmu_levels; gops->mm.init_pdb = gk20a_mm_init_pdb; gops->mm.init_mm_setup_hw = gk20a_init_mm_setup_hw; + gops->mm.bar1_bind = gm20b_mm_bar1_bind; } -- cgit v1.2.2