gpu: nvgpu: move ctxsw related data to gr falcon

Added new function to add require sw initionaltions. before enabling
gr hw. Added nvgpu_netlist_init_ctx_vars and nvgpu_gr_falcon_init_support
as part of this function:
int nvgpu_gr_prepare_sw(struct gk20a *g)

Moved following structure defs from gr_gk20a.h to gr_falcon.h and
renamed appropriately:
gk20a_ctxsw_ucode_segment -> nvgpu_ctxsw_ucode_segment
gk20a_ctxsw_ucode_segments -> nvgpu_ctxsw_ucode_segments

Moved following struct to gr_falcon_priv.h:
gk20a_ctxsw_ucode_info -> nvgpu_ctxsw_ucode_info

Moved following data from struct gk20a to new structure in gr_falcon_priv.h
struct nvgpu_gr_falcon:
struct nvgpu_mutex ctxsw_disable_lock;
int ctxsw_disable_count;
struct gk20a_ctxsw_ucode_info ctxsw_ucode_info;

Also moved following data from gr_gk20.h to struct nvgpu_gr_falcon:
struct nvgpu_mutex fecs_mutex;
bool skip_ucode_init;
wait_ucode_status
GR_IS_UCODE related enums
eUcodeHandshakeInit enums

Now add a pointer to this new data structure from struct gr_gk20a to
access gr_falcon related data and modified code to reflect this
change:
struct nvgpu_gr_falcon *falcon;

Added following functions to access gr_falcon data:
struct nvgpu_mutex *nvgpu_gr_falcon_get_fecs_mutex(
				struct nvgpu_gr_falcon *falcon);
struct nvgpu_ctxsw_ucode_segments *nvgpu_gr_falcon_get_fecs_ucode_segments(
				struct nvgpu_gr_falcon *falcon);
struct nvgpu_ctxsw_ucode_segments *nvgpu_gr_falcon_get_gpccs_ucode_segments(
				struct nvgpu_gr_falcon *falcon);
void *nvgpu_gr_falcon_get_surface_desc_cpu_va(
				struct nvgpu_gr_falcon *falcon);

JIRA NVGPU-1881

Change-Id: I9100891989b0d6b57c49f2bf00ad839a72bc7c7e
Signed-off-by: Seshendra Gadagottu <sgadagottu@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2091358
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Seshendra Gadagottu
2019-04-06 09:39:50 -07:00
committed by mobile promotions
parent 2cf8feedd8
commit 12a06fe060
22 changed files with 384 additions and 278 deletions

View File

@@ -67,6 +67,8 @@ int nvgpu_acr_lsf_fecs_ucode_details_v0(struct gk20a *g, void *lsf_ucode_img)
struct lsf_ucode_desc *lsf_desc; struct lsf_ucode_desc *lsf_desc;
struct nvgpu_firmware *fecs_sig; struct nvgpu_firmware *fecs_sig;
struct flcn_ucode_img *p_img = (struct flcn_ucode_img *)lsf_ucode_img; struct flcn_ucode_img *p_img = (struct flcn_ucode_img *)lsf_ucode_img;
struct nvgpu_ctxsw_ucode_segments *fecs =
nvgpu_gr_falcon_get_fecs_ucode_segments(g->gr.falcon);
int err; int err;
fecs_sig = nvgpu_request_firmware(g, GM20B_FECS_UCODE_SIG, 0); fecs_sig = nvgpu_request_firmware(g, GM20B_FECS_UCODE_SIG, 0);
@@ -90,34 +92,25 @@ int nvgpu_acr_lsf_fecs_ucode_details_v0(struct gk20a *g, void *lsf_ucode_img)
goto free_lsf_desc; goto free_lsf_desc;
} }
p_img->desc->bootloader_start_offset = p_img->desc->bootloader_start_offset = fecs->boot.offset;
g->ctxsw_ucode_info.fecs.boot.offset; p_img->desc->bootloader_size = ALIGN(fecs->boot.size, 256);
p_img->desc->bootloader_size = p_img->desc->bootloader_imem_offset = fecs->boot_imem_offset;
ALIGN(g->ctxsw_ucode_info.fecs.boot.size, 256); p_img->desc->bootloader_entry_point = fecs->boot_entry;
p_img->desc->bootloader_imem_offset =
g->ctxsw_ucode_info.fecs.boot_imem_offset;
p_img->desc->bootloader_entry_point =
g->ctxsw_ucode_info.fecs.boot_entry;
p_img->desc->image_size = p_img->desc->image_size = ALIGN(fecs->boot.size, 256) +
ALIGN(g->ctxsw_ucode_info.fecs.boot.size, 256) + ALIGN(fecs->code.size, 256) + ALIGN(fecs->data.size, 256);
ALIGN(g->ctxsw_ucode_info.fecs.code.size, 256) + p_img->desc->app_size = ALIGN(fecs->code.size, 256) +
ALIGN(g->ctxsw_ucode_info.fecs.data.size, 256); ALIGN(fecs->data.size, 256);
p_img->desc->app_size = ALIGN(g->ctxsw_ucode_info.fecs.code.size, 256) + p_img->desc->app_start_offset = fecs->code.offset;
ALIGN(g->ctxsw_ucode_info.fecs.data.size, 256);
p_img->desc->app_start_offset = g->ctxsw_ucode_info.fecs.code.offset;
p_img->desc->app_imem_offset = 0; p_img->desc->app_imem_offset = 0;
p_img->desc->app_imem_entry = 0; p_img->desc->app_imem_entry = 0;
p_img->desc->app_dmem_offset = 0; p_img->desc->app_dmem_offset = 0;
p_img->desc->app_resident_code_offset = 0; p_img->desc->app_resident_code_offset = 0;
p_img->desc->app_resident_code_size = p_img->desc->app_resident_code_size = fecs->code.size;
g->ctxsw_ucode_info.fecs.code.size;
p_img->desc->app_resident_data_offset = p_img->desc->app_resident_data_offset =
g->ctxsw_ucode_info.fecs.data.offset - fecs->data.offset - fecs->code.offset;
g->ctxsw_ucode_info.fecs.code.offset; p_img->desc->app_resident_data_size = fecs->data.size;
p_img->desc->app_resident_data_size = p_img->data = nvgpu_gr_falcon_get_surface_desc_cpu_va(g->gr.falcon);
g->ctxsw_ucode_info.fecs.data.size;
p_img->data = g->ctxsw_ucode_info.surface_desc.cpu_va;
p_img->data_size = p_img->desc->image_size; p_img->data_size = p_img->desc->image_size;
p_img->fw_ver = NULL; p_img->fw_ver = NULL;
@@ -138,6 +131,8 @@ int nvgpu_acr_lsf_gpccs_ucode_details_v0(struct gk20a *g, void *lsf_ucode_img)
struct lsf_ucode_desc *lsf_desc; struct lsf_ucode_desc *lsf_desc;
struct nvgpu_firmware *gpccs_sig; struct nvgpu_firmware *gpccs_sig;
struct flcn_ucode_img *p_img = (struct flcn_ucode_img *)lsf_ucode_img; struct flcn_ucode_img *p_img = (struct flcn_ucode_img *)lsf_ucode_img;
struct nvgpu_ctxsw_ucode_segments *gpccs =
nvgpu_gr_falcon_get_gpccs_ucode_segments(g->gr.falcon);
int err; int err;
if (!nvgpu_is_enabled(g, NVGPU_SEC_SECUREGPCCS)) { if (!nvgpu_is_enabled(g, NVGPU_SEC_SECUREGPCCS)) {
@@ -166,33 +161,26 @@ int nvgpu_acr_lsf_gpccs_ucode_details_v0(struct gk20a *g, void *lsf_ucode_img)
p_img->desc->bootloader_start_offset = p_img->desc->bootloader_start_offset =
0; 0;
p_img->desc->bootloader_size = p_img->desc->bootloader_size = ALIGN(gpccs->boot.size, 256);
ALIGN(g->ctxsw_ucode_info.gpccs.boot.size, 256); p_img->desc->bootloader_imem_offset = gpccs->boot_imem_offset;
p_img->desc->bootloader_imem_offset = p_img->desc->bootloader_entry_point = gpccs->boot_entry;
g->ctxsw_ucode_info.gpccs.boot_imem_offset;
p_img->desc->bootloader_entry_point =
g->ctxsw_ucode_info.gpccs.boot_entry;
p_img->desc->image_size = p_img->desc->image_size = ALIGN(gpccs->boot.size, 256) +
ALIGN(g->ctxsw_ucode_info.gpccs.boot.size, 256) + ALIGN(gpccs->code.size, 256) + ALIGN(gpccs->data.size, 256);
ALIGN(g->ctxsw_ucode_info.gpccs.code.size, 256) + p_img->desc->app_size =
ALIGN(g->ctxsw_ucode_info.gpccs.data.size, 256); ALIGN(gpccs->code.size, 256) + ALIGN(gpccs->data.size, 256);
p_img->desc->app_size = ALIGN(g->ctxsw_ucode_info.gpccs.code.size, 256)
+ ALIGN(g->ctxsw_ucode_info.gpccs.data.size, 256);
p_img->desc->app_start_offset = p_img->desc->bootloader_size; p_img->desc->app_start_offset = p_img->desc->bootloader_size;
p_img->desc->app_imem_offset = 0; p_img->desc->app_imem_offset = 0;
p_img->desc->app_imem_entry = 0; p_img->desc->app_imem_entry = 0;
p_img->desc->app_dmem_offset = 0; p_img->desc->app_dmem_offset = 0;
p_img->desc->app_resident_code_offset = 0; p_img->desc->app_resident_code_offset = 0;
p_img->desc->app_resident_code_size = p_img->desc->app_resident_code_size = ALIGN(gpccs->code.size, 256);
ALIGN(g->ctxsw_ucode_info.gpccs.code.size, 256); p_img->desc->app_resident_data_offset = ALIGN(gpccs->data.offset, 256) -
p_img->desc->app_resident_data_offset = ALIGN(gpccs->code.offset, 256);
ALIGN(g->ctxsw_ucode_info.gpccs.data.offset, 256) - p_img->desc->app_resident_data_size = ALIGN(gpccs->data.size, 256);
ALIGN(g->ctxsw_ucode_info.gpccs.code.offset, 256); p_img->data = (u32 *)
p_img->desc->app_resident_data_size = ((u8 *)nvgpu_gr_falcon_get_surface_desc_cpu_va(g->gr.falcon) +
ALIGN(g->ctxsw_ucode_info.gpccs.data.size, 256); gpccs->boot.offset);
p_img->data = (u32 *)((u8 *)g->ctxsw_ucode_info.surface_desc.cpu_va +
g->ctxsw_ucode_info.gpccs.boot.offset);
p_img->data_size = ALIGN(p_img->desc->image_size, 256); p_img->data_size = ALIGN(p_img->desc->image_size, 256);
p_img->fw_ver = NULL; p_img->fw_ver = NULL;
p_img->header = NULL; p_img->header = NULL;
@@ -820,7 +808,7 @@ int nvgpu_acr_prepare_ucode_blob_v0(struct gk20a *g)
return err; return err;
} }
err = nvgpu_gr_falcon_init_ctxsw_ucode(g); err = nvgpu_gr_falcon_init_ctxsw_ucode(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "gr_falcon_init_ctxsw_ucode failed err=%d", err); nvgpu_err(g, "gr_falcon_init_ctxsw_ucode failed err=%d", err);
return err; return err;

