diff options
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/pmu_gk20a.c | 129 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/pmu_gk20a.h | 15 |
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 | ||
523 | void *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 | |||
523 | static u32 *pmu_allocation_get_dmem_offset_addr_v2(struct pmu_gk20a *pmu, | 531 | static 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 | ||
4389 | void 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 | |||
4398 | int 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 | |||
4414 | int 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 | |||
4430 | void 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 | |||
4359 | int gk20a_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd, | 4436 | int 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 | ||
528 | struct pmu_surface { | ||
529 | struct mem_desc vidmem_desc; | ||
530 | struct mem_desc sysmem_desc; | ||
531 | struct flcn_mem_desc_v0 params; | ||
532 | }; | ||
533 | |||
528 | typedef void (*pmu_callback)(struct gk20a *, struct pmu_msg *, void *, u32, | 534 | typedef 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); | |||
797 | int pmu_idle(struct pmu_gk20a *pmu); | 805 | int pmu_idle(struct pmu_gk20a *pmu); |
798 | int pmu_enable_hw(struct pmu_gk20a *pmu, bool enable); | 806 | int pmu_enable_hw(struct pmu_gk20a *pmu, bool enable); |
799 | 807 | ||
808 | void gk20a_pmu_surface_free(struct gk20a *g, struct mem_desc *mem); | ||
809 | void gk20a_pmu_surface_describe(struct gk20a *g, struct mem_desc *mem, | ||
810 | struct flcn_mem_desc_v0 *fb); | ||
811 | int gk20a_pmu_vidmem_surface_alloc(struct gk20a *g, struct mem_desc *mem, | ||
812 | u32 size); | ||
813 | int 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__*/ |