summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2014-06-18 07:39:25 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:10:17 -0400
commit7878824093972a6b8805dd8c00f1838e24a61ec0 (patch)
treeefbef295366773abb59c53aa26c3768a6619c3ad /drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
parent7ed71374e90f8e5c8554cb7d2f14aa8e9a807862 (diff)
gpu: nvgpu: Separate PMU firmware load from init
Separate the code to load PMU firmware from the software init. This allows folding ACR and non-ACR PMU software initialization sequences. Bug 200006956 Change-Id: I74b289747852167e8ebf1be63036c790ae634da4 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/424768 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/pmu_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.c157
1 files changed, 86 insertions, 71 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
index e8acf503..ac66dbef 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
@@ -1519,6 +1519,88 @@ int gk20a_init_pmu_reset_enable_hw(struct gk20a *g)
1519 return 0; 1519 return 0;
1520} 1520}
1521 1521
1522static int gk20a_prepare_ucode(struct gk20a *g)
1523{
1524 struct pmu_gk20a *pmu = &g->pmu;
1525 int i, err = 0;
1526 struct sg_table *sgt_pmu_ucode;
1527 dma_addr_t iova;
1528 struct device *d = dev_from_gk20a(g);
1529 struct mm_gk20a *mm = &g->mm;
1530 struct vm_gk20a *vm = &mm->pmu.vm;
1531 void *ucode_ptr;
1532 DEFINE_DMA_ATTRS(attrs);
1533
1534 if (!g->pmu_fw) {
1535 g->pmu_fw = gk20a_request_firmware(g, GK20A_PMU_UCODE_IMAGE);
1536 if (!g->pmu_fw) {
1537 gk20a_err(d, "failed to load pmu ucode!!");
1538 return err;
1539 }
1540 }
1541
1542 gk20a_dbg_fn("firmware loaded");
1543
1544 pmu->desc = (struct pmu_ucode_desc *)g->pmu_fw->data;
1545 pmu->ucode_image = (u32 *)((u8 *)pmu->desc +
1546 pmu->desc->descriptor_size);
1547
1548 dma_set_attr(DMA_ATTR_READ_ONLY, &attrs);
1549 pmu->ucode.cpuva = dma_alloc_attrs(d, GK20A_PMU_UCODE_SIZE_MAX,
1550 &iova,
1551 GFP_KERNEL,
1552 &attrs);
1553 if (!pmu->ucode.cpuva) {
1554 gk20a_err(d, "failed to allocate memory\n");
1555 err = -ENOMEM;
1556 goto err_release_fw;
1557 }
1558
1559 pmu->ucode.iova = iova;
1560
1561 err = gk20a_get_sgtable(d, &sgt_pmu_ucode,
1562 pmu->ucode.cpuva,
1563 pmu->ucode.iova,
1564 GK20A_PMU_UCODE_SIZE_MAX);
1565 if (err) {
1566 gk20a_err(d, "failed to allocate sg table\n");
1567 goto err_free_pmu_ucode;
1568 }
1569
1570 pmu->ucode.pmu_va = gk20a_gmmu_map(vm, &sgt_pmu_ucode,
1571 GK20A_PMU_UCODE_SIZE_MAX,
1572 0, /* flags */
1573 gk20a_mem_flag_read_only);
1574 if (!pmu->ucode.pmu_va) {
1575 gk20a_err(d, "failed to map pmu ucode memory!!");
1576 goto err_free_ucode_sgt;
1577 }
1578
1579 ucode_ptr = pmu->ucode.cpuva;
1580
1581 for (i = 0; i < (pmu->desc->app_start_offset +
1582 pmu->desc->app_size) >> 2; i++)
1583 gk20a_mem_wr32(ucode_ptr, i, pmu->ucode_image[i]);
1584
1585 gk20a_free_sgtable(&sgt_pmu_ucode);
1586
1587 gk20a_init_pmu(pmu);
1588
1589 return 0;
1590
1591 err_free_ucode_sgt:
1592 gk20a_free_sgtable(&sgt_pmu_ucode);
1593 err_free_pmu_ucode:
1594 dma_free_attrs(d, GK20A_PMU_UCODE_SIZE_MAX,
1595 pmu->ucode.cpuva, pmu->ucode.iova, &attrs);
1596 pmu->ucode.cpuva = NULL;
1597 pmu->ucode.iova = 0;
1598 err_release_fw:
1599 release_firmware(g->pmu_fw);
1600
1601 return err;
1602}
1603
1522int gk20a_init_pmu_setup_sw(struct gk20a *g) 1604int gk20a_init_pmu_setup_sw(struct gk20a *g)
1523{ 1605{
1524 struct pmu_gk20a *pmu = &g->pmu; 1606 struct pmu_gk20a *pmu = &g->pmu;
@@ -1527,10 +1609,7 @@ int gk20a_init_pmu_setup_sw(struct gk20a *g)
1527 struct device *d = dev_from_gk20a(g); 1609 struct device *d = dev_from_gk20a(g);
1528 int i, err = 0; 1610 int i, err = 0;
1529 u8 *ptr; 1611 u8 *ptr;
1530 void *ucode_ptr;
1531 struct sg_table *sgt_pmu_ucode;
1532 struct sg_table *sgt_seq_buf; 1612 struct sg_table *sgt_seq_buf;
1533 DEFINE_DMA_ATTRS(attrs);
1534 dma_addr_t iova; 1613 dma_addr_t iova;
1535 1614
1536 gk20a_dbg_fn(""); 1615 gk20a_dbg_fn("");
@@ -1575,71 +1654,26 @@ int gk20a_init_pmu_setup_sw(struct gk20a *g)
1575 1654
1576 pmu_seq_init(pmu); 1655 pmu_seq_init(pmu);
1577 1656
1578 if (!g->pmu_fw) {
1579 g->pmu_fw = gk20a_request_firmware(g, GK20A_PMU_UCODE_IMAGE);
1580 if (!g->pmu_fw) {
1581 gk20a_err(d, "failed to load pmu ucode!!");
1582 err = -ENOENT;
1583 goto err_free_seq;
1584 }
1585 }
1586
1587 gk20a_dbg_fn("firmware loaded");
1588
1589 pmu->desc = (struct pmu_ucode_desc *)g->pmu_fw->data;
1590 pmu->ucode_image = (u32 *)((u8 *)pmu->desc +
1591 pmu->desc->descriptor_size);
1592
1593 INIT_WORK(&pmu->pg_init, pmu_setup_hw); 1657 INIT_WORK(&pmu->pg_init, pmu_setup_hw);
1594 1658
1595 dma_set_attr(DMA_ATTR_READ_ONLY, &attrs);
1596 pmu->ucode.cpuva = dma_alloc_attrs(d, GK20A_PMU_UCODE_SIZE_MAX,
1597 &iova,
1598 GFP_KERNEL,
1599 &attrs);
1600 if (!pmu->ucode.cpuva) {
1601 gk20a_err(d, "failed to allocate memory\n");
1602 err = -ENOMEM;
1603 goto err_release_fw;
1604 }
1605
1606 pmu->ucode.iova = iova;
1607 pmu->seq_buf.cpuva = dma_alloc_coherent(d, GK20A_PMU_SEQ_BUF_SIZE, 1659 pmu->seq_buf.cpuva = dma_alloc_coherent(d, GK20A_PMU_SEQ_BUF_SIZE,
1608 &iova, 1660 &iova,
1609 GFP_KERNEL); 1661 GFP_KERNEL);
1610 if (!pmu->seq_buf.cpuva) { 1662 if (!pmu->seq_buf.cpuva) {
1611 gk20a_err(d, "failed to allocate memory\n"); 1663 gk20a_err(d, "failed to allocate memory\n");
1612 err = -ENOMEM; 1664 err = -ENOMEM;
1613 goto err_free_pmu_ucode; 1665 goto err_free_seq;
1614 } 1666 }
1615 1667
1616 pmu->seq_buf.iova = iova; 1668 pmu->seq_buf.iova = iova;
1617 1669
1618 err = gk20a_get_sgtable(d, &sgt_pmu_ucode,
1619 pmu->ucode.cpuva,
1620 pmu->ucode.iova,
1621 GK20A_PMU_UCODE_SIZE_MAX);
1622 if (err) {
1623 gk20a_err(d, "failed to allocate sg table\n");
1624 goto err_free_seq_buf;
1625 }
1626
1627 pmu->ucode.pmu_va = gk20a_gmmu_map(vm, &sgt_pmu_ucode,
1628 GK20A_PMU_UCODE_SIZE_MAX,
1629 0, /* flags */
1630 gk20a_mem_flag_read_only);
1631 if (!pmu->ucode.pmu_va) {
1632 gk20a_err(d, "failed to map pmu ucode memory!!");
1633 goto err_free_ucode_sgt;
1634 }
1635
1636 err = gk20a_get_sgtable(d, &sgt_seq_buf, 1670 err = gk20a_get_sgtable(d, &sgt_seq_buf,
1637 pmu->seq_buf.cpuva, 1671 pmu->seq_buf.cpuva,
1638 pmu->seq_buf.iova, 1672 pmu->seq_buf.iova,
1639 GK20A_PMU_SEQ_BUF_SIZE); 1673 GK20A_PMU_SEQ_BUF_SIZE);
1640 if (err) { 1674 if (err) {
1641 gk20a_err(d, "failed to allocate sg table\n"); 1675 gk20a_err(d, "failed to allocate sg table\n");
1642 goto err_unmap_ucode; 1676 goto err_free_seq_buf;
1643 } 1677 }
1644 1678
1645 pmu->seq_buf.pmu_va = gk20a_gmmu_map(vm, &sgt_seq_buf, 1679 pmu->seq_buf.pmu_va = gk20a_gmmu_map(vm, &sgt_seq_buf,
@@ -1665,13 +1699,6 @@ int gk20a_init_pmu_setup_sw(struct gk20a *g)
1665 1699
1666 pmu->seq_buf.size = GK20A_PMU_SEQ_BUF_SIZE; 1700 pmu->seq_buf.size = GK20A_PMU_SEQ_BUF_SIZE;
1667 1701
1668 ucode_ptr = pmu->ucode.cpuva;
1669
1670 for (i = 0; i < (pmu->desc->app_start_offset +
1671 pmu->desc->app_size) >> 2; i++)
1672 gk20a_mem_wr32(ucode_ptr, i, pmu->ucode_image[i]);
1673
1674 gk20a_free_sgtable(&sgt_pmu_ucode);
1675 gk20a_free_sgtable(&sgt_seq_buf); 1702 gk20a_free_sgtable(&sgt_seq_buf);
1676 1703
1677 pmu->sw_ready = true; 1704 pmu->sw_ready = true;
@@ -1700,23 +1727,11 @@ skip_init:
1700 GK20A_PMU_SEQ_BUF_SIZE, gk20a_mem_flag_none); 1727 GK20A_PMU_SEQ_BUF_SIZE, gk20a_mem_flag_none);
1701 err_free_seq_buf_sgt: 1728 err_free_seq_buf_sgt:
1702 gk20a_free_sgtable(&sgt_seq_buf); 1729 gk20a_free_sgtable(&sgt_seq_buf);
1703 err_unmap_ucode:
1704 gk20a_gmmu_unmap(vm, pmu->ucode.pmu_va,
1705 GK20A_PMU_UCODE_SIZE_MAX, gk20a_mem_flag_none);
1706 err_free_ucode_sgt:
1707 gk20a_free_sgtable(&sgt_pmu_ucode);
1708 err_free_seq_buf: 1730 err_free_seq_buf:
1709 dma_free_coherent(d, GK20A_PMU_SEQ_BUF_SIZE, 1731 dma_free_coherent(d, GK20A_PMU_SEQ_BUF_SIZE,
1710 pmu->seq_buf.cpuva, pmu->seq_buf.iova); 1732 pmu->seq_buf.cpuva, pmu->seq_buf.iova);
1711 pmu->seq_buf.cpuva = NULL; 1733 pmu->seq_buf.cpuva = NULL;
1712 pmu->seq_buf.iova = 0; 1734 pmu->seq_buf.iova = 0;
1713 err_free_pmu_ucode:
1714 dma_free_attrs(d, GK20A_PMU_UCODE_SIZE_MAX,
1715 pmu->ucode.cpuva, pmu->ucode.iova, &attrs);
1716 pmu->ucode.cpuva = NULL;
1717 pmu->ucode.iova = 0;
1718 err_release_fw:
1719 release_firmware(g->pmu_fw);
1720 err_free_seq: 1735 err_free_seq:
1721 kfree(pmu->seq); 1736 kfree(pmu->seq);
1722 err_free_mutex: 1737 err_free_mutex:
@@ -1977,7 +1992,7 @@ static void pmu_setup_hw_enable_elpg(struct gk20a *g)
1977 1992
1978void gk20a_init_pmu_ops(struct gpu_ops *gops) 1993void gk20a_init_pmu_ops(struct gpu_ops *gops)
1979{ 1994{
1980 gops->pmu.pmu_setup_sw = gk20a_init_pmu_setup_sw; 1995 gops->pmu.prepare_ucode = gk20a_prepare_ucode;
1981 gops->pmu.pmu_setup_hw_and_bootstrap = gk20a_init_pmu_setup_hw1; 1996 gops->pmu.pmu_setup_hw_and_bootstrap = gk20a_init_pmu_setup_hw1;
1982} 1997}
1983 1998
@@ -1996,7 +2011,7 @@ int gk20a_init_pmu_support(struct gk20a *g)
1996 return err; 2011 return err;
1997 2012
1998 if (support_gk20a_pmu()) { 2013 if (support_gk20a_pmu()) {
1999 err = g->ops.pmu.pmu_setup_sw(g); 2014 err = gk20a_init_pmu_setup_sw(g);
2000 if (err) 2015 if (err)
2001 return err; 2016 return err;
2002 err = g->ops.pmu.pmu_setup_hw_and_bootstrap(g); 2017 err = g->ops.pmu.pmu_setup_hw_and_bootstrap(g);