View File

@@ -75,6 +75,8 @@ int nvgpu_acr_lsf_fecs_ucode_details_v1(struct gk20a *g, void *lsf_ucode_img)
struct nvgpu_firmware *fecs_sig = NULL; struct nvgpu_firmware *fecs_sig = NULL;
struct flcn_ucode_img_v1 *p_img = struct flcn_ucode_img_v1 *p_img =
(struct flcn_ucode_img_v1 *)lsf_ucode_img; (struct flcn_ucode_img_v1 *)lsf_ucode_img;
struct nvgpu_ctxsw_ucode_segments *fecs =
nvgpu_gr_falcon_get_fecs_ucode_segments(g->gr.falcon);
int err; int err;
switch (ver) { switch (ver) {
@@ -113,34 +115,25 @@ int nvgpu_acr_lsf_fecs_ucode_details_v1(struct gk20a *g, void *lsf_ucode_img)
goto free_lsf_desc; goto free_lsf_desc;
} }
p_img->desc->bootloader_start_offset = p_img->desc->bootloader_start_offset = fecs->boot.offset;
g->ctxsw_ucode_info.fecs.boot.offset; p_img->desc->bootloader_size = ALIGN(fecs->boot.size, 256);
p_img->desc->bootloader_size = p_img->desc->bootloader_imem_offset = fecs->boot_imem_offset;
ALIGN(g->ctxsw_ucode_info.fecs.boot.size, 256); p_img->desc->bootloader_entry_point = fecs->boot_entry;
p_img->desc->bootloader_imem_offset =
g->ctxsw_ucode_info.fecs.boot_imem_offset;
p_img->desc->bootloader_entry_point =
g->ctxsw_ucode_info.fecs.boot_entry;
p_img->desc->image_size = p_img->desc->image_size = ALIGN(fecs->boot.size, 256) +
ALIGN(g->ctxsw_ucode_info.fecs.boot.size, 256) + ALIGN(fecs->code.size, 256) + ALIGN(fecs->data.size, 256);
ALIGN(g->ctxsw_ucode_info.fecs.code.size, 256) + p_img->desc->app_size = ALIGN(fecs->code.size, 256) +
ALIGN(g->ctxsw_ucode_info.fecs.data.size, 256); ALIGN(fecs->data.size, 256);
p_img->desc->app_size = ALIGN(g->ctxsw_ucode_info.fecs.code.size, 256) + p_img->desc->app_start_offset = fecs->code.offset;
ALIGN(g->ctxsw_ucode_info.fecs.data.size, 256);
p_img->desc->app_start_offset = g->ctxsw_ucode_info.fecs.code.offset;
p_img->desc->app_imem_offset = 0; p_img->desc->app_imem_offset = 0;
p_img->desc->app_imem_entry = 0; p_img->desc->app_imem_entry = 0;
p_img->desc->app_dmem_offset = 0; p_img->desc->app_dmem_offset = 0;
p_img->desc->app_resident_code_offset = 0; p_img->desc->app_resident_code_offset = 0;
p_img->desc->app_resident_code_size = p_img->desc->app_resident_code_size = fecs->code.size;
g->ctxsw_ucode_info.fecs.code.size; p_img->desc->app_resident_data_offset = fecs->data.offset -
p_img->desc->app_resident_data_offset = fecs->code.offset;
g->ctxsw_ucode_info.fecs.data.offset - p_img->desc->app_resident_data_size = fecs->data.size;
g->ctxsw_ucode_info.fecs.code.offset; p_img->data = nvgpu_gr_falcon_get_surface_desc_cpu_va(g->gr.falcon);
p_img->desc->app_resident_data_size =
g->ctxsw_ucode_info.fecs.data.size;
p_img->data = g->ctxsw_ucode_info.surface_desc.cpu_va;
p_img->data_size = p_img->desc->image_size; p_img->data_size = p_img->desc->image_size;
p_img->fw_ver = NULL; p_img->fw_ver = NULL;
@@ -166,6 +159,8 @@ int nvgpu_acr_lsf_gpccs_ucode_details_v1(struct gk20a *g, void *lsf_ucode_img)
struct nvgpu_firmware *gpccs_sig = NULL; struct nvgpu_firmware *gpccs_sig = NULL;
struct flcn_ucode_img_v1 *p_img = struct flcn_ucode_img_v1 *p_img =
(struct flcn_ucode_img_v1 *)lsf_ucode_img; (struct flcn_ucode_img_v1 *)lsf_ucode_img;
struct nvgpu_ctxsw_ucode_segments *gpccs =
nvgpu_gr_falcon_get_gpccs_ucode_segments(g->gr.falcon);
int err; int err;
if (!nvgpu_is_enabled(g, NVGPU_SEC_SECUREGPCCS)) { if (!nvgpu_is_enabled(g, NVGPU_SEC_SECUREGPCCS)) {
@@ -208,33 +203,26 @@ int nvgpu_acr_lsf_gpccs_ucode_details_v1(struct gk20a *g, void *lsf_ucode_img)
} }
p_img->desc->bootloader_start_offset = 0; p_img->desc->bootloader_start_offset = 0;
p_img->desc->bootloader_size = p_img->desc->bootloader_size = ALIGN(gpccs->boot.size, 256);
ALIGN(g->ctxsw_ucode_info.gpccs.boot.size, 256); p_img->desc->bootloader_imem_offset = gpccs->boot_imem_offset;
p_img->desc->bootloader_imem_offset = p_img->desc->bootloader_entry_point = gpccs->boot_entry;
g->ctxsw_ucode_info.gpccs.boot_imem_offset;
p_img->desc->bootloader_entry_point =
g->ctxsw_ucode_info.gpccs.boot_entry;
p_img->desc->image_size = p_img->desc->image_size = ALIGN(gpccs->boot.size, 256) +
ALIGN(g->ctxsw_ucode_info.gpccs.boot.size, 256) + ALIGN(gpccs->code.size, 256) + ALIGN(gpccs->data.size, 256);
ALIGN(g->ctxsw_ucode_info.gpccs.code.size, 256) + p_img->desc->app_size = ALIGN(gpccs->code.size, 256)
ALIGN(g->ctxsw_ucode_info.gpccs.data.size, 256); + ALIGN(gpccs->data.size, 256);
p_img->desc->app_size = ALIGN(g->ctxsw_ucode_info.gpccs.code.size, 256)
+ ALIGN(g->ctxsw_ucode_info.gpccs.data.size, 256);
p_img->desc->app_start_offset = p_img->desc->bootloader_size; p_img->desc->app_start_offset = p_img->desc->bootloader_size;
p_img->desc->app_imem_offset = 0; p_img->desc->app_imem_offset = 0;
p_img->desc->app_imem_entry = 0; p_img->desc->app_imem_entry = 0;
p_img->desc->app_dmem_offset = 0; p_img->desc->app_dmem_offset = 0;
p_img->desc->app_resident_code_offset = 0; p_img->desc->app_resident_code_offset = 0;
p_img->desc->app_resident_code_size = p_img->desc->app_resident_code_size = ALIGN(gpccs->code.size, 256);
ALIGN(g->ctxsw_ucode_info.gpccs.code.size, 256); p_img->desc->app_resident_data_offset = ALIGN(gpccs->data.offset, 256) -
p_img->desc->app_resident_data_offset = ALIGN(gpccs->code.offset, 256);
ALIGN(g->ctxsw_ucode_info.gpccs.data.offset, 256) - p_img->desc->app_resident_data_size = ALIGN(gpccs->data.size, 256);
ALIGN(g->ctxsw_ucode_info.gpccs.code.offset, 256); p_img->data = (u32 *)
p_img->desc->app_resident_data_size = ((u8 *)nvgpu_gr_falcon_get_surface_desc_cpu_va(g->gr.falcon) +
ALIGN(g->ctxsw_ucode_info.gpccs.data.size, 256); gpccs->boot.offset);
p_img->data = (u32 *)((u8 *)g->ctxsw_ucode_info.surface_desc.cpu_va +
g->ctxsw_ucode_info.gpccs.boot.offset);
p_img->data_size = ALIGN(p_img->desc->image_size, 256); p_img->data_size = ALIGN(p_img->desc->image_size, 256);
p_img->fw_ver = NULL; p_img->fw_ver = NULL;
p_img->header = NULL; p_img->header = NULL;
@@ -943,7 +931,7 @@ int nvgpu_acr_prepare_ucode_blob_v1(struct gk20a *g)
plsfm = &lsfm_l; plsfm = &lsfm_l;
(void) memset((void *)plsfm, 0, sizeof(struct ls_flcn_mgr_v1)); (void) memset((void *)plsfm, 0, sizeof(struct ls_flcn_mgr_v1));
err = nvgpu_gr_falcon_init_ctxsw_ucode(g); err = nvgpu_gr_falcon_init_ctxsw_ucode(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "gr_falcon_init_ctxsw_ucode failed err=%d", err); nvgpu_err(g, "gr_falcon_init_ctxsw_ucode failed err=%d", err);
return err; return err;

View File

@@ -1483,7 +1483,7 @@ void nvgpu_channel_recover(struct gk20a *g, struct channel_gk20a *ch,
/* stop context switching to prevent engine assignments from /* stop context switching to prevent engine assignments from
changing until channel is recovered */ changing until channel is recovered */
nvgpu_mutex_acquire(&g->dbg_sessions_lock); nvgpu_mutex_acquire(&g->dbg_sessions_lock);
err = g->ops.gr.falcon.disable_ctxsw(g); err = g->ops.gr.falcon.disable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "failed to disable ctxsw"); nvgpu_err(g, "failed to disable ctxsw");
goto fail; goto fail;
@@ -1502,7 +1502,7 @@ void nvgpu_channel_recover(struct gk20a *g, struct channel_gk20a *ch,
} }
} }
err = g->ops.gr.falcon.enable_ctxsw(g); err = g->ops.gr.falcon.enable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "failed to enable ctxsw"); nvgpu_err(g, "failed to enable ctxsw");
} }

