aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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/include/core/client.h3
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/init.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/base.c35
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/base.c4
-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.c7
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.h1
-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
17 files changed, 114 insertions, 52 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/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/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/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
index 2917d552689b..690ed438b2ad 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
@@ -1534,7 +1534,6 @@ init_io(struct nvbios_init *init)
1534 mdelay(10); 1534 mdelay(10);
1535 init_wr32(init, 0x614100, 0x10000018); 1535 init_wr32(init, 0x614100, 0x10000018);
1536 init_wr32(init, 0x614900, 0x10000018); 1536 init_wr32(init, 0x614900, 0x10000018);
1537 return;
1538 } 1537 }
1539 1538
1540 value = init_rdport(init, port) & mask; 1539 value = init_rdport(init, port) & mask;
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/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/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/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_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 180a45e3b525..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;
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/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)