diff options
author | Seema Khowala <seemaj@nvidia.com> | 2017-06-27 19:36:48 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-07-02 13:20:08 -0400 |
commit | 8a0221cfc735f79c94447ff5922e26c313e0f177 (patch) | |
tree | b05cd72d9ae236cae90a843e9ecf1cc027d616c6 | |
parent | 5a57be6ba1d491b4a3258281c82345fdb4a83675 (diff) |
gpu: nvgpu: gv11b: implement eng method buffer init/deinit
When CE hits a page fault it needs to save out methods, it will
save it out to a per runqueue per TSG method buffer. The method buffers
(one per TSG runqueue) are allocated in BAR2 space during TSG creation
All channels in a TSG that are mapped to the same runqueue will point
to the same buffer.
S/w will insert channel's method buffer pointer in the channel's
instance block entries NV_RAMIN_ENG_METHOD_BUFFER_ADDR_LO and
NV_RAMIN_ENG_METHOD_BUFFER_ADDR_HI. Method buffer in memory will
be 32B aligned.
Eng method buffer allocated per tsg will be de-allocated during
tsg_release.
JIRA GPUT19X-46
Change-Id: Ib480ae5840d9815d24fe2eadc169ac3102854cd0
Signed-off-by: Seema Khowala <seemaj@nvidia.com>
Reviewed-on: https://git-master/r/1509747
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/fifo_gv11b.c | 109 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/fifo_gv11b.h | 4 |
2 files changed, 113 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c index 1194663b..3e73a29e 100644 --- a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c | |||
@@ -48,6 +48,9 @@ | |||
48 | #define CHANNEL_INFO_VEID0 0 | 48 | #define CHANNEL_INFO_VEID0 0 |
49 | #define PBDMA_SUBDEVICE_ID 1 | 49 | #define PBDMA_SUBDEVICE_ID 1 |
50 | 50 | ||
51 | static void gv11b_fifo_init_ramfc_eng_method_buffer(struct gk20a *g, | ||
52 | struct channel_gk20a *ch, struct nvgpu_mem *mem); | ||
53 | |||
51 | static inline void gv11b_usermode_writel(struct gk20a *g, u32 r, u32 v) | 54 | static inline void gv11b_usermode_writel(struct gk20a *g, u32 r, u32 v) |
52 | { | 55 | { |
53 | struct fifo_gk20a *f = &g->fifo; | 56 | struct fifo_gk20a *f = &g->fifo; |
@@ -180,6 +183,8 @@ static int channel_gv11b_setup_ramfc(struct channel_gk20a *c, | |||
180 | pbdma_set_channel_info_scg_type_graphics_compute0_f() | | 183 | pbdma_set_channel_info_scg_type_graphics_compute0_f() | |
181 | pbdma_set_channel_info_veid_f(CHANNEL_INFO_VEID0)); | 184 | pbdma_set_channel_info_veid_f(CHANNEL_INFO_VEID0)); |
182 | 185 | ||
186 | gv11b_fifo_init_ramfc_eng_method_buffer(g, c, mem); | ||
187 | |||
183 | if (c->is_privileged_channel) { | 188 | if (c->is_privileged_channel) { |
184 | /* Set privilege level for channel */ | 189 | /* Set privilege level for channel */ |
185 | nvgpu_mem_wr32(g, mem, ram_fc_config_w(), | 190 | nvgpu_mem_wr32(g, mem, ram_fc_config_w(), |
@@ -1470,6 +1475,106 @@ static unsigned int gv11b_fifo_handle_pbdma_intr_1(struct gk20a *g, | |||
1470 | return rc_type; | 1475 | return rc_type; |
1471 | } | 1476 | } |
1472 | 1477 | ||
1478 | static void gv11b_fifo_init_ramfc_eng_method_buffer(struct gk20a *g, | ||
1479 | struct channel_gk20a *ch, struct nvgpu_mem *mem) | ||
1480 | { | ||
1481 | struct tsg_gk20a *tsg; | ||
1482 | struct nvgpu_mem *method_buffer_per_runque; | ||
1483 | |||
1484 | tsg = tsg_gk20a_from_ch(ch); | ||
1485 | if (tsg == NULL) { | ||
1486 | nvgpu_err(g, "channel is not part of tsg"); | ||
1487 | return; | ||
1488 | } | ||
1489 | if (tsg->eng_method_buffers == NULL) { | ||
1490 | nvgpu_log_info(g, "eng method buffer NULL"); | ||
1491 | return; | ||
1492 | } | ||
1493 | if (tsg->runlist_id == gk20a_fifo_get_fast_ce_runlist_id(g)) | ||
1494 | method_buffer_per_runque = | ||
1495 | &tsg->eng_method_buffers[ASYNC_CE_RUNQUE]; | ||
1496 | else | ||
1497 | method_buffer_per_runque = | ||
1498 | &tsg->eng_method_buffers[GR_RUNQUE]; | ||
1499 | |||
1500 | nvgpu_mem_wr32(g, mem, ram_in_eng_method_buffer_addr_lo_w(), | ||
1501 | u64_lo32(method_buffer_per_runque->gpu_va)); | ||
1502 | nvgpu_mem_wr32(g, mem, ram_in_eng_method_buffer_addr_hi_w(), | ||
1503 | u64_hi32(method_buffer_per_runque->gpu_va)); | ||
1504 | |||
1505 | nvgpu_log_info(g, "init ramfc with method buffer"); | ||
1506 | } | ||
1507 | |||
1508 | unsigned int gv11b_fifo_get_eng_method_buffer_size(struct gk20a *g) | ||
1509 | { | ||
1510 | unsigned int buffer_size; | ||
1511 | |||
1512 | buffer_size = ((9 + 1 + 3) * g->ops.ce2.get_num_pce(g)) + 2; | ||
1513 | buffer_size = (27 * 5 * buffer_size); | ||
1514 | buffer_size = roundup(buffer_size, PAGE_SIZE); | ||
1515 | nvgpu_log_info(g, "method buffer size in bytes %d", buffer_size); | ||
1516 | |||
1517 | return buffer_size; | ||
1518 | } | ||
1519 | |||
1520 | static void gv11b_fifo_init_eng_method_buffers(struct gk20a *g, | ||
1521 | struct tsg_gk20a *tsg) | ||
1522 | { | ||
1523 | struct vm_gk20a *vm = g->mm.bar2.vm; | ||
1524 | int err = 0; | ||
1525 | unsigned int i, runque, method_buffer_size; | ||
1526 | unsigned int num_pbdma = g->fifo.num_pbdma; | ||
1527 | |||
1528 | if (tsg->eng_method_buffers != NULL) | ||
1529 | return; | ||
1530 | |||
1531 | method_buffer_size = gv11b_fifo_get_eng_method_buffer_size(g); | ||
1532 | if (method_buffer_size == 0) { | ||
1533 | nvgpu_info(g, "ce will hit MTHD_BUFFER_FAULT"); | ||
1534 | return; | ||
1535 | } | ||
1536 | |||
1537 | tsg->eng_method_buffers = nvgpu_kzalloc(g, | ||
1538 | num_pbdma * sizeof(struct nvgpu_mem)); | ||
1539 | |||
1540 | for (runque = 0; runque < num_pbdma; runque++) { | ||
1541 | err = nvgpu_dma_alloc_map_sys(vm, method_buffer_size, | ||
1542 | &tsg->eng_method_buffers[runque]); | ||
1543 | if (err) | ||
1544 | break; | ||
1545 | } | ||
1546 | if (err) { | ||
1547 | for (i = runque; i < runque; i--) | ||
1548 | nvgpu_dma_unmap_free(vm, | ||
1549 | &tsg->eng_method_buffers[runque]); | ||
1550 | |||
1551 | nvgpu_kfree(g, tsg->eng_method_buffers); | ||
1552 | tsg->eng_method_buffers = NULL; | ||
1553 | nvgpu_err(g, "could not alloc eng method buffers"); | ||
1554 | return; | ||
1555 | } | ||
1556 | nvgpu_log_info(g, "eng method buffers allocated"); | ||
1557 | |||
1558 | } | ||
1559 | |||
1560 | static void gv11b_fifo_deinit_eng_method_buffers(struct gk20a *g, | ||
1561 | struct tsg_gk20a *tsg) | ||
1562 | { | ||
1563 | struct vm_gk20a *vm = g->mm.bar2.vm; | ||
1564 | unsigned int runque; | ||
1565 | |||
1566 | if (tsg->eng_method_buffers == NULL) | ||
1567 | return; | ||
1568 | |||
1569 | for (runque = 0; runque < g->fifo.num_pbdma; runque++) | ||
1570 | nvgpu_dma_unmap_free(vm, &tsg->eng_method_buffers[runque]); | ||
1571 | |||
1572 | nvgpu_kfree(g, tsg->eng_method_buffers); | ||
1573 | tsg->eng_method_buffers = NULL; | ||
1574 | |||
1575 | nvgpu_log_info(g, "eng method buffers de-allocated"); | ||
1576 | } | ||
1577 | |||
1473 | #ifdef CONFIG_TEGRA_GK20A_NVHOST | 1578 | #ifdef CONFIG_TEGRA_GK20A_NVHOST |
1474 | static int gv11b_fifo_alloc_syncpt_buf(struct channel_gk20a *c, | 1579 | static int gv11b_fifo_alloc_syncpt_buf(struct channel_gk20a *c, |
1475 | u32 syncpt_id, struct nvgpu_mem *syncpt_buf) | 1580 | u32 syncpt_id, struct nvgpu_mem *syncpt_buf) |
@@ -1633,6 +1738,10 @@ void gv11b_init_fifo(struct gpu_ops *gops) | |||
1633 | gv11b_fifo_handle_pbdma_intr_0; | 1738 | gv11b_fifo_handle_pbdma_intr_0; |
1634 | gops->fifo.handle_pbdma_intr_1 = | 1739 | gops->fifo.handle_pbdma_intr_1 = |
1635 | gv11b_fifo_handle_pbdma_intr_1; | 1740 | gv11b_fifo_handle_pbdma_intr_1; |
1741 | gops->fifo.init_eng_method_buffers = | ||
1742 | gv11b_fifo_init_eng_method_buffers; | ||
1743 | gops->fifo.deinit_eng_method_buffers = | ||
1744 | gv11b_fifo_deinit_eng_method_buffers; | ||
1636 | #ifdef CONFIG_TEGRA_GK20A_NVHOST | 1745 | #ifdef CONFIG_TEGRA_GK20A_NVHOST |
1637 | gops->fifo.alloc_syncpt_buf = gv11b_fifo_alloc_syncpt_buf; | 1746 | gops->fifo.alloc_syncpt_buf = gv11b_fifo_alloc_syncpt_buf; |
1638 | gops->fifo.free_syncpt_buf = gv11b_fifo_free_syncpt_buf; | 1747 | gops->fifo.free_syncpt_buf = gv11b_fifo_free_syncpt_buf; |
diff --git a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.h b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.h index ab56b876..94b7934f 100644 --- a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.h +++ b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.h | |||
@@ -31,6 +31,10 @@ | |||
31 | */ | 31 | */ |
32 | #define SCHED_ERROR_CODE_BAD_TSG 0x00000020 | 32 | #define SCHED_ERROR_CODE_BAD_TSG 0x00000020 |
33 | 33 | ||
34 | /* can be removed after runque support is added */ | ||
35 | |||
36 | #define GR_RUNQUE 0 /* pbdma 0 */ | ||
37 | #define ASYNC_CE_RUNQUE 2 /* pbdma 2 */ | ||
34 | 38 | ||
35 | struct gpu_ops; | 39 | struct gpu_ops; |
36 | void gv11b_init_fifo(struct gpu_ops *gops); | 40 | void gv11b_init_fifo(struct gpu_ops *gops); |