View File

@@ -289,7 +289,7 @@ void nvgpu_tsg_recover(struct gk20a *g, struct tsg_gk20a *tsg,
* changing until engine status is checked to make sure tsg * changing until engine status is checked to make sure tsg
* being recovered is not loaded on the engines * being recovered is not loaded on the engines
*/ */
err = g->ops.gr.falcon.disable_ctxsw(g); err = g->ops.gr.falcon.disable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
/* if failed to disable ctxsw, just abort tsg */ /* if failed to disable ctxsw, just abort tsg */
@@ -306,7 +306,7 @@ void nvgpu_tsg_recover(struct gk20a *g, struct tsg_gk20a *tsg,
* By that time if tsg is not on the engine, engine need not * By that time if tsg is not on the engine, engine need not
* be reset. * be reset.
*/ */
err = g->ops.gr.falcon.enable_ctxsw(g); err = g->ops.gr.falcon.enable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "failed to enable ctxsw"); nvgpu_err(g, "failed to enable ctxsw");
} }

View File

@@ -271,6 +271,9 @@ static void gr_remove_support(struct gr_gk20a *gr)
nvgpu_gr_hwpm_map_deinit(g, gr->hwpm_map); nvgpu_gr_hwpm_map_deinit(g, gr->hwpm_map);
nvgpu_gr_falcon_remove_support(g, gr->falcon);
gr->falcon = NULL;
nvgpu_ecc_remove_support(g); nvgpu_ecc_remove_support(g);
nvgpu_gr_zbc_deinit(g, gr->zbc); nvgpu_gr_zbc_deinit(g, gr->zbc);
nvgpu_gr_zcull_deinit(g, gr->zcull); nvgpu_gr_zcull_deinit(g, gr->zcull);
@@ -498,7 +501,31 @@ out:
return 0; return 0;
} }
static void gr_init_prepare(struct gk20a *g) int nvgpu_gr_prepare_sw(struct gk20a *g)
{
struct gr_gk20a *gr = &g->gr;
int err = 0;
nvgpu_log_fn(g, " ");
err = nvgpu_netlist_init_ctx_vars(g);
if (err != 0) {
nvgpu_err(g, "failed to parse netlist");
return err;
}
if (gr->falcon == NULL) {
gr->falcon = nvgpu_gr_falcon_init_support(g);
if (gr->falcon == NULL) {
nvgpu_err(g, "failed to init gr falcon");
err = -ENOMEM;
return err;
}
}
return err;
}
static void gr_init_prepare_hw(struct gk20a *g)
{ {
/* reset gr engine */ /* reset gr engine */
g->ops.mc.reset(g, g->ops.mc.reset_mask(g, NVGPU_UNIT_GRAPH) | g->ops.mc.reset(g, g->ops.mc.reset_mask(g, NVGPU_UNIT_GRAPH) |
@@ -520,13 +547,7 @@ int nvgpu_gr_enable_hw(struct gk20a *g)
nvgpu_log_fn(g, " "); nvgpu_log_fn(g, " ");
gr_init_prepare(g); gr_init_prepare_hw(g);
err = nvgpu_netlist_init_ctx_vars(g);
if (err != 0) {
nvgpu_err(g, "failed to parse netlist");
return err;
}
err = gr_init_reset_enable_hw(g); err = gr_init_reset_enable_hw(g);
if (err != 0) { if (err != 0) {
@@ -541,30 +562,32 @@ int nvgpu_gr_enable_hw(struct gk20a *g)
int nvgpu_gr_reset(struct gk20a *g) int nvgpu_gr_reset(struct gk20a *g)
{ {
int err; int err;
struct nvgpu_mutex *fecs_mutex =
nvgpu_gr_falcon_get_fecs_mutex(g->gr.falcon);
g->gr.initialized = false; g->gr.initialized = false;
nvgpu_mutex_acquire(&g->gr.fecs_mutex); nvgpu_mutex_acquire(fecs_mutex);
err = nvgpu_gr_enable_hw(g); err = nvgpu_gr_enable_hw(g);
if (err != 0) { if (err != 0) {
nvgpu_mutex_release(&g->gr.fecs_mutex); nvgpu_mutex_release(fecs_mutex);
return err; return err;
} }
err = gr_init_setup_hw(g); err = gr_init_setup_hw(g);
if (err != 0) { if (err != 0) {
nvgpu_mutex_release(&g->gr.fecs_mutex); nvgpu_mutex_release(fecs_mutex);
return err; return err;
} }
err = nvgpu_gr_falcon_init_ctxsw(g); err = nvgpu_gr_falcon_init_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_mutex_release(&g->gr.fecs_mutex); nvgpu_mutex_release(fecs_mutex);
return err; return err;
} }
nvgpu_mutex_release(&g->gr.fecs_mutex); nvgpu_mutex_release(fecs_mutex);
/* this appears query for sw states but fecs actually init /* this appears query for sw states but fecs actually init
ramchain, etc so this is hw init */ ramchain, etc so this is hw init */
@@ -598,14 +621,7 @@ int nvgpu_gr_init_support(struct gk20a *g)
g->gr.initialized = false; g->gr.initialized = false;
/* this is required before gr_gk20a_init_ctx_state */ err = nvgpu_gr_falcon_init_ctxsw(g, g->gr.falcon);
err = nvgpu_mutex_init(&g->gr.fecs_mutex);
if (err != 0) {
nvgpu_err(g, "Error in gr.fecs_mutex initialization");
return err;
}
err = nvgpu_gr_falcon_init_ctxsw(g);
if (err != 0) { if (err != 0) {
return err; return err;
} }

View File

@@ -37,6 +37,53 @@
#include "gr_falcon_priv.h" #include "gr_falcon_priv.h"
#define NVGPU_FECS_UCODE_IMAGE "fecs.bin"
#define NVGPU_GPCCS_UCODE_IMAGE "gpccs.bin"
struct nvgpu_gr_falcon *nvgpu_gr_falcon_init_support(struct gk20a *g)
{
struct nvgpu_gr_falcon *falcon;
int err = 0;
nvgpu_log_fn(g, " ");
falcon = nvgpu_kzalloc(g, sizeof(*falcon));
if (falcon == NULL) {
return falcon;
}
err = nvgpu_mutex_init(&falcon->ctxsw_disable_mutex);
if (err != 0) {
nvgpu_err(g, "Error in ctxsw_disable_mutex init");
goto done;
}
falcon->ctxsw_disable_count = 0;
err = nvgpu_mutex_init(&falcon->fecs_mutex);
if (err != 0) {
nvgpu_err(g, "Error in fecs_mutex init");
goto done;
}
done:
if (err != 0) {
nvgpu_kfree(g, falcon);
falcon = NULL;
}
return falcon;
}
void nvgpu_gr_falcon_remove_support(struct gk20a *g,
struct nvgpu_gr_falcon *falcon)
{
nvgpu_log_fn(g, " ");
if (falcon == NULL) {
return;
}
nvgpu_kfree(g, falcon);
}
int nvgpu_gr_falcon_bind_fecs_elpg(struct gk20a *g) int nvgpu_gr_falcon_bind_fecs_elpg(struct gk20a *g)
{ {
struct nvgpu_pmu *pmu = &g->pmu; struct nvgpu_pmu *pmu = &g->pmu;
@@ -88,13 +135,13 @@ int nvgpu_gr_falcon_bind_fecs_elpg(struct gk20a *g)
return err; return err;
} }
int nvgpu_gr_falcon_init_ctxsw(struct gk20a *g) int nvgpu_gr_falcon_init_ctxsw(struct gk20a *g, struct nvgpu_gr_falcon *falcon)
{ {
int err = 0; int err = 0;
nvgpu_log_fn(g, " "); nvgpu_log_fn(g, " ");
err = g->ops.gr.falcon.load_ctxsw_ucode(g); err = g->ops.gr.falcon.load_ctxsw_ucode(g, falcon);
if (err != 0) { if (err != 0) {
goto out; goto out;
} }
@@ -145,11 +192,12 @@ out:
return err; return err;
} }
static int nvgpu_gr_falcon_init_ctxsw_ucode_vaspace(struct gk20a *g) static int nvgpu_gr_falcon_init_ctxsw_ucode_vaspace(struct gk20a *g,
struct nvgpu_gr_falcon *falcon)
{ {
struct mm_gk20a *mm = &g->mm; struct mm_gk20a *mm = &g->mm;
struct vm_gk20a *vm = mm->pmu.vm; struct vm_gk20a *vm = mm->pmu.vm;
struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; struct nvgpu_ctxsw_ucode_info *ucode_info = &falcon->ctxsw_ucode_info;
int err; int err;
err = g->ops.mm.alloc_inst_block(g, &ucode_info->inst_blk_desc); err = g->ops.mm.alloc_inst_block(g, &ucode_info->inst_blk_desc);
@@ -176,7 +224,7 @@ static int nvgpu_gr_falcon_init_ctxsw_ucode_vaspace(struct gk20a *g)
} }
static void nvgpu_gr_falcon_init_ctxsw_ucode_segment( static void nvgpu_gr_falcon_init_ctxsw_ucode_segment(
struct gk20a_ctxsw_ucode_segment *p_seg, u32 *offset, u32 size) struct nvgpu_ctxsw_ucode_segment *p_seg, u32 *offset, u32 size)
{ {
p_seg->offset = *offset; p_seg->offset = *offset;
p_seg->size = size; p_seg->size = size;
@@ -184,7 +232,7 @@ static void nvgpu_gr_falcon_init_ctxsw_ucode_segment(
} }
static void nvgpu_gr_falcon_init_ctxsw_ucode_segments( static void nvgpu_gr_falcon_init_ctxsw_ucode_segments(
struct gk20a_ctxsw_ucode_segments *segments, u32 *offset, struct nvgpu_ctxsw_ucode_segments *segments, u32 *offset,
struct nvgpu_ctxsw_bootloader_desc *bootdesc, struct nvgpu_ctxsw_bootloader_desc *bootdesc,
u32 code_size, u32 data_size) u32 code_size, u32 data_size)
{ {
@@ -203,7 +251,7 @@ static void nvgpu_gr_falcon_init_ctxsw_ucode_segments(
static int nvgpu_gr_falcon_copy_ctxsw_ucode_segments( static int nvgpu_gr_falcon_copy_ctxsw_ucode_segments(
struct gk20a *g, struct gk20a *g,
struct nvgpu_mem *dst, struct nvgpu_mem *dst,
struct gk20a_ctxsw_ucode_segments *segments, struct nvgpu_ctxsw_ucode_segments *segments,
u32 *bootimage, u32 *bootimage,
u32 *code, u32 *data) u32 *code, u32 *data)
{ {
@@ -225,7 +273,8 @@ static int nvgpu_gr_falcon_copy_ctxsw_ucode_segments(
return 0; return 0;
} }
int nvgpu_gr_falcon_init_ctxsw_ucode(struct gk20a *g) int nvgpu_gr_falcon_init_ctxsw_ucode(struct gk20a *g,
struct nvgpu_gr_falcon *falcon)
{ {
struct mm_gk20a *mm = &g->mm; struct mm_gk20a *mm = &g->mm;
struct vm_gk20a *vm = mm->pmu.vm; struct vm_gk20a *vm = mm->pmu.vm;
@@ -235,11 +284,11 @@ int nvgpu_gr_falcon_init_ctxsw_ucode(struct gk20a *g)
struct nvgpu_firmware *gpccs_fw; struct nvgpu_firmware *gpccs_fw;
u32 *fecs_boot_image; u32 *fecs_boot_image;
u32 *gpccs_boot_image; u32 *gpccs_boot_image;
struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; struct nvgpu_ctxsw_ucode_info *ucode_info = &falcon->ctxsw_ucode_info;
u32 ucode_size; u32 ucode_size;
int err = 0; int err = 0;
fecs_fw = nvgpu_request_firmware(g, GK20A_FECS_UCODE_IMAGE, 0); fecs_fw = nvgpu_request_firmware(g, NVGPU_FECS_UCODE_IMAGE, 0);
if (fecs_fw == NULL) { if (fecs_fw == NULL) {
nvgpu_err(g, "failed to load fecs ucode!!"); nvgpu_err(g, "failed to load fecs ucode!!");
return -ENOENT; return -ENOENT;
@@ -249,7 +298,7 @@ int nvgpu_gr_falcon_init_ctxsw_ucode(struct gk20a *g)
fecs_boot_image = (void *)(fecs_fw->data + fecs_boot_image = (void *)(fecs_fw->data +
sizeof(struct nvgpu_ctxsw_bootloader_desc)); sizeof(struct nvgpu_ctxsw_bootloader_desc));
gpccs_fw = nvgpu_request_firmware(g, GK20A_GPCCS_UCODE_IMAGE, 0); gpccs_fw = nvgpu_request_firmware(g, NVGPU_GPCCS_UCODE_IMAGE, 0);
if (gpccs_fw == NULL) { if (gpccs_fw == NULL) {
nvgpu_release_firmware(g, fecs_fw); nvgpu_release_firmware(g, fecs_fw);
nvgpu_err(g, "failed to load gpccs ucode!!"); nvgpu_err(g, "failed to load gpccs ucode!!");
@@ -293,7 +342,7 @@ int nvgpu_gr_falcon_init_ctxsw_ucode(struct gk20a *g)
nvgpu_release_firmware(g, gpccs_fw); nvgpu_release_firmware(g, gpccs_fw);
gpccs_fw = NULL; gpccs_fw = NULL;
err = nvgpu_gr_falcon_init_ctxsw_ucode_vaspace(g); err = nvgpu_gr_falcon_init_ctxsw_ucode_vaspace(g, falcon);
if (err != 0) { if (err != 0) {
goto clean_up; goto clean_up;
} }
@@ -352,9 +401,11 @@ static void nvgpu_gr_falcon_load_imem(struct gk20a *g)
nvgpu_log_fn(g, "done"); nvgpu_log_fn(g, "done");
} }
static void nvgpu_gr_falcon_bind_instblk(struct gk20a *g) static void nvgpu_gr_falcon_bind_instblk(struct gk20a *g,
struct nvgpu_gr_falcon *falcon)
{ {
struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; struct nvgpu_ctxsw_ucode_info *ucode_info =
&falcon->ctxsw_ucode_info;
u64 inst_ptr; u64 inst_ptr;
inst_ptr = nvgpu_inst_block_addr(g, &ucode_info->inst_blk_desc); inst_ptr = nvgpu_inst_block_addr(g, &ucode_info->inst_blk_desc);
@@ -365,7 +416,7 @@ static void nvgpu_gr_falcon_bind_instblk(struct gk20a *g)
} }
static void nvgpu_gr_falcon_load_ctxsw_ucode_header(struct gk20a *g, static void nvgpu_gr_falcon_load_ctxsw_ucode_header(struct gk20a *g,
u64 addr_base, struct gk20a_ctxsw_ucode_segments *segments, u64 addr_base, struct nvgpu_ctxsw_ucode_segments *segments,
u32 reg_offset) u32 reg_offset)
{ {
u32 addr_code32 = u64_lo32((addr_base + segments->code.offset) >> 8); u32 addr_code32 = u64_lo32((addr_base + segments->code.offset) >> 8);
@@ -377,7 +428,7 @@ static void nvgpu_gr_falcon_load_ctxsw_ucode_header(struct gk20a *g,
} }
static void nvgpu_gr_falcon_load_ctxsw_ucode_boot(struct gk20a *g, static void nvgpu_gr_falcon_load_ctxsw_ucode_boot(struct gk20a *g,
u64 addr_base, struct gk20a_ctxsw_ucode_segments *segments, u64 addr_base, struct nvgpu_ctxsw_ucode_segments *segments,
u32 reg_offset) u32 reg_offset)
{ {
u32 addr_load32 = u64_lo32((addr_base + segments->boot.offset) >> 8); u32 addr_load32 = u64_lo32((addr_base + segments->boot.offset) >> 8);
@@ -391,7 +442,7 @@ static void nvgpu_gr_falcon_load_ctxsw_ucode_boot(struct gk20a *g,
static void nvgpu_gr_falcon_load_ctxsw_ucode_segments( static void nvgpu_gr_falcon_load_ctxsw_ucode_segments(
struct gk20a *g, u64 addr_base, struct gk20a *g, u64 addr_base,
struct gk20a_ctxsw_ucode_segments *segments, u32 reg_offset) struct nvgpu_ctxsw_ucode_segments *segments, u32 reg_offset)
{ {
/* Copy falcon bootloader into dmem */ /* Copy falcon bootloader into dmem */
@@ -402,24 +453,28 @@ static void nvgpu_gr_falcon_load_ctxsw_ucode_segments(
} }
static void nvgpu_gr_falcon_load_with_bootloader(struct gk20a *g) static void nvgpu_gr_falcon_load_with_bootloader(struct gk20a *g,
struct nvgpu_gr_falcon *falcon)
{ {
struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; struct nvgpu_ctxsw_ucode_info *ucode_info =
&falcon->ctxsw_ucode_info;
u64 addr_base = ucode_info->surface_desc.gpu_va; u64 addr_base = ucode_info->surface_desc.gpu_va;
nvgpu_gr_falcon_bind_instblk(g); nvgpu_gr_falcon_bind_instblk(g, falcon);
nvgpu_gr_falcon_load_ctxsw_ucode_segments(g, addr_base, nvgpu_gr_falcon_load_ctxsw_ucode_segments(g, addr_base,
&g->ctxsw_ucode_info.fecs, 0); &falcon->ctxsw_ucode_info.fecs, 0);
nvgpu_gr_falcon_load_ctxsw_ucode_segments(g, addr_base, nvgpu_gr_falcon_load_ctxsw_ucode_segments(g, addr_base,
&g->ctxsw_ucode_info.gpccs, &falcon->ctxsw_ucode_info.gpccs,
g->ops.gr.falcon.get_gpccs_start_reg_offset()); g->ops.gr.falcon.get_gpccs_start_reg_offset());
} }
int nvgpu_gr_falcon_load_ctxsw_ucode(struct gk20a *g) int nvgpu_gr_falcon_load_ctxsw_ucode(struct gk20a *g,
struct nvgpu_gr_falcon *falcon)
{ {
int err; int err;
struct gr_gk20a *gr = &g->gr;
nvgpu_log_fn(g, " "); nvgpu_log_fn(g, " ");
@@ -436,32 +491,35 @@ int nvgpu_gr_falcon_load_ctxsw_ucode(struct gk20a *g)
nvgpu_gr_falcon_load_imem(g); nvgpu_gr_falcon_load_imem(g);
g->ops.gr.falcon.start_ucode(g); g->ops.gr.falcon.start_ucode(g);
} else { } else {
if (!g->gr.skip_ucode_init) { if (!gr->falcon->skip_ucode_init) {
err = nvgpu_gr_falcon_init_ctxsw_ucode(g); err = nvgpu_gr_falcon_init_ctxsw_ucode(g, falcon);
if (err != 0) { if (err != 0) {
return err; return err;
} }
} }
nvgpu_gr_falcon_load_with_bootloader(g); nvgpu_gr_falcon_load_with_bootloader(g, falcon);
g->gr.skip_ucode_init = true; gr->falcon->skip_ucode_init = true;
} }
nvgpu_log_fn(g, "done"); nvgpu_log_fn(g, "done");
return 0; return 0;
} }
static void nvgpu_gr_falcon_load_gpccs_with_bootloader(struct gk20a *g) static void nvgpu_gr_falcon_load_gpccs_with_bootloader(struct gk20a *g,
struct nvgpu_gr_falcon *falcon)
{ {
struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; struct nvgpu_ctxsw_ucode_info *ucode_info =
&falcon->ctxsw_ucode_info;
u64 addr_base = ucode_info->surface_desc.gpu_va; u64 addr_base = ucode_info->surface_desc.gpu_va;
nvgpu_gr_falcon_bind_instblk(g); nvgpu_gr_falcon_bind_instblk(g, falcon);
nvgpu_gr_falcon_load_ctxsw_ucode_segments(g, addr_base, nvgpu_gr_falcon_load_ctxsw_ucode_segments(g, addr_base,
&g->ctxsw_ucode_info.gpccs, &falcon->ctxsw_ucode_info.gpccs,
g->ops.gr.falcon.get_gpccs_start_reg_offset()); g->ops.gr.falcon.get_gpccs_start_reg_offset());
} }
int nvgpu_gr_falcon_load_secure_ctxsw_ucode(struct gk20a *g) int nvgpu_gr_falcon_load_secure_ctxsw_ucode(struct gk20a *g,
struct nvgpu_gr_falcon *falcon)
{ {
int err = 0; int err = 0;
u8 falcon_id_mask = 0; u8 falcon_id_mask = 0;
@@ -475,12 +533,12 @@ int nvgpu_gr_falcon_load_secure_ctxsw_ucode(struct gk20a *g)
if (nvgpu_is_enabled(g, NVGPU_PMU_FECS_BOOTSTRAP_DONE)) { if (nvgpu_is_enabled(g, NVGPU_PMU_FECS_BOOTSTRAP_DONE)) {
/* this must be recovery so bootstrap fecs and gpccs */ /* this must be recovery so bootstrap fecs and gpccs */
if (!nvgpu_is_enabled(g, NVGPU_SEC_SECUREGPCCS)) { if (!nvgpu_is_enabled(g, NVGPU_SEC_SECUREGPCCS)) {
nvgpu_gr_falcon_load_gpccs_with_bootloader(g); nvgpu_gr_falcon_load_gpccs_with_bootloader(g, falcon);
err = nvgpu_pmu_lsfm_bootstrap_ls_falcon(g, &g->pmu, err = nvgpu_pmu_lsfm_bootstrap_ls_falcon(g, &g->pmu,
g->pmu.lsfm, BIT32(FALCON_ID_FECS)); g->pmu.lsfm, BIT32(FALCON_ID_FECS));
} else { } else {
/* bind WPR VA inst block */ /* bind WPR VA inst block */
nvgpu_gr_falcon_bind_instblk(g); nvgpu_gr_falcon_bind_instblk(g, falcon);
if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SEC2_RTOS)) { if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SEC2_RTOS)) {
err = nvgpu_sec2_bootstrap_ls_falcons(g, err = nvgpu_sec2_bootstrap_ls_falcons(g,
&g->sec2, FALCON_ID_FECS); &g->sec2, FALCON_ID_FECS);
@@ -508,10 +566,10 @@ int nvgpu_gr_falcon_load_secure_ctxsw_ucode(struct gk20a *g)
/* cold boot or rg exit */ /* cold boot or rg exit */
nvgpu_set_enabled(g, NVGPU_PMU_FECS_BOOTSTRAP_DONE, true); nvgpu_set_enabled(g, NVGPU_PMU_FECS_BOOTSTRAP_DONE, true);
if (!nvgpu_is_enabled(g, NVGPU_SEC_SECUREGPCCS)) { if (!nvgpu_is_enabled(g, NVGPU_SEC_SECUREGPCCS)) {
nvgpu_gr_falcon_load_gpccs_with_bootloader(g); nvgpu_gr_falcon_load_gpccs_with_bootloader(g, falcon);
} else { } else {
/* bind WPR VA inst block */ /* bind WPR VA inst block */
nvgpu_gr_falcon_bind_instblk(g); nvgpu_gr_falcon_bind_instblk(g, falcon);
if (nvgpu_acr_is_lsf_lazy_bootstrap(g, g->acr, if (nvgpu_acr_is_lsf_lazy_bootstrap(g, g->acr,
FALCON_ID_FECS)) { FALCON_ID_FECS)) {
falcon_id_mask |= BIT8(FALCON_ID_FECS); falcon_id_mask |= BIT8(FALCON_ID_FECS);
@@ -558,53 +616,55 @@ int nvgpu_gr_falcon_load_secure_ctxsw_ucode(struct gk20a *g)
* to pmu elpg sequence. It could come as pmu halt or abort or * to pmu elpg sequence. It could come as pmu halt or abort or
* maybe ext error too. * maybe ext error too.
*/ */
int nvgpu_gr_falcon_disable_ctxsw(struct gk20a *g) int nvgpu_gr_falcon_disable_ctxsw(struct gk20a *g,
struct nvgpu_gr_falcon *falcon)
{ {
int err = 0; int err = 0;
nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " ");
nvgpu_mutex_acquire(&g->ctxsw_disable_lock); nvgpu_mutex_acquire(&falcon->ctxsw_disable_mutex);
g->ctxsw_disable_count++; falcon->ctxsw_disable_count++;
if (g->ctxsw_disable_count == 1) { if (falcon->ctxsw_disable_count == 1) {
err = nvgpu_pg_elpg_disable(g); err = nvgpu_pg_elpg_disable(g);
if (err != 0) { if (err != 0) {
nvgpu_err(g, nvgpu_err(g,
"failed to disable elpg for stop_ctxsw"); "failed to disable elpg for stop_ctxsw");
/* stop ctxsw command is not sent */ /* stop ctxsw command is not sent */
g->ctxsw_disable_count--; falcon->ctxsw_disable_count--;
} else { } else {
err = g->ops.gr.falcon.ctrl_ctxsw(g, err = g->ops.gr.falcon.ctrl_ctxsw(g,
NVGPU_GR_FALCON_METHOD_CTXSW_STOP, 0U, NULL); NVGPU_GR_FALCON_METHOD_CTXSW_STOP, 0U, NULL);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "failed to stop fecs ctxsw"); nvgpu_err(g, "failed to stop fecs ctxsw");
/* stop ctxsw failed */ /* stop ctxsw failed */
g->ctxsw_disable_count--; falcon->ctxsw_disable_count--;
} }
} }
} else { } else {
nvgpu_log_info(g, "ctxsw disabled, ctxsw_disable_count: %d", nvgpu_log_info(g, "ctxsw disabled, ctxsw_disable_count: %d",
g->ctxsw_disable_count); falcon->ctxsw_disable_count);
} }
nvgpu_mutex_release(&g->ctxsw_disable_lock); nvgpu_mutex_release(&falcon->ctxsw_disable_mutex);
return err; return err;
} }
/* Start processing (continue) context switches at FECS */ /* Start processing (continue) context switches at FECS */
int nvgpu_gr_falcon_enable_ctxsw(struct gk20a *g) int nvgpu_gr_falcon_enable_ctxsw(struct gk20a *g,
struct nvgpu_gr_falcon *falcon)
{ {
int err = 0; int err = 0;
nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " "); nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " ");
nvgpu_mutex_acquire(&g->ctxsw_disable_lock); nvgpu_mutex_acquire(&falcon->ctxsw_disable_mutex);
if (g->ctxsw_disable_count == 0) { if (falcon->ctxsw_disable_count == 0) {
goto ctxsw_already_enabled; goto ctxsw_already_enabled;
} }
g->ctxsw_disable_count--; falcon->ctxsw_disable_count--;
WARN_ON(g->ctxsw_disable_count < 0); WARN_ON(falcon->ctxsw_disable_count < 0);
if (g->ctxsw_disable_count == 0) { if (falcon->ctxsw_disable_count == 0) {
err = g->ops.gr.falcon.ctrl_ctxsw(g, err = g->ops.gr.falcon.ctrl_ctxsw(g,
NVGPU_GR_FALCON_METHOD_CTXSW_START, 0U, NULL); NVGPU_GR_FALCON_METHOD_CTXSW_START, 0U, NULL);
if (err != 0) { if (err != 0) {
@@ -617,10 +677,10 @@ int nvgpu_gr_falcon_enable_ctxsw(struct gk20a *g)
} }
} else { } else {
nvgpu_log_info(g, "ctxsw_disable_count: %d is not 0 yet", nvgpu_log_info(g, "ctxsw_disable_count: %d is not 0 yet",
g->ctxsw_disable_count); falcon->ctxsw_disable_count);
} }
ctxsw_already_enabled: ctxsw_already_enabled:
nvgpu_mutex_release(&g->ctxsw_disable_lock); nvgpu_mutex_release(&falcon->ctxsw_disable_mutex);
return err; return err;
} }
@@ -630,3 +690,23 @@ int nvgpu_gr_falcon_halt_pipe(struct gk20a *g)
return g->ops.gr.falcon.ctrl_ctxsw(g, return g->ops.gr.falcon.ctrl_ctxsw(g,
NVGPU_GR_FALCON_METHOD_HALT_PIPELINE, 0U, NULL); NVGPU_GR_FALCON_METHOD_HALT_PIPELINE, 0U, NULL);
} }
struct nvgpu_mutex *nvgpu_gr_falcon_get_fecs_mutex(
struct nvgpu_gr_falcon *falcon)
{
return &falcon->fecs_mutex;
}
struct nvgpu_ctxsw_ucode_segments *nvgpu_gr_falcon_get_fecs_ucode_segments(
struct nvgpu_gr_falcon *falcon)
{
return &falcon->ctxsw_ucode_info.fecs;
}
struct nvgpu_ctxsw_ucode_segments *nvgpu_gr_falcon_get_gpccs_ucode_segments(
struct nvgpu_gr_falcon *falcon)
{
return &falcon->ctxsw_ucode_info.gpccs;
}
void *nvgpu_gr_falcon_get_surface_desc_cpu_va(struct nvgpu_gr_falcon *falcon)
{
return falcon->ctxsw_ucode_info.surface_desc.cpu_va;
}

View File

@@ -24,6 +24,9 @@
#define GR_FALOCN_PRIV_H #define GR_FALOCN_PRIV_H
#include <nvgpu/types.h> #include <nvgpu/types.h>
#include <nvgpu/nvgpu_mem.h>
struct nvgpu_ctxsw_ucode_segments;
struct nvgpu_fecs_method_op { struct nvgpu_fecs_method_op {
struct { struct {
@@ -54,5 +57,66 @@ struct nvgpu_ctxsw_bootloader_desc {
u32 entry_point; u32 entry_point;
}; };
struct nvgpu_ctxsw_ucode_info {
u64 *p_va;
struct nvgpu_mem inst_blk_desc;
struct nvgpu_mem surface_desc;
struct nvgpu_ctxsw_ucode_segments fecs;
struct nvgpu_ctxsw_ucode_segments gpccs;
};
struct nvgpu_gr_falcon {
struct nvgpu_ctxsw_ucode_info ctxsw_ucode_info;
struct nvgpu_mutex ctxsw_disable_mutex;
int ctxsw_disable_count;
struct nvgpu_mutex fecs_mutex; /* protect fecs method */
bool skip_ucode_init;
};
enum wait_ucode_status {
WAIT_UCODE_LOOP,
WAIT_UCODE_TIMEOUT,
WAIT_UCODE_ERROR,
WAIT_UCODE_OK
};
enum {
GR_IS_UCODE_OP_EQUAL,
GR_IS_UCODE_OP_NOT_EQUAL,
GR_IS_UCODE_OP_AND,
GR_IS_UCODE_OP_LESSER,
GR_IS_UCODE_OP_LESSER_EQUAL,
GR_IS_UCODE_OP_SKIP
};
enum {
eUcodeHandshakeInitComplete = 1,
eUcodeHandshakeMethodFinished
};
/* sums over the ucode files as sequences of u32, computed to the
* boot_signature field in the structure above */
/* T18X FECS remains same as T21X,
* so FALCON_UCODE_SIG_T21X_FECS_WITH_RESERVED used
* for T18X*/
#define FALCON_UCODE_SIG_T18X_GPCCS_WITH_RESERVED 0x68edab34U
#define FALCON_UCODE_SIG_T21X_FECS_WITH_DMEM_SIZE 0x9121ab5cU
#define FALCON_UCODE_SIG_T21X_FECS_WITH_RESERVED 0x9125ab5cU
#define FALCON_UCODE_SIG_T12X_FECS_WITH_RESERVED 0x8a621f78U
#define FALCON_UCODE_SIG_T12X_FECS_WITHOUT_RESERVED 0x67e5344bU
#define FALCON_UCODE_SIG_T12X_FECS_OLDER 0x56da09fU
#define FALCON_UCODE_SIG_T21X_GPCCS_WITH_RESERVED 0x3d3d65e2U
#define FALCON_UCODE_SIG_T12X_GPCCS_WITH_RESERVED 0x303465d5U
#define FALCON_UCODE_SIG_T12X_GPCCS_WITHOUT_RESERVED 0x3fdd33d3U
#define FALCON_UCODE_SIG_T12X_GPCCS_OLDER 0x53d7877U
#define FALCON_UCODE_SIG_T21X_FECS_WITHOUT_RESERVED 0x93671b7dU
#define FALCON_UCODE_SIG_T21X_FECS_WITHOUT_RESERVED2 0x4d6cbc10U
#define FALCON_UCODE_SIG_T21X_GPCCS_WITHOUT_RESERVED 0x393161daU
#endif /* GR_FALOCN_PRIV_H */ #endif /* GR_FALOCN_PRIV_H */

View File

@@ -331,6 +331,14 @@ int gk20a_finalize_poweron(struct gk20a *g)
} }
} }
/* prepare portion of sw required for enable hw */
err = nvgpu_gr_prepare_sw(g);
if (err != 0) {
nvgpu_err(g, "failed to prepare sw");
nvgpu_mutex_release(&g->tpc_pg_lock);
goto done;
}
err = nvgpu_gr_enable_hw(g); err = nvgpu_gr_enable_hw(g);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "failed to enable gr"); nvgpu_err(g, "failed to enable gr");

View File

@@ -176,7 +176,7 @@ int gk20a_fifo_deferred_reset(struct gk20a *g, struct channel_gk20a *ch)
return 0; return 0;
} }
err = g->ops.gr.falcon.disable_ctxsw(g); err = g->ops.gr.falcon.disable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "failed to disable ctxsw"); nvgpu_err(g, "failed to disable ctxsw");
goto fail; goto fail;
@@ -211,7 +211,7 @@ int gk20a_fifo_deferred_reset(struct gk20a *g, struct channel_gk20a *ch)
nvgpu_mutex_release(&f->deferred_reset_mutex); nvgpu_mutex_release(&f->deferred_reset_mutex);
clean_up: clean_up:
err = g->ops.gr.falcon.enable_ctxsw(g); err = g->ops.gr.falcon.enable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "failed to enable ctxsw"); nvgpu_err(g, "failed to enable ctxsw");
} }

View File

@@ -2326,7 +2326,7 @@ int gr_gk20a_exec_ctx_ops(struct channel_gk20a *ch,
* at that point the hardware state can be inspected to * at that point the hardware state can be inspected to
* determine if the context we're interested in is current. * determine if the context we're interested in is current.
*/ */
err = g->ops.gr.falcon.disable_ctxsw(g); err = g->ops.gr.falcon.disable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "unable to stop gr ctxsw"); nvgpu_err(g, "unable to stop gr ctxsw");
/* this should probably be ctx-fatal... */ /* this should probably be ctx-fatal... */
@@ -2343,7 +2343,7 @@ int gr_gk20a_exec_ctx_ops(struct channel_gk20a *ch,
err = __gr_gk20a_exec_ctx_ops(ch, ctx_ops, num_ops, num_ctx_wr_ops, err = __gr_gk20a_exec_ctx_ops(ch, ctx_ops, num_ops, num_ctx_wr_ops,
num_ctx_rd_ops, ch_is_curr_ctx); num_ctx_rd_ops, ch_is_curr_ctx);
tmp_err = g->ops.gr.falcon.enable_ctxsw(g); tmp_err = g->ops.gr.falcon.enable_ctxsw(g, g->gr.falcon);
if (tmp_err != 0) { if (tmp_err != 0) {
nvgpu_err(g, "unable to restart ctxsw!"); nvgpu_err(g, "unable to restart ctxsw!");
err = tmp_err; err = tmp_err;
@@ -2689,7 +2689,7 @@ int gr_gk20a_suspend_contexts(struct gk20a *g,
nvgpu_mutex_acquire(&g->dbg_sessions_lock); nvgpu_mutex_acquire(&g->dbg_sessions_lock);
err = g->ops.gr.falcon.disable_ctxsw(g); err = g->ops.gr.falcon.disable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "unable to stop gr ctxsw"); nvgpu_err(g, "unable to stop gr ctxsw");
goto clean_up; goto clean_up;
@@ -2709,7 +2709,7 @@ int gr_gk20a_suspend_contexts(struct gk20a *g,
nvgpu_mutex_release(&dbg_s->ch_list_lock); nvgpu_mutex_release(&dbg_s->ch_list_lock);
err = g->ops.gr.falcon.enable_ctxsw(g); err = g->ops.gr.falcon.enable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "unable to restart ctxsw!"); nvgpu_err(g, "unable to restart ctxsw!");
} }
@@ -2734,7 +2734,7 @@ int gr_gk20a_resume_contexts(struct gk20a *g,
nvgpu_mutex_acquire(&g->dbg_sessions_lock); nvgpu_mutex_acquire(&g->dbg_sessions_lock);
err = g->ops.gr.falcon.disable_ctxsw(g); err = g->ops.gr.falcon.disable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "unable to stop gr ctxsw"); nvgpu_err(g, "unable to stop gr ctxsw");
goto clean_up; goto clean_up;
@@ -2750,7 +2750,7 @@ int gr_gk20a_resume_contexts(struct gk20a *g,
} }
} }
err = g->ops.gr.falcon.enable_ctxsw(g); err = g->ops.gr.falcon.enable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "unable to restart ctxsw!"); nvgpu_err(g, "unable to restart ctxsw!");
} }

View File

@@ -31,13 +31,8 @@
#include <nvgpu/comptags.h> #include <nvgpu/comptags.h>
#include <nvgpu/cond.h> #include <nvgpu/cond.h>
#define GR_FECS_POLL_INTERVAL 5U /* usec */
#define INVALID_MAX_WAYS 0xFFFFFFFFU #define INVALID_MAX_WAYS 0xFFFFFFFFU
#define GK20A_FECS_UCODE_IMAGE "fecs.bin"
#define GK20A_GPCCS_UCODE_IMAGE "gpccs.bin"
#define GK20A_TIMEOUT_FPGA 100000U /* 100 sec */ #define GK20A_TIMEOUT_FPGA 100000U /* 100 sec */
/* Flags to be passed to g->ops.gr.alloc_obj_ctx() */ /* Flags to be passed to g->ops.gr.alloc_obj_ctx() */
@@ -49,6 +44,7 @@ struct nvgpu_gr_ctx;
struct channel_gk20a; struct channel_gk20a;
struct nvgpu_warpstate; struct nvgpu_warpstate;
struct nvgpu_gr_ctx_desc; struct nvgpu_gr_ctx_desc;
struct nvgpu_gr_falcon;
struct nvgpu_gr_global_ctx_buffer_desc; struct nvgpu_gr_global_ctx_buffer_desc;
struct nvgpu_gr_global_ctx_local_golden_image; struct nvgpu_gr_global_ctx_local_golden_image;
struct nvgpu_gr_zbc; struct nvgpu_gr_zbc;
@@ -58,27 +54,6 @@ struct nvgpu_gr_ctx_desc;
enum ctxsw_addr_type; enum ctxsw_addr_type;
enum wait_ucode_status {
WAIT_UCODE_LOOP,
WAIT_UCODE_TIMEOUT,
WAIT_UCODE_ERROR,
WAIT_UCODE_OK
};
enum {
GR_IS_UCODE_OP_EQUAL,
GR_IS_UCODE_OP_NOT_EQUAL,
GR_IS_UCODE_OP_AND,
GR_IS_UCODE_OP_LESSER,
GR_IS_UCODE_OP_LESSER_EQUAL,
GR_IS_UCODE_OP_SKIP
};
enum {
eUcodeHandshakeInitComplete = 1,
eUcodeHandshakeMethodFinished
};
enum { enum {
ELCG_MODE = (1 << 0), ELCG_MODE = (1 << 0),
BLCG_MODE = (1 << 1), BLCG_MODE = (1 << 1),
@@ -135,7 +110,6 @@ struct gr_gk20a {
} ctx_vars; } ctx_vars;
struct nvgpu_mutex ctx_mutex; /* protect golden ctx init */ struct nvgpu_mutex ctx_mutex; /* protect golden ctx init */
struct nvgpu_mutex fecs_mutex; /* protect fecs method */
struct nvgpu_cond init_wq; struct nvgpu_cond init_wq;
bool initialized; bool initialized;
@@ -160,6 +134,8 @@ struct gr_gk20a {
struct nvgpu_gr_zbc *zbc; struct nvgpu_gr_zbc *zbc;
struct nvgpu_gr_falcon *falcon;
#define GR_CHANNEL_MAP_TLB_SIZE 2U /* must of power of 2 */ #define GR_CHANNEL_MAP_TLB_SIZE 2U /* must of power of 2 */
struct gr_channel_map_tlb_entry chid_tlb[GR_CHANNEL_MAP_TLB_SIZE]; struct gr_channel_map_tlb_entry chid_tlb[GR_CHANNEL_MAP_TLB_SIZE];
u32 channel_tlb_flush_index; u32 channel_tlb_flush_index;
@@ -167,7 +143,6 @@ struct gr_gk20a {
void (*remove_support)(struct gr_gk20a *gr); void (*remove_support)(struct gr_gk20a *gr);
bool sw_ready; bool sw_ready;
bool skip_ucode_init;
u32 fecs_feature_override_ecc_val; u32 fecs_feature_override_ecc_val;
@@ -184,50 +159,7 @@ struct gr_gk20a {
u32 max_ctxsw_ring_buffer_size; u32 max_ctxsw_ring_buffer_size;
}; };
struct gk20a_ctxsw_ucode_segment {
u32 offset;
u32 size;
};
struct gk20a_ctxsw_ucode_segments {
u32 boot_entry;
u32 boot_imem_offset;
u32 boot_signature;
struct gk20a_ctxsw_ucode_segment boot;
struct gk20a_ctxsw_ucode_segment code;
struct gk20a_ctxsw_ucode_segment data;
};
/* sums over the ucode files as sequences of u32, computed to the
* boot_signature field in the structure above */
/* T18X FECS remains same as T21X,
* so FALCON_UCODE_SIG_T21X_FECS_WITH_RESERVED used
* for T18X*/
#define FALCON_UCODE_SIG_T18X_GPCCS_WITH_RESERVED 0x68edab34U
#define FALCON_UCODE_SIG_T21X_FECS_WITH_DMEM_SIZE 0x9121ab5cU
#define FALCON_UCODE_SIG_T21X_FECS_WITH_RESERVED 0x9125ab5cU
#define FALCON_UCODE_SIG_T12X_FECS_WITH_RESERVED 0x8a621f78U
#define FALCON_UCODE_SIG_T12X_FECS_WITHOUT_RESERVED 0x67e5344bU
#define FALCON_UCODE_SIG_T12X_FECS_OLDER 0x56da09fU
#define FALCON_UCODE_SIG_T21X_GPCCS_WITH_RESERVED 0x3d3d65e2U
#define FALCON_UCODE_SIG_T12X_GPCCS_WITH_RESERVED 0x303465d5U
#define FALCON_UCODE_SIG_T12X_GPCCS_WITHOUT_RESERVED 0x3fdd33d3U
#define FALCON_UCODE_SIG_T12X_GPCCS_OLDER 0x53d7877U
#define FALCON_UCODE_SIG_T21X_FECS_WITHOUT_RESERVED 0x93671b7dU
#define FALCON_UCODE_SIG_T21X_FECS_WITHOUT_RESERVED2 0x4d6cbc10U
#define FALCON_UCODE_SIG_T21X_GPCCS_WITHOUT_RESERVED 0x393161daU
struct gk20a_ctxsw_ucode_info {
u64 *p_va;
struct nvgpu_mem inst_blk_desc;
struct nvgpu_mem surface_desc;
struct gk20a_ctxsw_ucode_segments fecs;
struct gk20a_ctxsw_ucode_segments gpccs;
};
struct nvgpu_warpstate { struct nvgpu_warpstate {
u64 valid_warps[2]; u64 valid_warps[2];

View File

@@ -695,7 +695,7 @@ int gm20b_gr_clear_sm_error_state(struct gk20a *g,
(void) memset(&tsg->sm_error_states[sm_id], 0, (void) memset(&tsg->sm_error_states[sm_id], 0,
sizeof(*tsg->sm_error_states)); sizeof(*tsg->sm_error_states));
err = g->ops.gr.falcon.disable_ctxsw(g); err = g->ops.gr.falcon.disable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "unable to stop gr ctxsw"); nvgpu_err(g, "unable to stop gr ctxsw");
goto fail; goto fail;
@@ -716,7 +716,7 @@ int gm20b_gr_clear_sm_error_state(struct gk20a *g,
0); 0);
} }
err = g->ops.gr.falcon.enable_ctxsw(g); err = g->ops.gr.falcon.enable_ctxsw(g, g->gr.falcon);
fail: fail:
nvgpu_mutex_release(&g->dbg_sessions_lock); nvgpu_mutex_release(&g->dbg_sessions_lock);

View File

@@ -57,8 +57,6 @@ void gr_gm20b_get_sm_dsm_perf_ctrl_regs(struct gk20a *g,
u32 **sm_dsm_perf_ctrl_regs, u32 **sm_dsm_perf_ctrl_regs,
u32 *ctrl_register_stride); u32 *ctrl_register_stride);
void gr_gm20b_set_gpc_tpc_mask(struct gk20a *g, u32 gpc_index); void gr_gm20b_set_gpc_tpc_mask(struct gk20a *g, u32 gpc_index);
void gr_gm20b_load_ctxsw_ucode_segments(struct gk20a *g, u64 addr_base,
struct gk20a_ctxsw_ucode_segments *segments, u32 reg_offset);
bool gr_gm20b_is_tpc_addr(struct gk20a *g, u32 addr); bool gr_gm20b_is_tpc_addr(struct gk20a *g, u32 addr);
u32 gr_gm20b_get_tpc_num(struct gk20a *g, u32 addr); u32 gr_gm20b_get_tpc_num(struct gk20a *g, u32 addr);
int gr_gm20b_dump_gr_status_regs(struct gk20a *g, int gr_gm20b_dump_gr_status_regs(struct gk20a *g,

View File

@@ -1053,7 +1053,7 @@ int gr_gp10b_suspend_contexts(struct gk20a *g,
nvgpu_mutex_acquire(&g->dbg_sessions_lock); nvgpu_mutex_acquire(&g->dbg_sessions_lock);
err = g->ops.gr.falcon.disable_ctxsw(g); err = g->ops.gr.falcon.disable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "unable to stop gr ctxsw"); nvgpu_err(g, "unable to stop gr ctxsw");
nvgpu_mutex_release(&g->dbg_sessions_lock); nvgpu_mutex_release(&g->dbg_sessions_lock);
@@ -1078,7 +1078,7 @@ int gr_gp10b_suspend_contexts(struct gk20a *g,
nvgpu_mutex_release(&dbg_s->ch_list_lock); nvgpu_mutex_release(&dbg_s->ch_list_lock);
err = g->ops.gr.falcon.enable_ctxsw(g); err = g->ops.gr.falcon.enable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_mutex_release(&g->dbg_sessions_lock); nvgpu_mutex_release(&g->dbg_sessions_lock);
goto clean_up; goto clean_up;

View File

@@ -3185,7 +3185,7 @@ int gv11b_gr_clear_sm_error_state(struct gk20a *g,
(void)memset(&tsg->sm_error_states[sm_id], 0, sizeof(*tsg->sm_error_states)); (void)memset(&tsg->sm_error_states[sm_id], 0, sizeof(*tsg->sm_error_states));
err = g->ops.gr.falcon.disable_ctxsw(g); err = g->ops.gr.falcon.disable_ctxsw(g, g->gr.falcon);
if (err != 0) { if (err != 0) {
nvgpu_err(g, "unable to stop gr ctxsw"); nvgpu_err(g, "unable to stop gr ctxsw");
goto fail; goto fail;
@@ -3217,7 +3217,7 @@ int gv11b_gr_clear_sm_error_state(struct gk20a *g,
0); 0);
} }
err = g->ops.gr.falcon.enable_ctxsw(g); err = g->ops.gr.falcon.enable_ctxsw(g, g->gr.falcon);
fail: fail:
nvgpu_mutex_release(&g->dbg_sessions_lock); nvgpu_mutex_release(&g->dbg_sessions_lock);

View File

@@ -33,6 +33,8 @@
#include <nvgpu/hw/gm20b/hw_gr_gm20b.h> #include <nvgpu/hw/gm20b/hw_gr_gm20b.h>
#include <nvgpu/hw/gm20b/hw_ram_gm20b.h> #include <nvgpu/hw/gm20b/hw_ram_gm20b.h>
#define GR_FECS_POLL_INTERVAL 5U /* usec */
#define FECS_ARB_CMD_TIMEOUT_MAX_US 40U #define FECS_ARB_CMD_TIMEOUT_MAX_US 40U
#define FECS_ARB_CMD_TIMEOUT_DEFAULT_US 2U #define FECS_ARB_CMD_TIMEOUT_DEFAULT_US 2U
#define CTXSW_MEM_SCRUBBING_TIMEOUT_MAX_US 1000U #define CTXSW_MEM_SCRUBBING_TIMEOUT_MAX_US 1000U
@@ -733,10 +735,10 @@ int gm20b_gr_falcon_submit_fecs_method_op(struct gk20a *g,
struct nvgpu_fecs_method_op op, struct nvgpu_fecs_method_op op,
bool sleepduringwait) bool sleepduringwait)
{ {
struct gr_gk20a *gr = &g->gr;
int ret; int ret;
struct gr_gk20a *gr = &g->gr;
nvgpu_mutex_acquire(&gr->fecs_mutex); nvgpu_mutex_acquire(&gr->falcon->fecs_mutex);
if (op.mailbox.id != 0U) { if (op.mailbox.id != 0U) {
nvgpu_writel(g, gr_fecs_ctxsw_mailbox_r(op.mailbox.id), nvgpu_writel(g, gr_fecs_ctxsw_mailbox_r(op.mailbox.id),
@@ -766,7 +768,7 @@ int gm20b_gr_falcon_submit_fecs_method_op(struct gk20a *g,
op.method.data, op.method.addr); op.method.data, op.method.addr);
} }
nvgpu_mutex_release(&gr->fecs_mutex); nvgpu_mutex_release(&gr->falcon->fecs_mutex);
return ret; return ret;
} }
@@ -775,10 +777,10 @@ int gm20b_gr_falcon_submit_fecs_method_op(struct gk20a *g,
int gm20b_gr_falcon_submit_fecs_sideband_method_op(struct gk20a *g, int gm20b_gr_falcon_submit_fecs_sideband_method_op(struct gk20a *g,
struct nvgpu_fecs_method_op op) struct nvgpu_fecs_method_op op)
{ {
struct gr_gk20a *gr = &g->gr;
int ret; int ret;
struct gr_gk20a *gr = &g->gr;
nvgpu_mutex_acquire(&gr->fecs_mutex); nvgpu_mutex_acquire(&gr->falcon->fecs_mutex);
nvgpu_writel(g, gr_fecs_ctxsw_mailbox_clear_r(op.mailbox.id), nvgpu_writel(g, gr_fecs_ctxsw_mailbox_clear_r(op.mailbox.id),
gr_fecs_ctxsw_mailbox_clear_value_f(op.mailbox.clr)); gr_fecs_ctxsw_mailbox_clear_value_f(op.mailbox.clr));
@@ -796,7 +798,7 @@ int gm20b_gr_falcon_submit_fecs_sideband_method_op(struct gk20a *g,
op.method.data, op.method.addr); op.method.data, op.method.addr);
} }
nvgpu_mutex_release(&gr->fecs_mutex); nvgpu_mutex_release(&gr->falcon->fecs_mutex);
return ret; return ret;
} }

View File

@@ -56,6 +56,7 @@ struct perf_pmupstate;
struct boardobjgrp; struct boardobjgrp;
struct boardobjgrp_pmu_cmd; struct boardobjgrp_pmu_cmd;
struct boardobjgrpmask; struct boardobjgrpmask;
struct nvgpu_gr_falcon;
struct nvgpu_sgt; struct nvgpu_sgt;
struct nvgpu_sgl; struct nvgpu_sgl;
struct nvgpu_device_info; struct nvgpu_device_info;
@@ -564,7 +565,8 @@ struct gpu_ops {
void (*load_ctxsw_ucode_boot)(struct gk20a *g, void (*load_ctxsw_ucode_boot)(struct gk20a *g,
u32 reg_offset, u32 boot_entry, u32 reg_offset, u32 boot_entry,
u32 addr_load32, u32 blocks, u32 dst); u32 addr_load32, u32 blocks, u32 dst);
int (*load_ctxsw_ucode)(struct gk20a *g); int (*load_ctxsw_ucode)(struct gk20a *g,
struct nvgpu_gr_falcon *falcon);
int (*wait_mem_scrubbing)(struct gk20a *g); int (*wait_mem_scrubbing)(struct gk20a *g);
int (*wait_ctxsw_ready)(struct gk20a *g); int (*wait_ctxsw_ready)(struct gk20a *g);
int (*submit_fecs_method_op)(struct gk20a *g, int (*submit_fecs_method_op)(struct gk20a *g,
@@ -575,8 +577,10 @@ struct gpu_ops {
int (*ctrl_ctxsw)(struct gk20a *g, u32 fecs_method, int (*ctrl_ctxsw)(struct gk20a *g, u32 fecs_method,
u32 fecs_data, u32 *ret_val); u32 fecs_data, u32 *ret_val);
int (*halt_pipe)(struct gk20a *g); int (*halt_pipe)(struct gk20a *g);
int (*disable_ctxsw)(struct gk20a *g); int (*disable_ctxsw)(struct gk20a *g,
int (*enable_ctxsw)(struct gk20a *g); struct nvgpu_gr_falcon *falcon);
int (*enable_ctxsw)(struct gk20a *g,
struct nvgpu_gr_falcon *falcon);
u32 (*get_current_ctx)(struct gk20a *g); u32 (*get_current_ctx)(struct gk20a *g);
u32 (*get_ctx_ptr)(u32 ctx); u32 (*get_ctx_ptr)(u32 ctx);
u32 (*get_fecs_current_ctx_data)(struct gk20a *g, u32 (*get_fecs_current_ctx_data)(struct gk20a *g,
@@ -1988,9 +1992,6 @@ struct gk20a {
nvgpu_atomic_t usage_count; nvgpu_atomic_t usage_count;
struct nvgpu_mutex ctxsw_disable_lock;
int ctxsw_disable_count;
struct nvgpu_ref refcount; struct nvgpu_ref refcount;
const char *name; const char *name;
@@ -2087,8 +2088,6 @@ struct gk20a {
u32 emc3d_ratio; u32 emc3d_ratio;
struct gk20a_ctxsw_ucode_info ctxsw_ucode_info;
/* /*
* A group of semaphore pools. One for each channel. * A group of semaphore pools. One for each channel.
*/ */

View File

@@ -25,6 +25,7 @@
#include <nvgpu/types.h> #include <nvgpu/types.h>
int nvgpu_gr_prepare_sw(struct gk20a *g);
int nvgpu_gr_enable_hw(struct gk20a *g); int nvgpu_gr_enable_hw(struct gk20a *g);
int nvgpu_gr_reset(struct gk20a *g); int nvgpu_gr_reset(struct gk20a *g);
int nvgpu_gr_init_support(struct gk20a *g); int nvgpu_gr_init_support(struct gk20a *g);

View File

@@ -26,6 +26,21 @@
#include <nvgpu/types.h> #include <nvgpu/types.h>
struct gk20a; struct gk20a;
struct nvgpu_gr_falcon;
struct nvgpu_ctxsw_ucode_segment {
u32 offset;
u32 size;
};
struct nvgpu_ctxsw_ucode_segments {
u32 boot_entry;
u32 boot_imem_offset;
u32 boot_signature;
struct nvgpu_ctxsw_ucode_segment boot;
struct nvgpu_ctxsw_ucode_segment code;
struct nvgpu_ctxsw_ucode_segment data;
};
#define NVGPU_GR_FALCON_METHOD_CTXSW_STOP 0 #define NVGPU_GR_FALCON_METHOD_CTXSW_STOP 0
#define NVGPU_GR_FALCON_METHOD_CTXSW_START 1 #define NVGPU_GR_FALCON_METHOD_CTXSW_START 1
@@ -57,14 +72,31 @@ struct nvgpu_fecs_host_intr_status {
bool watchdog_active; bool watchdog_active;
}; };
struct nvgpu_gr_falcon *nvgpu_gr_falcon_init_support(struct gk20a *g);
void nvgpu_gr_falcon_remove_support(struct gk20a *g,
struct nvgpu_gr_falcon *falcon);
int nvgpu_gr_falcon_bind_fecs_elpg(struct gk20a *g); int nvgpu_gr_falcon_bind_fecs_elpg(struct gk20a *g);
int nvgpu_gr_falcon_init_ctxsw(struct gk20a *g); int nvgpu_gr_falcon_init_ctxsw(struct gk20a *g, struct nvgpu_gr_falcon *falcon);
int nvgpu_gr_falcon_init_ctx_state(struct gk20a *g); int nvgpu_gr_falcon_init_ctx_state(struct gk20a *g);
int nvgpu_gr_falcon_init_ctxsw_ucode(struct gk20a *g); int nvgpu_gr_falcon_init_ctxsw_ucode(struct gk20a *g,
int nvgpu_gr_falcon_load_ctxsw_ucode(struct gk20a *g); struct nvgpu_gr_falcon *falcon);
int nvgpu_gr_falcon_load_secure_ctxsw_ucode(struct gk20a *g); int nvgpu_gr_falcon_load_ctxsw_ucode(struct gk20a *g,
int nvgpu_gr_falcon_disable_ctxsw(struct gk20a *g); struct nvgpu_gr_falcon *falcon);
int nvgpu_gr_falcon_enable_ctxsw(struct gk20a *g); int nvgpu_gr_falcon_load_secure_ctxsw_ucode(struct gk20a *g,
struct nvgpu_gr_falcon *falcon);
int nvgpu_gr_falcon_disable_ctxsw(struct gk20a *g,
struct nvgpu_gr_falcon *falcon);
int nvgpu_gr_falcon_enable_ctxsw(struct gk20a *g,
struct nvgpu_gr_falcon *falcon);
int nvgpu_gr_falcon_halt_pipe(struct gk20a *g); int nvgpu_gr_falcon_halt_pipe(struct gk20a *g);
struct nvgpu_mutex *nvgpu_gr_falcon_get_fecs_mutex(
struct nvgpu_gr_falcon *falcon);
struct nvgpu_ctxsw_ucode_segments *nvgpu_gr_falcon_get_fecs_ucode_segments(
struct nvgpu_gr_falcon *falcon);
struct nvgpu_ctxsw_ucode_segments *nvgpu_gr_falcon_get_gpccs_ucode_segments(
struct nvgpu_gr_falcon *falcon);
void *nvgpu_gr_falcon_get_surface_desc_cpu_va(
struct nvgpu_gr_falcon *falcon);
#endif /* NVGPU_GR_FALCON_H */ #endif /* NVGPU_GR_FALCON_H */

View File

@@ -63,7 +63,6 @@ static void nvgpu_init_vars(struct gk20a *g)
nvgpu_mutex_init(&g->dbg_sessions_lock); nvgpu_mutex_init(&g->dbg_sessions_lock);
nvgpu_mutex_init(&g->client_lock); nvgpu_mutex_init(&g->client_lock);
nvgpu_mutex_init(&g->power_lock); nvgpu_mutex_init(&g->power_lock);
nvgpu_mutex_init(&g->ctxsw_disable_lock);
nvgpu_mutex_init(&g->tpc_pg_lock); nvgpu_mutex_init(&g->tpc_pg_lock);
nvgpu_mutex_init(&g->clk_arb_enable_lock); nvgpu_mutex_init(&g->clk_arb_enable_lock);
nvgpu_mutex_init(&g->cg_pg_lock); nvgpu_mutex_init(&g->cg_pg_lock);

View File

@@ -1101,7 +1101,7 @@ static int nvgpu_dbg_gpu_ioctl_suspend_resume_sm(
nvgpu_mutex_acquire(&g->dbg_sessions_lock); nvgpu_mutex_acquire(&g->dbg_sessions_lock);
/* Suspend GPU context switching */ /* Suspend GPU context switching */
err = g->ops.gr.falcon.disable_ctxsw(g); err = g->ops.gr.falcon.disable_ctxsw(g, g->gr.falcon);
if (err) { if (err) {
nvgpu_err(g, "unable to stop gr ctxsw"); nvgpu_err(g, "unable to stop gr ctxsw");
/* this should probably be ctx-fatal... */ /* this should probably be ctx-fatal... */
@@ -1119,7 +1119,7 @@ static int nvgpu_dbg_gpu_ioctl_suspend_resume_sm(
break; break;
} }
err = g->ops.gr.falcon.enable_ctxsw(g); err = g->ops.gr.falcon.enable_ctxsw(g, g->gr.falcon);
if (err) if (err)
nvgpu_err(g, "unable to restart ctxsw!"); nvgpu_err(g, "unable to restart ctxsw!");

View File

@@ -81,7 +81,6 @@ static void vgpu_init_vars(struct gk20a *g, struct gk20a_platform *platform)
struct vgpu_priv_data *priv = vgpu_get_priv_data(g); struct vgpu_priv_data *priv = vgpu_get_priv_data(g);
nvgpu_mutex_init(&g->power_lock); nvgpu_mutex_init(&g->power_lock);
nvgpu_mutex_init(&g->ctxsw_disable_lock);
nvgpu_mutex_init(&g->clk_arb_enable_lock); nvgpu_mutex_init(&g->clk_arb_enable_lock);
nvgpu_mutex_init(&g->cg_pg_lock); nvgpu_mutex_init(&g->cg_pg_lock);