diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/fifo_gv11b.c | 136 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/platform_gv11b_tegra.c | 38 |
2 files changed, 173 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c index a153de7c..4b4c97b4 100644 --- a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c | |||
@@ -14,11 +14,17 @@ | |||
14 | */ | 14 | */ |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #ifdef CONFIG_TEGRA_GK20A_NVHOST | ||
18 | #include <linux/nvhost.h> | ||
19 | #include <linux/nvhost_t194.h> | ||
20 | #endif | ||
17 | 21 | ||
18 | #include <nvgpu/semaphore.h> | 22 | #include <nvgpu/semaphore.h> |
19 | #include <nvgpu/timers.h> | 23 | #include <nvgpu/timers.h> |
20 | #include <nvgpu/log.h> | 24 | #include <nvgpu/log.h> |
21 | 25 | #include <nvgpu/dma.h> | |
26 | #include <nvgpu/nvgpu_mem.h> | ||
27 | #include <nvgpu/gmmu.h> | ||
22 | 28 | ||
23 | #include "gk20a/gk20a.h" | 29 | #include "gk20a/gk20a.h" |
24 | #include "gk20a/fifo_gk20a.h" | 30 | #include "gk20a/fifo_gk20a.h" |
@@ -1411,6 +1417,123 @@ static unsigned int gv11b_fifo_handle_pbdma_intr_0(struct gk20a *g, | |||
1411 | return rc_type; | 1417 | return rc_type; |
1412 | } | 1418 | } |
1413 | 1419 | ||
1420 | #ifdef CONFIG_TEGRA_GK20A_NVHOST | ||
1421 | static int gv11b_fifo_alloc_syncpt_buf(struct channel_gk20a *c, | ||
1422 | u32 syncpt_id, struct nvgpu_mem *syncpt_buf) | ||
1423 | { | ||
1424 | struct page **pages; | ||
1425 | u32 nr_pages; | ||
1426 | u32 i; | ||
1427 | int err = 0; | ||
1428 | struct gk20a *g = c->g; | ||
1429 | |||
1430 | /* | ||
1431 | * Add rw mapping for entire syncpt shim for current channel vm | ||
1432 | * TODO : This needs to replaced with a new mecahnism where | ||
1433 | * only current syncpoint range will be rw and other sync | ||
1434 | * points range is read only for current channel vm. Also share | ||
1435 | * these mapping accross channels if they share same vm | ||
1436 | */ | ||
1437 | nr_pages = DIV_ROUND_UP(g->syncpt_unit_size, PAGE_SIZE); | ||
1438 | pages = nvgpu_kzalloc(g, sizeof(struct page *) * nr_pages); | ||
1439 | for (i = 0; i < nr_pages; i++) | ||
1440 | pages[i] = phys_to_page(g->syncpt_unit_base + | ||
1441 | PAGE_SIZE * i); | ||
1442 | __nvgpu_mem_create_from_pages(g, syncpt_buf, pages, nr_pages); | ||
1443 | nvgpu_kfree(g, pages); | ||
1444 | syncpt_buf->gpu_va = nvgpu_gmmu_map(c->vm, syncpt_buf, | ||
1445 | g->syncpt_unit_size, 0, gk20a_mem_flag_none, | ||
1446 | false, APERTURE_SYSMEM); | ||
1447 | |||
1448 | if (!syncpt_buf->gpu_va) { | ||
1449 | nvgpu_err(c->g, "failed to map syncpt buffer"); | ||
1450 | nvgpu_dma_free(c->g, syncpt_buf); | ||
1451 | err = -ENOMEM; | ||
1452 | } | ||
1453 | return err; | ||
1454 | } | ||
1455 | |||
1456 | static void gv11b_fifo_free_syncpt_buf(struct channel_gk20a *c, | ||
1457 | struct nvgpu_mem *syncpt_buf) | ||
1458 | { | ||
1459 | nvgpu_gmmu_unmap(c->vm, syncpt_buf, syncpt_buf->gpu_va); | ||
1460 | nvgpu_dma_free(c->g, syncpt_buf); | ||
1461 | } | ||
1462 | |||
1463 | static void gv11b_fifo_add_syncpt_wait_cmd(struct gk20a *g, | ||
1464 | struct priv_cmd_entry *cmd, u32 off, | ||
1465 | u32 id, u32 thresh, u64 gpu_va_base) | ||
1466 | { | ||
1467 | u64 gpu_va = gpu_va_base + | ||
1468 | nvhost_syncpt_unit_interface_get_byte_offset(id); | ||
1469 | |||
1470 | gk20a_dbg_fn(""); | ||
1471 | |||
1472 | off = cmd->off + off; | ||
1473 | |||
1474 | /* semaphore_a */ | ||
1475 | nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010004); | ||
1476 | nvgpu_mem_wr32(g, cmd->mem, off++, | ||
1477 | (gpu_va >> 32) & 0xff); | ||
1478 | /* semaphore_b */ | ||
1479 | nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010005); | ||
1480 | /* offset */ | ||
1481 | nvgpu_mem_wr32(g, cmd->mem, off++, gpu_va & 0xffffffff); | ||
1482 | |||
1483 | /* semaphore_c */ | ||
1484 | nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010006); | ||
1485 | /* payload */ | ||
1486 | nvgpu_mem_wr32(g, cmd->mem, off++, 0x0); | ||
1487 | /* semaphore_d */ | ||
1488 | nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010007); | ||
1489 | /* operation: acq_geq, switch_en */ | ||
1490 | nvgpu_mem_wr32(g, cmd->mem, off++, 0x4 | (0x1 << 12)); | ||
1491 | } | ||
1492 | |||
1493 | static u32 gv11b_fifo_get_syncpt_wait_cmd_size(void) | ||
1494 | { | ||
1495 | return 8; | ||
1496 | } | ||
1497 | |||
1498 | static void gv11b_fifo_add_syncpt_incr_cmd(struct gk20a *g, | ||
1499 | bool wfi_cmd, struct priv_cmd_entry *cmd, | ||
1500 | u32 id, u64 gpu_va_base) | ||
1501 | { | ||
1502 | u32 off = cmd->off; | ||
1503 | u64 gpu_va = gpu_va_base + | ||
1504 | nvhost_syncpt_unit_interface_get_byte_offset(id); | ||
1505 | |||
1506 | gk20a_dbg_fn(""); | ||
1507 | |||
1508 | /* semaphore_a */ | ||
1509 | nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010004); | ||
1510 | nvgpu_mem_wr32(g, cmd->mem, off++, | ||
1511 | (gpu_va >> 32) & 0xff); | ||
1512 | /* semaphore_b */ | ||
1513 | nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010005); | ||
1514 | /* offset */ | ||
1515 | nvgpu_mem_wr32(g, cmd->mem, off++, gpu_va & 0xffffffff); | ||
1516 | |||
1517 | /* semaphore_c */ | ||
1518 | nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010006); | ||
1519 | /* payload */ | ||
1520 | nvgpu_mem_wr32(g, cmd->mem, off++, 0x0); | ||
1521 | /* semaphore_d */ | ||
1522 | nvgpu_mem_wr32(g, cmd->mem, off++, 0x20010007); | ||
1523 | |||
1524 | /* operation: release, wfi */ | ||
1525 | nvgpu_mem_wr32(g, cmd->mem, off++, | ||
1526 | 0x2 | ((wfi_cmd ? 0x0 : 0x1) << 20)); | ||
1527 | /* ignored */ | ||
1528 | nvgpu_mem_wr32(g, cmd->mem, off++, 0); | ||
1529 | } | ||
1530 | |||
1531 | static u32 gv11b_fifo_get_syncpt_incr_cmd_size(bool wfi_cmd) | ||
1532 | { | ||
1533 | return 9; | ||
1534 | } | ||
1535 | #endif /* CONFIG_TEGRA_GK20A_NVHOST */ | ||
1536 | |||
1414 | void gv11b_init_fifo(struct gpu_ops *gops) | 1537 | void gv11b_init_fifo(struct gpu_ops *gops) |
1415 | { | 1538 | { |
1416 | gp10b_init_fifo(gops); | 1539 | gp10b_init_fifo(gops); |
@@ -1446,4 +1569,15 @@ void gv11b_init_fifo(struct gpu_ops *gops) | |||
1446 | gops->fifo.handle_ctxsw_timeout = gv11b_fifo_handle_ctxsw_timeout; | 1569 | gops->fifo.handle_ctxsw_timeout = gv11b_fifo_handle_ctxsw_timeout; |
1447 | gops->fifo.handle_pbdma_intr_0 = | 1570 | gops->fifo.handle_pbdma_intr_0 = |
1448 | gv11b_fifo_handle_pbdma_intr_0; | 1571 | gv11b_fifo_handle_pbdma_intr_0; |
1572 | #ifdef CONFIG_TEGRA_GK20A_NVHOST | ||
1573 | gops->fifo.alloc_syncpt_buf = gv11b_fifo_alloc_syncpt_buf; | ||
1574 | gops->fifo.free_syncpt_buf = gv11b_fifo_free_syncpt_buf; | ||
1575 | gops->fifo.add_syncpt_wait_cmd = gv11b_fifo_add_syncpt_wait_cmd; | ||
1576 | gops->fifo.get_syncpt_wait_cmd_size = | ||
1577 | gv11b_fifo_get_syncpt_wait_cmd_size; | ||
1578 | gops->fifo.add_syncpt_incr_cmd = gv11b_fifo_add_syncpt_incr_cmd; | ||
1579 | gops->fifo.get_syncpt_incr_cmd_size = | ||
1580 | gv11b_fifo_get_syncpt_incr_cmd_size; | ||
1581 | #endif | ||
1582 | |||
1449 | } | 1583 | } |
diff --git a/drivers/gpu/nvgpu/gv11b/platform_gv11b_tegra.c b/drivers/gpu/nvgpu/gv11b/platform_gv11b_tegra.c index 1cfa2ef2..8733cae9 100644 --- a/drivers/gpu/nvgpu/gv11b/platform_gv11b_tegra.c +++ b/drivers/gpu/nvgpu/gv11b/platform_gv11b_tegra.c | |||
@@ -19,6 +19,9 @@ | |||
19 | #include <linux/nvmap.h> | 19 | #include <linux/nvmap.h> |
20 | #include <linux/reset.h> | 20 | #include <linux/reset.h> |
21 | #include <linux/hashtable.h> | 21 | #include <linux/hashtable.h> |
22 | #ifdef CONFIG_TEGRA_GK20A_NVHOST | ||
23 | #include <linux/nvhost_t194.h> | ||
24 | #endif | ||
22 | 25 | ||
23 | #include <uapi/linux/nvgpu.h> | 26 | #include <uapi/linux/nvgpu.h> |
24 | 27 | ||
@@ -37,7 +40,42 @@ static void gr_gv11b_remove_sysfs(struct device *dev); | |||
37 | 40 | ||
38 | static int gv11b_tegra_probe(struct device *dev) | 41 | static int gv11b_tegra_probe(struct device *dev) |
39 | { | 42 | { |
43 | int err = 0; | ||
40 | struct gk20a_platform *platform = dev_get_drvdata(dev); | 44 | struct gk20a_platform *platform = dev_get_drvdata(dev); |
45 | struct gk20a *g = platform->g; | ||
46 | struct device_node *np = dev->of_node; | ||
47 | struct device_node *host1x_node; | ||
48 | struct platform_device *host1x_pdev; | ||
49 | const __be32 *host1x_ptr; | ||
50 | |||
51 | #ifdef CONFIG_TEGRA_GK20A_NVHOST | ||
52 | host1x_ptr = of_get_property(np, "nvidia,host1x", NULL); | ||
53 | if (!host1x_ptr) { | ||
54 | dev_err(dev, "host1x device not available"); | ||
55 | return -ENOSYS; | ||
56 | } | ||
57 | |||
58 | host1x_node = of_find_node_by_phandle(be32_to_cpup(host1x_ptr)); | ||
59 | host1x_pdev = of_find_device_by_node(host1x_node); | ||
60 | if (!host1x_pdev) { | ||
61 | dev_err(dev, "host1x device not available"); | ||
62 | return -ENOSYS; | ||
63 | } | ||
64 | |||
65 | platform->g->host1x_dev = host1x_pdev; | ||
66 | err = nvhost_syncpt_unit_interface_get_aperture( | ||
67 | g->host1x_dev, | ||
68 | &g->syncpt_unit_base, | ||
69 | &g->syncpt_unit_size); | ||
70 | if (err) { | ||
71 | dev_err(dev, "Failed to get syncpt interface"); | ||
72 | return -ENOSYS; | ||
73 | } | ||
74 | g->syncpt_size = nvhost_syncpt_unit_interface_get_byte_offset(1); | ||
75 | gk20a_dbg_info("syncpt_unit_base %llx syncpt_unit_size %zx size %x\n", | ||
76 | g->syncpt_unit_base, g->syncpt_unit_size, | ||
77 | g->syncpt_size); | ||
78 | #endif | ||
41 | 79 | ||
42 | platform->bypass_smmu = !device_is_iommuable(dev); | 80 | platform->bypass_smmu = !device_is_iommuable(dev); |
43 | platform->disable_bigpage = platform->bypass_smmu; | 81 | platform->disable_bigpage = platform->bypass_smmu; |