summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h2
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.c129
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.h15
3 files changed, 138 insertions, 8 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index b1d3f3e3..83d388a7 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -403,6 +403,8 @@ struct gpu_ops {
403 struct pmu_gk20a *pmu, void *pmu_alloc_ptr); 403 struct pmu_gk20a *pmu, void *pmu_alloc_ptr);
404 void (*pmu_allocation_set_dmem_offset)(struct pmu_gk20a *pmu, 404 void (*pmu_allocation_set_dmem_offset)(struct pmu_gk20a *pmu,
405 void *pmu_alloc_ptr, u32 offset); 405 void *pmu_alloc_ptr, u32 offset);
406 void * (*pmu_allocation_get_fb_addr)(
407 struct pmu_gk20a *pmu, void *pmu_alloc_ptr);
406 void (*get_pmu_init_msg_pmu_queue_params)( 408 void (*get_pmu_init_msg_pmu_queue_params)(
407 struct pmu_queue *queue, u32 id, 409 struct pmu_queue *queue, u32 id,
408 void *pmu_init_msg); 410 void *pmu_init_msg);
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
index 98d6e2df..b6c07793 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
@@ -520,6 +520,14 @@ static u32 *pmu_allocation_get_dmem_offset_addr_v3(struct pmu_gk20a *pmu,
520 return &pmu_a_ptr->alloc.dmem.offset; 520 return &pmu_a_ptr->alloc.dmem.offset;
521} 521}
522 522
523void *pmu_allocation_get_fb_addr_v3(
524 struct pmu_gk20a *pmu, void *pmu_alloc_ptr)
525{
526 struct pmu_allocation_v3 *pmu_a_ptr =
527 (struct pmu_allocation_v3 *)pmu_alloc_ptr;
528 return (void *)&pmu_a_ptr->alloc.fb;
529}
530
523static u32 *pmu_allocation_get_dmem_offset_addr_v2(struct pmu_gk20a *pmu, 531static u32 *pmu_allocation_get_dmem_offset_addr_v2(struct pmu_gk20a *pmu,
524 void *pmu_alloc_ptr) 532 void *pmu_alloc_ptr)
525{ 533{
@@ -1500,7 +1508,8 @@ int gk20a_init_pmu(struct pmu_gk20a *pmu)
1500 pmu_allocation_get_dmem_offset_addr_v3; 1508 pmu_allocation_get_dmem_offset_addr_v3;
1501 g->ops.pmu_ver.pmu_allocation_set_dmem_offset = 1509 g->ops.pmu_ver.pmu_allocation_set_dmem_offset =
1502 pmu_allocation_set_dmem_offset_v3; 1510 pmu_allocation_set_dmem_offset_v3;
1503 1511 g->ops.pmu_ver.pmu_allocation_get_fb_addr =
1512 pmu_allocation_get_fb_addr_v3;
1504 if(pmu->desc->app_version != APP_VERSION_NV_GPU && 1513 if(pmu->desc->app_version != APP_VERSION_NV_GPU &&
1505 pmu->desc->app_version != APP_VERSION_NV_GPU_1) { 1514 pmu->desc->app_version != APP_VERSION_NV_GPU_1) {
1506 g->ops.pmu_ver.get_pmu_init_msg_pmu_queue_params = 1515 g->ops.pmu_ver.get_pmu_init_msg_pmu_queue_params =
@@ -3763,6 +3772,27 @@ static int pmu_response_handle(struct pmu_gk20a *pmu,
3763 pv->pmu_allocation_get_dmem_offset(pmu, 3772 pv->pmu_allocation_get_dmem_offset(pmu,
3764 pv->get_pmu_seq_out_a_ptr(seq))); 3773 pv->get_pmu_seq_out_a_ptr(seq)));
3765 3774
3775 if (seq->out_mem != NULL) {
3776 memset(pv->pmu_allocation_get_fb_addr(pmu,
3777 pv->get_pmu_seq_out_a_ptr(seq)), 0x0,
3778 pv->get_pmu_allocation_struct_size(pmu));
3779
3780 gk20a_pmu_surface_free(g, seq->out_mem);
3781 if (seq->out_mem != seq->in_mem)
3782 kfree(seq->out_mem);
3783 else
3784 seq->out_mem = NULL;
3785 }
3786
3787 if (seq->in_mem != NULL) {
3788 memset(pv->pmu_allocation_get_fb_addr(pmu,
3789 pv->get_pmu_seq_in_a_ptr(seq)), 0x0,
3790 pv->get_pmu_allocation_struct_size(pmu));
3791
3792 gk20a_pmu_surface_free(g, seq->in_mem);
3793 kfree(seq->in_mem);
3794 }
3795
3766 if (seq->callback) 3796 if (seq->callback)
3767 seq->callback(g, msg, seq->cb_params, seq->desc, ret); 3797 seq->callback(g, msg, seq->cb_params, seq->desc, ret);
3768 3798
@@ -4356,6 +4386,53 @@ clean_up:
4356 return err; 4386 return err;
4357} 4387}
4358 4388
4389void gk20a_pmu_surface_describe(struct gk20a *g, struct mem_desc *mem,
4390 struct flcn_mem_desc_v0 *fb)
4391{
4392 fb->address.lo = u64_lo32(mem->gpu_va);
4393 fb->address.hi = u64_hi32(mem->gpu_va);
4394 fb->params = ((u32)mem->size & 0xFFFFFF);
4395 fb->params |= (GK20A_PMU_DMAIDX_VIRT << 24);
4396}
4397
4398int gk20a_pmu_vidmem_surface_alloc(struct gk20a *g, struct mem_desc *mem,
4399 u32 size)
4400{
4401 struct mm_gk20a *mm = &g->mm;
4402 struct vm_gk20a *vm = &mm->pmu.vm;
4403 int err;
4404
4405 err = gk20a_gmmu_alloc_map_vid(vm, size, mem);
4406 if (err) {
4407 gk20a_err(g->dev, "memory allocation failed");
4408 return -ENOMEM;
4409 }
4410
4411 return 0;
4412}
4413
4414int gk20a_pmu_sysmem_surface_alloc(struct gk20a *g, struct mem_desc *mem,
4415 u32 size)
4416{
4417 struct mm_gk20a *mm = &g->mm;
4418 struct vm_gk20a *vm = &mm->pmu.vm;
4419 int err;
4420
4421 err = gk20a_gmmu_alloc_map_sys(vm, size, mem);
4422 if (err) {
4423 gk20a_err(g->dev, "failed to allocate memory\n");
4424 return -ENOMEM;
4425 }
4426
4427 return 0;
4428}
4429
4430void gk20a_pmu_surface_free(struct gk20a *g, struct mem_desc *mem)
4431{
4432 gk20a_gmmu_free_attr(g, DMA_ATTR_NO_KERNEL_MAPPING, mem);
4433 memset(mem, 0, sizeof(struct mem_desc));
4434}
4435
4359int gk20a_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd, 4436int gk20a_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd,
4360 struct pmu_msg *msg, struct pmu_payload *payload, 4437 struct pmu_msg *msg, struct pmu_payload *payload,
4361 u32 queue_id, pmu_callback callback, void* cb_param, 4438 u32 queue_id, pmu_callback callback, void* cb_param,
@@ -4425,9 +4502,28 @@ int gk20a_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd,
4425 if (!*(pv->pmu_allocation_get_dmem_offset_addr(pmu, in))) 4502 if (!*(pv->pmu_allocation_get_dmem_offset_addr(pmu, in)))
4426 goto clean_up; 4503 goto clean_up;
4427 4504
4428 pmu_copy_to_dmem(pmu, (pv->pmu_allocation_get_dmem_offset(pmu, 4505 if (payload->in.fb_size != 0x0) {
4429 in)), 4506 seq->in_mem = kzalloc(sizeof(struct mem_desc),
4430 payload->in.buf, payload->in.size, 0); 4507 GFP_KERNEL);
4508 if (!seq->in_mem) {
4509 err = -ENOMEM;
4510 goto clean_up;
4511 }
4512
4513 gk20a_pmu_vidmem_surface_alloc(g, seq->in_mem,
4514 payload->in.fb_size);
4515 gk20a_pmu_surface_describe(g, seq->in_mem,
4516 (struct flcn_mem_desc_v0 *)
4517 pv->pmu_allocation_get_fb_addr(pmu, in));
4518
4519 gk20a_mem_wr_n(g, seq->in_mem, 0,
4520 payload->in.buf, payload->in.fb_size);
4521
4522 } else {
4523 pmu_copy_to_dmem(pmu,
4524 (pv->pmu_allocation_get_dmem_offset(pmu, in)),
4525 payload->in.buf, payload->in.size, 0);
4526 }
4431 pv->pmu_allocation_set_dmem_size(pmu, 4527 pv->pmu_allocation_set_dmem_size(pmu,
4432 pv->get_pmu_seq_in_a_ptr(seq), 4528 pv->get_pmu_seq_in_a_ptr(seq),
4433 pv->pmu_allocation_get_dmem_size(pmu, in)); 4529 pv->pmu_allocation_get_dmem_size(pmu, in));
@@ -4442,28 +4538,45 @@ int gk20a_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd,
4442 pv->pmu_allocation_set_dmem_size(pmu, out, 4538 pv->pmu_allocation_set_dmem_size(pmu, out,
4443 (u16)payload->out.size); 4539 (u16)payload->out.size);
4444 4540
4445 if (payload->out.buf != payload->in.buf) { 4541 if (payload->in.buf != payload->out.buf) {
4446
4447 *(pv->pmu_allocation_get_dmem_offset_addr(pmu, out)) = 4542 *(pv->pmu_allocation_get_dmem_offset_addr(pmu, out)) =
4448 gk20a_alloc(&pmu->dmem, 4543 gk20a_alloc(&pmu->dmem,
4449 pv->pmu_allocation_get_dmem_size(pmu, out)); 4544 pv->pmu_allocation_get_dmem_size(pmu, out));
4450 if (!*(pv->pmu_allocation_get_dmem_offset_addr(pmu, 4545 if (!*(pv->pmu_allocation_get_dmem_offset_addr(pmu,
4451 out))) 4546 out)))
4452 goto clean_up; 4547 goto clean_up;
4548
4549 if (payload->out.fb_size != 0x0) {
4550 seq->out_mem = kzalloc(sizeof(struct mem_desc),
4551 GFP_KERNEL);
4552 if (!seq->out_mem) {
4553 err = -ENOMEM;
4554 goto clean_up;
4555 }
4556 gk20a_pmu_vidmem_surface_alloc(g, seq->out_mem,
4557 payload->out.fb_size);
4558 gk20a_pmu_surface_describe(g, seq->out_mem,
4559 (struct flcn_mem_desc_v0 *)
4560 pv->pmu_allocation_get_fb_addr(pmu,
4561 out));
4562 }
4453 } else { 4563 } else {
4454 BUG_ON(in == NULL); 4564 BUG_ON(in == NULL);
4565 seq->out_mem = seq->in_mem;
4455 pv->pmu_allocation_set_dmem_offset(pmu, out, 4566 pv->pmu_allocation_set_dmem_offset(pmu, out,
4456 pv->pmu_allocation_get_dmem_offset(pmu, in)); 4567 pv->pmu_allocation_get_dmem_offset(pmu, in));
4457 } 4568 }
4458
4459 pv->pmu_allocation_set_dmem_size(pmu, 4569 pv->pmu_allocation_set_dmem_size(pmu,
4460 pv->get_pmu_seq_out_a_ptr(seq), 4570 pv->get_pmu_seq_out_a_ptr(seq),
4461 pv->pmu_allocation_get_dmem_size(pmu, out)); 4571 pv->pmu_allocation_get_dmem_size(pmu, out));
4462 pv->pmu_allocation_set_dmem_offset(pmu, 4572 pv->pmu_allocation_set_dmem_offset(pmu,
4463 pv->get_pmu_seq_out_a_ptr(seq), 4573 pv->get_pmu_seq_out_a_ptr(seq),
4464 pv->pmu_allocation_get_dmem_offset(pmu, out)); 4574 pv->pmu_allocation_get_dmem_offset(pmu, out));
4575
4465 } 4576 }
4466 4577
4578
4579
4467 seq->state = PMU_SEQ_STATE_USED; 4580 seq->state = PMU_SEQ_STATE_USED;
4468 err = pmu_write_cmd(pmu, cmd, queue_id, timeout); 4581 err = pmu_write_cmd(pmu, cmd, queue_id, timeout);
4469 if (err) 4582 if (err)
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
index d8af5d7c..93247411 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
@@ -525,6 +525,12 @@ struct pmu_payload {
525 } in, out; 525 } in, out;
526}; 526};
527 527
528struct pmu_surface {
529 struct mem_desc vidmem_desc;
530 struct mem_desc sysmem_desc;
531 struct flcn_mem_desc_v0 params;
532};
533
528typedef void (*pmu_callback)(struct gk20a *, struct pmu_msg *, void *, u32, 534typedef void (*pmu_callback)(struct gk20a *, struct pmu_msg *, void *, u32,
529 u32); 535 u32);
530 536
@@ -539,12 +545,14 @@ struct pmu_sequence {
539 struct pmu_allocation_v2 in_v2; 545 struct pmu_allocation_v2 in_v2;
540 struct pmu_allocation_v3 in_v3; 546 struct pmu_allocation_v3 in_v3;
541 }; 547 };
548 struct mem_desc *in_mem;
542 union { 549 union {
543 struct pmu_allocation_v0 out_v0; 550 struct pmu_allocation_v0 out_v0;
544 struct pmu_allocation_v1 out_v1; 551 struct pmu_allocation_v1 out_v1;
545 struct pmu_allocation_v2 out_v2; 552 struct pmu_allocation_v2 out_v2;
546 struct pmu_allocation_v3 out_v3; 553 struct pmu_allocation_v3 out_v3;
547 }; 554 };
555 struct mem_desc *out_mem;
548 u8 *out_payload; 556 u8 *out_payload;
549 pmu_callback callback; 557 pmu_callback callback;
550 void* cb_params; 558 void* cb_params;
@@ -797,4 +805,11 @@ int gk20a_pmu_reset(struct gk20a *g);
797int pmu_idle(struct pmu_gk20a *pmu); 805int pmu_idle(struct pmu_gk20a *pmu);
798int pmu_enable_hw(struct pmu_gk20a *pmu, bool enable); 806int pmu_enable_hw(struct pmu_gk20a *pmu, bool enable);
799 807
808void gk20a_pmu_surface_free(struct gk20a *g, struct mem_desc *mem);
809void gk20a_pmu_surface_describe(struct gk20a *g, struct mem_desc *mem,
810 struct flcn_mem_desc_v0 *fb);
811int gk20a_pmu_vidmem_surface_alloc(struct gk20a *g, struct mem_desc *mem,
812 u32 size);
813int gk20a_pmu_sysmem_surface_alloc(struct gk20a *g, struct mem_desc *mem,
814 u32 size);
800#endif /*__PMU_GK20A_H__*/ 815#endif /*__PMU_GK20A_H__*/