aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/core/core/client.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/core/handle.c5
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.c46
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc5
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h17
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc10
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h147
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc13
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h157
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c11
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nve0.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/client.h3
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h8
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/gpio.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/base.c5
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c128
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/init.c66
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nve0.c28
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/base.c9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/base.c35
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mxm/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/base.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c30
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c9
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c11
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_prime.c1
-rw-r--r--drivers/gpu/drm/nouveau/nv04_dfp.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv10_fence.c8
-rw-r--r--drivers/gpu/drm/nouveau/nv50_fence.c1
40 files changed, 509 insertions, 299 deletions
diff --git a/drivers/gpu/drm/nouveau/core/core/client.c b/drivers/gpu/drm/nouveau/core/core/client.c
index c617f0480071..8bbb58f94a19 100644
--- a/drivers/gpu/drm/nouveau/core/core/client.c
+++ b/drivers/gpu/drm/nouveau/core/core/client.c
@@ -66,10 +66,8 @@ nouveau_client_create_(const char *name, u64 devname, const char *cfg,
66 66
67 ret = nouveau_handle_create(nv_object(client), ~0, ~0, 67 ret = nouveau_handle_create(nv_object(client), ~0, ~0,
68 nv_object(client), &client->root); 68 nv_object(client), &client->root);
69 if (ret) { 69 if (ret)
70 nouveau_namedb_destroy(&client->base);
71 return ret; 70 return ret;
72 }
73 71
74 /* prevent init/fini being called, os in in charge of this */ 72 /* prevent init/fini being called, os in in charge of this */
75 atomic_set(&nv_object(client)->usecount, 2); 73 atomic_set(&nv_object(client)->usecount, 2);
diff --git a/drivers/gpu/drm/nouveau/core/core/handle.c b/drivers/gpu/drm/nouveau/core/core/handle.c
index b8d2cbf8a7a7..264c2b338ac3 100644
--- a/drivers/gpu/drm/nouveau/core/core/handle.c
+++ b/drivers/gpu/drm/nouveau/core/core/handle.c
@@ -109,7 +109,7 @@ nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle,
109 while (!nv_iclass(namedb, NV_NAMEDB_CLASS)) 109 while (!nv_iclass(namedb, NV_NAMEDB_CLASS))
110 namedb = namedb->parent; 110 namedb = namedb->parent;
111 111
112 handle = *phandle = kzalloc(sizeof(*handle), GFP_KERNEL); 112 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
113 if (!handle) 113 if (!handle)
114 return -ENOMEM; 114 return -ENOMEM;
115 115
@@ -146,6 +146,9 @@ nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle,
146 } 146 }
147 147
148 hprintk(handle, TRACE, "created\n"); 148 hprintk(handle, TRACE, "created\n");
149
150 *phandle = handle;
151
149 return 0; 152 return 0;
150} 153}
151 154
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
index 0f09af135415..ca1a7d76a95b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -851,20 +851,23 @@ exec_script(struct nv50_disp_priv *priv, int head, int id)
851 for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) 851 for (i = 0; !(ctrl & (1 << head)) && i < 3; i++)
852 ctrl = nv_rd32(priv, 0x610b5c + (i * 8)); 852 ctrl = nv_rd32(priv, 0x610b5c + (i * 8));
853 853
854 if (nv_device(priv)->chipset < 0x90 || 854 if (!(ctrl & (1 << head))) {
855 nv_device(priv)->chipset == 0x92 || 855 if (nv_device(priv)->chipset < 0x90 ||
856 nv_device(priv)->chipset == 0xa0) { 856 nv_device(priv)->chipset == 0x92 ||
857 for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) 857 nv_device(priv)->chipset == 0xa0) {
858 ctrl = nv_rd32(priv, 0x610b74 + (i * 8)); 858 for (i = 0; !(ctrl & (1 << head)) && i < 2; i++)
859 i += 3; 859 ctrl = nv_rd32(priv, 0x610b74 + (i * 8));
860 } else { 860 i += 4;
861 for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) 861 } else {
862 ctrl = nv_rd32(priv, 0x610798 + (i * 8)); 862 for (i = 0; !(ctrl & (1 << head)) && i < 4; i++)
863 i += 3; 863 ctrl = nv_rd32(priv, 0x610798 + (i * 8));
864 i += 4;
865 }
864 } 866 }
865 867
866 if (!(ctrl & (1 << head))) 868 if (!(ctrl & (1 << head)))
867 return false; 869 return false;
870 i--;
868 871
869 data = exec_lookup(priv, head, i, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info); 872 data = exec_lookup(priv, head, i, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info);
870 if (data) { 873 if (data) {
@@ -898,20 +901,23 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk,
898 for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) 901 for (i = 0; !(ctrl & (1 << head)) && i < 3; i++)
899 ctrl = nv_rd32(priv, 0x610b58 + (i * 8)); 902 ctrl = nv_rd32(priv, 0x610b58 + (i * 8));
900 903
901 if (nv_device(priv)->chipset < 0x90 || 904 if (!(ctrl & (1 << head))) {
902 nv_device(priv)->chipset == 0x92 || 905 if (nv_device(priv)->chipset < 0x90 ||
903 nv_device(priv)->chipset == 0xa0) { 906 nv_device(priv)->chipset == 0x92 ||
904 for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) 907 nv_device(priv)->chipset == 0xa0) {
905 ctrl = nv_rd32(priv, 0x610b70 + (i * 8)); 908 for (i = 0; !(ctrl & (1 << head)) && i < 2; i++)
906 i += 3; 909 ctrl = nv_rd32(priv, 0x610b70 + (i * 8));
907 } else { 910 i += 4;
908 for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) 911 } else {
909 ctrl = nv_rd32(priv, 0x610794 + (i * 8)); 912 for (i = 0; !(ctrl & (1 << head)) && i < 4; i++)
910 i += 3; 913 ctrl = nv_rd32(priv, 0x610794 + (i * 8));
914 i += 4;
915 }
911 } 916 }
912 917
913 if (!(ctrl & (1 << head))) 918 if (!(ctrl & (1 << head)))
914 return 0x0000; 919 return 0x0000;
920 i--;
915 921
916 data = exec_lookup(priv, head, i, ctrl, outp, &ver, &hdr, &cnt, &len, &info1); 922 data = exec_lookup(priv, head, i, ctrl, outp, &ver, &hdr, &cnt, &len, &info1);
917 if (!data) 923 if (!data)
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc
index 7b715fda2763..62ab231cd6b6 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc
@@ -57,6 +57,11 @@ chipsets:
57.b16 #nve4_gpc_mmio_tail 57.b16 #nve4_gpc_mmio_tail
58.b16 #nve4_tpc_mmio_head 58.b16 #nve4_tpc_mmio_head
59.b16 #nve4_tpc_mmio_tail 59.b16 #nve4_tpc_mmio_tail
60.b8 0xe6 0 0 0
61.b16 #nve4_gpc_mmio_head
62.b16 #nve4_gpc_mmio_tail
63.b16 #nve4_tpc_mmio_head
64.b16 #nve4_tpc_mmio_tail
60.b8 0 0 0 0 65.b8 0 0 0 0
61 66
62// GPC mmio lists 67// GPC mmio lists
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h
index 26c2165bad0f..09ee4702c8b2 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h
@@ -34,13 +34,16 @@ uint32_t nve0_grgpc_data[] = {
34 0x00000000, 34 0x00000000,
35/* 0x0064: chipsets */ 35/* 0x0064: chipsets */
36 0x000000e4, 36 0x000000e4,
37 0x01040080, 37 0x0110008c,
38 0x014c0104, 38 0x01580110,
39 0x000000e7, 39 0x000000e7,
40 0x01040080, 40 0x0110008c,
41 0x014c0104, 41 0x01580110,
42 0x000000e6,
43 0x0110008c,
44 0x01580110,
42 0x00000000, 45 0x00000000,
43/* 0x0080: nve4_gpc_mmio_head */ 46/* 0x008c: nve4_gpc_mmio_head */
44 0x00000380, 47 0x00000380,
45 0x04000400, 48 0x04000400,
46 0x0800040c, 49 0x0800040c,
@@ -74,8 +77,8 @@ uint32_t nve0_grgpc_data[] = {
74 0x14003100, 77 0x14003100,
75 0x000031d0, 78 0x000031d0,
76 0x040031e0, 79 0x040031e0,
77/* 0x0104: nve4_gpc_mmio_tail */ 80/* 0x0110: nve4_gpc_mmio_tail */
78/* 0x0104: nve4_tpc_mmio_head */ 81/* 0x0110: nve4_tpc_mmio_head */
79 0x00000048, 82 0x00000048,
80 0x00000064, 83 0x00000064,
81 0x00000088, 84 0x00000088,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc
index acfc457654bd..0bcfa4d447e5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc
@@ -754,6 +754,16 @@ ctx_mmio_exec:
754// on load it means: "a save preceeded this load" 754// on load it means: "a save preceeded this load"
755// 755//
756ctx_xfer: 756ctx_xfer:
757 // according to mwk, some kind of wait for idle
758 mov $r15 0xc00
759 shl b32 $r15 6
760 mov $r14 4
761 iowr I[$r15 + 0x200] $r14
762 ctx_xfer_idle:
763 iord $r14 I[$r15 + 0x000]
764 and $r14 0x2000
765 bra ne #ctx_xfer_idle
766
757 bra not $p1 #ctx_xfer_pre 767 bra not $p1 #ctx_xfer_pre
758 bra $p2 #ctx_xfer_pre_load 768 bra $p2 #ctx_xfer_pre_load
759 ctx_xfer_pre: 769 ctx_xfer_pre:
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h
index 85a8d556f484..bb03d2a1d57b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h
@@ -799,79 +799,80 @@ uint32_t nvc0_grhub_code[] = {
799 0x01fa0613, 799 0x01fa0613,
800 0xf803f806, 800 0xf803f806,
801/* 0x0829: ctx_xfer */ 801/* 0x0829: ctx_xfer */
802 0x0611f400, 802 0x00f7f100,
803/* 0x082f: ctx_xfer_pre */ 803 0x06f4b60c,
804 0xf01102f4, 804 0xd004e7f0,
805 0x21f510f7, 805/* 0x0836: ctx_xfer_idle */
806 0x21f50698, 806 0xfecf80fe,
807 0x11f40631, 807 0x00e4f100,
808/* 0x083d: ctx_xfer_pre_load */ 808 0xf91bf420,
809 0x02f7f01c, 809 0xf40611f4,
810 0x065721f5, 810/* 0x0846: ctx_xfer_pre */
811 0x066621f5, 811 0xf7f01102,
812 0x067821f5, 812 0x9821f510,
813 0x21f5f4bd, 813 0x3121f506,
814 0x21f50657, 814 0x1c11f406,
815/* 0x0856: ctx_xfer_exec */ 815/* 0x0854: ctx_xfer_pre_load */
816 0x019806b8, 816 0xf502f7f0,
817 0x1427f116, 817 0xf5065721,
818 0x0624b604, 818 0xf5066621,
819 0xf10020d0, 819 0xbd067821,
820 0xf0a500e7, 820 0x5721f5f4,
821 0x1fb941e3, 821 0xb821f506,
822 0x8d21f402, 822/* 0x086d: ctx_xfer_exec */
823 0xf004e0b6, 823 0x16019806,
824 0x2cf001fc, 824 0x041427f1,
825 0x0124b602, 825 0xd00624b6,
826 0xf405f2fd, 826 0xe7f10020,
827 0x17f18d21, 827 0xe3f0a500,
828 0x13f04afc, 828 0x021fb941,
829 0x0c27f002, 829 0xb68d21f4,
830 0xf50012d0, 830 0xfcf004e0,
831 0xf1020721, 831 0x022cf001,
832 0xf047fc27, 832 0xfd0124b6,
833 0x20d00223, 833 0x21f405f2,
834 0x012cf000, 834 0xfc17f18d,
835 0xd00320b6, 835 0x0213f04a,
836 0xacf00012, 836 0xd00c27f0,
837 0x06a5f001, 837 0x21f50012,
838 0x9800b7f0, 838 0x27f10207,
839 0x0d98140c, 839 0x23f047fc,
840 0x00e7f015, 840 0x0020d002,
841 0x015c21f5, 841 0xb6012cf0,
842 0xf508a7f0, 842 0x12d00320,
843 0xf5010321, 843 0x01acf000,
844 0xf4020721, 844 0xf006a5f0,
845 0xa7f02201, 845 0x0c9800b7,
846 0xc921f40c, 846 0x150d9814,
847 0x0a1017f1, 847 0xf500e7f0,
848 0xf00614b6, 848 0xf0015c21,
849 0x12d00527, 849 0x21f508a7,
850/* 0x08dd: ctx_xfer_post_save_wait */ 850 0x21f50103,
851 0x0012cf00, 851 0x01f40207,
852 0xf40522fd, 852 0x0ca7f022,
853 0x02f4fa1b, 853 0xf1c921f4,
854/* 0x08e9: ctx_xfer_post */ 854 0xb60a1017,
855 0x02f7f032, 855 0x27f00614,
856 0x065721f5, 856 0x0012d005,
857 0x21f5f4bd, 857/* 0x08f4: ctx_xfer_post_save_wait */
858 0x21f50698, 858 0xfd0012cf,
859 0x21f50226, 859 0x1bf40522,
860 0xf4bd0666, 860 0x3202f4fa,
861 0x065721f5, 861/* 0x0900: ctx_xfer_post */
862 0x981011f4, 862 0xf502f7f0,
863 0x11fd8001, 863 0xbd065721,
864 0x070bf405, 864 0x9821f5f4,
865 0x07df21f5, 865 0x2621f506,
866/* 0x0914: ctx_xfer_no_post_mmio */ 866 0x6621f502,
867 0x064921f5, 867 0xf5f4bd06,
868/* 0x0918: ctx_xfer_done */ 868 0xf4065721,
869 0x000000f8, 869 0x01981011,
870 0x00000000, 870 0x0511fd80,
871 0x00000000, 871 0xf5070bf4,
872 0x00000000, 872/* 0x092b: ctx_xfer_no_post_mmio */
873 0x00000000, 873 0xf507df21,
874 0x00000000, 874/* 0x092f: ctx_xfer_done */
875 0xf8064921,
875 0x00000000, 876 0x00000000,
876 0x00000000, 877 0x00000000,
877 0x00000000, 878 0x00000000,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc
index 138eeaa28665..7fe9d7cf486b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc
@@ -44,6 +44,9 @@ chipsets:
44.b8 0xe7 0 0 0 44.b8 0xe7 0 0 0
45.b16 #nve4_hub_mmio_head 45.b16 #nve4_hub_mmio_head
46.b16 #nve4_hub_mmio_tail 46.b16 #nve4_hub_mmio_tail
47.b8 0xe6 0 0 0
48.b16 #nve4_hub_mmio_head
49.b16 #nve4_hub_mmio_tail
47.b8 0 0 0 0 50.b8 0 0 0 0
48 51
49nve4_hub_mmio_head: 52nve4_hub_mmio_head:
@@ -680,6 +683,16 @@ ctx_mmio_exec:
680// on load it means: "a save preceeded this load" 683// on load it means: "a save preceeded this load"
681// 684//
682ctx_xfer: 685ctx_xfer:
686 // according to mwk, some kind of wait for idle
687 mov $r15 0xc00
688 shl b32 $r15 6
689 mov $r14 4
690 iowr I[$r15 + 0x200] $r14
691 ctx_xfer_idle:
692 iord $r14 I[$r15 + 0x000]
693 and $r14 0x2000
694 bra ne #ctx_xfer_idle
695
683 bra not $p1 #ctx_xfer_pre 696 bra not $p1 #ctx_xfer_pre
684 bra $p2 #ctx_xfer_pre_load 697 bra $p2 #ctx_xfer_pre_load
685 ctx_xfer_pre: 698 ctx_xfer_pre:
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
index decf0c60ca3b..e3421af68ab9 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
@@ -30,11 +30,13 @@ uint32_t nve0_grhub_data[] = {
30 0x00000000, 30 0x00000000,
31/* 0x005c: chipsets */ 31/* 0x005c: chipsets */
32 0x000000e4, 32 0x000000e4,
33 0x013c0070, 33 0x01440078,
34 0x000000e7, 34 0x000000e7,
35 0x013c0070, 35 0x01440078,
36 0x000000e6,
37 0x01440078,
36 0x00000000, 38 0x00000000,
37/* 0x0070: nve4_hub_mmio_head */ 39/* 0x0078: nve4_hub_mmio_head */
38 0x0417e91c, 40 0x0417e91c,
39 0x04400204, 41 0x04400204,
40 0x18404010, 42 0x18404010,
@@ -86,9 +88,7 @@ uint32_t nve0_grhub_data[] = {
86 0x00408840, 88 0x00408840,
87 0x08408900, 89 0x08408900,
88 0x00408980, 90 0x00408980,
89/* 0x013c: nve4_hub_mmio_tail */ 91/* 0x0144: nve4_hub_mmio_tail */
90 0x00000000,
91 0x00000000,
92 0x00000000, 92 0x00000000,
93 0x00000000, 93 0x00000000,
94 0x00000000, 94 0x00000000,
@@ -781,77 +781,78 @@ uint32_t nve0_grhub_code[] = {
781 0x0613f002, 781 0x0613f002,
782 0xf80601fa, 782 0xf80601fa,
783/* 0x07fb: ctx_xfer */ 783/* 0x07fb: ctx_xfer */
784 0xf400f803, 784 0xf100f803,
785 0x02f40611, 785 0xb60c00f7,
786/* 0x0801: ctx_xfer_pre */ 786 0xe7f006f4,
787 0x10f7f00d, 787 0x80fed004,
788 0x067221f5, 788/* 0x0808: ctx_xfer_idle */
789/* 0x080b: ctx_xfer_pre_load */ 789 0xf100fecf,
790 0xf01c11f4, 790 0xf42000e4,
791 0x21f502f7, 791 0x11f4f91b,
792 0x21f50631, 792 0x0d02f406,
793 0x21f50640, 793/* 0x0818: ctx_xfer_pre */
794 0xf4bd0652, 794 0xf510f7f0,
795 0x063121f5, 795 0xf4067221,
796 0x069221f5, 796/* 0x0822: ctx_xfer_pre_load */
797/* 0x0824: ctx_xfer_exec */ 797 0xf7f01c11,
798 0xf1160198, 798 0x3121f502,
799 0xb6041427, 799 0x4021f506,
800 0x20d00624, 800 0x5221f506,
801 0x00e7f100, 801 0xf5f4bd06,
802 0x41e3f0a5, 802 0xf5063121,
803 0xf4021fb9, 803/* 0x083b: ctx_xfer_exec */
804 0xe0b68d21, 804 0x98069221,
805 0x01fcf004, 805 0x27f11601,
806 0xb6022cf0, 806 0x24b60414,
807 0xf2fd0124, 807 0x0020d006,
808 0x8d21f405, 808 0xa500e7f1,
809 0x4afc17f1, 809 0xb941e3f0,
810 0xf00213f0, 810 0x21f4021f,
811 0x12d00c27, 811 0x04e0b68d,
812 0x0721f500, 812 0xf001fcf0,
813 0xfc27f102, 813 0x24b6022c,
814 0x0223f047, 814 0x05f2fd01,
815 0xf00020d0, 815 0xf18d21f4,
816 0x20b6012c, 816 0xf04afc17,
817 0x0012d003, 817 0x27f00213,
818 0xf001acf0, 818 0x0012d00c,
819 0xb7f006a5, 819 0x020721f5,
820 0x140c9800, 820 0x47fc27f1,
821 0xf0150d98, 821 0xd00223f0,
822 0x21f500e7, 822 0x2cf00020,
823 0xa7f0015c, 823 0x0320b601,
824 0x0321f508, 824 0xf00012d0,
825 0x0721f501, 825 0xa5f001ac,
826 0x2201f402, 826 0x00b7f006,
827 0xf40ca7f0, 827 0x98140c98,
828 0x17f1c921, 828 0xe7f0150d,
829 0x14b60a10, 829 0x5c21f500,
830 0x0527f006, 830 0x08a7f001,
831/* 0x08ab: ctx_xfer_post_save_wait */ 831 0x010321f5,
832 0xcf0012d0, 832 0x020721f5,
833 0x22fd0012, 833 0xf02201f4,
834 0xfa1bf405, 834 0x21f40ca7,
835/* 0x08b7: ctx_xfer_post */ 835 0x1017f1c9,
836 0xf02e02f4, 836 0x0614b60a,
837 0x21f502f7, 837 0xd00527f0,
838 0xf4bd0631, 838/* 0x08c2: ctx_xfer_post_save_wait */
839 0x067221f5, 839 0x12cf0012,
840 0x022621f5, 840 0x0522fd00,
841 0x064021f5, 841 0xf4fa1bf4,
842 0x21f5f4bd, 842/* 0x08ce: ctx_xfer_post */
843 0x11f40631, 843 0xf7f02e02,
844 0x80019810, 844 0x3121f502,
845 0xf40511fd, 845 0xf5f4bd06,
846 0x21f5070b, 846 0xf5067221,
847/* 0x08e2: ctx_xfer_no_post_mmio */ 847 0xf5022621,
848/* 0x08e2: ctx_xfer_done */ 848 0xbd064021,
849 0x00f807b1, 849 0x3121f5f4,
850 0x00000000, 850 0x1011f406,
851 0x00000000, 851 0xfd800198,
852 0x00000000, 852 0x0bf40511,
853 0x00000000, 853 0xb121f507,
854 0x00000000, 854/* 0x08f9: ctx_xfer_no_post_mmio */
855 0x00000000, 855/* 0x08f9: ctx_xfer_done */
856 0x0000f807,
856 0x00000000, 857 0x00000000,
857}; 858};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
index 47a02081d708..45aff5f5085a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
@@ -516,18 +516,9 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
516{ 516{
517 struct nouveau_device *device = nv_device(parent); 517 struct nouveau_device *device = nv_device(parent);
518 struct nvc0_graph_priv *priv; 518 struct nvc0_graph_priv *priv;
519 bool enable = true;
520 int ret, i; 519 int ret, i;
521 520
522 switch (device->chipset) { 521 ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
523 case 0xd9: /* known broken without binary driver firmware */
524 enable = false;
525 break;
526 default:
527 break;
528 }
529
530 ret = nouveau_graph_create(parent, engine, oclass, enable, &priv);
531 *pobject = nv_object(priv); 522 *pobject = nv_object(priv);
532 if (ret) 523 if (ret)
533 return ret; 524 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
index 18d2210e12eb..a1e78de46456 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
@@ -121,6 +121,7 @@ nvc0_graph_class(void *obj)
121 return 0x9297; 121 return 0x9297;
122 case 0xe4: 122 case 0xe4:
123 case 0xe7: 123 case 0xe7:
124 case 0xe6:
124 return 0xa097; 125 return 0xa097;
125 default: 126 default:
126 return 0; 127 return 0;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
index 539d4c72f192..9f82e9702b46 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
@@ -203,7 +203,7 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
203 struct nvc0_graph_priv *priv; 203 struct nvc0_graph_priv *priv;
204 int ret, i; 204 int ret, i;
205 205
206 ret = nouveau_graph_create(parent, engine, oclass, false, &priv); 206 ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
207 *pobject = nv_object(priv); 207 *pobject = nv_object(priv);
208 if (ret) 208 if (ret)
209 return ret; 209 return ret;
@@ -252,6 +252,7 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
252 priv->magic_not_rop_nr = 1; 252 priv->magic_not_rop_nr = 1;
253 break; 253 break;
254 case 0xe7: 254 case 0xe7:
255 case 0xe6:
255 priv->magic_not_rop_nr = 1; 256 priv->magic_not_rop_nr = 1;
256 break; 257 break;
257 default: 258 default:
diff --git a/drivers/gpu/drm/nouveau/core/include/core/client.h b/drivers/gpu/drm/nouveau/core/include/core/client.h
index 0193532ceac9..63acc0346ff2 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/client.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/client.h
@@ -36,6 +36,9 @@ nouveau_client(void *obj)
36 36
37int nouveau_client_create_(const char *name, u64 device, const char *cfg, 37int nouveau_client_create_(const char *name, u64 device, const char *cfg,
38 const char *dbg, int, void **); 38 const char *dbg, int, void **);
39#define nouveau_client_destroy(p) \
40 nouveau_namedb_destroy(&(p)->base)
41
39int nouveau_client_init(struct nouveau_client *); 42int nouveau_client_init(struct nouveau_client *);
40int nouveau_client_fini(struct nouveau_client *, bool suspend); 43int nouveau_client_fini(struct nouveau_client *, bool suspend);
41 44
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios.h
index d145b25e6be4..5bd1ca8cd20d 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios.h
@@ -17,6 +17,7 @@ struct nouveau_bios {
17 u8 chip; 17 u8 chip;
18 u8 minor; 18 u8 minor;
19 u8 micro; 19 u8 micro;
20 u8 patch;
20 } version; 21 } version;
21}; 22};
22 23
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h
index 2bf178082a36..e6563b5cb08e 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h
@@ -25,9 +25,11 @@ struct dcb_gpio_func {
25 u8 param; 25 u8 param;
26}; 26};
27 27
28u16 dcb_gpio_table(struct nouveau_bios *); 28u16 dcb_gpio_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
29u16 dcb_gpio_entry(struct nouveau_bios *, int idx, int ent, u8 *ver); 29u16 dcb_gpio_entry(struct nouveau_bios *, int idx, int ent, u8 *ver, u8 *len);
30int dcb_gpio_parse(struct nouveau_bios *, int idx, u8 func, u8 line, 30u16 dcb_gpio_parse(struct nouveau_bios *, int idx, int ent, u8 *ver, u8 *len,
31 struct dcb_gpio_func *); 31 struct dcb_gpio_func *);
32u16 dcb_gpio_match(struct nouveau_bios *, int idx, u8 func, u8 line,
33 u8 *ver, u8 *len, struct dcb_gpio_func *);
32 34
33#endif 35#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h
index e69a8bdc6e97..ca2f6bf37f46 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h
@@ -13,6 +13,7 @@ struct nvbios_init {
13 u32 nested; 13 u32 nested;
14 u16 repeat; 14 u16 repeat;
15 u16 repend; 15 u16 repend;
16 u32 ramcfg;
16}; 17};
17 18
18int nvbios_exec(struct nvbios_init *); 19int nvbios_exec(struct nvbios_init *);
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h
index c345097592f2..b2f3d4d0aa49 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h
@@ -38,6 +38,8 @@ enum nvbios_pll_type {
38 PLL_UNK42 = 0x42, 38 PLL_UNK42 = 0x42,
39 PLL_VPLL0 = 0x80, 39 PLL_VPLL0 = 0x80,
40 PLL_VPLL1 = 0x81, 40 PLL_VPLL1 = 0x81,
41 PLL_VPLL2 = 0x82,
42 PLL_VPLL3 = 0x83,
41 PLL_MAX = 0xff 43 PLL_MAX = 0xff
42}; 44};
43 45
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h
index 9ea2b12cc15d..b75e8f18e52c 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h
@@ -11,7 +11,7 @@ struct nouveau_gpio {
11 struct nouveau_subdev base; 11 struct nouveau_subdev base;
12 12
13 /* hardware interfaces */ 13 /* hardware interfaces */
14 void (*reset)(struct nouveau_gpio *); 14 void (*reset)(struct nouveau_gpio *, u8 func);
15 int (*drive)(struct nouveau_gpio *, int line, int dir, int out); 15 int (*drive)(struct nouveau_gpio *, int line, int dir, int out);
16 int (*sense)(struct nouveau_gpio *, int line); 16 int (*sense)(struct nouveau_gpio *, int line);
17 void (*irq_enable)(struct nouveau_gpio *, int line, bool); 17 void (*irq_enable)(struct nouveau_gpio *, int line, bool);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
index dd111947eb86..f621f69fa1a2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
@@ -447,6 +447,7 @@ nouveau_bios_ctor(struct nouveau_object *parent,
447 bios->version.chip = nv_ro08(bios, bit_i.offset + 2); 447 bios->version.chip = nv_ro08(bios, bit_i.offset + 2);
448 bios->version.minor = nv_ro08(bios, bit_i.offset + 1); 448 bios->version.minor = nv_ro08(bios, bit_i.offset + 1);
449 bios->version.micro = nv_ro08(bios, bit_i.offset + 0); 449 bios->version.micro = nv_ro08(bios, bit_i.offset + 0);
450 bios->version.patch = nv_ro08(bios, bit_i.offset + 4);
450 } else 451 } else
451 if (bmp_version(bios)) { 452 if (bmp_version(bios)) {
452 bios->version.major = nv_ro08(bios, bios->bmp_offset + 13); 453 bios->version.major = nv_ro08(bios, bios->bmp_offset + 13);
@@ -455,9 +456,9 @@ nouveau_bios_ctor(struct nouveau_object *parent,
455 bios->version.micro = nv_ro08(bios, bios->bmp_offset + 10); 456 bios->version.micro = nv_ro08(bios, bios->bmp_offset + 10);
456 } 457 }
457 458
458 nv_info(bios, "version %02x.%02x.%02x.%02x\n", 459 nv_info(bios, "version %02x.%02x.%02x.%02x.%02x\n",
459 bios->version.major, bios->version.chip, 460 bios->version.major, bios->version.chip,
460 bios->version.minor, bios->version.micro); 461 bios->version.minor, bios->version.micro, bios->version.patch);
461 462
462 return 0; 463 return 0;
463} 464}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c b/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c
index c90d4aa3ae4f..c84e93fa6d95 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c
@@ -27,84 +27,105 @@
27#include <subdev/bios/gpio.h> 27#include <subdev/bios/gpio.h>
28 28
29u16 29u16
30dcb_gpio_table(struct nouveau_bios *bios) 30dcb_gpio_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
31{ 31{
32 u8 ver, hdr, cnt, len; 32 u16 data = 0x0000;
33 u16 dcb = dcb_table(bios, &ver, &hdr, &cnt, &len); 33 u16 dcb = dcb_table(bios, ver, hdr, cnt, len);
34 if (dcb) { 34 if (dcb) {
35 if (ver >= 0x30 && hdr >= 0x0c) 35 if (*ver >= 0x30 && *hdr >= 0x0c)
36 return nv_ro16(bios, dcb + 0x0a); 36 data = nv_ro16(bios, dcb + 0x0a);
37 if (ver >= 0x22 && nv_ro08(bios, dcb - 1) >= 0x13) 37 else
38 return nv_ro16(bios, dcb - 0x0f); 38 if (*ver >= 0x22 && nv_ro08(bios, dcb - 1) >= 0x13)
39 data = nv_ro16(bios, dcb - 0x0f);
40
41 if (data) {
42 *ver = nv_ro08(bios, data + 0x00);
43 if (*ver < 0x30) {
44 *hdr = 3;
45 *cnt = nv_ro08(bios, data + 0x02);
46 *len = nv_ro08(bios, data + 0x01);
47 } else
48 if (*ver <= 0x41) {
49 *hdr = nv_ro08(bios, data + 0x01);
50 *cnt = nv_ro08(bios, data + 0x02);
51 *len = nv_ro08(bios, data + 0x03);
52 } else {
53 data = 0x0000;
54 }
55 }
39 } 56 }
40 return 0x0000; 57 return data;
41} 58}
42 59
43u16 60u16
44dcb_gpio_entry(struct nouveau_bios *bios, int idx, int ent, u8 *ver) 61dcb_gpio_entry(struct nouveau_bios *bios, int idx, int ent, u8 *ver, u8 *len)
45{ 62{
46 u16 gpio = dcb_gpio_table(bios); 63 u8 hdr, cnt;
47 if (gpio) { 64 u16 gpio = !idx ? dcb_gpio_table(bios, ver, &hdr, &cnt, len) : 0x0000;
48 *ver = nv_ro08(bios, gpio); 65 if (gpio && ent < cnt)
49 if (*ver < 0x30 && ent < nv_ro08(bios, gpio + 2)) 66 return gpio + hdr + (ent * *len);
50 return gpio + 3 + (ent * nv_ro08(bios, gpio + 1));
51 else if (ent < nv_ro08(bios, gpio + 2))
52 return gpio + nv_ro08(bios, gpio + 1) +
53 (ent * nv_ro08(bios, gpio + 3));
54 }
55 return 0x0000; 67 return 0x0000;
56} 68}
57 69
58int 70u16
59dcb_gpio_parse(struct nouveau_bios *bios, int idx, u8 func, u8 line, 71dcb_gpio_parse(struct nouveau_bios *bios, int idx, int ent, u8 *ver, u8 *len,
60 struct dcb_gpio_func *gpio) 72 struct dcb_gpio_func *gpio)
61{ 73{
62 u8 ver, hdr, cnt, len; 74 u16 data = dcb_gpio_entry(bios, idx, ent, ver, len);
63 u16 entry; 75 if (data) {
64 int i = -1; 76 if (*ver < 0x40) {
65 77 u16 info = nv_ro16(bios, data);
66 while ((entry = dcb_gpio_entry(bios, idx, ++i, &ver))) {
67 if (ver < 0x40) {
68 u16 data = nv_ro16(bios, entry);
69 *gpio = (struct dcb_gpio_func) { 78 *gpio = (struct dcb_gpio_func) {
70 .line = (data & 0x001f) >> 0, 79 .line = (info & 0x001f) >> 0,
71 .func = (data & 0x07e0) >> 5, 80 .func = (info & 0x07e0) >> 5,
72 .log[0] = (data & 0x1800) >> 11, 81 .log[0] = (info & 0x1800) >> 11,
73 .log[1] = (data & 0x6000) >> 13, 82 .log[1] = (info & 0x6000) >> 13,
74 .param = !!(data & 0x8000), 83 .param = !!(info & 0x8000),
75 }; 84 };
76 } else 85 } else
77 if (ver < 0x41) { 86 if (*ver < 0x41) {
78 u32 data = nv_ro32(bios, entry); 87 u32 info = nv_ro32(bios, data);
79 *gpio = (struct dcb_gpio_func) { 88 *gpio = (struct dcb_gpio_func) {
80 .line = (data & 0x0000001f) >> 0, 89 .line = (info & 0x0000001f) >> 0,
81 .func = (data & 0x0000ff00) >> 8, 90 .func = (info & 0x0000ff00) >> 8,
82 .log[0] = (data & 0x18000000) >> 27, 91 .log[0] = (info & 0x18000000) >> 27,
83 .log[1] = (data & 0x60000000) >> 29, 92 .log[1] = (info & 0x60000000) >> 29,
84 .param = !!(data & 0x80000000), 93 .param = !!(info & 0x80000000),
85 }; 94 };
86 } else { 95 } else {
87 u32 data = nv_ro32(bios, entry + 0); 96 u32 info = nv_ro32(bios, data + 0);
88 u8 data1 = nv_ro32(bios, entry + 4); 97 u8 info1 = nv_ro32(bios, data + 4);
89 *gpio = (struct dcb_gpio_func) { 98 *gpio = (struct dcb_gpio_func) {
90 .line = (data & 0x0000003f) >> 0, 99 .line = (info & 0x0000003f) >> 0,
91 .func = (data & 0x0000ff00) >> 8, 100 .func = (info & 0x0000ff00) >> 8,
92 .log[0] = (data1 & 0x30) >> 4, 101 .log[0] = (info1 & 0x30) >> 4,
93 .log[1] = (data1 & 0xc0) >> 6, 102 .log[1] = (info1 & 0xc0) >> 6,
94 .param = !!(data & 0x80000000), 103 .param = !!(info & 0x80000000),
95 }; 104 };
96 } 105 }
106 }
107
108 return data;
109}
97 110
111u16
112dcb_gpio_match(struct nouveau_bios *bios, int idx, u8 func, u8 line,
113 u8 *ver, u8 *len, struct dcb_gpio_func *gpio)
114{
115 u8 hdr, cnt, i = 0;
116 u16 data;
117
118 while ((data = dcb_gpio_parse(bios, idx, i++, ver, len, gpio))) {
98 if ((line == 0xff || line == gpio->line) && 119 if ((line == 0xff || line == gpio->line) &&
99 (func == 0xff || func == gpio->func)) 120 (func == 0xff || func == gpio->func))
100 return 0; 121 return data;
101 } 122 }
102 123
103 /* DCB 2.2, fixed TVDAC GPIO data */ 124 /* DCB 2.2, fixed TVDAC GPIO data */
104 if ((entry = dcb_table(bios, &ver, &hdr, &cnt, &len))) { 125 if ((data = dcb_table(bios, ver, &hdr, &cnt, len))) {
105 if (ver >= 0x22 && ver < 0x30 && func == DCB_GPIO_TVDAC0) { 126 if (*ver >= 0x22 && *ver < 0x30 && func == DCB_GPIO_TVDAC0) {
106 u8 conf = nv_ro08(bios, entry - 5); 127 u8 conf = nv_ro08(bios, data - 5);
107 u8 addr = nv_ro08(bios, entry - 4); 128 u8 addr = nv_ro08(bios, data - 4);
108 if (conf & 0x01) { 129 if (conf & 0x01) {
109 *gpio = (struct dcb_gpio_func) { 130 *gpio = (struct dcb_gpio_func) {
110 .func = DCB_GPIO_TVDAC0, 131 .func = DCB_GPIO_TVDAC0,
@@ -112,10 +133,11 @@ dcb_gpio_parse(struct nouveau_bios *bios, int idx, u8 func, u8 line,
112 .log[0] = !!(conf & 0x02), 133 .log[0] = !!(conf & 0x02),
113 .log[1] = !(conf & 0x02), 134 .log[1] = !(conf & 0x02),
114 }; 135 };
115 return 0; 136 *ver = 0x00;
137 return data;
116 } 138 }
117 } 139 }
118 } 140 }
119 141
120 return -EINVAL; 142 return 0x0000;
121} 143}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
index ae168bbb86d8..690ed438b2ad 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
@@ -2,11 +2,12 @@
2#include <core/device.h> 2#include <core/device.h>
3 3
4#include <subdev/bios.h> 4#include <subdev/bios.h>
5#include <subdev/bios/conn.h>
6#include <subdev/bios/bmp.h> 5#include <subdev/bios/bmp.h>
7#include <subdev/bios/bit.h> 6#include <subdev/bios/bit.h>
7#include <subdev/bios/conn.h>
8#include <subdev/bios/dcb.h> 8#include <subdev/bios/dcb.h>
9#include <subdev/bios/dp.h> 9#include <subdev/bios/dp.h>
10#include <subdev/bios/gpio.h>
10#include <subdev/bios/init.h> 11#include <subdev/bios/init.h>
11#include <subdev/devinit.h> 12#include <subdev/devinit.h>
12#include <subdev/clock.h> 13#include <subdev/clock.h>
@@ -410,9 +411,25 @@ init_ram_restrict_group_count(struct nvbios_init *init)
410} 411}
411 412
412static u8 413static u8
414init_ram_restrict_strap(struct nvbios_init *init)
415{
416 /* This appears to be the behaviour of the VBIOS parser, and *is*
417 * important to cache the NV_PEXTDEV_BOOT0 on later chipsets to
418 * avoid fucking up the memory controller (somehow) by reading it
419 * on every INIT_RAM_RESTRICT_ZM_GROUP opcode.
420 *
421 * Preserving the non-caching behaviour on earlier chipsets just
422 * in case *not* re-reading the strap causes similar breakage.
423 */
424 if (!init->ramcfg || init->bios->version.major < 0x70)
425 init->ramcfg = init_rd32(init, 0x101000);
426 return (init->ramcfg & 0x00000003c) >> 2;
427}
428
429static u8
413init_ram_restrict(struct nvbios_init *init) 430init_ram_restrict(struct nvbios_init *init)
414{ 431{
415 u32 strap = (init_rd32(init, 0x101000) & 0x0000003c) >> 2; 432 u8 strap = init_ram_restrict_strap(init);
416 u16 table = init_ram_restrict_table(init); 433 u16 table = init_ram_restrict_table(init);
417 if (table) 434 if (table)
418 return nv_ro08(init->bios, table + strap); 435 return nv_ro08(init->bios, table + strap);
@@ -1517,7 +1534,6 @@ init_io(struct nvbios_init *init)
1517 mdelay(10); 1534 mdelay(10);
1518 init_wr32(init, 0x614100, 0x10000018); 1535 init_wr32(init, 0x614100, 0x10000018);
1519 init_wr32(init, 0x614900, 0x10000018); 1536 init_wr32(init, 0x614900, 0x10000018);
1520 return;
1521 } 1537 }
1522 1538
1523 value = init_rdport(init, port) & mask; 1539 value = init_rdport(init, port) & mask;
@@ -1781,7 +1797,7 @@ init_gpio(struct nvbios_init *init)
1781 init->offset += 1; 1797 init->offset += 1;
1782 1798
1783 if (init_exec(init) && gpio && gpio->reset) 1799 if (init_exec(init) && gpio && gpio->reset)
1784 gpio->reset(gpio); 1800 gpio->reset(gpio, DCB_GPIO_UNUSED);
1785} 1801}
1786 1802
1787/** 1803/**
@@ -1995,6 +2011,47 @@ init_i2c_long_if(struct nvbios_init *init)
1995 init_exec_set(init, false); 2011 init_exec_set(init, false);
1996} 2012}
1997 2013
2014/**
2015 * INIT_GPIO_NE - opcode 0xa9
2016 *
2017 */
2018static void
2019init_gpio_ne(struct nvbios_init *init)
2020{
2021 struct nouveau_bios *bios = init->bios;
2022 struct nouveau_gpio *gpio = nouveau_gpio(bios);
2023 struct dcb_gpio_func func;
2024 u8 count = nv_ro08(bios, init->offset + 1);
2025 u8 idx = 0, ver, len;
2026 u16 data, i;
2027
2028 trace("GPIO_NE\t");
2029 init->offset += 2;
2030
2031 for (i = init->offset; i < init->offset + count; i++)
2032 cont("0x%02x ", nv_ro08(bios, i));
2033 cont("\n");
2034
2035 while ((data = dcb_gpio_parse(bios, 0, idx++, &ver, &len, &func))) {
2036 if (func.func != DCB_GPIO_UNUSED) {
2037 for (i = init->offset; i < init->offset + count; i++) {
2038 if (func.func == nv_ro08(bios, i))
2039 break;
2040 }
2041
2042 trace("\tFUNC[0x%02x]", func.func);
2043 if (i == (init->offset + count)) {
2044 cont(" *");
2045 if (init_exec(init) && gpio && gpio->reset)
2046 gpio->reset(gpio, func.func);
2047 }
2048 cont("\n");
2049 }
2050 }
2051
2052 init->offset += count;
2053}
2054
1998static struct nvbios_init_opcode { 2055static struct nvbios_init_opcode {
1999 void (*exec)(struct nvbios_init *); 2056 void (*exec)(struct nvbios_init *);
2000} init_opcode[] = { 2057} init_opcode[] = {
@@ -2059,6 +2116,7 @@ static struct nvbios_init_opcode {
2059 [0x98] = { init_auxch }, 2116 [0x98] = { init_auxch },
2060 [0x99] = { init_zm_auxch }, 2117 [0x99] = { init_zm_auxch },
2061 [0x9a] = { init_i2c_long_if }, 2118 [0x9a] = { init_i2c_long_if },
2119 [0xa9] = { init_gpio_ne },
2062}; 2120};
2063 2121
2064#define init_opcode_nr (sizeof(init_opcode) / sizeof(init_opcode[0])) 2122#define init_opcode_nr (sizeof(init_opcode) / sizeof(init_opcode[0]))
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
index f6962c9b6c36..7c9626258a46 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
@@ -52,6 +52,8 @@ nvc0_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
52 switch (info.type) { 52 switch (info.type) {
53 case PLL_VPLL0: 53 case PLL_VPLL0:
54 case PLL_VPLL1: 54 case PLL_VPLL1:
55 case PLL_VPLL2:
56 case PLL_VPLL3:
55 nv_mask(priv, info.reg + 0x0c, 0x00000000, 0x00000100); 57 nv_mask(priv, info.reg + 0x0c, 0x00000000, 0x00000100);
56 nv_wr32(priv, info.reg + 0x04, (P << 16) | (N << 8) | M); 58 nv_wr32(priv, info.reg + 0x04, (P << 16) | (N << 8) | M);
57 nv_wr32(priv, info.reg + 0x10, fN << 16); 59 nv_wr32(priv, info.reg + 0x10, fN << 16);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
index 9b7881e76634..03a652876e73 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
@@ -109,6 +109,34 @@ nve0_identify(struct nouveau_device *device)
109 device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; 109 device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
110 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; 110 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
111 break; 111 break;
112 case 0xe6:
113 device->cname = "GK106";
114 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
115 device->oclass[NVDEV_SUBDEV_GPIO ] = &nvd0_gpio_oclass;
116 device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
117 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
118 device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
119 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
120 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
121 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
122 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
123 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
124 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
125 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
126 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
127 device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
128 device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
129 device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
130 device->oclass[NVDEV_ENGINE_FIFO ] = &nve0_fifo_oclass;
131 device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
132 device->oclass[NVDEV_ENGINE_GR ] = &nve0_graph_oclass;
133 device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass;
134 device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
135 device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
136 device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
137 device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
138 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
139 break;
112 default: 140 default:
113 nv_fatal(device, "unknown Kepler chipset\n"); 141 nv_fatal(device, "unknown Kepler chipset\n");
114 return -EINVAL; 142 return -EINVAL;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
index 306bdf121452..7606ed15b6fa 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
@@ -145,14 +145,14 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
145 mem->memtype = type; 145 mem->memtype = type;
146 mem->size = size; 146 mem->size = size;
147 147
148 mutex_lock(&mm->mutex); 148 mutex_lock(&pfb->base.mutex);
149 do { 149 do {
150 if (back) 150 if (back)
151 ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r); 151 ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
152 else 152 else
153 ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r); 153 ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r);
154 if (ret) { 154 if (ret) {
155 mutex_unlock(&mm->mutex); 155 mutex_unlock(&pfb->base.mutex);
156 pfb->ram.put(pfb, &mem); 156 pfb->ram.put(pfb, &mem);
157 return ret; 157 return ret;
158 } 158 }
@@ -160,7 +160,7 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
160 list_add_tail(&r->rl_entry, &mem->regions); 160 list_add_tail(&r->rl_entry, &mem->regions);
161 size -= r->length; 161 size -= r->length;
162 } while (size); 162 } while (size);
163 mutex_unlock(&mm->mutex); 163 mutex_unlock(&pfb->base.mutex);
164 164
165 r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry); 165 r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
166 mem->offset = (u64)r->offset << 12; 166 mem->offset = (u64)r->offset << 12;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
index acf818c58bf0..9fb0f9b92d49 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
@@ -43,10 +43,15 @@ static int
43nouveau_gpio_find(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line, 43nouveau_gpio_find(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line,
44 struct dcb_gpio_func *func) 44 struct dcb_gpio_func *func)
45{ 45{
46 struct nouveau_bios *bios = nouveau_bios(gpio);
47 u8 ver, len;
48 u16 data;
49
46 if (line == 0xff && tag == 0xff) 50 if (line == 0xff && tag == 0xff)
47 return -EINVAL; 51 return -EINVAL;
48 52
49 if (!dcb_gpio_parse(nouveau_bios(gpio), idx, tag, line, func)) 53 data = dcb_gpio_match(bios, idx, tag, line, &ver, &len, func);
54 if (data)
50 return 0; 55 return 0;
51 56
52 /* Apple iMac G4 NV18 */ 57 /* Apple iMac G4 NV18 */
@@ -265,7 +270,7 @@ nouveau_gpio_init(struct nouveau_gpio *gpio)
265 int ret = nouveau_subdev_init(&gpio->base); 270 int ret = nouveau_subdev_init(&gpio->base);
266 if (ret == 0 && gpio->reset) { 271 if (ret == 0 && gpio->reset) {
267 if (dmi_check_system(gpio_reset_ids)) 272 if (dmi_check_system(gpio_reset_ids))
268 gpio->reset(gpio); 273 gpio->reset(gpio, DCB_GPIO_UNUSED);
269 } 274 }
270 return ret; 275 return ret;
271} 276}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
index f3502c961cd9..bf13a1200f26 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
@@ -29,15 +29,15 @@ struct nv50_gpio_priv {
29}; 29};
30 30
31static void 31static void
32nv50_gpio_reset(struct nouveau_gpio *gpio) 32nv50_gpio_reset(struct nouveau_gpio *gpio, u8 match)
33{ 33{
34 struct nouveau_bios *bios = nouveau_bios(gpio); 34 struct nouveau_bios *bios = nouveau_bios(gpio);
35 struct nv50_gpio_priv *priv = (void *)gpio; 35 struct nv50_gpio_priv *priv = (void *)gpio;
36 u8 ver, len;
36 u16 entry; 37 u16 entry;
37 u8 ver;
38 int ent = -1; 38 int ent = -1;
39 39
40 while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver))) { 40 while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver, &len))) {
41 static const u32 regs[] = { 0xe100, 0xe28c }; 41 static const u32 regs[] = { 0xe100, 0xe28c };
42 u32 data = nv_ro32(bios, entry); 42 u32 data = nv_ro32(bios, entry);
43 u8 line = (data & 0x0000001f); 43 u8 line = (data & 0x0000001f);
@@ -48,7 +48,8 @@ nv50_gpio_reset(struct nouveau_gpio *gpio)
48 u32 val = (unk1 << 16) | unk0; 48 u32 val = (unk1 << 16) | unk0;
49 u32 reg = regs[line >> 4]; line &= 0x0f; 49 u32 reg = regs[line >> 4]; line &= 0x0f;
50 50
51 if (func == 0xff) 51 if ( func == DCB_GPIO_UNUSED ||
52 (match != DCB_GPIO_UNUSED && match != func))
52 continue; 53 continue;
53 54
54 gpio->set(gpio, 0, func, line, defs); 55 gpio->set(gpio, 0, func, line, defs);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c
index 8d18fcad26e0..83e8b8f16e6a 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c
@@ -29,15 +29,15 @@ struct nvd0_gpio_priv {
29}; 29};
30 30
31static void 31static void
32nvd0_gpio_reset(struct nouveau_gpio *gpio) 32nvd0_gpio_reset(struct nouveau_gpio *gpio, u8 match)
33{ 33{
34 struct nouveau_bios *bios = nouveau_bios(gpio); 34 struct nouveau_bios *bios = nouveau_bios(gpio);
35 struct nvd0_gpio_priv *priv = (void *)gpio; 35 struct nvd0_gpio_priv *priv = (void *)gpio;
36 u8 ver, len;
36 u16 entry; 37 u16 entry;
37 u8 ver;
38 int ent = -1; 38 int ent = -1;
39 39
40 while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver))) { 40 while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver, &len))) {
41 u32 data = nv_ro32(bios, entry); 41 u32 data = nv_ro32(bios, entry);
42 u8 line = (data & 0x0000003f); 42 u8 line = (data & 0x0000003f);
43 u8 defs = !!(data & 0x00000080); 43 u8 defs = !!(data & 0x00000080);
@@ -45,7 +45,8 @@ nvd0_gpio_reset(struct nouveau_gpio *gpio)
45 u8 unk0 = (data & 0x00ff0000) >> 16; 45 u8 unk0 = (data & 0x00ff0000) >> 16;
46 u8 unk1 = (data & 0x1f000000) >> 24; 46 u8 unk1 = (data & 0x1f000000) >> 24;
47 47
48 if (func == 0xff) 48 if ( func == DCB_GPIO_UNUSED ||
49 (match != DCB_GPIO_UNUSED && match != func))
49 continue; 50 continue;
50 51
51 gpio->set(gpio, 0, func, line, defs); 52 gpio->set(gpio, 0, func, line, defs);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c
index 1188227ca6aa..6565f3dbbe04 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c
@@ -40,15 +40,21 @@ nouveau_instobj_create_(struct nouveau_object *parent,
40 if (ret) 40 if (ret)
41 return ret; 41 return ret;
42 42
43 mutex_lock(&imem->base.mutex);
43 list_add(&iobj->head, &imem->list); 44 list_add(&iobj->head, &imem->list);
45 mutex_unlock(&imem->base.mutex);
44 return 0; 46 return 0;
45} 47}
46 48
47void 49void
48nouveau_instobj_destroy(struct nouveau_instobj *iobj) 50nouveau_instobj_destroy(struct nouveau_instobj *iobj)
49{ 51{
50 if (iobj->head.prev) 52 struct nouveau_subdev *subdev = nv_subdev(iobj->base.engine);
51 list_del(&iobj->head); 53
54 mutex_lock(&subdev->mutex);
55 list_del(&iobj->head);
56 mutex_unlock(&subdev->mutex);
57
52 return nouveau_object_destroy(&iobj->base); 58 return nouveau_object_destroy(&iobj->base);
53} 59}
54 60
@@ -88,6 +94,8 @@ nouveau_instmem_init(struct nouveau_instmem *imem)
88 if (ret) 94 if (ret)
89 return ret; 95 return ret;
90 96
97 mutex_lock(&imem->base.mutex);
98
91 list_for_each_entry(iobj, &imem->list, head) { 99 list_for_each_entry(iobj, &imem->list, head) {
92 if (iobj->suspend) { 100 if (iobj->suspend) {
93 for (i = 0; i < iobj->size; i += 4) 101 for (i = 0; i < iobj->size; i += 4)
@@ -97,6 +105,8 @@ nouveau_instmem_init(struct nouveau_instmem *imem)
97 } 105 }
98 } 106 }
99 107
108 mutex_unlock(&imem->base.mutex);
109
100 return 0; 110 return 0;
101} 111}
102 112
@@ -104,17 +114,26 @@ int
104nouveau_instmem_fini(struct nouveau_instmem *imem, bool suspend) 114nouveau_instmem_fini(struct nouveau_instmem *imem, bool suspend)
105{ 115{
106 struct nouveau_instobj *iobj; 116 struct nouveau_instobj *iobj;
107 int i; 117 int i, ret = 0;
108 118
109 if (suspend) { 119 if (suspend) {
120 mutex_lock(&imem->base.mutex);
121
110 list_for_each_entry(iobj, &imem->list, head) { 122 list_for_each_entry(iobj, &imem->list, head) {
111 iobj->suspend = vmalloc(iobj->size); 123 iobj->suspend = vmalloc(iobj->size);
112 if (iobj->suspend) { 124 if (!iobj->suspend) {
113 for (i = 0; i < iobj->size; i += 4) 125 ret = -ENOMEM;
114 iobj->suspend[i / 4] = nv_ro32(iobj, i); 126 break;
115 } else 127 }
116 return -ENOMEM; 128
129 for (i = 0; i < iobj->size; i += 4)
130 iobj->suspend[i / 4] = nv_ro32(iobj, i);
117 } 131 }
132
133 mutex_unlock(&imem->base.mutex);
134
135 if (ret)
136 return ret;
118 } 137 }
119 138
120 return nouveau_subdev_fini(&imem->base, suspend); 139 return nouveau_subdev_fini(&imem->base, suspend);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
index 93e3ddf7303a..e286e132c7e7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
@@ -260,7 +260,7 @@ nouveau_mxm_create_(struct nouveau_object *parent,
260 260
261 data = mxm_table(bios, &ver, &len); 261 data = mxm_table(bios, &ver, &len);
262 if (!data || !(ver = nv_ro08(bios, data))) { 262 if (!data || !(ver = nv_ro08(bios, data))) {
263 nv_info(mxm, "no VBIOS data, nothing to do\n"); 263 nv_debug(mxm, "no VBIOS data, nothing to do\n");
264 return 0; 264 return 0;
265 } 265 }
266 266
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
index 082c11b75acb..77c67fc970e6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
@@ -352,7 +352,7 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length,
352 u64 mm_length = (offset + length) - mm_offset; 352 u64 mm_length = (offset + length) - mm_offset;
353 int ret; 353 int ret;
354 354
355 vm = *pvm = kzalloc(sizeof(*vm), GFP_KERNEL); 355 vm = kzalloc(sizeof(*vm), GFP_KERNEL);
356 if (!vm) 356 if (!vm)
357 return -ENOMEM; 357 return -ENOMEM;
358 358
@@ -376,6 +376,8 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length,
376 return ret; 376 return ret;
377 } 377 }
378 378
379 *pvm = vm;
380
379 return 0; 381 return 0;
380} 382}
381 383
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 5614c89148cb..69d7b1d0b9d6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1276,7 +1276,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
1276 if (drm->agp.stat == ENABLED) { 1276 if (drm->agp.stat == ENABLED) {
1277 mem->bus.offset = mem->start << PAGE_SHIFT; 1277 mem->bus.offset = mem->start << PAGE_SHIFT;
1278 mem->bus.base = drm->agp.base; 1278 mem->bus.base = drm->agp.base;
1279 mem->bus.is_iomem = true; 1279 mem->bus.is_iomem = !dev->agp->cant_use_aperture;
1280 } 1280 }
1281#endif 1281#endif
1282 break; 1282 break;
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index ac340ba32017..e620ba8271b4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -127,12 +127,26 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
127 struct nouveau_encoder **pnv_encoder) 127 struct nouveau_encoder **pnv_encoder)
128{ 128{
129 struct drm_device *dev = connector->dev; 129 struct drm_device *dev = connector->dev;
130 struct nouveau_connector *nv_connector = nouveau_connector(connector);
130 struct nouveau_drm *drm = nouveau_drm(dev); 131 struct nouveau_drm *drm = nouveau_drm(dev);
132 struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
131 struct nouveau_i2c *i2c = nouveau_i2c(drm->device); 133 struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
132 int i; 134 struct nouveau_i2c_port *port = NULL;
135 int i, panel = -ENODEV;
136
137 /* eDP panels need powering on by us (if the VBIOS doesn't default it
138 * to on) before doing any AUX channel transactions. LVDS panel power
139 * is handled by the SOR itself, and not required for LVDS DDC.
140 */
141 if (nv_connector->type == DCB_CONNECTOR_eDP) {
142 panel = gpio->get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff);
143 if (panel == 0) {
144 gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1);
145 msleep(300);
146 }
147 }
133 148
134 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 149 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
135 struct nouveau_i2c_port *port = NULL;
136 struct nouveau_encoder *nv_encoder; 150 struct nouveau_encoder *nv_encoder;
137 struct drm_mode_object *obj; 151 struct drm_mode_object *obj;
138 int id; 152 int id;
@@ -150,11 +164,19 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
150 port = i2c->find(i2c, nv_encoder->dcb->i2c_index); 164 port = i2c->find(i2c, nv_encoder->dcb->i2c_index);
151 if (port && nv_probe_i2c(port, 0x50)) { 165 if (port && nv_probe_i2c(port, 0x50)) {
152 *pnv_encoder = nv_encoder; 166 *pnv_encoder = nv_encoder;
153 return port; 167 break;
154 } 168 }
169
170 port = NULL;
155 } 171 }
156 172
157 return NULL; 173 /* eDP panel not detected, restore panel power GPIO to previous
174 * state to avoid confusing the SOR for other output types.
175 */
176 if (!port && panel == 0)
177 gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel);
178
179 return port;
158} 180}
159 181
160static struct nouveau_encoder * 182static struct nouveau_encoder *
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index e4188f24fc75..508b00a2ce0d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -225,15 +225,6 @@ nouveau_display_init(struct drm_device *dev)
225 if (ret) 225 if (ret)
226 return ret; 226 return ret;
227 227
228 /* power on internal panel if it's not already. the init tables of
229 * some vbios default this to off for some reason, causing the
230 * panel to not work after resume
231 */
232 if (gpio && gpio->get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff) == 0) {
233 gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1);
234 msleep(300);
235 }
236
237 /* enable polling for external displays */ 228 /* enable polling for external displays */
238 drm_kms_helper_poll_enable(dev); 229 drm_kms_helper_poll_enable(dev);
239 230
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 01c403ddb99b..8b090f1eb51d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -84,11 +84,16 @@ nouveau_cli_create(struct pci_dev *pdev, const char *name,
84 struct nouveau_cli *cli; 84 struct nouveau_cli *cli;
85 int ret; 85 int ret;
86 86
87 *pcli = NULL;
87 ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config, 88 ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config,
88 nouveau_debug, size, pcli); 89 nouveau_debug, size, pcli);
89 cli = *pcli; 90 cli = *pcli;
90 if (ret) 91 if (ret) {
92 if (cli)
93 nouveau_client_destroy(&cli->base);
94 *pcli = NULL;
91 return ret; 95 return ret;
96 }
92 97
93 mutex_init(&cli->mutex); 98 mutex_init(&cli->mutex);
94 return 0; 99 return 0;
@@ -189,8 +194,8 @@ nouveau_accel_init(struct nouveau_drm *drm)
189 nouveau_bo_move_init(drm); 194 nouveau_bo_move_init(drm);
190} 195}
191 196
192static int __devinit 197static int nouveau_drm_probe(struct pci_dev *pdev,
193nouveau_drm_probe(struct pci_dev *pdev, const struct pci_device_id *pent) 198 const struct pci_device_id *pent)
194{ 199{
195 struct nouveau_device *device; 200 struct nouveau_device *device;
196 struct apertures_struct *aper; 201 struct apertures_struct *aper;
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h
index bedafd1c9539..cdb83acdffe2 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.h
@@ -60,6 +60,7 @@ u32 nv10_fence_read(struct nouveau_channel *);
60void nv10_fence_context_del(struct nouveau_channel *); 60void nv10_fence_context_del(struct nouveau_channel *);
61void nv10_fence_destroy(struct nouveau_drm *); 61void nv10_fence_destroy(struct nouveau_drm *);
62int nv10_fence_create(struct nouveau_drm *); 62int nv10_fence_create(struct nouveau_drm *);
63void nv17_fence_resume(struct nouveau_drm *drm);
63 64
64int nv50_fence_create(struct nouveau_drm *); 65int nv50_fence_create(struct nouveau_drm *);
65int nv84_fence_create(struct nouveau_drm *); 66int nv84_fence_create(struct nouveau_drm *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 5566172774df..a701ff5ffa5b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -698,10 +698,10 @@ static int
698nouveau_hwmon_init(struct drm_device *dev) 698nouveau_hwmon_init(struct drm_device *dev)
699{ 699{
700 struct nouveau_pm *pm = nouveau_pm(dev); 700 struct nouveau_pm *pm = nouveau_pm(dev);
701 struct nouveau_drm *drm = nouveau_drm(dev);
702 struct nouveau_therm *therm = nouveau_therm(drm->device);
703 701
704#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) 702#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
703 struct nouveau_drm *drm = nouveau_drm(dev);
704 struct nouveau_therm *therm = nouveau_therm(drm->device);
705 struct device *hwmon_dev; 705 struct device *hwmon_dev;
706 int ret = 0; 706 int ret = 0;
707 707
diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c
index 3543fec2355e..b8e05ae38212 100644
--- a/drivers/gpu/drm/nouveau/nouveau_prime.c
+++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
@@ -193,6 +193,7 @@ struct drm_gem_object *nouveau_gem_prime_import(struct drm_device *dev,
193 if (nvbo->gem) { 193 if (nvbo->gem) {
194 if (nvbo->gem->dev == dev) { 194 if (nvbo->gem->dev == dev) {
195 drm_gem_object_reference(nvbo->gem); 195 drm_gem_object_reference(nvbo->gem);
196 dma_buf_put(dma_buf);
196 return nvbo->gem; 197 return nvbo->gem;
197 } 198 }
198 } 199 }
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c
index 184cdf806761..39ffc07f906b 100644
--- a/drivers/gpu/drm/nouveau/nv04_dfp.c
+++ b/drivers/gpu/drm/nouveau/nv04_dfp.c
@@ -505,7 +505,7 @@ static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode)
505 505
506static inline bool is_powersaving_dpms(int mode) 506static inline bool is_powersaving_dpms(int mode)
507{ 507{
508 return (mode != DRM_MODE_DPMS_ON); 508 return mode != DRM_MODE_DPMS_ON && mode != NV_DPMS_CLEARED;
509} 509}
510 510
511static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) 511static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode)
diff --git a/drivers/gpu/drm/nouveau/nv10_fence.c b/drivers/gpu/drm/nouveau/nv10_fence.c
index 7ae7f97a6d4d..03017f24d593 100644
--- a/drivers/gpu/drm/nouveau/nv10_fence.c
+++ b/drivers/gpu/drm/nouveau/nv10_fence.c
@@ -162,6 +162,13 @@ nv10_fence_destroy(struct nouveau_drm *drm)
162 kfree(priv); 162 kfree(priv);
163} 163}
164 164
165void nv17_fence_resume(struct nouveau_drm *drm)
166{
167 struct nv10_fence_priv *priv = drm->fence;
168
169 nouveau_bo_wr32(priv->bo, 0, priv->sequence);
170}
171
165int 172int
166nv10_fence_create(struct nouveau_drm *drm) 173nv10_fence_create(struct nouveau_drm *drm)
167{ 174{
@@ -197,6 +204,7 @@ nv10_fence_create(struct nouveau_drm *drm)
197 if (ret == 0) { 204 if (ret == 0) {
198 nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); 205 nouveau_bo_wr32(priv->bo, 0x000, 0x00000000);
199 priv->base.sync = nv17_fence_sync; 206 priv->base.sync = nv17_fence_sync;
207 priv->base.resume = nv17_fence_resume;
200 } 208 }
201 } 209 }
202 210
diff --git a/drivers/gpu/drm/nouveau/nv50_fence.c b/drivers/gpu/drm/nouveau/nv50_fence.c
index c20f2727ea0b..d889f3ac0d41 100644
--- a/drivers/gpu/drm/nouveau/nv50_fence.c
+++ b/drivers/gpu/drm/nouveau/nv50_fence.c
@@ -122,6 +122,7 @@ nv50_fence_create(struct nouveau_drm *drm)
122 if (ret == 0) { 122 if (ret == 0) {
123 nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); 123 nouveau_bo_wr32(priv->bo, 0x000, 0x00000000);
124 priv->base.sync = nv17_fence_sync; 124 priv->base.sync = nv17_fence_sync;
125 priv->base.resume = nv17_fence_resume;
125 } 126 }
126 127
127 if (ret) 128 if (ret)