diff --git a/drivers/gpu/nvgpu/common/pmu/ipc/pmu_cmd.c b/drivers/gpu/nvgpu/common/pmu/ipc/pmu_cmd.c index 33fc09e02..e1b2ea667 100644 --- a/drivers/gpu/nvgpu/common/pmu/ipc/pmu_cmd.c +++ b/drivers/gpu/nvgpu/common/pmu/ipc/pmu_cmd.c @@ -600,7 +600,7 @@ int nvgpu_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd, return -EINVAL; } - err = nvgpu_pmu_seq_acquire(g, &pmu->sequences, &seq, callback, + err = nvgpu_pmu_seq_acquire(g, pmu->sequences, &seq, callback, cb_param); if (err != 0) { return err; @@ -624,7 +624,7 @@ int nvgpu_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd, err = pmu_fbq_cmd_setup(g, cmd, fb_queue, payload, seq); if (err != 0) { nvgpu_err(g, "FBQ cmd setup failed"); - nvgpu_pmu_seq_release(g, &pmu->sequences, seq); + nvgpu_pmu_seq_release(g, pmu->sequences, seq); goto exit; } @@ -651,7 +651,7 @@ int nvgpu_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd, pmu->fw.ops.allocation_set_dmem_size(pmu, pmu->fw.ops.get_seq_out_alloc_ptr(seq), 0); - nvgpu_pmu_seq_release(g, &pmu->sequences, seq); + nvgpu_pmu_seq_release(g, pmu->sequences, seq); goto exit; } diff --git a/drivers/gpu/nvgpu/common/pmu/ipc/pmu_msg.c b/drivers/gpu/nvgpu/common/pmu/ipc/pmu_msg.c index a42b3e741..e4d8d6bc1 100644 --- a/drivers/gpu/nvgpu/common/pmu/ipc/pmu_msg.c +++ b/drivers/gpu/nvgpu/common/pmu/ipc/pmu_msg.c @@ -161,7 +161,7 @@ static int pmu_response_handle(struct nvgpu_pmu *pmu, nvgpu_log_fn(g, " "); - seq = nvgpu_pmu_sequences_get_seq(&pmu->sequences, msg->hdr.seq_id); + seq = nvgpu_pmu_sequences_get_seq(pmu->sequences, msg->hdr.seq_id); state = nvgpu_pmu_seq_get_state(seq); id = nvgpu_pmu_seq_get_id(seq); @@ -190,7 +190,7 @@ exit: nvgpu_pmu_seq_callback(g, seq, msg, err); - nvgpu_pmu_seq_release(g, &pmu->sequences, seq); + nvgpu_pmu_seq_release(g, pmu->sequences, seq); /* TBD: notify client waiting for available dmem */ diff --git a/drivers/gpu/nvgpu/common/pmu/ipc/pmu_seq.c b/drivers/gpu/nvgpu/common/pmu/ipc/pmu_seq.c index d4e1108b1..bdca71b01 100644 --- a/drivers/gpu/nvgpu/common/pmu/ipc/pmu_seq.c +++ b/drivers/gpu/nvgpu/common/pmu/ipc/pmu_seq.c @@ -25,60 +25,17 @@ #include #include #include +#include -void *nvgpu_get_pmu_sequence_in_alloc_ptr_v3(struct pmu_sequence *seq) -{ - return (void *)(&seq->in_v3); -} +struct nvgpu_pmu; -void *nvgpu_get_pmu_sequence_in_alloc_ptr_v1(struct pmu_sequence *seq) -{ - return (void *)(&seq->in_v1); -} - -void *nvgpu_get_pmu_sequence_out_alloc_ptr_v3(struct pmu_sequence *seq) -{ - return (void *)(&seq->out_v3); -} - -void *nvgpu_get_pmu_sequence_out_alloc_ptr_v1(struct pmu_sequence *seq) -{ - return (void *)(&seq->out_v1); -} - -int nvgpu_pmu_sequences_alloc(struct gk20a *g, - struct pmu_sequences *sequences) -{ - int err; - - sequences->seq = nvgpu_kzalloc(g, PMU_MAX_NUM_SEQUENCES * - sizeof(struct pmu_sequence)); - if (sequences->seq == NULL) { - return -ENOMEM; - } - - err = nvgpu_mutex_init(&sequences->pmu_seq_lock); - if (err != 0) { - nvgpu_kfree(g, sequences->seq); - return err; - } - - return 0; -} - -void nvgpu_pmu_sequences_free(struct gk20a *g, - struct pmu_sequences *sequences) -{ - nvgpu_mutex_destroy(&sequences->pmu_seq_lock); - if (sequences->seq != NULL) { - nvgpu_kfree(g, sequences->seq); - } -} - -void nvgpu_pmu_sequences_init(struct pmu_sequences *sequences) +void nvgpu_pmu_sequences_sw_setup(struct gk20a *g, struct nvgpu_pmu *pmu, + struct pmu_sequences *sequences) { u32 i; + nvgpu_log_fn(g, " "); + (void) memset(sequences->seq, 0, sizeof(struct pmu_sequence) * PMU_MAX_NUM_SEQUENCES); (void) memset(sequences->pmu_seq_tbl, 0, @@ -89,6 +46,63 @@ void nvgpu_pmu_sequences_init(struct pmu_sequences *sequences) } } +int nvgpu_pmu_sequences_init(struct gk20a *g, struct nvgpu_pmu *pmu, + struct pmu_sequences **sequences_p) +{ + int err = 0; + struct pmu_sequences *sequences; + + nvgpu_log_fn(g, " "); + + if (*sequences_p != NULL) { + /* skip alloc/reinit for unrailgate sequence */ + nvgpu_pmu_dbg(g, "skip sequences init for unrailgate sequence"); + goto exit; + } + + sequences = (struct pmu_sequences *) + nvgpu_kzalloc(g, sizeof(struct pmu_sequences)); + if (sequences == NULL) { + err = -ENOMEM; + goto exit; + } + + sequences->seq = (struct pmu_sequence *) + nvgpu_kzalloc(g, PMU_MAX_NUM_SEQUENCES * + sizeof(struct pmu_sequence)); + if (sequences->seq == NULL) { + nvgpu_kfree(g, sequences); + return -ENOMEM; + } + + err = nvgpu_mutex_init(&sequences->pmu_seq_lock); + if (err != 0) { + nvgpu_kfree(g, sequences->seq); + nvgpu_kfree(g, sequences); + return err; + } + + *sequences_p = sequences; +exit: + return err; +} + +void nvgpu_pmu_sequences_deinit(struct gk20a *g, struct nvgpu_pmu *pmu, + struct pmu_sequences *sequences) +{ + nvgpu_log_fn(g, " "); + + if (sequences == NULL) { + return; + } + + nvgpu_mutex_destroy(&sequences->pmu_seq_lock); + if (sequences->seq != NULL) { + nvgpu_kfree(g, sequences->seq); + } + nvgpu_kfree(g, sequences); +} + void nvgpu_pmu_seq_payload_free(struct gk20a *g, struct pmu_sequence *seq) { nvgpu_log_fn(g, " "); diff --git a/drivers/gpu/nvgpu/common/pmu/pmu.c b/drivers/gpu/nvgpu/common/pmu/pmu.c index d0bc577ae..1b7312d92 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu.c @@ -161,9 +161,11 @@ static int nvgpu_init_pmu_setup_sw(struct gk20a *g) } } + /* set default value to sequences */ + nvgpu_pmu_sequences_sw_setup(g, pmu, pmu->sequences); + if (pmu->sw_ready) { nvgpu_pmu_mutexes_init(&pmu->mutexes); - nvgpu_pmu_sequences_init(&pmu->sequences); nvgpu_log_fn(g, "skip init"); goto skip_init; @@ -176,23 +178,11 @@ static int nvgpu_init_pmu_setup_sw(struct gk20a *g) nvgpu_pmu_mutexes_init(&pmu->mutexes); - err = nvgpu_pmu_sequences_alloc(g, &pmu->sequences); - if (err != 0) { - goto err_free_mutex; - } - - nvgpu_pmu_sequences_init(&pmu->sequences); - - if (err != 0) { - nvgpu_err(g, "failed to allocate memory"); - goto err_free_seq; - } - 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_free_seq; + goto err_free_mutex; } } @@ -213,8 +203,7 @@ skip_init: nvgpu_dma_unmap_free(vm, nvgpu_pmu_super_surface_mem(g, pmu, pmu->super_surface)); } - err_free_seq: - nvgpu_pmu_sequences_free(g, &pmu->sequences); + err_free_mutex: nvgpu_pmu_mutexes_free(g, &pmu->mutexes); err: @@ -360,7 +349,7 @@ static void nvgpu_remove_pmu_support(struct nvgpu_pmu *pmu) nvgpu_pmu_pg_deinit(g, pmu, pmu->pg); nvgpu_mutex_destroy(&pmu->isr_mutex); - nvgpu_pmu_sequences_free(g, &pmu->sequences); + nvgpu_pmu_sequences_deinit(g, pmu, pmu->sequences); nvgpu_pmu_mutexes_free(g, &pmu->mutexes); } @@ -402,6 +391,12 @@ int nvgpu_early_init_pmu_sw(struct gk20a *g, struct nvgpu_pmu *pmu) 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) { diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu.h b/drivers/gpu/nvgpu/include/nvgpu/pmu.h index 3ceca1c31..e688facd7 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmu.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu.h @@ -155,7 +155,7 @@ struct nvgpu_pmu { struct pmu_sha1_gid gid_info; struct pmu_queues queues; - struct pmu_sequences sequences; + struct pmu_sequences *sequences; struct pmu_mutexes mutexes; diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu/seq.h b/drivers/gpu/nvgpu/include/nvgpu/pmu/seq.h index c43d3d36a..ee4fe7e16 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmu/seq.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu/seq.h @@ -30,6 +30,7 @@ struct nvgpu_engine_fb_queue; struct nvgpu_mem; struct pmu_msg; struct gk20a; +struct nvgpu_pmu;; #define PMU_MAX_NUM_SEQUENCES (256U) #define PMU_SEQ_BIT_SHIFT (5U) @@ -91,16 +92,13 @@ struct pmu_sequences { unsigned long pmu_seq_tbl[PMU_SEQ_TBL_SIZE]; }; -void *nvgpu_get_pmu_sequence_in_alloc_ptr_v3(struct pmu_sequence *seq); -void *nvgpu_get_pmu_sequence_in_alloc_ptr_v1(struct pmu_sequence *seq); -void *nvgpu_get_pmu_sequence_out_alloc_ptr_v3(struct pmu_sequence *seq); -void *nvgpu_get_pmu_sequence_out_alloc_ptr_v1(struct pmu_sequence *seq); +void nvgpu_pmu_sequences_sw_setup(struct gk20a *g, struct nvgpu_pmu *pmu, + struct pmu_sequences *sequences); +int nvgpu_pmu_sequences_init(struct gk20a *g, struct nvgpu_pmu *pmu, + struct pmu_sequences **sequences_p); +void nvgpu_pmu_sequences_deinit(struct gk20a *g, struct nvgpu_pmu *pmu, + struct pmu_sequences *sequences); -int nvgpu_pmu_sequences_alloc(struct gk20a *g, - struct pmu_sequences *sequences); -void nvgpu_pmu_sequences_free(struct gk20a *g, - struct pmu_sequences *sequences); -void nvgpu_pmu_sequences_init(struct pmu_sequences *sequences); void nvgpu_pmu_seq_payload_free(struct gk20a *g, struct pmu_sequence *seq); int nvgpu_pmu_seq_acquire(struct gk20a *g, struct pmu_sequences *sequences,