summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c6
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h2
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.c157
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.c151
4 files changed, 94 insertions, 222 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index 790b366c..5305f612 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -897,6 +897,12 @@ static int gk20a_pm_finalize_poweron(struct device *dev)
897 goto done; 897 goto done;
898 } 898 }
899 899
900 err = g->ops.pmu.prepare_ucode(g);
901 if (err) {
902 gk20a_err(dev, "failed to init pmu ucode");
903 goto done;
904 }
905
900 err = gk20a_init_pmu_support(g); 906 err = gk20a_init_pmu_support(g);
901 if (err) { 907 if (err) {
902 gk20a_err(dev, "failed to init gk20a pmu"); 908 gk20a_err(dev, "failed to init gk20a pmu");
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 127cb85c..07826675 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -220,7 +220,7 @@ struct gpu_ops {
220 u32 num_pages, u32 pgsz_idx); 220 u32 num_pages, u32 pgsz_idx);
221 } mm; 221 } mm;
222 struct { 222 struct {
223 int (*pmu_setup_sw)(struct gk20a *g); 223 int (*prepare_ucode)(struct gk20a *g);
224 int (*pmu_setup_hw_and_bootstrap)(struct gk20a *g); 224 int (*pmu_setup_hw_and_bootstrap)(struct gk20a *g);
225 } pmu; 225 } pmu;
226}; 226};
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);
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
index 1a136cdb..2b7be4f7 100644
--- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
@@ -68,7 +68,7 @@ void start_gm20b_pmu(struct gk20a *g)
68 68
69void gm20b_init_secure_pmu(struct gpu_ops *gops) 69void gm20b_init_secure_pmu(struct gpu_ops *gops)
70{ 70{
71 gops->pmu.pmu_setup_sw = gm20b_pmu_setup_sw; 71 gops->pmu.prepare_ucode = prepare_ucode_blob;
72 gops->pmu.pmu_setup_hw_and_bootstrap = gm20b_bootstrap_hs_flcn; 72 gops->pmu.pmu_setup_hw_and_bootstrap = gm20b_bootstrap_hs_flcn;
73} 73}
74 74
@@ -77,155 +77,6 @@ static void free_blob_res(struct gk20a *g)
77 /*TODO */ 77 /*TODO */
78} 78}
79 79
80int gm20b_pmu_setup_sw(struct gk20a *g)
81{
82 /*from pmu_gk20a.c*/
83 struct pmu_gk20a *pmu = &g->pmu;
84 struct mm_gk20a *mm = &g->mm;
85 struct vm_gk20a *vm = &mm->pmu.vm;
86 struct device *d = dev_from_gk20a(g);
87 int i, err = 0;
88 u8 *ptr;
89 struct sg_table *sgt_seq_buf;
90 dma_addr_t iova;
91
92 gk20a_dbg_fn("");
93 /* Make any ACR structure settings here if ever need be*/
94
95 if (pmu->sw_ready) {
96 for (i = 0; i < pmu->mutex_cnt; i++) {
97 pmu->mutex[i].id = i;
98 pmu->mutex[i].index = i;
99 }
100 pmu_seq_init(pmu);
101
102 mutex_init(&pmu->elpg_mutex);
103 mutex_init(&pmu->isr_mutex);
104 mutex_init(&pmu->pmu_copy_lock);
105 mutex_init(&pmu->pmu_seq_lock);
106 gk20a_dbg_fn("skip init");
107 goto skip_init;
108 }
109 gm20b_dbg_pmu("gk20a_init_pmu_setup_sw 2\n");
110
111 /* TBD: sysmon subtask */
112
113 if (IS_ENABLED(CONFIG_TEGRA_GK20A_PERFMON))
114 pmu->perfmon_sampling_enabled = true;
115
116 pmu->mutex_cnt = pwr_pmu_mutex__size_1_v();
117 pmu->mutex = kzalloc(pmu->mutex_cnt *
118 sizeof(struct pmu_mutex), GFP_KERNEL);
119 if (!pmu->mutex) {
120 err = -ENOMEM;
121 goto err;
122 }
123
124 for (i = 0; i < pmu->mutex_cnt; i++) {
125 pmu->mutex[i].id = i;
126 pmu->mutex[i].index = i;
127 }
128 gm20b_dbg_pmu("gk20a_init_pmu_setup_sw 3\n");
129
130 pmu->seq = kzalloc(PMU_MAX_NUM_SEQUENCES *
131 sizeof(struct pmu_sequence), GFP_KERNEL);
132 if (!pmu->seq) {
133 err = -ENOMEM;
134 goto err_free_mutex;
135 }
136
137 pmu_seq_init(pmu);
138 mutex_init(&pmu->elpg_mutex);
139 mutex_init(&pmu->isr_mutex);
140 mutex_init(&pmu->pmu_copy_lock);
141 mutex_init(&pmu->pmu_seq_lock);
142
143 err = prepare_ucode_blob(g);
144 if (err)
145 goto err_free_seq;
146 INIT_WORK(&pmu->pg_init, pmu_setup_hw);
147 pmu->seq_buf.cpuva = dma_alloc_coherent(d, GK20A_PMU_SEQ_BUF_SIZE,
148 &iova,
149 GFP_KERNEL);
150 if (!pmu->seq_buf.cpuva) {
151 gk20a_err(d, "failed to allocate memory\n");
152 err = -ENOMEM;
153 goto err_free_blob_res;
154 }
155
156 pmu->seq_buf.iova = iova;
157 err = gk20a_get_sgtable(d, &sgt_seq_buf,
158 pmu->seq_buf.cpuva,
159 pmu->seq_buf.iova,
160 GK20A_PMU_SEQ_BUF_SIZE);
161 if (err) {
162 gk20a_err(d, "failed to allocate sg table\n");
163 goto err_free_seq_buf;
164 }
165
166 pmu->seq_buf.pmu_va = gk20a_gmmu_map(vm, &sgt_seq_buf,
167 GK20A_PMU_SEQ_BUF_SIZE,
168 0, /* flags */
169 gk20a_mem_flag_none);
170 if (!pmu->seq_buf.pmu_va) {
171 gk20a_err(d, "failed to map pmu ucode memory!!");
172 goto err_free_seq_buf_sgt;
173 }
174
175 ptr = (u8 *)pmu->seq_buf.cpuva;
176 if (!ptr) {
177 gk20a_err(d, "failed to map cpu ptr for zbc buffer");
178 goto err_unmap_seq_buf;
179 }
180
181 /* TBD: remove this if ZBC save/restore is handled by PMU
182 * end an empty ZBC sequence for now */
183 ptr[0] = 0x16; /* opcode EXIT */
184 ptr[1] = 0; ptr[2] = 1; ptr[3] = 0;
185 ptr[4] = 0; ptr[5] = 0; ptr[6] = 0; ptr[7] = 0;
186
187 pmu->seq_buf.size = GK20A_PMU_SEQ_BUF_SIZE;
188
189 gk20a_dbg_fn("done");
190 gk20a_free_sgtable(&sgt_seq_buf);
191
192 pmu->sw_ready = true;
193
194skip_init:
195 pmu->perfmon_counter.index = 3; /* GR & CE2 */
196 pmu->perfmon_counter.group_id = PMU_DOMAIN_GROUP_PSTATE;
197
198 pmu->remove_support = gk20a_remove_pmu_support;
199 err = gk20a_init_pmu(pmu);
200 if (err) {
201 gk20a_err(d, "failed to set function pointers\n");
202 goto err_unmap_seq_buf;
203 }
204
205 gk20a_dbg_fn("done");
206 return 0;
207
208 err_unmap_seq_buf:
209 gk20a_gmmu_unmap(vm, pmu->seq_buf.pmu_va,
210 GK20A_PMU_SEQ_BUF_SIZE, gk20a_mem_flag_none);
211 err_free_seq_buf_sgt:
212 gk20a_free_sgtable(&sgt_seq_buf);
213 err_free_seq_buf:
214 dma_free_coherent(d, GK20A_PMU_SEQ_BUF_SIZE,
215 pmu->seq_buf.cpuva, pmu->seq_buf.iova);
216 pmu->seq_buf.cpuva = NULL;
217 pmu->seq_buf.iova = 0;
218 err_free_blob_res:
219 free_blob_res(g);
220 err_free_seq:
221 kfree(pmu->seq);
222 err_free_mutex:
223 kfree(pmu->mutex);
224 err:
225 gk20a_dbg_fn("fail");
226 return err;
227}
228
229int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) 80int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
230{ 81{
231 const struct firmware *pmu_fw; 82 const struct firmware *pmu_fw;