diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c index d73eae86c..88a933b87 100644 --- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c @@ -588,10 +588,6 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg case NVGPU_GPU_IOCTL_ZBC_SET_TABLE: set_table_args = (struct nvgpu_gpu_zbc_set_table_args *)buf; - /* not supported for vgpu */ - if (gk20a_gpu_is_virtual(dev)) - return -ENOMEM; - zbc_val = kzalloc(sizeof(struct zbc_entry), GFP_KERNEL); if (zbc_val == NULL) return -ENOMEM; @@ -616,7 +612,7 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg if (!err) { err = gk20a_busy(dev); if (!err) { - err = gk20a_gr_zbc_set_table(g, &g->gr, + err = g->ops.gr.zbc_set_table(g, &g->gr, zbc_val); gk20a_idle(dev); } @@ -635,7 +631,7 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg zbc_tbl->type = query_table_args->type; zbc_tbl->index_size = query_table_args->index_size; - err = gr_gk20a_query_zbc(g, &g->gr, zbc_tbl); + err = g->ops.gr.zbc_query_table(g, &g->gr, zbc_tbl); if (!err) { switch (zbc_tbl->type) { diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 29fa40218..a52d97f36 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -152,6 +152,10 @@ struct gpu_ops { struct zbc_entry *color_val, u32 index); int (*add_zbc_depth)(struct gk20a *g, struct gr_gk20a *gr, struct zbc_entry *depth_val, u32 index); + int (*zbc_set_table)(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *zbc_val); + int (*zbc_query_table)(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_query_params *query_params); u32 (*pagepool_default_size)(struct gk20a *g); int (*init_ctx_state)(struct gk20a *g); int (*alloc_gr_ctx)(struct gk20a *g, diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 85d1a8860..603fc3a4a 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -7325,6 +7325,8 @@ void gk20a_init_gr_ops(struct gpu_ops *gops) gops->gr.detect_sm_arch = gr_gk20a_detect_sm_arch; gops->gr.add_zbc_color = gr_gk20a_add_zbc_color; gops->gr.add_zbc_depth = gr_gk20a_add_zbc_depth; + gops->gr.zbc_set_table = gk20a_gr_zbc_set_table; + gops->gr.zbc_query_table = gr_gk20a_query_zbc; gops->gr.pagepool_default_size = gr_gk20a_pagepool_default_size; gops->gr.init_ctx_state = gr_gk20a_init_ctx_state; gops->gr.alloc_gr_ctx = gr_gk20a_alloc_gr_ctx; diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c index 8351b5547..74a43a6ca 100644 --- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c @@ -1103,6 +1103,8 @@ void gm20b_init_gr(struct gpu_ops *gops) gops->gr.detect_sm_arch = gr_gm20b_detect_sm_arch; gops->gr.add_zbc_color = gr_gk20a_add_zbc_color; gops->gr.add_zbc_depth = gr_gk20a_add_zbc_depth; + gops->gr.zbc_set_table = gk20a_gr_zbc_set_table; + gops->gr.zbc_query_table = gr_gk20a_query_zbc; gops->gr.pagepool_default_size = gr_gm20b_pagepool_default_size; gops->gr.init_ctx_state = gr_gk20a_init_ctx_state; gops->gr.alloc_gr_ctx = gr_gm20b_alloc_gr_ctx; diff --git a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c index 8d0bb6cf1..f6f12c7ba 100644 --- a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c @@ -661,6 +661,81 @@ static u32 vgpu_gr_get_fbp_en_mask(struct gk20a *g) return fbp_en_mask; } +static int vgpu_gr_add_zbc(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_entry *zbc_val) +{ + struct gk20a_platform *platform = gk20a_get_platform(g->dev); + struct tegra_vgpu_cmd_msg msg = {0}; + struct tegra_vgpu_zbc_set_table_params *p = &msg.params.zbc_set_table; + int err; + + gk20a_dbg_fn(""); + + msg.cmd = TEGRA_VGPU_CMD_ZBC_SET_TABLE; + msg.handle = platform->virt_handle; + + p->type = zbc_val->type; + p->format = zbc_val->format; + switch (p->type) { + case GK20A_ZBC_TYPE_COLOR: + memcpy(p->color_ds, zbc_val->color_ds, sizeof(p->color_ds)); + memcpy(p->color_l2, zbc_val->color_l2, sizeof(p->color_l2)); + break; + case GK20A_ZBC_TYPE_DEPTH: + p->depth = zbc_val->depth; + break; + default: + return -EINVAL; + } + + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + + return (err || msg.ret) ? -ENOMEM : 0; +} + +static int vgpu_gr_query_zbc(struct gk20a *g, struct gr_gk20a *gr, + struct zbc_query_params *query_params) +{ + struct gk20a_platform *platform = gk20a_get_platform(g->dev); + struct tegra_vgpu_cmd_msg msg = {0}; + struct tegra_vgpu_zbc_query_table_params *p = + &msg.params.zbc_query_table; + int err; + + gk20a_dbg_fn(""); + + msg.cmd = TEGRA_VGPU_CMD_ZBC_QUERY_TABLE; + msg.handle = platform->virt_handle; + + p->type = query_params->type; + p->index_size = query_params->index_size; + + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + if (err || msg.ret) + return -ENOMEM; + + switch (query_params->type) { + case GK20A_ZBC_TYPE_COLOR: + memcpy(query_params->color_ds, p->color_ds, + sizeof(query_params->color_ds)); + memcpy(query_params->color_l2, p->color_l2, + sizeof(query_params->color_l2)); + break; + case GK20A_ZBC_TYPE_DEPTH: + query_params->depth = p->depth; + break; + case GK20A_ZBC_TYPE_INVALID: + query_params->index_size = p->index_size; + break; + default: + return -EINVAL; + } + query_params->ref_cnt = p->ref_cnt; + query_params->format = p->format; + + return 0; +} + static void vgpu_remove_gr_support(struct gr_gk20a *gr) { gk20a_dbg_fn(""); @@ -782,4 +857,6 @@ void vgpu_init_gr_ops(struct gpu_ops *gops) gops->gr.get_gpc_tpc_mask = vgpu_gr_get_gpc_tpc_mask; gops->gr.get_max_fbps_count = vgpu_gr_get_max_fbps_count; gops->gr.get_fbp_en_mask = vgpu_gr_get_fbp_en_mask; + gops->gr.zbc_set_table = vgpu_gr_add_zbc; + gops->gr.zbc_query_table = vgpu_gr_query_zbc; } diff --git a/include/linux/tegra_vgpu.h b/include/linux/tegra_vgpu.h index e16744407..a295c9efc 100644 --- a/include/linux/tegra_vgpu.h +++ b/include/linux/tegra_vgpu.h @@ -62,7 +62,9 @@ enum { TEGRA_VGPU_CMD_CHANNEL_BIND_ZCULL, TEGRA_VGPU_CMD_CACHE_MAINT, TEGRA_VGPU_CMD_SUBMIT_RUNLIST, - TEGRA_VGPU_CMD_GET_ZCULL_INFO + TEGRA_VGPU_CMD_GET_ZCULL_INFO, + TEGRA_VGPU_CMD_ZBC_SET_TABLE, + TEGRA_VGPU_CMD_ZBC_QUERY_TABLE }; struct tegra_vgpu_connect_params { @@ -191,6 +193,29 @@ struct tegra_vgpu_zcull_info_params { u32 subregion_count; }; +#define TEGRA_VGPU_ZBC_COLOR_VALUE_SIZE 4 +#define TEGRA_VGPU_ZBC_TYPE_INVALID 0 +#define TEGRA_VGPU_ZBC_TYPE_COLOR 1 +#define TEGRA_VGPU_ZBC_TYPE_DEPTH 2 + +struct tegra_vgpu_zbc_set_table_params { + u32 color_ds[TEGRA_VGPU_ZBC_COLOR_VALUE_SIZE]; + u32 color_l2[TEGRA_VGPU_ZBC_COLOR_VALUE_SIZE]; + u32 depth; + u32 format; + u32 type; /* color or depth */ +}; + +struct tegra_vgpu_zbc_query_table_params { + u32 color_ds[TEGRA_VGPU_ZBC_COLOR_VALUE_SIZE]; + u32 color_l2[TEGRA_VGPU_ZBC_COLOR_VALUE_SIZE]; + u32 depth; + u32 ref_cnt; + u32 format; + u32 type; /* color or depth */ + u32 index_size; /* [out] size, [in] index */ +}; + struct tegra_vgpu_cmd_msg { u32 cmd; int ret; @@ -211,6 +236,8 @@ struct tegra_vgpu_cmd_msg { struct tegra_vgpu_runlist_params runlist; struct tegra_vgpu_golden_ctx_params golden_ctx; struct tegra_vgpu_zcull_info_params zcull_info; + struct tegra_vgpu_zbc_set_table_params zbc_set_table; + struct tegra_vgpu_zbc_query_table_params zbc_query_table; } params; };