mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 18:16:01 +03:00
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 <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/1123941
This commit is contained in:
@@ -475,6 +475,7 @@ struct gpu_ops {
|
|||||||
void (*init_pdb)(struct gk20a *g, void *inst_ptr, u64 pdb_addr);
|
void (*init_pdb)(struct gk20a *g, void *inst_ptr, u64 pdb_addr);
|
||||||
u64 (*get_iova_addr)(struct gk20a *g, struct scatterlist *sgl,
|
u64 (*get_iova_addr)(struct gk20a *g, struct scatterlist *sgl,
|
||||||
u32 flags);
|
u32 flags);
|
||||||
|
int (*bar1_bind)(struct gk20a *g, u64 bar1_iova);
|
||||||
} mm;
|
} mm;
|
||||||
struct {
|
struct {
|
||||||
int (*init_therm_setup_hw)(struct gk20a *g);
|
int (*init_therm_setup_hw)(struct gk20a *g);
|
||||||
|
|||||||
@@ -493,15 +493,7 @@ int gk20a_init_mm_setup_hw(struct gk20a *g)
|
|||||||
g->ops.fb.set_use_full_comp_tag_line(g);
|
g->ops.fb.set_use_full_comp_tag_line(g);
|
||||||
|
|
||||||
|
|
||||||
inst_pa = (u32)(inst_pa >> bar1_instance_block_shift_gk20a());
|
g->ops.mm.bar1_bind(g, inst_pa);
|
||||||
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));
|
|
||||||
|
|
||||||
if (g->ops.mm.init_bar2_mm_hw_setup) {
|
if (g->ops.mm.init_bar2_mm_hw_setup) {
|
||||||
err = g->ops.mm.init_bar2_mm_hw_setup(g);
|
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;
|
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)
|
int gk20a_init_mm_support(struct gk20a *g)
|
||||||
{
|
{
|
||||||
u32 err;
|
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.get_mmu_levels = gk20a_mm_get_mmu_levels;
|
||||||
gops->mm.init_pdb = gk20a_mm_init_pdb;
|
gops->mm.init_pdb = gk20a_mm_init_pdb;
|
||||||
gops->mm.init_mm_setup_hw = gk20a_init_mm_setup_hw;
|
gops->mm.init_mm_setup_hw = gk20a_init_mm_setup_hw;
|
||||||
|
gops->mm.bar1_bind = gk20a_mm_bar1_bind;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,58 @@ static inline u32 bus_bar2_block_ptr_shift_v(void)
|
|||||||
{
|
{
|
||||||
return 0x0000000c;
|
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)
|
static inline u32 bus_intr_0_r(void)
|
||||||
{
|
{
|
||||||
return 0x00001100;
|
return 0x00001100;
|
||||||
|
|||||||
@@ -14,12 +14,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#include "gk20a/gk20a.h"
|
#include "gk20a/gk20a.h"
|
||||||
#include "mm_gm20b.h"
|
#include "mm_gm20b.h"
|
||||||
#include "hw_gmmu_gm20b.h"
|
#include "hw_gmmu_gm20b.h"
|
||||||
#include "hw_fb_gm20b.h"
|
#include "hw_fb_gm20b.h"
|
||||||
#include "hw_gr_gm20b.h"
|
#include "hw_gr_gm20b.h"
|
||||||
#include "hw_ram_gm20b.h"
|
#include "hw_ram_gm20b.h"
|
||||||
|
#include "hw_bus_gm20b.h"
|
||||||
|
|
||||||
static int gm20b_mm_mmu_vpr_info_fetch_wait(struct gk20a *g,
|
static int gm20b_mm_mmu_vpr_info_fetch_wait(struct gk20a *g,
|
||||||
const unsigned int msec)
|
const unsigned int msec)
|
||||||
@@ -133,6 +135,32 @@ static bool gm20b_mm_support_sparse(struct gk20a *g)
|
|||||||
return true;
|
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)
|
void gm20b_init_mm(struct gpu_ops *gops)
|
||||||
{
|
{
|
||||||
gops->mm.support_sparse = gm20b_mm_support_sparse;
|
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.get_mmu_levels = gk20a_mm_get_mmu_levels;
|
||||||
gops->mm.init_pdb = gk20a_mm_init_pdb;
|
gops->mm.init_pdb = gk20a_mm_init_pdb;
|
||||||
gops->mm.init_mm_setup_hw = gk20a_init_mm_setup_hw;
|
gops->mm.init_mm_setup_hw = gk20a_init_mm_setup_hw;
|
||||||
|
gops->mm.bar1_bind = gm20b_mm_bar1_bind;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user