diff options
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/core/client.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/core/handle.c | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | 46 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/include/core/client.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/bios/init.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/instmem/base.c | 35 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/vm/base.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_connector.c | 30 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_display.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drm.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fence.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv04_dfp.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv10_fence.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv50_fence.c | 1 |
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 | ||
| 37 | int nouveau_client_create_(const char *name, u64 device, const char *cfg, | 37 | int 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 | |||
| 39 | int nouveau_client_init(struct nouveau_client *); | 42 | int nouveau_client_init(struct nouveau_client *); |
| 40 | int nouveau_client_fini(struct nouveau_client *, bool suspend); | 43 | int 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 | ||
| 47 | void | 49 | void |
| 48 | nouveau_instobj_destroy(struct nouveau_instobj *iobj) | 50 | nouveau_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 | |||
| 104 | nouveau_instmem_fini(struct nouveau_instmem *imem, bool suspend) | 114 | nouveau_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 | ||
| 160 | static struct nouveau_encoder * | 182 | static 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 *); | |||
| 60 | void nv10_fence_context_del(struct nouveau_channel *); | 60 | void nv10_fence_context_del(struct nouveau_channel *); |
| 61 | void nv10_fence_destroy(struct nouveau_drm *); | 61 | void nv10_fence_destroy(struct nouveau_drm *); |
| 62 | int nv10_fence_create(struct nouveau_drm *); | 62 | int nv10_fence_create(struct nouveau_drm *); |
| 63 | void nv17_fence_resume(struct nouveau_drm *drm); | ||
| 63 | 64 | ||
| 64 | int nv50_fence_create(struct nouveau_drm *); | 65 | int nv50_fence_create(struct nouveau_drm *); |
| 65 | int nv84_fence_create(struct nouveau_drm *); | 66 | int 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 | ||
| 506 | static inline bool is_powersaving_dpms(int mode) | 506 | static 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 | ||
| 511 | static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) | 511 | static 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 | ||
| 165 | void 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 | |||
| 165 | int | 172 | int |
| 166 | nv10_fence_create(struct nouveau_drm *drm) | 173 | nv10_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) |
