hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
....@@ -26,9 +26,9 @@
2626 #include "fuc/os.h"
2727
2828 #include <core/client.h>
29
-#include <core/option.h>
3029 #include <core/firmware.h>
31
-#include <subdev/secboot.h>
30
+#include <core/option.h>
31
+#include <subdev/acr.h>
3232 #include <subdev/fb.h>
3333 #include <subdev/mc.h>
3434 #include <subdev/pmu.h>
....@@ -714,6 +714,211 @@
714714 /*******************************************************************************
715715 * PGRAPH engine/subdev functions
716716 ******************************************************************************/
717
+
718
+static u32
719
+gf100_gr_ctxsw_inst(struct nvkm_gr *gr)
720
+{
721
+ return nvkm_rd32(gr->engine.subdev.device, 0x409b00);
722
+}
723
+
724
+static int
725
+gf100_gr_fecs_ctrl_ctxsw(struct gf100_gr *gr, u32 mthd)
726
+{
727
+ struct nvkm_device *device = gr->base.engine.subdev.device;
728
+
729
+ nvkm_wr32(device, 0x409804, 0xffffffff);
730
+ nvkm_wr32(device, 0x409840, 0xffffffff);
731
+ nvkm_wr32(device, 0x409500, 0xffffffff);
732
+ nvkm_wr32(device, 0x409504, mthd);
733
+ nvkm_msec(device, 2000,
734
+ u32 stat = nvkm_rd32(device, 0x409804);
735
+ if (stat == 0x00000002)
736
+ return -EIO;
737
+ if (stat == 0x00000001)
738
+ return 0;
739
+ );
740
+
741
+ return -ETIMEDOUT;
742
+}
743
+
744
+static int
745
+gf100_gr_fecs_start_ctxsw(struct nvkm_gr *base)
746
+{
747
+ struct gf100_gr *gr = gf100_gr(base);
748
+ int ret = 0;
749
+
750
+ mutex_lock(&gr->fecs.mutex);
751
+ if (!--gr->fecs.disable) {
752
+ if (WARN_ON(ret = gf100_gr_fecs_ctrl_ctxsw(gr, 0x39)))
753
+ gr->fecs.disable++;
754
+ }
755
+ mutex_unlock(&gr->fecs.mutex);
756
+ return ret;
757
+}
758
+
759
+static int
760
+gf100_gr_fecs_stop_ctxsw(struct nvkm_gr *base)
761
+{
762
+ struct gf100_gr *gr = gf100_gr(base);
763
+ int ret = 0;
764
+
765
+ mutex_lock(&gr->fecs.mutex);
766
+ if (!gr->fecs.disable++) {
767
+ if (WARN_ON(ret = gf100_gr_fecs_ctrl_ctxsw(gr, 0x38)))
768
+ gr->fecs.disable--;
769
+ }
770
+ mutex_unlock(&gr->fecs.mutex);
771
+ return ret;
772
+}
773
+
774
+int
775
+gf100_gr_fecs_bind_pointer(struct gf100_gr *gr, u32 inst)
776
+{
777
+ struct nvkm_device *device = gr->base.engine.subdev.device;
778
+
779
+ nvkm_wr32(device, 0x409840, 0x00000030);
780
+ nvkm_wr32(device, 0x409500, inst);
781
+ nvkm_wr32(device, 0x409504, 0x00000003);
782
+ nvkm_msec(device, 2000,
783
+ u32 stat = nvkm_rd32(device, 0x409800);
784
+ if (stat & 0x00000020)
785
+ return -EIO;
786
+ if (stat & 0x00000010)
787
+ return 0;
788
+ );
789
+
790
+ return -ETIMEDOUT;
791
+}
792
+
793
+static int
794
+gf100_gr_fecs_set_reglist_virtual_address(struct gf100_gr *gr, u64 addr)
795
+{
796
+ struct nvkm_device *device = gr->base.engine.subdev.device;
797
+
798
+ nvkm_wr32(device, 0x409810, addr >> 8);
799
+ nvkm_wr32(device, 0x409800, 0x00000000);
800
+ nvkm_wr32(device, 0x409500, 0x00000001);
801
+ nvkm_wr32(device, 0x409504, 0x00000032);
802
+ nvkm_msec(device, 2000,
803
+ if (nvkm_rd32(device, 0x409800) == 0x00000001)
804
+ return 0;
805
+ );
806
+
807
+ return -ETIMEDOUT;
808
+}
809
+
810
+static int
811
+gf100_gr_fecs_set_reglist_bind_instance(struct gf100_gr *gr, u32 inst)
812
+{
813
+ struct nvkm_device *device = gr->base.engine.subdev.device;
814
+
815
+ nvkm_wr32(device, 0x409810, inst);
816
+ nvkm_wr32(device, 0x409800, 0x00000000);
817
+ nvkm_wr32(device, 0x409500, 0x00000001);
818
+ nvkm_wr32(device, 0x409504, 0x00000031);
819
+ nvkm_msec(device, 2000,
820
+ if (nvkm_rd32(device, 0x409800) == 0x00000001)
821
+ return 0;
822
+ );
823
+
824
+ return -ETIMEDOUT;
825
+}
826
+
827
+static int
828
+gf100_gr_fecs_discover_reglist_image_size(struct gf100_gr *gr, u32 *psize)
829
+{
830
+ struct nvkm_device *device = gr->base.engine.subdev.device;
831
+
832
+ nvkm_wr32(device, 0x409800, 0x00000000);
833
+ nvkm_wr32(device, 0x409500, 0x00000001);
834
+ nvkm_wr32(device, 0x409504, 0x00000030);
835
+ nvkm_msec(device, 2000,
836
+ if ((*psize = nvkm_rd32(device, 0x409800)))
837
+ return 0;
838
+ );
839
+
840
+ return -ETIMEDOUT;
841
+}
842
+
843
+static int
844
+gf100_gr_fecs_elpg_bind(struct gf100_gr *gr)
845
+{
846
+ u32 size;
847
+ int ret;
848
+
849
+ ret = gf100_gr_fecs_discover_reglist_image_size(gr, &size);
850
+ if (ret)
851
+ return ret;
852
+
853
+ /*XXX: We need to allocate + map the above into PMU's inst block,
854
+ * which which means we probably need a proper PMU before we
855
+ * even bother.
856
+ */
857
+
858
+ ret = gf100_gr_fecs_set_reglist_bind_instance(gr, 0);
859
+ if (ret)
860
+ return ret;
861
+
862
+ return gf100_gr_fecs_set_reglist_virtual_address(gr, 0);
863
+}
864
+
865
+static int
866
+gf100_gr_fecs_discover_pm_image_size(struct gf100_gr *gr, u32 *psize)
867
+{
868
+ struct nvkm_device *device = gr->base.engine.subdev.device;
869
+
870
+ nvkm_wr32(device, 0x409840, 0xffffffff);
871
+ nvkm_wr32(device, 0x409500, 0x00000000);
872
+ nvkm_wr32(device, 0x409504, 0x00000025);
873
+ nvkm_msec(device, 2000,
874
+ if ((*psize = nvkm_rd32(device, 0x409800)))
875
+ return 0;
876
+ );
877
+
878
+ return -ETIMEDOUT;
879
+}
880
+
881
+static int
882
+gf100_gr_fecs_discover_zcull_image_size(struct gf100_gr *gr, u32 *psize)
883
+{
884
+ struct nvkm_device *device = gr->base.engine.subdev.device;
885
+
886
+ nvkm_wr32(device, 0x409840, 0xffffffff);
887
+ nvkm_wr32(device, 0x409500, 0x00000000);
888
+ nvkm_wr32(device, 0x409504, 0x00000016);
889
+ nvkm_msec(device, 2000,
890
+ if ((*psize = nvkm_rd32(device, 0x409800)))
891
+ return 0;
892
+ );
893
+
894
+ return -ETIMEDOUT;
895
+}
896
+
897
+static int
898
+gf100_gr_fecs_discover_image_size(struct gf100_gr *gr, u32 *psize)
899
+{
900
+ struct nvkm_device *device = gr->base.engine.subdev.device;
901
+
902
+ nvkm_wr32(device, 0x409840, 0xffffffff);
903
+ nvkm_wr32(device, 0x409500, 0x00000000);
904
+ nvkm_wr32(device, 0x409504, 0x00000010);
905
+ nvkm_msec(device, 2000,
906
+ if ((*psize = nvkm_rd32(device, 0x409800)))
907
+ return 0;
908
+ );
909
+
910
+ return -ETIMEDOUT;
911
+}
912
+
913
+static void
914
+gf100_gr_fecs_set_watchdog_timeout(struct gf100_gr *gr, u32 timeout)
915
+{
916
+ struct nvkm_device *device = gr->base.engine.subdev.device;
917
+
918
+ nvkm_wr32(device, 0x409840, 0xffffffff);
919
+ nvkm_wr32(device, 0x409500, timeout);
920
+ nvkm_wr32(device, 0x409504, 0x00000021);
921
+}
717922
718923 static bool
719924 gf100_gr_chsw_load(struct nvkm_gr *base)
....@@ -1431,7 +1636,7 @@
14311636
14321637 static void
14331638 gf100_gr_init_fw(struct nvkm_falcon *falcon,
1434
- struct gf100_gr_fuc *code, struct gf100_gr_fuc *data)
1639
+ struct nvkm_blob *code, struct nvkm_blob *data)
14351640 {
14361641 nvkm_falcon_load_dmem(falcon, data->data, 0x0, data->size, 0);
14371642 nvkm_falcon_load_imem(falcon, code->data, 0x0, code->size, 0, 0, false);
....@@ -1485,25 +1690,30 @@
14851690 {
14861691 struct nvkm_subdev *subdev = &gr->base.engine.subdev;
14871692 struct nvkm_device *device = subdev->device;
1488
- struct nvkm_secboot *sb = device->secboot;
1489
- u32 secboot_mask = 0;
1693
+ u32 lsf_mask = 0;
1694
+ int ret;
14901695
14911696 /* load fuc microcode */
14921697 nvkm_mc_unk260(device, 0);
14931698
14941699 /* securely-managed falcons must be reset using secure boot */
1495
- if (nvkm_secboot_is_managed(sb, NVKM_SECBOOT_FALCON_FECS))
1496
- secboot_mask |= BIT(NVKM_SECBOOT_FALCON_FECS);
1497
- else
1498
- gf100_gr_init_fw(gr->fecs, &gr->fuc409c, &gr->fuc409d);
14991700
1500
- if (nvkm_secboot_is_managed(sb, NVKM_SECBOOT_FALCON_GPCCS))
1501
- secboot_mask |= BIT(NVKM_SECBOOT_FALCON_GPCCS);
1502
- else
1503
- gf100_gr_init_fw(gr->gpccs, &gr->fuc41ac, &gr->fuc41ad);
1701
+ if (!nvkm_acr_managed_falcon(device, NVKM_ACR_LSF_FECS)) {
1702
+ gf100_gr_init_fw(&gr->fecs.falcon, &gr->fecs.inst,
1703
+ &gr->fecs.data);
1704
+ } else {
1705
+ lsf_mask |= BIT(NVKM_ACR_LSF_FECS);
1706
+ }
15041707
1505
- if (secboot_mask != 0) {
1506
- int ret = nvkm_secboot_reset(sb, secboot_mask);
1708
+ if (!nvkm_acr_managed_falcon(device, NVKM_ACR_LSF_GPCCS)) {
1709
+ gf100_gr_init_fw(&gr->gpccs.falcon, &gr->gpccs.inst,
1710
+ &gr->gpccs.data);
1711
+ } else {
1712
+ lsf_mask |= BIT(NVKM_ACR_LSF_GPCCS);
1713
+ }
1714
+
1715
+ if (lsf_mask) {
1716
+ ret = nvkm_acr_bootstrap_falcons(device, lsf_mask);
15071717 if (ret)
15081718 return ret;
15091719 }
....@@ -1515,8 +1725,8 @@
15151725 nvkm_wr32(device, 0x41a10c, 0x00000000);
15161726 nvkm_wr32(device, 0x40910c, 0x00000000);
15171727
1518
- nvkm_falcon_start(gr->gpccs);
1519
- nvkm_falcon_start(gr->fecs);
1728
+ nvkm_falcon_start(&gr->gpccs.falcon);
1729
+ nvkm_falcon_start(&gr->fecs.falcon);
15201730
15211731 if (nvkm_msec(device, 2000,
15221732 if (nvkm_rd32(device, 0x409800) & 0x00000001)
....@@ -1524,72 +1734,36 @@
15241734 ) < 0)
15251735 return -EBUSY;
15261736
1527
- nvkm_wr32(device, 0x409840, 0xffffffff);
1528
- nvkm_wr32(device, 0x409500, 0x7fffffff);
1529
- nvkm_wr32(device, 0x409504, 0x00000021);
1737
+ gf100_gr_fecs_set_watchdog_timeout(gr, 0x7fffffff);
15301738
1531
- nvkm_wr32(device, 0x409840, 0xffffffff);
1532
- nvkm_wr32(device, 0x409500, 0x00000000);
1533
- nvkm_wr32(device, 0x409504, 0x00000010);
1534
- if (nvkm_msec(device, 2000,
1535
- if ((gr->size = nvkm_rd32(device, 0x409800)))
1536
- break;
1537
- ) < 0)
1538
- return -EBUSY;
1739
+ /* Determine how much memory is required to store main context image. */
1740
+ ret = gf100_gr_fecs_discover_image_size(gr, &gr->size);
1741
+ if (ret)
1742
+ return ret;
15391743
1540
- nvkm_wr32(device, 0x409840, 0xffffffff);
1541
- nvkm_wr32(device, 0x409500, 0x00000000);
1542
- nvkm_wr32(device, 0x409504, 0x00000016);
1543
- if (nvkm_msec(device, 2000,
1544
- if (nvkm_rd32(device, 0x409800))
1545
- break;
1546
- ) < 0)
1547
- return -EBUSY;
1744
+ /* Determine how much memory is required to store ZCULL image. */
1745
+ ret = gf100_gr_fecs_discover_zcull_image_size(gr, &gr->size_zcull);
1746
+ if (ret)
1747
+ return ret;
15481748
1549
- nvkm_wr32(device, 0x409840, 0xffffffff);
1550
- nvkm_wr32(device, 0x409500, 0x00000000);
1551
- nvkm_wr32(device, 0x409504, 0x00000025);
1552
- if (nvkm_msec(device, 2000,
1553
- if (nvkm_rd32(device, 0x409800))
1554
- break;
1555
- ) < 0)
1556
- return -EBUSY;
1749
+ /* Determine how much memory is required to store PerfMon image. */
1750
+ ret = gf100_gr_fecs_discover_pm_image_size(gr, &gr->size_pm);
1751
+ if (ret)
1752
+ return ret;
15571753
1558
- if (device->chipset >= 0xe0) {
1559
- nvkm_wr32(device, 0x409800, 0x00000000);
1560
- nvkm_wr32(device, 0x409500, 0x00000001);
1561
- nvkm_wr32(device, 0x409504, 0x00000030);
1562
- if (nvkm_msec(device, 2000,
1563
- if (nvkm_rd32(device, 0x409800))
1564
- break;
1565
- ) < 0)
1566
- return -EBUSY;
1567
-
1568
- nvkm_wr32(device, 0x409810, 0xb00095c8);
1569
- nvkm_wr32(device, 0x409800, 0x00000000);
1570
- nvkm_wr32(device, 0x409500, 0x00000001);
1571
- nvkm_wr32(device, 0x409504, 0x00000031);
1572
- if (nvkm_msec(device, 2000,
1573
- if (nvkm_rd32(device, 0x409800))
1574
- break;
1575
- ) < 0)
1576
- return -EBUSY;
1577
-
1578
- nvkm_wr32(device, 0x409810, 0x00080420);
1579
- nvkm_wr32(device, 0x409800, 0x00000000);
1580
- nvkm_wr32(device, 0x409500, 0x00000001);
1581
- nvkm_wr32(device, 0x409504, 0x00000032);
1582
- if (nvkm_msec(device, 2000,
1583
- if (nvkm_rd32(device, 0x409800))
1584
- break;
1585
- ) < 0)
1586
- return -EBUSY;
1587
-
1588
- nvkm_wr32(device, 0x409614, 0x00000070);
1589
- nvkm_wr32(device, 0x409614, 0x00000770);
1590
- nvkm_wr32(device, 0x40802c, 0x00000001);
1754
+ /*XXX: We (likely) require PMU support to even bother with this.
1755
+ *
1756
+ * Also, it seems like not all GPUs support ELPG. Traces I
1757
+ * have here show RM enabling it on Kepler/Turing, but none
1758
+ * of the GPUs between those. NVGPU decides this by PCIID.
1759
+ */
1760
+ if (0) {
1761
+ ret = gf100_gr_fecs_elpg_bind(gr);
1762
+ if (ret)
1763
+ return ret;
15911764 }
15921765
1766
+ /* Generate golden context image. */
15931767 if (gr->data == NULL) {
15941768 int ret = gf100_grctx_generate(gr);
15951769 if (ret) {
....@@ -1614,15 +1788,19 @@
16141788
16151789 /* load HUB microcode */
16161790 nvkm_mc_unk260(device, 0);
1617
- nvkm_falcon_load_dmem(gr->fecs, gr->func->fecs.ucode->data.data, 0x0,
1791
+ nvkm_falcon_load_dmem(&gr->fecs.falcon,
1792
+ gr->func->fecs.ucode->data.data, 0x0,
16181793 gr->func->fecs.ucode->data.size, 0);
1619
- nvkm_falcon_load_imem(gr->fecs, gr->func->fecs.ucode->code.data, 0x0,
1794
+ nvkm_falcon_load_imem(&gr->fecs.falcon,
1795
+ gr->func->fecs.ucode->code.data, 0x0,
16201796 gr->func->fecs.ucode->code.size, 0, 0, false);
16211797
16221798 /* load GPC microcode */
1623
- nvkm_falcon_load_dmem(gr->gpccs, gr->func->gpccs.ucode->data.data, 0x0,
1799
+ nvkm_falcon_load_dmem(&gr->gpccs.falcon,
1800
+ gr->func->gpccs.ucode->data.data, 0x0,
16241801 gr->func->gpccs.ucode->data.size, 0);
1625
- nvkm_falcon_load_imem(gr->gpccs, gr->func->gpccs.ucode->code.data, 0x0,
1802
+ nvkm_falcon_load_imem(&gr->gpccs.falcon,
1803
+ gr->func->gpccs.ucode->code.data, 0x0,
16261804 gr->func->gpccs.ucode->code.size, 0, 0, false);
16271805 nvkm_mc_unk260(device, 1);
16281806
....@@ -1767,15 +1945,6 @@
17671945 struct nvkm_subdev *subdev = &gr->base.engine.subdev;
17681946 struct nvkm_device *device = subdev->device;
17691947 int i, j;
1770
- int ret;
1771
-
1772
- ret = nvkm_falcon_v1_new(subdev, "FECS", 0x409000, &gr->fecs);
1773
- if (ret)
1774
- return ret;
1775
-
1776
- ret = nvkm_falcon_v1_new(subdev, "GPCCS", 0x41a000, &gr->gpccs);
1777
- if (ret)
1778
- return ret;
17791948
17801949 nvkm_pmu_pgob(device->pmu, false);
17811950
....@@ -1812,15 +1981,41 @@
18121981 {
18131982 struct gf100_gr *gr = gf100_gr(base);
18141983 struct nvkm_subdev *subdev = &base->engine.subdev;
1984
+ struct nvkm_device *device = subdev->device;
1985
+ bool reset = device->chipset == 0x137 || device->chipset == 0x138;
18151986 u32 ret;
1987
+
1988
+ /* On certain GP107/GP108 boards, we trigger a weird issue where
1989
+ * GR will stop responding to PRI accesses after we've asked the
1990
+ * SEC2 RTOS to boot the GR falcons. This happens with far more
1991
+ * frequency when cold-booting a board (ie. returning from D3).
1992
+ *
1993
+ * The root cause for this is not known and has proven difficult
1994
+ * to isolate, with many avenues being dead-ends.
1995
+ *
1996
+ * A workaround was discovered by Karol, whereby putting GR into
1997
+ * reset for an extended period right before initialisation
1998
+ * prevents the problem from occuring.
1999
+ *
2000
+ * XXX: As RM does not require any such workaround, this is more
2001
+ * of a hack than a true fix.
2002
+ */
2003
+ reset = nvkm_boolopt(device->cfgopt, "NvGrResetWar", reset);
2004
+ if (reset) {
2005
+ nvkm_mask(device, 0x000200, 0x00001000, 0x00000000);
2006
+ nvkm_rd32(device, 0x000200);
2007
+ msleep(50);
2008
+ nvkm_mask(device, 0x000200, 0x00001000, 0x00001000);
2009
+ nvkm_rd32(device, 0x000200);
2010
+ }
18162011
18172012 nvkm_pmu_pgob(gr->base.engine.subdev.device->pmu, false);
18182013
1819
- ret = nvkm_falcon_get(gr->fecs, subdev);
2014
+ ret = nvkm_falcon_get(&gr->fecs.falcon, subdev);
18202015 if (ret)
18212016 return ret;
18222017
1823
- ret = nvkm_falcon_get(gr->gpccs, subdev);
2018
+ ret = nvkm_falcon_get(&gr->gpccs.falcon, subdev);
18242019 if (ret)
18252020 return ret;
18262021
....@@ -1828,49 +2023,34 @@
18282023 }
18292024
18302025 static int
1831
-gf100_gr_fini_(struct nvkm_gr *base, bool suspend)
2026
+gf100_gr_fini(struct nvkm_gr *base, bool suspend)
18322027 {
18332028 struct gf100_gr *gr = gf100_gr(base);
18342029 struct nvkm_subdev *subdev = &gr->base.engine.subdev;
1835
- nvkm_falcon_put(gr->gpccs, subdev);
1836
- nvkm_falcon_put(gr->fecs, subdev);
2030
+ nvkm_falcon_put(&gr->gpccs.falcon, subdev);
2031
+ nvkm_falcon_put(&gr->fecs.falcon, subdev);
18372032 return 0;
18382033 }
18392034
1840
-void
1841
-gf100_gr_dtor_fw(struct gf100_gr_fuc *fuc)
1842
-{
1843
- kfree(fuc->data);
1844
- fuc->data = NULL;
1845
-}
1846
-
1847
-static void
1848
-gf100_gr_dtor_init(struct gf100_gr_pack *pack)
1849
-{
1850
- vfree(pack);
1851
-}
1852
-
1853
-void *
2035
+static void *
18542036 gf100_gr_dtor(struct nvkm_gr *base)
18552037 {
18562038 struct gf100_gr *gr = gf100_gr(base);
18572039
1858
- if (gr->func->dtor)
1859
- gr->func->dtor(gr);
18602040 kfree(gr->data);
18612041
1862
- nvkm_falcon_del(&gr->gpccs);
1863
- nvkm_falcon_del(&gr->fecs);
2042
+ nvkm_falcon_dtor(&gr->gpccs.falcon);
2043
+ nvkm_falcon_dtor(&gr->fecs.falcon);
18642044
1865
- gf100_gr_dtor_fw(&gr->fuc409c);
1866
- gf100_gr_dtor_fw(&gr->fuc409d);
1867
- gf100_gr_dtor_fw(&gr->fuc41ac);
1868
- gf100_gr_dtor_fw(&gr->fuc41ad);
2045
+ nvkm_blob_dtor(&gr->fecs.inst);
2046
+ nvkm_blob_dtor(&gr->fecs.data);
2047
+ nvkm_blob_dtor(&gr->gpccs.inst);
2048
+ nvkm_blob_dtor(&gr->gpccs.data);
18692049
1870
- gf100_gr_dtor_init(gr->fuc_bundle);
1871
- gf100_gr_dtor_init(gr->fuc_method);
1872
- gf100_gr_dtor_init(gr->fuc_sw_ctx);
1873
- gf100_gr_dtor_init(gr->fuc_sw_nonctx);
2050
+ vfree(gr->bundle);
2051
+ vfree(gr->method);
2052
+ vfree(gr->sw_ctx);
2053
+ vfree(gr->sw_nonctx);
18742054
18752055 return gr;
18762056 }
....@@ -1880,97 +2060,35 @@
18802060 .dtor = gf100_gr_dtor,
18812061 .oneinit = gf100_gr_oneinit,
18822062 .init = gf100_gr_init_,
1883
- .fini = gf100_gr_fini_,
2063
+ .fini = gf100_gr_fini,
18842064 .intr = gf100_gr_intr,
18852065 .units = gf100_gr_units,
18862066 .chan_new = gf100_gr_chan_new,
18872067 .object_get = gf100_gr_object_get,
18882068 .chsw_load = gf100_gr_chsw_load,
2069
+ .ctxsw.pause = gf100_gr_fecs_stop_ctxsw,
2070
+ .ctxsw.resume = gf100_gr_fecs_start_ctxsw,
2071
+ .ctxsw.inst = gf100_gr_ctxsw_inst,
2072
+};
2073
+
2074
+static const struct nvkm_falcon_func
2075
+gf100_gr_flcn = {
2076
+ .fbif = 0x600,
2077
+ .load_imem = nvkm_falcon_v1_load_imem,
2078
+ .load_dmem = nvkm_falcon_v1_load_dmem,
2079
+ .read_dmem = nvkm_falcon_v1_read_dmem,
2080
+ .bind_context = nvkm_falcon_v1_bind_context,
2081
+ .wait_for_halt = nvkm_falcon_v1_wait_for_halt,
2082
+ .clear_interrupt = nvkm_falcon_v1_clear_interrupt,
2083
+ .set_start_addr = nvkm_falcon_v1_set_start_addr,
2084
+ .start = nvkm_falcon_v1_start,
2085
+ .enable = nvkm_falcon_v1_enable,
2086
+ .disable = nvkm_falcon_v1_disable,
18892087 };
18902088
18912089 int
1892
-gf100_gr_ctor_fw_legacy(struct gf100_gr *gr, const char *fwname,
1893
- struct gf100_gr_fuc *fuc, int ret)
1894
-{
1895
- struct nvkm_subdev *subdev = &gr->base.engine.subdev;
1896
- struct nvkm_device *device = subdev->device;
1897
- const struct firmware *fw;
1898
- char f[32];
1899
-
1900
- /* see if this firmware has a legacy path */
1901
- if (!strcmp(fwname, "fecs_inst"))
1902
- fwname = "fuc409c";
1903
- else if (!strcmp(fwname, "fecs_data"))
1904
- fwname = "fuc409d";
1905
- else if (!strcmp(fwname, "gpccs_inst"))
1906
- fwname = "fuc41ac";
1907
- else if (!strcmp(fwname, "gpccs_data"))
1908
- fwname = "fuc41ad";
1909
- else {
1910
- /* nope, let's just return the error we got */
1911
- nvkm_error(subdev, "failed to load %s\n", fwname);
1912
- return ret;
1913
- }
1914
-
1915
- /* yes, try to load from the legacy path */
1916
- nvkm_debug(subdev, "%s: falling back to legacy path\n", fwname);
1917
-
1918
- snprintf(f, sizeof(f), "nouveau/nv%02x_%s", device->chipset, fwname);
1919
- ret = request_firmware(&fw, f, device->dev);
1920
- if (ret) {
1921
- snprintf(f, sizeof(f), "nouveau/%s", fwname);
1922
- ret = request_firmware(&fw, f, device->dev);
1923
- if (ret) {
1924
- nvkm_error(subdev, "failed to load %s\n", fwname);
1925
- return ret;
1926
- }
1927
- }
1928
-
1929
- fuc->size = fw->size;
1930
- fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
1931
- release_firmware(fw);
1932
- return (fuc->data != NULL) ? 0 : -ENOMEM;
1933
-}
1934
-
1935
-int
1936
-gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
1937
- struct gf100_gr_fuc *fuc)
1938
-{
1939
- struct nvkm_subdev *subdev = &gr->base.engine.subdev;
1940
- struct nvkm_device *device = subdev->device;
1941
- const struct firmware *fw;
1942
- int ret;
1943
-
1944
- ret = nvkm_firmware_get(device, fwname, &fw);
1945
- if (ret) {
1946
- ret = gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret);
1947
- if (ret)
1948
- return -ENODEV;
1949
- return 0;
1950
- }
1951
-
1952
- fuc->size = fw->size;
1953
- fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
1954
- nvkm_firmware_put(fw);
1955
- return (fuc->data != NULL) ? 0 : -ENOMEM;
1956
-}
1957
-
1958
-int
1959
-gf100_gr_ctor(const struct gf100_gr_func *func, struct nvkm_device *device,
1960
- int index, struct gf100_gr *gr)
1961
-{
1962
- gr->func = func;
1963
- gr->firmware = nvkm_boolopt(device->cfgopt, "NvGrUseFW",
1964
- func->fecs.ucode == NULL);
1965
-
1966
- return nvkm_gr_ctor(&gf100_gr_, device, index,
1967
- gr->firmware || func->fecs.ucode != NULL,
1968
- &gr->base);
1969
-}
1970
-
1971
-int
1972
-gf100_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device,
1973
- int index, struct nvkm_gr **pgr)
2090
+gf100_gr_new_(const struct gf100_gr_fwif *fwif,
2091
+ struct nvkm_device *device, int index, struct nvkm_gr **pgr)
19742092 {
19752093 struct gf100_gr *gr;
19762094 int ret;
....@@ -1979,19 +2097,46 @@
19792097 return -ENOMEM;
19802098 *pgr = &gr->base;
19812099
1982
- ret = gf100_gr_ctor(func, device, index, gr);
2100
+ ret = nvkm_gr_ctor(&gf100_gr_, device, index, true, &gr->base);
19832101 if (ret)
19842102 return ret;
19852103
1986
- if (gr->firmware) {
1987
- if (gf100_gr_ctor_fw(gr, "fecs_inst", &gr->fuc409c) ||
1988
- gf100_gr_ctor_fw(gr, "fecs_data", &gr->fuc409d) ||
1989
- gf100_gr_ctor_fw(gr, "gpccs_inst", &gr->fuc41ac) ||
1990
- gf100_gr_ctor_fw(gr, "gpccs_data", &gr->fuc41ad))
1991
- return -ENODEV;
1992
- }
2104
+ fwif = nvkm_firmware_load(&gr->base.engine.subdev, fwif, "Gr", gr);
2105
+ if (IS_ERR(fwif))
2106
+ return PTR_ERR(fwif);
2107
+
2108
+ gr->func = fwif->func;
2109
+
2110
+ ret = nvkm_falcon_ctor(&gf100_gr_flcn, &gr->base.engine.subdev,
2111
+ "fecs", 0x409000, &gr->fecs.falcon);
2112
+ if (ret)
2113
+ return ret;
2114
+
2115
+ mutex_init(&gr->fecs.mutex);
2116
+
2117
+ ret = nvkm_falcon_ctor(&gf100_gr_flcn, &gr->base.engine.subdev,
2118
+ "gpccs", 0x41a000, &gr->gpccs.falcon);
2119
+ if (ret)
2120
+ return ret;
19932121
19942122 return 0;
2123
+}
2124
+
2125
+void
2126
+gf100_gr_init_num_tpc_per_gpc(struct gf100_gr *gr, bool pd, bool ds)
2127
+{
2128
+ struct nvkm_device *device = gr->base.engine.subdev.device;
2129
+ int gpc, i, j;
2130
+ u32 data;
2131
+
2132
+ for (gpc = 0, i = 0; i < 4; i++) {
2133
+ for (data = 0, j = 0; j < 8 && gpc < gr->gpc_nr; j++, gpc++)
2134
+ data |= gr->tpc_nr[gpc] << (j * 4);
2135
+ if (pd)
2136
+ nvkm_wr32(device, 0x406028 + (i * 4), data);
2137
+ if (ds)
2138
+ nvkm_wr32(device, 0x405870 + (i * 4), data);
2139
+ }
19952140 }
19962141
19972142 void
....@@ -2118,8 +2263,8 @@
21182263
21192264 gr->func->init_gpc_mmu(gr);
21202265
2121
- if (gr->fuc_sw_nonctx)
2122
- gf100_gr_mmio(gr, gr->fuc_sw_nonctx);
2266
+ if (gr->sw_nonctx)
2267
+ gf100_gr_mmio(gr, gr->sw_nonctx);
21232268 else
21242269 gf100_gr_mmio(gr, gr->func->mmio);
21252270
....@@ -2143,6 +2288,8 @@
21432288 gr->func->init_bios_2(gr);
21442289 if (gr->func->init_swdx_pes_mask)
21452290 gr->func->init_swdx_pes_mask(gr);
2291
+ if (gr->func->init_fs)
2292
+ gr->func->init_fs(gr);
21462293
21472294 nvkm_wr32(device, 0x400500, 0x00010001);
21482295
....@@ -2161,8 +2308,8 @@
21612308 if (gr->func->init_40601c)
21622309 gr->func->init_40601c(gr);
21632310
2164
- nvkm_wr32(device, 0x404490, 0xc0000000);
21652311 nvkm_wr32(device, 0x406018, 0xc0000000);
2312
+ nvkm_wr32(device, 0x404490, 0xc0000000);
21662313
21672314 if (gr->func->init_sked_hww_esr)
21682315 gr->func->init_sked_hww_esr(gr);
....@@ -2277,7 +2424,66 @@
22772424 };
22782425
22792426 int
2427
+gf100_gr_nofw(struct gf100_gr *gr, int ver, const struct gf100_gr_fwif *fwif)
2428
+{
2429
+ gr->firmware = false;
2430
+ return 0;
2431
+}
2432
+
2433
+static int
2434
+gf100_gr_load_fw(struct gf100_gr *gr, const char *name,
2435
+ struct nvkm_blob *blob)
2436
+{
2437
+ struct nvkm_subdev *subdev = &gr->base.engine.subdev;
2438
+ struct nvkm_device *device = subdev->device;
2439
+ const struct firmware *fw;
2440
+ char f[32];
2441
+ int ret;
2442
+
2443
+ snprintf(f, sizeof(f), "nouveau/nv%02x_%s", device->chipset, name);
2444
+ ret = request_firmware(&fw, f, device->dev);
2445
+ if (ret) {
2446
+ snprintf(f, sizeof(f), "nouveau/%s", name);
2447
+ ret = request_firmware(&fw, f, device->dev);
2448
+ if (ret) {
2449
+ nvkm_error(subdev, "failed to load %s\n", name);
2450
+ return ret;
2451
+ }
2452
+ }
2453
+
2454
+ blob->size = fw->size;
2455
+ blob->data = kmemdup(fw->data, blob->size, GFP_KERNEL);
2456
+ release_firmware(fw);
2457
+ return (blob->data != NULL) ? 0 : -ENOMEM;
2458
+}
2459
+
2460
+int
2461
+gf100_gr_load(struct gf100_gr *gr, int ver, const struct gf100_gr_fwif *fwif)
2462
+{
2463
+ struct nvkm_device *device = gr->base.engine.subdev.device;
2464
+
2465
+ if (!nvkm_boolopt(device->cfgopt, "NvGrUseFW", false))
2466
+ return -EINVAL;
2467
+
2468
+ if (gf100_gr_load_fw(gr, "fuc409c", &gr->fecs.inst) ||
2469
+ gf100_gr_load_fw(gr, "fuc409d", &gr->fecs.data) ||
2470
+ gf100_gr_load_fw(gr, "fuc41ac", &gr->gpccs.inst) ||
2471
+ gf100_gr_load_fw(gr, "fuc41ad", &gr->gpccs.data))
2472
+ return -ENOENT;
2473
+
2474
+ gr->firmware = true;
2475
+ return 0;
2476
+}
2477
+
2478
+static const struct gf100_gr_fwif
2479
+gf100_gr_fwif[] = {
2480
+ { -1, gf100_gr_load, &gf100_gr },
2481
+ { -1, gf100_gr_nofw, &gf100_gr },
2482
+ {}
2483
+};
2484
+
2485
+int
22802486 gf100_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
22812487 {
2282
- return gf100_gr_new_(&gf100_gr, device, index, pgr);
2488
+ return gf100_gr_new_(gf100_gr_fwif, device, index, pgr);
22832489 }