diff --git a/drivers/gpu/nvgpu/common/init/nvgpu_init.c b/drivers/gpu/nvgpu/common/init/nvgpu_init.c index ac5764cc0..0b98ba284 100644 --- a/drivers/gpu/nvgpu/common/init/nvgpu_init.c +++ b/drivers/gpu/nvgpu/common/init/nvgpu_init.c @@ -100,7 +100,7 @@ int gk20a_prepare_poweroff(struct gk20a *g) /* disable elpg before gr or fifo suspend */ if (g->support_ls_pmu) { - ret = nvgpu_pmu_destroy(g); + ret = nvgpu_pmu_destroy(g, &g->pmu); } if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SEC2_RTOS)) { @@ -205,7 +205,7 @@ int gk20a_finalize_poweron(struct gk20a *g) goto done_gsp; } - err = nvgpu_early_init_pmu_sw(g, &g->pmu); + err = nvgpu_pmu_early_init(g, &g->pmu); if (err != 0) { nvgpu_err(g, "failed to early init pmu sw"); goto done; @@ -364,7 +364,7 @@ int gk20a_finalize_poweron(struct gk20a *g) } } - err = nvgpu_init_pmu_support(g); + err = nvgpu_pmu_init(g, &g->pmu); if (err != 0) { nvgpu_err(g, "failed to init gk20a pmu"); nvgpu_mutex_release(&g->tpc_pg_lock); diff --git a/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c b/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c index 92be67b28..02b80f535 100644 --- a/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c +++ b/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "pg_sw_gm20b.h" #include "pg_sw_gv11b.h" @@ -1041,7 +1042,9 @@ void nvgpu_pmu_pg_deinit(struct gk20a *g, struct nvgpu_pmu *pmu, return; } - nvgpu_dma_unmap_free(vm, &pg->seq_buf); + if (nvgpu_mem_is_valid(&pg->seq_buf)) { + nvgpu_dma_unmap_free(vm, &pg->seq_buf); + } nvgpu_mutex_destroy(&pg->elpg_mutex); nvgpu_mutex_destroy(&pg->pg_mutex); nvgpu_kfree(g, pg); diff --git a/drivers/gpu/nvgpu/common/pmu/pmu.c b/drivers/gpu/nvgpu/common/pmu/pmu.c index 783639937..659980df1 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -42,9 +44,327 @@ #include #include #include +#include #include #include +/* PMU locks used to sync with PMU-RTOS */ +int nvgpu_pmu_lock_acquire(struct gk20a *g, struct nvgpu_pmu *pmu, + u32 id, u32 *token) +{ + if (!g->support_ls_pmu) { + return 0; + } + + if (!g->can_elpg) { + return 0; + } + + if (!pmu->pg->initialized) { + return -EINVAL; + } + + return nvgpu_pmu_mutex_acquire(g, pmu->mutexes, id, token); +} + +int nvgpu_pmu_lock_release(struct gk20a *g, struct nvgpu_pmu *pmu, + u32 id, u32 *token) +{ + if (!g->support_ls_pmu) { + return 0; + } + + if (!g->can_elpg) { + return 0; + } + + if (!pmu->pg->initialized) { + return -EINVAL; + } + + return nvgpu_pmu_mutex_release(g, pmu->mutexes, id, token); +} + +/* PMU RTOS init/setup functions */ +int nvgpu_pmu_destroy(struct gk20a *g, struct nvgpu_pmu *pmu) +{ + nvgpu_log_fn(g, " "); + + if (!g->support_ls_pmu) { + return 0; + } + + if (g->can_elpg) { + nvgpu_pmu_pg_destroy(g, pmu, pmu->pg); + } + + nvgpu_mutex_acquire(&pmu->isr_mutex); + g->ops.pmu.pmu_enable_irq(pmu, false); + pmu->isr_enabled = false; + nvgpu_mutex_release(&pmu->isr_mutex); + + nvgpu_pmu_queues_free(g, &pmu->queues); + + nvgpu_pmu_fw_state_change(g, pmu, PMU_FW_STATE_OFF, false); + nvgpu_pmu_set_fw_ready(g, pmu, false); + pmu->pmu_perfmon->perfmon_ready = false; + + nvgpu_set_enabled(g, NVGPU_PMU_FECS_BOOTSTRAP_DONE, false); + + nvgpu_log_fn(g, "done"); + return 0; +} + +static void remove_pmu_support(struct nvgpu_pmu *pmu) +{ + struct gk20a *g = gk20a_from_pmu(pmu); + struct boardobj *pboardobj, *pboardobj_tmp; + struct boardobjgrp *pboardobjgrp, *pboardobjgrp_tmp; + int err = 0; + + nvgpu_log_fn(g, " "); + + if (nvgpu_alloc_initialized(&pmu->dmem)) { + nvgpu_alloc_destroy(&pmu->dmem); + } + + if (nvgpu_is_enabled(g, NVGPU_PMU_PSTATE)) { + nvgpu_list_for_each_entry_safe(pboardobjgrp, + pboardobjgrp_tmp, &g->boardobjgrp_head, + boardobjgrp, node) { + err = pboardobjgrp->destruct(pboardobjgrp); + if (err != 0) { + nvgpu_err(g, "pboardobjgrp destruct failed"); + } + } + + nvgpu_list_for_each_entry_safe(pboardobj, pboardobj_tmp, + &g->boardobj_head, boardobj, node) { + pboardobj->destruct(pboardobj); + } + } + + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_PMU_SUPER_SURFACE)) { + nvgpu_pmu_super_surface_deinit(g, pmu, pmu->super_surface); + } + + nvgpu_pmu_debug_deinit(g, pmu); + nvgpu_pmu_lsfm_deinit(g, pmu, pmu->lsfm); + nvgpu_pmu_pg_deinit(g, pmu, pmu->pg); + nvgpu_pmu_sequences_deinit(g, pmu, pmu->sequences); + nvgpu_pmu_mutexe_deinit(g, pmu, pmu->mutexes); + nvgpu_pmu_fw_release(g, pmu); + nvgpu_pmu_deinitialize_perfmon(g, pmu); + nvgpu_mutex_destroy(&pmu->isr_mutex); +} + +static int pmu_sw_setup(struct gk20a *g, struct nvgpu_pmu *pmu ) +{ + int err = 0; + + nvgpu_log_fn(g, " "); + + /* set default value to mutexes */ + nvgpu_pmu_mutex_sw_setup(g, pmu, pmu->mutexes); + + /* set default value to sequences */ + nvgpu_pmu_sequences_sw_setup(g, pmu, pmu->sequences); + + if (g->can_elpg) { + err = nvgpu_pmu_pg_sw_setup(g, pmu, pmu->pg); + if (err != 0){ + goto exit; + } + } + + if (pmu->sw_ready) { + nvgpu_log_fn(g, "skip PMU-RTOS shared buffer realloc"); + goto exit; + } + + /* alloc shared buffer to read PMU-RTOS debug message */ + err = nvgpu_pmu_debug_init(g, pmu); + if (err != 0) { + goto exit; + } + + /* alloc shared buffer super buffer to communicate with PMU-RTOS */ + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_PMU_SUPER_SURFACE)) { + err = nvgpu_pmu_super_surface_buf_alloc(g, + pmu, pmu->super_surface); + if (err != 0) { + goto exit; + } + } + + pmu->sw_ready = true; +exit: + if (err != 0) { + remove_pmu_support(pmu); + } + + return err; +} + +int nvgpu_pmu_init(struct gk20a *g, struct nvgpu_pmu *pmu) +{ + int err = 0; + + nvgpu_log_fn(g, " "); + + if (!g->support_ls_pmu) { + goto exit; + } + + err = pmu_sw_setup(g, pmu); + if (err != 0) { + goto exit; + } + + if (nvgpu_is_enabled(g, NVGPU_SEC_PRIVSECURITY)) { + + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SEC2_RTOS)) { + /* Reset PMU engine */ + err = nvgpu_falcon_reset(&g->pmu.flcn); + + /* Bootstrap PMU from SEC2 RTOS*/ + err = nvgpu_sec2_bootstrap_ls_falcons(g, &g->sec2, + FALCON_ID_PMU); + if (err != 0) { + goto exit; + } + } + + /* + * clear halt interrupt to avoid PMU-RTOS ucode + * hitting breakpoint due to PMU halt + */ + err = nvgpu_falcon_clear_halt_intr_status(&g->pmu.flcn, + nvgpu_get_poll_timeout(g)); + if (err != 0) { + goto exit; + } + + if (g->ops.pmu.setup_apertures != NULL) { + g->ops.pmu.setup_apertures(g); + } + + err = nvgpu_pmu_lsfm_ls_pmu_cmdline_args_copy(g, pmu, + pmu->lsfm); + if (err != 0) { + goto exit; + } + + if (g->ops.pmu.pmu_enable_irq != NULL) { + nvgpu_mutex_acquire(&g->pmu.isr_mutex); + g->ops.pmu.pmu_enable_irq(&g->pmu, true); + g->pmu.isr_enabled = true; + nvgpu_mutex_release(&g->pmu.isr_mutex); + } + + /*Once in LS mode, cpuctl_alias is only accessible*/ + if (g->ops.pmu.secured_pmu_start != NULL) { + g->ops.pmu.secured_pmu_start(g); + } + } else { + /* non-secure boot */ + err = nvgpu_pmu_ns_fw_bootstrap(g, pmu); + if (err != 0) { + goto exit; + } + } + + nvgpu_pmu_fw_state_change(g, pmu, PMU_FW_STATE_STARTING, false); + +exit: + return err; +} + +int nvgpu_pmu_early_init(struct gk20a *g, struct nvgpu_pmu *pmu) +{ + int err = 0; + + nvgpu_log_fn(g, " "); + + pmu->g = g; + + if (!g->support_ls_pmu) { + goto exit; + } + + if (!g->ops.pmu.is_pmu_supported(g)) { + g->support_ls_pmu = false; + + /* Disable LS PMU global checkers */ + g->can_elpg = false; + g->elpg_enabled = false; + g->aelpg_enabled = false; + nvgpu_set_enabled(g, NVGPU_PMU_PERFMON, false); + goto exit; + } + + err = nvgpu_mutex_init(&pmu->isr_mutex); + if (err != 0) { + goto init_failed; + } + + /* Allocate memory for pmu_perfmon */ + err = nvgpu_pmu_initialize_perfmon(g, pmu, &pmu->pmu_perfmon); + if (err != 0) { + goto exit; + } + + err = nvgpu_pmu_init_pmu_fw(g, pmu); + if (err != 0) { + goto init_failed; + } + + err = nvgpu_pmu_init_mutexe(g, pmu, &pmu->mutexes); + if (err != 0) { + goto init_failed; + } + + err = nvgpu_pmu_sequences_init(g, pmu, &pmu->sequences); + if (err != 0) { + goto init_failed; + } + + if (g->can_elpg) { + err = nvgpu_pmu_pg_init(g, pmu, &pmu->pg); + if (err != 0) { + goto init_failed; + } + } + + err = nvgpu_pmu_lsfm_init(g, &pmu->lsfm); + if (err != 0) { + goto init_failed; + } + + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_PMU_SUPER_SURFACE)) { + err = nvgpu_pmu_super_surface_init(g, pmu, + &pmu->super_surface); + if (err != 0) { + goto init_failed; + } + } + + pmu->remove_support = remove_pmu_support; + + goto exit; + +init_failed: + remove_pmu_support(pmu); +exit: + return err; +} + +struct gk20a *gk20a_from_pmu(struct nvgpu_pmu *pmu) +{ + return pmu->g; +} + +/* PMU H/W error functions */ static void pmu_report_error(struct gk20a *g, u32 err_type, u32 status, u32 pmu_err_type) { @@ -60,6 +380,15 @@ static void pmu_report_error(struct gk20a *g, u32 err_type, } } +void nvgpu_pmu_report_bar0_pri_err_status(struct gk20a *g, u32 bar0_status, + u32 error_type) +{ + pmu_report_error(g, + GPU_PMU_BAR0_ERROR_TIMEOUT, bar0_status, error_type); + return; +} + +/* PMU engine reset functions */ static int pmu_enable_hw(struct nvgpu_pmu *pmu, bool enable) { struct gk20a *g = pmu->g; @@ -145,330 +474,3 @@ exit: return err; } -static int nvgpu_init_pmu_setup_sw(struct gk20a *g) -{ - struct nvgpu_pmu *pmu = &g->pmu; - struct mm_gk20a *mm = &g->mm; - struct vm_gk20a *vm = mm->pmu.vm; - int err = 0; - - nvgpu_log_fn(g, " "); - - if (g->can_elpg) { - err = nvgpu_pmu_pg_sw_setup(g, pmu, pmu->pg); - if (err != 0){ - goto skip_init; - } - } - - /* set default value to mutexes */ - nvgpu_pmu_mutex_sw_setup(g, pmu, pmu->mutexes); - - /* set default value to sequences */ - nvgpu_pmu_sequences_sw_setup(g, pmu, pmu->sequences); - - if (pmu->sw_ready) { - nvgpu_log_fn(g, "skip init"); - goto skip_init; - } - - if (nvgpu_is_enabled(g, NVGPU_SUPPORT_PMU_SUPER_SURFACE)) { - err = nvgpu_pmu_super_surface_buf_alloc(g, - pmu, pmu->super_surface); - if (err != 0) { - goto err; - } - } - - /* alloc shared buffer to read PMU-RTOS debug message */ - err = nvgpu_pmu_debug_init(g, pmu); - if (err != 0) { - goto err_free_super_surface; - } - - pmu->sw_ready = true; - -skip_init: - nvgpu_log_fn(g, "done"); - return 0; - err_free_super_surface: - if (nvgpu_is_enabled(g, NVGPU_SUPPORT_PMU_SUPER_SURFACE)) { - nvgpu_dma_unmap_free(vm, nvgpu_pmu_super_surface_mem(g, - pmu, pmu->super_surface)); - } - - err: - nvgpu_log_fn(g, "fail"); - return err; -} - -int nvgpu_init_pmu_support(struct gk20a *g) -{ - struct nvgpu_pmu *pmu = &g->pmu; - int err = 0; - - nvgpu_log_fn(g, " "); - - if (!g->support_ls_pmu) { - goto exit; - } - - err = nvgpu_init_pmu_setup_sw(g); - if (err != 0) { - goto exit; - } - - if (nvgpu_is_enabled(g, NVGPU_SEC_PRIVSECURITY)) { - - if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SEC2_RTOS)) { - /* Reset PMU engine */ - err = nvgpu_falcon_reset(&g->pmu.flcn); - - /* Bootstrap PMU from SEC2 RTOS*/ - err = nvgpu_sec2_bootstrap_ls_falcons(g, &g->sec2, - FALCON_ID_PMU); - if (err != 0) { - goto exit; - } - } - - /* - * clear halt interrupt to avoid PMU-RTOS ucode - * hitting breakpoint due to PMU halt - */ - err = nvgpu_falcon_clear_halt_intr_status(&g->pmu.flcn, - nvgpu_get_poll_timeout(g)); - if (err != 0) { - goto exit; - } - - if (g->ops.pmu.setup_apertures != NULL) { - g->ops.pmu.setup_apertures(g); - } - - err = nvgpu_pmu_lsfm_ls_pmu_cmdline_args_copy(g, pmu, - pmu->lsfm); - if (err != 0) { - goto exit; - } - - if (g->ops.pmu.pmu_enable_irq != NULL) { - nvgpu_mutex_acquire(&g->pmu.isr_mutex); - g->ops.pmu.pmu_enable_irq(&g->pmu, true); - g->pmu.isr_enabled = true; - nvgpu_mutex_release(&g->pmu.isr_mutex); - } - - /*Once in LS mode, cpuctl_alias is only accessible*/ - if (g->ops.pmu.secured_pmu_start != NULL) { - g->ops.pmu.secured_pmu_start(g); - } - } else { - /* non-secure boot */ - nvgpu_pmu_ns_fw_bootstrap(g, pmu); - } - - nvgpu_pmu_fw_state_change(g, pmu, PMU_FW_STATE_STARTING, false); - -exit: - return err; -} - -int nvgpu_pmu_destroy(struct gk20a *g) -{ - struct nvgpu_pmu *pmu = &g->pmu; - - nvgpu_log_fn(g, " "); - - if (!g->support_ls_pmu) { - return 0; - } - - if (g->can_elpg) { - nvgpu_pmu_pg_destroy(g, pmu, pmu->pg); - } - - nvgpu_mutex_acquire(&pmu->isr_mutex); - g->ops.pmu.pmu_enable_irq(pmu, false); - pmu->isr_enabled = false; - nvgpu_mutex_release(&pmu->isr_mutex); - - nvgpu_pmu_queues_free(g, &pmu->queues); - - nvgpu_pmu_fw_state_change(g, pmu, PMU_FW_STATE_OFF, false); - nvgpu_pmu_set_fw_ready(g, pmu, false); - pmu->pmu_perfmon->perfmon_ready = false; - - nvgpu_set_enabled(g, NVGPU_PMU_FECS_BOOTSTRAP_DONE, false); - - nvgpu_log_fn(g, "done"); - return 0; -} - -static void nvgpu_remove_pmu_support(struct nvgpu_pmu *pmu) -{ - struct gk20a *g = gk20a_from_pmu(pmu); - struct boardobj *pboardobj, *pboardobj_tmp; - struct boardobjgrp *pboardobjgrp, *pboardobjgrp_tmp; - - nvgpu_log_fn(g, " "); - - if (nvgpu_alloc_initialized(&pmu->dmem)) { - nvgpu_alloc_destroy(&pmu->dmem); - } - - if (nvgpu_is_enabled(g, NVGPU_PMU_PSTATE)) { - nvgpu_list_for_each_entry_safe(pboardobjgrp, - pboardobjgrp_tmp, &g->boardobjgrp_head, - boardobjgrp, node) { - pboardobjgrp->destruct(pboardobjgrp); - } - - nvgpu_list_for_each_entry_safe(pboardobj, pboardobj_tmp, - &g->boardobj_head, boardobj, node) { - pboardobj->destruct(pboardobj); - } - } - - nvgpu_pmu_fw_release(g, pmu); - - if (nvgpu_is_enabled(g, NVGPU_SUPPORT_PMU_SUPER_SURFACE)) { - nvgpu_pmu_super_surface_deinit(g, pmu, pmu->super_surface); - } - - nvgpu_pmu_debug_deinit(g, pmu); - nvgpu_pmu_lsfm_deinit(g, pmu, pmu->lsfm); - nvgpu_pmu_pg_deinit(g, pmu, pmu->pg); - - nvgpu_mutex_destroy(&pmu->isr_mutex); - nvgpu_pmu_mutexe_deinit(g, pmu, pmu->mutexes); - nvgpu_pmu_sequences_deinit(g, pmu, pmu->sequences); -} - -int nvgpu_early_init_pmu_sw(struct gk20a *g, struct nvgpu_pmu *pmu) -{ - int err = 0; - - nvgpu_log_fn(g, " "); - - pmu->g = g; - - if (!g->support_ls_pmu) { - goto exit; - } - - if (!g->ops.pmu.is_pmu_supported(g)) { - g->support_ls_pmu = false; - - /* Disable LS PMU global checkers */ - g->can_elpg = false; - g->elpg_enabled = false; - g->aelpg_enabled = false; - nvgpu_set_enabled(g, NVGPU_PMU_PERFMON, false); - goto exit; - } - - err = nvgpu_mutex_init(&pmu->isr_mutex); - if (err != 0) { - goto init_failed; - } - - /* Allocate memory for pmu_perfmon */ - err = nvgpu_pmu_initialize_perfmon(g, pmu, &pmu->pmu_perfmon); - if (err != 0) { - goto exit; - } - - err = nvgpu_pmu_init_pmu_fw(g, pmu); - if (err != 0) { - goto init_failed; - } - - err = nvgpu_pmu_init_mutexe(g, pmu, &pmu->mutexes); - if (err != 0) { - goto init_failed; - } - - err = nvgpu_pmu_sequences_init(g, pmu, &pmu->sequences); - if (err != 0) { - goto init_failed; - } - - if (g->can_elpg) { - err = nvgpu_pmu_pg_init(g, pmu, &pmu->pg); - if (err != 0) { - goto init_failed; - } - } - - err = nvgpu_pmu_lsfm_init(g, &pmu->lsfm); - if (err != 0) { - goto init_failed; - } - - if (nvgpu_is_enabled(g, NVGPU_SUPPORT_PMU_SUPER_SURFACE)) { - err = nvgpu_pmu_super_surface_init(g, pmu, - &pmu->super_surface); - if (err != 0) { - goto init_failed; - } - } - - pmu->remove_support = nvgpu_remove_pmu_support; - - goto exit; - -init_failed: - nvgpu_remove_pmu_support(pmu); -exit: - return err; -} - -struct gk20a *gk20a_from_pmu(struct nvgpu_pmu *pmu) -{ - return pmu->g; -} - -void nvgpu_pmu_report_bar0_pri_err_status(struct gk20a *g, u32 bar0_status, - u32 error_type) -{ - pmu_report_error(g, - GPU_PMU_BAR0_ERROR_TIMEOUT, bar0_status, error_type); - return; -} - -int nvgpu_pmu_lock_acquire(struct gk20a *g, struct nvgpu_pmu *pmu, - u32 id, u32 *token) -{ - if (!g->support_ls_pmu) { - return 0; - } - - if (!g->can_elpg) { - return 0; - } - - if (!pmu->pg->initialized) { - return -EINVAL; - } - - return nvgpu_pmu_mutex_acquire(g, pmu->mutexes, id, token); -} - -int nvgpu_pmu_lock_release(struct gk20a *g, struct nvgpu_pmu *pmu, - u32 id, u32 *token) -{ - if (!g->support_ls_pmu) { - return 0; - } - - if (!g->can_elpg) { - return 0; - } - - if (!pmu->pg->initialized) { - return -EINVAL; - } - - return nvgpu_pmu_mutex_release(g, pmu->mutexes, id, token); -} diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_debug.c b/drivers/gpu/nvgpu/common/pmu/pmu_debug.c index 7354039ce..4f64e88d9 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_debug.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_debug.c @@ -24,6 +24,7 @@ #include #include #include +#include bool nvgpu_find_hex_in_string(char *strings, struct gk20a *g, u32 *hex_pos) { diff --git a/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface.c b/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface.c index b3538058e..3f6b53fbe 100644 --- a/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface.c +++ b/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface.c @@ -179,13 +179,11 @@ void nvgpu_pmu_super_surface_deinit(struct gk20a *g, struct nvgpu_pmu *pmu, int nvgpu_pmu_super_surface_init(struct gk20a *g, struct nvgpu_pmu *pmu, struct pmu_super_surface **super_surface) { - int err = 0; - *super_surface = (struct pmu_super_surface *) nvgpu_kzalloc(g, sizeof(struct pmu_super_surface)); if (*super_surface == NULL) { - err = -ENOMEM; + return -ENOMEM; } - return err; + return 0; } diff --git a/drivers/gpu/nvgpu/hal/pmu/pmu_gk20a.c b/drivers/gpu/nvgpu/hal/pmu/pmu_gk20a.c index 8fb366da1..0424e76f5 100644 --- a/drivers/gpu/nvgpu/hal/pmu/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/hal/pmu/pmu_gk20a.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu.h b/drivers/gpu/nvgpu/include/nvgpu/pmu.h index 53b9a2628..a06ceb09f 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmu.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu.h @@ -38,6 +38,13 @@ #include #include +struct pmu_sequences; +struct pmu_mutexes; +struct nvgpu_pmu_lsfm; +struct pmu_super_surface; +struct nvgpu_pmu_pg; +struct nvgpu_pmu_perfmon; + #define nvgpu_pmu_dbg(g, fmt, args...) \ nvgpu_log(g, gpu_dbg_pmu, fmt, ##args) @@ -142,25 +149,21 @@ struct pmu_ucode_desc { struct nvgpu_pmu { struct gk20a *g; + bool sw_ready; + bool isr_enabled; + struct nvgpu_mutex isr_mutex; struct nvgpu_falcon flcn; - - struct pmu_rtos_fw fw; - - struct nvgpu_pmu_lsfm *lsfm; - + struct nvgpu_allocator dmem; struct nvgpu_mem trace_buf; - - struct pmu_super_surface *super_surface; - struct pmu_sha1_gid gid_info; + struct pmu_rtos_fw fw; struct pmu_queues queues; struct pmu_sequences *sequences; - struct pmu_mutexes *mutexes; - struct nvgpu_allocator dmem; - + struct nvgpu_pmu_lsfm *lsfm; + struct pmu_super_surface *super_surface; struct nvgpu_pmu_pg *pg; struct nvgpu_pmu_perfmon *pmu_perfmon; struct nvgpu_clk_pmupstate *clk_pmu; @@ -171,10 +174,6 @@ struct nvgpu_pmu { struct nv_pmu_rpc_header *rpc); void (*therm_event_handler)(struct gk20a *g, struct nvgpu_pmu *pmu, struct pmu_msg *msg, struct nv_pmu_rpc_header *rpc); - bool sw_ready; - - struct nvgpu_mutex isr_mutex; - bool isr_enabled; }; /*! @@ -186,32 +185,25 @@ struct pg_init_sequence_list { u32 writeval; }; +/* PMU locks used along with PMU-RTOS */ int nvgpu_pmu_lock_acquire(struct gk20a *g, struct nvgpu_pmu *pmu, - u32 id, u32 *token); + u32 id, u32 *token); int nvgpu_pmu_lock_release(struct gk20a *g, struct nvgpu_pmu *pmu, - u32 id, u32 *token); + u32 id, u32 *token); -/* PMU init */ -int nvgpu_init_pmu_support(struct gk20a *g); -int nvgpu_pmu_destroy(struct gk20a *g); -int nvgpu_pmu_super_surface_alloc(struct gk20a *g, - struct nvgpu_mem *mem_surface, u32 size); - -int nvgpu_early_init_pmu_sw(struct gk20a *g, struct nvgpu_pmu *pmu); - -/* PMU reset */ -int nvgpu_pmu_reset(struct gk20a *g); - -/* PMU debug */ -void nvgpu_pmu_dump_falcon_stats(struct nvgpu_pmu *pmu); -bool nvgpu_find_hex_in_string(char *strings, struct gk20a *g, u32 *hex_pos); -int nvgpu_pmu_debug_init(struct gk20a *g, struct nvgpu_pmu *pmu); -void nvgpu_pmu_debug_deinit(struct gk20a *g, struct nvgpu_pmu *pmu); - -struct gk20a *gk20a_from_pmu(struct nvgpu_pmu *pmu); +/* PMU RTOS init/setup functions */ +int nvgpu_pmu_early_init(struct gk20a *g, struct nvgpu_pmu *pmu); +int nvgpu_pmu_init(struct gk20a *g, struct nvgpu_pmu *pmu); +int nvgpu_pmu_destroy(struct gk20a *g, struct nvgpu_pmu *pmu); +/* PMU H/W error functions */ void nvgpu_pmu_report_bar0_pri_err_status(struct gk20a *g, u32 bar0_status, u32 error_type); +/* PMU engine reset function */ +int nvgpu_pmu_reset(struct gk20a *g); + +struct gk20a *gk20a_from_pmu(struct nvgpu_pmu *pmu); + #endif /* NVGPU_PMU_H */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu/debug.h b/drivers/gpu/nvgpu/include/nvgpu/pmu/debug.h new file mode 100644 index 000000000..7efeb1d44 --- /dev/null +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu/debug.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_PMU_DEBUG_H +#define NVGPU_PMU_DEBUG_H + +/* PMU debug */ +void nvgpu_pmu_dump_falcon_stats(struct nvgpu_pmu *pmu); +bool nvgpu_find_hex_in_string(char *strings, struct gk20a *g, u32 *hex_pos); +int nvgpu_pmu_debug_init(struct gk20a *g, struct nvgpu_pmu *pmu); +void nvgpu_pmu_debug_deinit(struct gk20a *g, struct nvgpu_pmu *pmu); + +#endif /* NVGPU_PMU_DEBUG_H */ diff --git a/drivers/gpu/nvgpu/os/linux/debug_pmu.c b/drivers/gpu/nvgpu/os/linux/debug_pmu.c index 2f2408424..34e4fefd7 100644 --- a/drivers/gpu/nvgpu/os/linux/debug_pmu.c +++ b/drivers/gpu/nvgpu/os/linux/debug_pmu.c @@ -14,6 +14,7 @@ #include #include +#include #include "debug_pmu.h" #include "os_linux.h"