diff options
Diffstat (limited to 'drivers/gpu')
49 files changed, 305 insertions, 258 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index e12f8b0cec94..7496d245f28c 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -185,8 +185,8 @@ drm_edid_block_valid(u8 *raw_edid) | |||
185 | bad: | 185 | bad: |
186 | if (raw_edid) { | 186 | if (raw_edid) { |
187 | printk(KERN_ERR "Raw EDID:\n"); | 187 | printk(KERN_ERR "Raw EDID:\n"); |
188 | print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH); | 188 | print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1, |
189 | printk(KERN_ERR "\n"); | 189 | raw_edid, EDID_LENGTH, false); |
190 | } | 190 | } |
191 | return 0; | 191 | return 0; |
192 | } | 192 | } |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 7c5b5f78f1fa..186d62eb063b 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -129,7 +129,7 @@ drm_gem_destroy(struct drm_device *dev) | |||
129 | } | 129 | } |
130 | 130 | ||
131 | /** | 131 | /** |
132 | * Initialize an already allocate GEM object of the specified size with | 132 | * Initialize an already allocated GEM object of the specified size with |
133 | * shmfs backing store. | 133 | * shmfs backing store. |
134 | */ | 134 | */ |
135 | int drm_gem_object_init(struct drm_device *dev, | 135 | int drm_gem_object_init(struct drm_device *dev, |
@@ -151,6 +151,27 @@ int drm_gem_object_init(struct drm_device *dev, | |||
151 | EXPORT_SYMBOL(drm_gem_object_init); | 151 | EXPORT_SYMBOL(drm_gem_object_init); |
152 | 152 | ||
153 | /** | 153 | /** |
154 | * Initialize an already allocated GEM object of the specified size with | ||
155 | * no GEM provided backing store. Instead the caller is responsible for | ||
156 | * backing the object and handling it. | ||
157 | */ | ||
158 | int drm_gem_private_object_init(struct drm_device *dev, | ||
159 | struct drm_gem_object *obj, size_t size) | ||
160 | { | ||
161 | BUG_ON((size & (PAGE_SIZE - 1)) != 0); | ||
162 | |||
163 | obj->dev = dev; | ||
164 | obj->filp = NULL; | ||
165 | |||
166 | kref_init(&obj->refcount); | ||
167 | atomic_set(&obj->handle_count, 0); | ||
168 | obj->size = size; | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | EXPORT_SYMBOL(drm_gem_private_object_init); | ||
173 | |||
174 | /** | ||
154 | * Allocate a GEM object of the specified size with shmfs backing store | 175 | * Allocate a GEM object of the specified size with shmfs backing store |
155 | */ | 176 | */ |
156 | struct drm_gem_object * | 177 | struct drm_gem_object * |
@@ -444,7 +465,8 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private) | |||
444 | void | 465 | void |
445 | drm_gem_object_release(struct drm_gem_object *obj) | 466 | drm_gem_object_release(struct drm_gem_object *obj) |
446 | { | 467 | { |
447 | fput(obj->filp); | 468 | if (obj->filp) |
469 | fput(obj->filp); | ||
448 | } | 470 | } |
449 | EXPORT_SYMBOL(drm_gem_object_release); | 471 | EXPORT_SYMBOL(drm_gem_object_release); |
450 | 472 | ||
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index c2d32f20e2fb..ad74fb4dc542 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -994,9 +994,10 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, | |||
994 | { | 994 | { |
995 | const char *name; | 995 | const char *name; |
996 | unsigned int namelen; | 996 | unsigned int namelen; |
997 | int res_specified = 0, bpp_specified = 0, refresh_specified = 0; | 997 | bool res_specified = false, bpp_specified = false, refresh_specified = false; |
998 | unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0; | 998 | unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0; |
999 | int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0; | 999 | bool yres_specified = false, cvt = false, rb = false; |
1000 | bool interlace = false, margins = false, was_digit = false; | ||
1000 | int i; | 1001 | int i; |
1001 | enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; | 1002 | enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; |
1002 | 1003 | ||
@@ -1015,54 +1016,65 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, | |||
1015 | for (i = namelen-1; i >= 0; i--) { | 1016 | for (i = namelen-1; i >= 0; i--) { |
1016 | switch (name[i]) { | 1017 | switch (name[i]) { |
1017 | case '@': | 1018 | case '@': |
1018 | namelen = i; | ||
1019 | if (!refresh_specified && !bpp_specified && | 1019 | if (!refresh_specified && !bpp_specified && |
1020 | !yres_specified) { | 1020 | !yres_specified && !cvt && !rb && was_digit) { |
1021 | refresh = simple_strtol(&name[i+1], NULL, 10); | 1021 | refresh = simple_strtol(&name[i+1], NULL, 10); |
1022 | refresh_specified = 1; | 1022 | refresh_specified = true; |
1023 | if (cvt || rb) | 1023 | was_digit = false; |
1024 | cvt = 0; | ||
1025 | } else | 1024 | } else |
1026 | goto done; | 1025 | goto done; |
1027 | break; | 1026 | break; |
1028 | case '-': | 1027 | case '-': |
1029 | namelen = i; | 1028 | if (!bpp_specified && !yres_specified && !cvt && |
1030 | if (!bpp_specified && !yres_specified) { | 1029 | !rb && was_digit) { |
1031 | bpp = simple_strtol(&name[i+1], NULL, 10); | 1030 | bpp = simple_strtol(&name[i+1], NULL, 10); |
1032 | bpp_specified = 1; | 1031 | bpp_specified = true; |
1033 | if (cvt || rb) | 1032 | was_digit = false; |
1034 | cvt = 0; | ||
1035 | } else | 1033 | } else |
1036 | goto done; | 1034 | goto done; |
1037 | break; | 1035 | break; |
1038 | case 'x': | 1036 | case 'x': |
1039 | if (!yres_specified) { | 1037 | if (!yres_specified && was_digit) { |
1040 | yres = simple_strtol(&name[i+1], NULL, 10); | 1038 | yres = simple_strtol(&name[i+1], NULL, 10); |
1041 | yres_specified = 1; | 1039 | yres_specified = true; |
1040 | was_digit = false; | ||
1042 | } else | 1041 | } else |
1043 | goto done; | 1042 | goto done; |
1044 | case '0' ... '9': | 1043 | case '0' ... '9': |
1044 | was_digit = true; | ||
1045 | break; | 1045 | break; |
1046 | case 'M': | 1046 | case 'M': |
1047 | if (!yres_specified) | 1047 | if (yres_specified || cvt || was_digit) |
1048 | cvt = 1; | 1048 | goto done; |
1049 | cvt = true; | ||
1049 | break; | 1050 | break; |
1050 | case 'R': | 1051 | case 'R': |
1051 | if (cvt) | 1052 | if (yres_specified || cvt || rb || was_digit) |
1052 | rb = 1; | 1053 | goto done; |
1054 | rb = true; | ||
1053 | break; | 1055 | break; |
1054 | case 'm': | 1056 | case 'm': |
1055 | if (!cvt) | 1057 | if (cvt || yres_specified || was_digit) |
1056 | margins = 1; | 1058 | goto done; |
1059 | margins = true; | ||
1057 | break; | 1060 | break; |
1058 | case 'i': | 1061 | case 'i': |
1059 | if (!cvt) | 1062 | if (cvt || yres_specified || was_digit) |
1060 | interlace = 1; | 1063 | goto done; |
1064 | interlace = true; | ||
1061 | break; | 1065 | break; |
1062 | case 'e': | 1066 | case 'e': |
1067 | if (yres_specified || bpp_specified || refresh_specified || | ||
1068 | was_digit || (force != DRM_FORCE_UNSPECIFIED)) | ||
1069 | goto done; | ||
1070 | |||
1063 | force = DRM_FORCE_ON; | 1071 | force = DRM_FORCE_ON; |
1064 | break; | 1072 | break; |
1065 | case 'D': | 1073 | case 'D': |
1074 | if (yres_specified || bpp_specified || refresh_specified || | ||
1075 | was_digit || (force != DRM_FORCE_UNSPECIFIED)) | ||
1076 | goto done; | ||
1077 | |||
1066 | if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && | 1078 | if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && |
1067 | (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) | 1079 | (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) |
1068 | force = DRM_FORCE_ON; | 1080 | force = DRM_FORCE_ON; |
@@ -1070,17 +1082,37 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, | |||
1070 | force = DRM_FORCE_ON_DIGITAL; | 1082 | force = DRM_FORCE_ON_DIGITAL; |
1071 | break; | 1083 | break; |
1072 | case 'd': | 1084 | case 'd': |
1085 | if (yres_specified || bpp_specified || refresh_specified || | ||
1086 | was_digit || (force != DRM_FORCE_UNSPECIFIED)) | ||
1087 | goto done; | ||
1088 | |||
1073 | force = DRM_FORCE_OFF; | 1089 | force = DRM_FORCE_OFF; |
1074 | break; | 1090 | break; |
1075 | default: | 1091 | default: |
1076 | goto done; | 1092 | goto done; |
1077 | } | 1093 | } |
1078 | } | 1094 | } |
1095 | |||
1079 | if (i < 0 && yres_specified) { | 1096 | if (i < 0 && yres_specified) { |
1080 | xres = simple_strtol(name, NULL, 10); | 1097 | char *ch; |
1081 | res_specified = 1; | 1098 | xres = simple_strtol(name, &ch, 10); |
1099 | if ((ch != NULL) && (*ch == 'x')) | ||
1100 | res_specified = true; | ||
1101 | else | ||
1102 | i = ch - name; | ||
1103 | } else if (!yres_specified && was_digit) { | ||
1104 | /* catch mode that begins with digits but has no 'x' */ | ||
1105 | i = 0; | ||
1082 | } | 1106 | } |
1083 | done: | 1107 | done: |
1108 | if (i >= 0) { | ||
1109 | printk(KERN_WARNING | ||
1110 | "parse error at position %i in video mode '%s'\n", | ||
1111 | i, name); | ||
1112 | mode->specified = false; | ||
1113 | return false; | ||
1114 | } | ||
1115 | |||
1084 | if (res_specified) { | 1116 | if (res_specified) { |
1085 | mode->specified = true; | 1117 | mode->specified = true; |
1086 | mode->xres = xres; | 1118 | mode->xres = xres; |
@@ -1096,9 +1128,10 @@ done: | |||
1096 | mode->bpp_specified = true; | 1128 | mode->bpp_specified = true; |
1097 | mode->bpp = bpp; | 1129 | mode->bpp = bpp; |
1098 | } | 1130 | } |
1099 | mode->rb = rb ? true : false; | 1131 | mode->rb = rb; |
1100 | mode->cvt = cvt ? true : false; | 1132 | mode->cvt = cvt; |
1101 | mode->interlace = interlace ? true : false; | 1133 | mode->interlace = interlace; |
1134 | mode->margins = margins; | ||
1102 | mode->force = force; | 1135 | mode->force = force; |
1103 | 1136 | ||
1104 | return true; | 1137 | return true; |
diff --git a/drivers/gpu/drm/drm_scatter.c b/drivers/gpu/drm/drm_scatter.c index d15e09b0ae0b..7525e0311e59 100644 --- a/drivers/gpu/drm/drm_scatter.c +++ b/drivers/gpu/drm/drm_scatter.c | |||
@@ -83,30 +83,26 @@ int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request) | |||
83 | if (dev->sg) | 83 | if (dev->sg) |
84 | return -EINVAL; | 84 | return -EINVAL; |
85 | 85 | ||
86 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); | 86 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
87 | if (!entry) | 87 | if (!entry) |
88 | return -ENOMEM; | 88 | return -ENOMEM; |
89 | 89 | ||
90 | memset(entry, 0, sizeof(*entry)); | ||
91 | pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; | 90 | pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; |
92 | DRM_DEBUG("size=%ld pages=%ld\n", request->size, pages); | 91 | DRM_DEBUG("size=%ld pages=%ld\n", request->size, pages); |
93 | 92 | ||
94 | entry->pages = pages; | 93 | entry->pages = pages; |
95 | entry->pagelist = kmalloc(pages * sizeof(*entry->pagelist), GFP_KERNEL); | 94 | entry->pagelist = kcalloc(pages, sizeof(*entry->pagelist), GFP_KERNEL); |
96 | if (!entry->pagelist) { | 95 | if (!entry->pagelist) { |
97 | kfree(entry); | 96 | kfree(entry); |
98 | return -ENOMEM; | 97 | return -ENOMEM; |
99 | } | 98 | } |
100 | 99 | ||
101 | memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist)); | 100 | entry->busaddr = kcalloc(pages, sizeof(*entry->busaddr), GFP_KERNEL); |
102 | |||
103 | entry->busaddr = kmalloc(pages * sizeof(*entry->busaddr), GFP_KERNEL); | ||
104 | if (!entry->busaddr) { | 101 | if (!entry->busaddr) { |
105 | kfree(entry->pagelist); | 102 | kfree(entry->pagelist); |
106 | kfree(entry); | 103 | kfree(entry); |
107 | return -ENOMEM; | 104 | return -ENOMEM; |
108 | } | 105 | } |
109 | memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr)); | ||
110 | 106 | ||
111 | entry->virtual = drm_vmalloc_dma(pages << PAGE_SHIFT); | 107 | entry->virtual = drm_vmalloc_dma(pages << PAGE_SHIFT); |
112 | if (!entry->virtual) { | 108 | if (!entry->virtual) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 1aa73d3957e1..b311faba34f8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -5966,6 +5966,12 @@ apply_dcb_connector_quirks(struct nvbios *bios, int idx) | |||
5966 | if (cte->type == DCB_CONNECTOR_HDMI_1) | 5966 | if (cte->type == DCB_CONNECTOR_HDMI_1) |
5967 | cte->type = DCB_CONNECTOR_DVI_I; | 5967 | cte->type = DCB_CONNECTOR_DVI_I; |
5968 | } | 5968 | } |
5969 | |||
5970 | /* Gigabyte GV-NX86T512H */ | ||
5971 | if (nv_match_device(dev, 0x0402, 0x1458, 0x3455)) { | ||
5972 | if (cte->type == DCB_CONNECTOR_HDMI_1) | ||
5973 | cte->type = DCB_CONNECTOR_DVI_I; | ||
5974 | } | ||
5969 | } | 5975 | } |
5970 | 5976 | ||
5971 | static const u8 hpd_gpio[16] = { | 5977 | static const u8 hpd_gpio[16] = { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 1595d0b6e815..939d4df07777 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -40,7 +40,7 @@ | |||
40 | static void nouveau_connector_hotplug(void *, int); | 40 | static void nouveau_connector_hotplug(void *, int); |
41 | 41 | ||
42 | static struct nouveau_encoder * | 42 | static struct nouveau_encoder * |
43 | find_encoder_by_type(struct drm_connector *connector, int type) | 43 | find_encoder(struct drm_connector *connector, int type) |
44 | { | 44 | { |
45 | struct drm_device *dev = connector->dev; | 45 | struct drm_device *dev = connector->dev; |
46 | struct nouveau_encoder *nv_encoder; | 46 | struct nouveau_encoder *nv_encoder; |
@@ -170,8 +170,8 @@ nouveau_connector_of_detect(struct drm_connector *connector) | |||
170 | struct device_node *cn, *dn = pci_device_to_OF_node(dev->pdev); | 170 | struct device_node *cn, *dn = pci_device_to_OF_node(dev->pdev); |
171 | 171 | ||
172 | if (!dn || | 172 | if (!dn || |
173 | !((nv_encoder = find_encoder_by_type(connector, OUTPUT_TMDS)) || | 173 | !((nv_encoder = find_encoder(connector, OUTPUT_TMDS)) || |
174 | (nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG)))) | 174 | (nv_encoder = find_encoder(connector, OUTPUT_ANALOG)))) |
175 | return NULL; | 175 | return NULL; |
176 | 176 | ||
177 | for_each_child_of_node(dn, cn) { | 177 | for_each_child_of_node(dn, cn) { |
@@ -233,6 +233,7 @@ nouveau_connector_detect(struct drm_connector *connector, bool force) | |||
233 | struct drm_device *dev = connector->dev; | 233 | struct drm_device *dev = connector->dev; |
234 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | 234 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
235 | struct nouveau_encoder *nv_encoder = NULL; | 235 | struct nouveau_encoder *nv_encoder = NULL; |
236 | struct nouveau_encoder *nv_partner; | ||
236 | struct nouveau_i2c_chan *i2c; | 237 | struct nouveau_i2c_chan *i2c; |
237 | int type; | 238 | int type; |
238 | 239 | ||
@@ -266,19 +267,22 @@ nouveau_connector_detect(struct drm_connector *connector, bool force) | |||
266 | * same i2c channel so the value returned from ddc_detect | 267 | * same i2c channel so the value returned from ddc_detect |
267 | * isn't necessarily correct. | 268 | * isn't necessarily correct. |
268 | */ | 269 | */ |
269 | if (nv_connector->dcb->type == DCB_CONNECTOR_DVI_I) { | 270 | nv_partner = NULL; |
271 | if (nv_encoder->dcb->type == OUTPUT_TMDS) | ||
272 | nv_partner = find_encoder(connector, OUTPUT_ANALOG); | ||
273 | if (nv_encoder->dcb->type == OUTPUT_ANALOG) | ||
274 | nv_partner = find_encoder(connector, OUTPUT_TMDS); | ||
275 | |||
276 | if (nv_partner && ((nv_encoder->dcb->type == OUTPUT_ANALOG && | ||
277 | nv_partner->dcb->type == OUTPUT_TMDS) || | ||
278 | (nv_encoder->dcb->type == OUTPUT_TMDS && | ||
279 | nv_partner->dcb->type == OUTPUT_ANALOG))) { | ||
270 | if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL) | 280 | if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL) |
271 | type = OUTPUT_TMDS; | 281 | type = OUTPUT_TMDS; |
272 | else | 282 | else |
273 | type = OUTPUT_ANALOG; | 283 | type = OUTPUT_ANALOG; |
274 | 284 | ||
275 | nv_encoder = find_encoder_by_type(connector, type); | 285 | nv_encoder = find_encoder(connector, type); |
276 | if (!nv_encoder) { | ||
277 | NV_ERROR(dev, "Detected %d encoder on %s, " | ||
278 | "but no object!\n", type, | ||
279 | drm_get_connector_name(connector)); | ||
280 | return connector_status_disconnected; | ||
281 | } | ||
282 | } | 286 | } |
283 | 287 | ||
284 | nouveau_connector_set_encoder(connector, nv_encoder); | 288 | nouveau_connector_set_encoder(connector, nv_encoder); |
@@ -292,9 +296,9 @@ nouveau_connector_detect(struct drm_connector *connector, bool force) | |||
292 | } | 296 | } |
293 | 297 | ||
294 | detect_analog: | 298 | detect_analog: |
295 | nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG); | 299 | nv_encoder = find_encoder(connector, OUTPUT_ANALOG); |
296 | if (!nv_encoder && !nouveau_tv_disable) | 300 | if (!nv_encoder && !nouveau_tv_disable) |
297 | nv_encoder = find_encoder_by_type(connector, OUTPUT_TV); | 301 | nv_encoder = find_encoder(connector, OUTPUT_TV); |
298 | if (nv_encoder && force) { | 302 | if (nv_encoder && force) { |
299 | struct drm_encoder *encoder = to_drm_encoder(nv_encoder); | 303 | struct drm_encoder *encoder = to_drm_encoder(nv_encoder); |
300 | struct drm_encoder_helper_funcs *helper = | 304 | struct drm_encoder_helper_funcs *helper = |
@@ -327,7 +331,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) | |||
327 | nv_connector->edid = NULL; | 331 | nv_connector->edid = NULL; |
328 | } | 332 | } |
329 | 333 | ||
330 | nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); | 334 | nv_encoder = find_encoder(connector, OUTPUT_LVDS); |
331 | if (!nv_encoder) | 335 | if (!nv_encoder) |
332 | return connector_status_disconnected; | 336 | return connector_status_disconnected; |
333 | 337 | ||
@@ -405,7 +409,7 @@ nouveau_connector_force(struct drm_connector *connector) | |||
405 | } else | 409 | } else |
406 | type = OUTPUT_ANY; | 410 | type = OUTPUT_ANY; |
407 | 411 | ||
408 | nv_encoder = find_encoder_by_type(connector, type); | 412 | nv_encoder = find_encoder(connector, type); |
409 | if (!nv_encoder) { | 413 | if (!nv_encoder) { |
410 | NV_ERROR(connector->dev, "can't find encoder to force %s on!\n", | 414 | NV_ERROR(connector->dev, "can't find encoder to force %s on!\n", |
411 | drm_get_connector_name(connector)); | 415 | drm_get_connector_name(connector)); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 8256370e5938..b30ddd8d2e2a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c | |||
@@ -214,10 +214,13 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) | |||
214 | pfifo->unload_context(dev); | 214 | pfifo->unload_context(dev); |
215 | 215 | ||
216 | for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) { | 216 | for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) { |
217 | if (dev_priv->eng[e]) { | 217 | if (!dev_priv->eng[e]) |
218 | ret = dev_priv->eng[e]->fini(dev, e); | 218 | continue; |
219 | if (ret) | 219 | |
220 | goto out_abort; | 220 | ret = dev_priv->eng[e]->fini(dev, e, true); |
221 | if (ret) { | ||
222 | NV_ERROR(dev, "... engine %d failed: %d\n", i, ret); | ||
223 | goto out_abort; | ||
221 | } | 224 | } |
222 | } | 225 | } |
223 | 226 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 72bfc143eb47..d7d51deb34b6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -312,7 +312,7 @@ struct nouveau_channel { | |||
312 | struct nouveau_exec_engine { | 312 | struct nouveau_exec_engine { |
313 | void (*destroy)(struct drm_device *, int engine); | 313 | void (*destroy)(struct drm_device *, int engine); |
314 | int (*init)(struct drm_device *, int engine); | 314 | int (*init)(struct drm_device *, int engine); |
315 | int (*fini)(struct drm_device *, int engine); | 315 | int (*fini)(struct drm_device *, int engine, bool suspend); |
316 | int (*context_new)(struct nouveau_channel *, int engine); | 316 | int (*context_new)(struct nouveau_channel *, int engine); |
317 | void (*context_del)(struct nouveau_channel *, int engine); | 317 | void (*context_del)(struct nouveau_channel *, int engine); |
318 | int (*object_new)(struct nouveau_channel *, int engine, | 318 | int (*object_new)(struct nouveau_channel *, int engine, |
@@ -1142,7 +1142,6 @@ extern int nvc0_fifo_unload_context(struct drm_device *); | |||
1142 | 1142 | ||
1143 | /* nv04_graph.c */ | 1143 | /* nv04_graph.c */ |
1144 | extern int nv04_graph_create(struct drm_device *); | 1144 | extern int nv04_graph_create(struct drm_device *); |
1145 | extern void nv04_graph_fifo_access(struct drm_device *, bool); | ||
1146 | extern int nv04_graph_object_new(struct nouveau_channel *, int, u32, u16); | 1145 | extern int nv04_graph_object_new(struct nouveau_channel *, int, u32, u16); |
1147 | extern int nv04_graph_mthd_page_flip(struct nouveau_channel *chan, | 1146 | extern int nv04_graph_mthd_page_flip(struct nouveau_channel *chan, |
1148 | u32 class, u32 mthd, u32 data); | 1147 | u32 class, u32 mthd, u32 data); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 2ba7265bc967..868c7fd74854 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
@@ -79,7 +79,7 @@ nouveau_irq_handler(DRM_IRQ_ARGS) | |||
79 | int i; | 79 | int i; |
80 | 80 | ||
81 | stat = nv_rd32(dev, NV03_PMC_INTR_0); | 81 | stat = nv_rd32(dev, NV03_PMC_INTR_0); |
82 | if (!stat) | 82 | if (stat == 0 || stat == ~0) |
83 | return IRQ_NONE; | 83 | return IRQ_NONE; |
84 | 84 | ||
85 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | 85 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index fa1e63210040..10656e430b44 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -694,7 +694,7 @@ out_engine: | |||
694 | for (e = e - 1; e >= 0; e--) { | 694 | for (e = e - 1; e >= 0; e--) { |
695 | if (!dev_priv->eng[e]) | 695 | if (!dev_priv->eng[e]) |
696 | continue; | 696 | continue; |
697 | dev_priv->eng[e]->fini(dev, e); | 697 | dev_priv->eng[e]->fini(dev, e, false); |
698 | dev_priv->eng[e]->destroy(dev,e ); | 698 | dev_priv->eng[e]->destroy(dev,e ); |
699 | } | 699 | } |
700 | } | 700 | } |
@@ -746,7 +746,7 @@ static void nouveau_card_takedown(struct drm_device *dev) | |||
746 | engine->fifo.takedown(dev); | 746 | engine->fifo.takedown(dev); |
747 | for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) { | 747 | for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) { |
748 | if (dev_priv->eng[e]) { | 748 | if (dev_priv->eng[e]) { |
749 | dev_priv->eng[e]->fini(dev, e); | 749 | dev_priv->eng[e]->fini(dev, e, false); |
750 | dev_priv->eng[e]->destroy(dev,e ); | 750 | dev_priv->eng[e]->destroy(dev,e ); |
751 | } | 751 | } |
752 | } | 752 | } |
diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index 3626ee7db3ba..dbdea8ed3925 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c | |||
@@ -450,13 +450,13 @@ nv04_graph_context_del(struct nouveau_channel *chan, int engine) | |||
450 | unsigned long flags; | 450 | unsigned long flags; |
451 | 451 | ||
452 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | 452 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
453 | nv04_graph_fifo_access(dev, false); | 453 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); |
454 | 454 | ||
455 | /* Unload the context if it's the currently active one */ | 455 | /* Unload the context if it's the currently active one */ |
456 | if (nv04_graph_channel(dev) == chan) | 456 | if (nv04_graph_channel(dev) == chan) |
457 | nv04_graph_unload_context(dev); | 457 | nv04_graph_unload_context(dev); |
458 | 458 | ||
459 | nv04_graph_fifo_access(dev, true); | 459 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); |
460 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | 460 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); |
461 | 461 | ||
462 | /* Free the context resources */ | 462 | /* Free the context resources */ |
@@ -538,24 +538,18 @@ nv04_graph_init(struct drm_device *dev, int engine) | |||
538 | } | 538 | } |
539 | 539 | ||
540 | static int | 540 | static int |
541 | nv04_graph_fini(struct drm_device *dev, int engine) | 541 | nv04_graph_fini(struct drm_device *dev, int engine, bool suspend) |
542 | { | 542 | { |
543 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); | ||
544 | if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) { | ||
545 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); | ||
546 | return -EBUSY; | ||
547 | } | ||
543 | nv04_graph_unload_context(dev); | 548 | nv04_graph_unload_context(dev); |
544 | nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); | 549 | nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); |
545 | return 0; | 550 | return 0; |
546 | } | 551 | } |
547 | 552 | ||
548 | void | ||
549 | nv04_graph_fifo_access(struct drm_device *dev, bool enabled) | ||
550 | { | ||
551 | if (enabled) | ||
552 | nv_wr32(dev, NV04_PGRAPH_FIFO, | ||
553 | nv_rd32(dev, NV04_PGRAPH_FIFO) | 1); | ||
554 | else | ||
555 | nv_wr32(dev, NV04_PGRAPH_FIFO, | ||
556 | nv_rd32(dev, NV04_PGRAPH_FIFO) & ~1); | ||
557 | } | ||
558 | |||
559 | static int | 553 | static int |
560 | nv04_graph_mthd_set_ref(struct nouveau_channel *chan, | 554 | nv04_graph_mthd_set_ref(struct nouveau_channel *chan, |
561 | u32 class, u32 mthd, u32 data) | 555 | u32 class, u32 mthd, u32 data) |
diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index 0930c6cb88e0..7255e4a4d3f3 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c | |||
@@ -708,8 +708,8 @@ static void nv10_graph_load_dma_vtxbuf(struct nouveau_channel *chan, | |||
708 | 0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c); | 708 | 0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c); |
709 | nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst); | 709 | nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst); |
710 | nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000); | 710 | nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000); |
711 | nv04_graph_fifo_access(dev, true); | 711 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); |
712 | nv04_graph_fifo_access(dev, false); | 712 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); |
713 | 713 | ||
714 | /* Restore the FIFO state */ | 714 | /* Restore the FIFO state */ |
715 | for (i = 0; i < ARRAY_SIZE(fifo); i++) | 715 | for (i = 0; i < ARRAY_SIZE(fifo); i++) |
@@ -879,13 +879,13 @@ nv10_graph_context_del(struct nouveau_channel *chan, int engine) | |||
879 | unsigned long flags; | 879 | unsigned long flags; |
880 | 880 | ||
881 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | 881 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
882 | nv04_graph_fifo_access(dev, false); | 882 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); |
883 | 883 | ||
884 | /* Unload the context if it's the currently active one */ | 884 | /* Unload the context if it's the currently active one */ |
885 | if (nv10_graph_channel(dev) == chan) | 885 | if (nv10_graph_channel(dev) == chan) |
886 | nv10_graph_unload_context(dev); | 886 | nv10_graph_unload_context(dev); |
887 | 887 | ||
888 | nv04_graph_fifo_access(dev, true); | 888 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); |
889 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | 889 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); |
890 | 890 | ||
891 | /* Free the context resources */ | 891 | /* Free the context resources */ |
@@ -957,8 +957,13 @@ nv10_graph_init(struct drm_device *dev, int engine) | |||
957 | } | 957 | } |
958 | 958 | ||
959 | static int | 959 | static int |
960 | nv10_graph_fini(struct drm_device *dev, int engine) | 960 | nv10_graph_fini(struct drm_device *dev, int engine, bool suspend) |
961 | { | 961 | { |
962 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); | ||
963 | if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) { | ||
964 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); | ||
965 | return -EBUSY; | ||
966 | } | ||
962 | nv10_graph_unload_context(dev); | 967 | nv10_graph_unload_context(dev); |
963 | nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); | 968 | nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); |
964 | return 0; | 969 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index affc7d7dd029..183e37512ef9 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c | |||
@@ -454,13 +454,13 @@ nv20_graph_context_del(struct nouveau_channel *chan, int engine) | |||
454 | unsigned long flags; | 454 | unsigned long flags; |
455 | 455 | ||
456 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | 456 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
457 | nv04_graph_fifo_access(dev, false); | 457 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); |
458 | 458 | ||
459 | /* Unload the context if it's the currently active one */ | 459 | /* Unload the context if it's the currently active one */ |
460 | if (nv10_graph_channel(dev) == chan) | 460 | if (nv10_graph_channel(dev) == chan) |
461 | nv20_graph_unload_context(dev); | 461 | nv20_graph_unload_context(dev); |
462 | 462 | ||
463 | nv04_graph_fifo_access(dev, true); | 463 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); |
464 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | 464 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); |
465 | 465 | ||
466 | /* Free the context resources */ | 466 | /* Free the context resources */ |
@@ -654,8 +654,13 @@ nv30_graph_init(struct drm_device *dev, int engine) | |||
654 | } | 654 | } |
655 | 655 | ||
656 | int | 656 | int |
657 | nv20_graph_fini(struct drm_device *dev, int engine) | 657 | nv20_graph_fini(struct drm_device *dev, int engine, bool suspend) |
658 | { | 658 | { |
659 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); | ||
660 | if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) { | ||
661 | nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); | ||
662 | return -EBUSY; | ||
663 | } | ||
659 | nv20_graph_unload_context(dev); | 664 | nv20_graph_unload_context(dev); |
660 | nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); | 665 | nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); |
661 | return 0; | 666 | return 0; |
@@ -753,6 +758,7 @@ nv20_graph_create(struct drm_device *dev) | |||
753 | break; | 758 | break; |
754 | default: | 759 | default: |
755 | NV_ERROR(dev, "PGRAPH: unknown chipset\n"); | 760 | NV_ERROR(dev, "PGRAPH: unknown chipset\n"); |
761 | kfree(pgraph); | ||
756 | return 0; | 762 | return 0; |
757 | } | 763 | } |
758 | } else { | 764 | } else { |
@@ -774,6 +780,7 @@ nv20_graph_create(struct drm_device *dev) | |||
774 | break; | 780 | break; |
775 | default: | 781 | default: |
776 | NV_ERROR(dev, "PGRAPH: unknown chipset\n"); | 782 | NV_ERROR(dev, "PGRAPH: unknown chipset\n"); |
783 | kfree(pgraph); | ||
777 | return 0; | 784 | return 0; |
778 | } | 785 | } |
779 | } | 786 | } |
diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 5beb01b8ace1..ba14a93d8afa 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c | |||
@@ -35,89 +35,6 @@ struct nv40_graph_engine { | |||
35 | u32 grctx_size; | 35 | u32 grctx_size; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | static struct nouveau_channel * | ||
39 | nv40_graph_channel(struct drm_device *dev) | ||
40 | { | ||
41 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
42 | struct nouveau_gpuobj *grctx; | ||
43 | uint32_t inst; | ||
44 | int i; | ||
45 | |||
46 | inst = nv_rd32(dev, NV40_PGRAPH_CTXCTL_CUR); | ||
47 | if (!(inst & NV40_PGRAPH_CTXCTL_CUR_LOADED)) | ||
48 | return NULL; | ||
49 | inst = (inst & NV40_PGRAPH_CTXCTL_CUR_INSTANCE) << 4; | ||
50 | |||
51 | for (i = 0; i < dev_priv->engine.fifo.channels; i++) { | ||
52 | if (!dev_priv->channels.ptr[i]) | ||
53 | continue; | ||
54 | |||
55 | grctx = dev_priv->channels.ptr[i]->engctx[NVOBJ_ENGINE_GR]; | ||
56 | if (grctx && grctx->pinst == inst) | ||
57 | return dev_priv->channels.ptr[i]; | ||
58 | } | ||
59 | |||
60 | return NULL; | ||
61 | } | ||
62 | |||
63 | static int | ||
64 | nv40_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save) | ||
65 | { | ||
66 | uint32_t old_cp, tv = 1000, tmp; | ||
67 | int i; | ||
68 | |||
69 | old_cp = nv_rd32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER); | ||
70 | nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); | ||
71 | |||
72 | tmp = nv_rd32(dev, NV40_PGRAPH_CTXCTL_0310); | ||
73 | tmp |= save ? NV40_PGRAPH_CTXCTL_0310_XFER_SAVE : | ||
74 | NV40_PGRAPH_CTXCTL_0310_XFER_LOAD; | ||
75 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_0310, tmp); | ||
76 | |||
77 | tmp = nv_rd32(dev, NV40_PGRAPH_CTXCTL_0304); | ||
78 | tmp |= NV40_PGRAPH_CTXCTL_0304_XFER_CTX; | ||
79 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_0304, tmp); | ||
80 | |||
81 | nouveau_wait_for_idle(dev); | ||
82 | |||
83 | for (i = 0; i < tv; i++) { | ||
84 | if (nv_rd32(dev, NV40_PGRAPH_CTXCTL_030C) == 0) | ||
85 | break; | ||
86 | } | ||
87 | |||
88 | nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, old_cp); | ||
89 | |||
90 | if (i == tv) { | ||
91 | uint32_t ucstat = nv_rd32(dev, NV40_PGRAPH_CTXCTL_UCODE_STAT); | ||
92 | NV_ERROR(dev, "Failed: Instance=0x%08x Save=%d\n", inst, save); | ||
93 | NV_ERROR(dev, "IP: 0x%02x, Opcode: 0x%08x\n", | ||
94 | ucstat >> NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT, | ||
95 | ucstat & NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK); | ||
96 | NV_ERROR(dev, "0x40030C = 0x%08x\n", | ||
97 | nv_rd32(dev, NV40_PGRAPH_CTXCTL_030C)); | ||
98 | return -EBUSY; | ||
99 | } | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int | ||
105 | nv40_graph_unload_context(struct drm_device *dev) | ||
106 | { | ||
107 | uint32_t inst; | ||
108 | int ret; | ||
109 | |||
110 | inst = nv_rd32(dev, NV40_PGRAPH_CTXCTL_CUR); | ||
111 | if (!(inst & NV40_PGRAPH_CTXCTL_CUR_LOADED)) | ||
112 | return 0; | ||
113 | inst &= NV40_PGRAPH_CTXCTL_CUR_INSTANCE; | ||
114 | |||
115 | ret = nv40_graph_transfer_context(dev, inst, 1); | ||
116 | |||
117 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, inst); | ||
118 | return ret; | ||
119 | } | ||
120 | |||
121 | static int | 38 | static int |
122 | nv40_graph_context_new(struct nouveau_channel *chan, int engine) | 39 | nv40_graph_context_new(struct nouveau_channel *chan, int engine) |
123 | { | 40 | { |
@@ -163,16 +80,16 @@ nv40_graph_context_del(struct nouveau_channel *chan, int engine) | |||
163 | struct nouveau_gpuobj *grctx = chan->engctx[engine]; | 80 | struct nouveau_gpuobj *grctx = chan->engctx[engine]; |
164 | struct drm_device *dev = chan->dev; | 81 | struct drm_device *dev = chan->dev; |
165 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 82 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
83 | u32 inst = 0x01000000 | (grctx->pinst >> 4); | ||
166 | unsigned long flags; | 84 | unsigned long flags; |
167 | 85 | ||
168 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | 86 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
169 | nv04_graph_fifo_access(dev, false); | 87 | nv_mask(dev, 0x400720, 0x00000000, 0x00000001); |
170 | 88 | if (nv_rd32(dev, 0x40032c) == inst) | |
171 | /* Unload the context if it's the currently active one */ | 89 | nv_mask(dev, 0x40032c, 0x01000000, 0x00000000); |
172 | if (nv40_graph_channel(dev) == chan) | 90 | if (nv_rd32(dev, 0x400330) == inst) |
173 | nv40_graph_unload_context(dev); | 91 | nv_mask(dev, 0x400330, 0x01000000, 0x00000000); |
174 | 92 | nv_mask(dev, 0x400720, 0x00000001, 0x00000001); | |
175 | nv04_graph_fifo_access(dev, true); | ||
176 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | 93 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); |
177 | 94 | ||
178 | /* Free the context resources */ | 95 | /* Free the context resources */ |
@@ -429,9 +346,20 @@ nv40_graph_init(struct drm_device *dev, int engine) | |||
429 | } | 346 | } |
430 | 347 | ||
431 | static int | 348 | static int |
432 | nv40_graph_fini(struct drm_device *dev, int engine) | 349 | nv40_graph_fini(struct drm_device *dev, int engine, bool suspend) |
433 | { | 350 | { |
434 | nv40_graph_unload_context(dev); | 351 | u32 inst = nv_rd32(dev, 0x40032c); |
352 | if (inst & 0x01000000) { | ||
353 | nv_wr32(dev, 0x400720, 0x00000000); | ||
354 | nv_wr32(dev, 0x400784, inst); | ||
355 | nv_mask(dev, 0x400310, 0x00000020, 0x00000020); | ||
356 | nv_mask(dev, 0x400304, 0x00000001, 0x00000001); | ||
357 | if (!nv_wait(dev, 0x400300, 0x00000001, 0x00000000)) { | ||
358 | u32 insn = nv_rd32(dev, 0x400308); | ||
359 | NV_ERROR(dev, "PGRAPH: ctxprog timeout 0x%08x\n", insn); | ||
360 | } | ||
361 | nv_mask(dev, 0x40032c, 0x01000000, 0x00000000); | ||
362 | } | ||
435 | return 0; | 363 | return 0; |
436 | } | 364 | } |
437 | 365 | ||
diff --git a/drivers/gpu/drm/nouveau/nv40_mpeg.c b/drivers/gpu/drm/nouveau/nv40_mpeg.c index 6d2af292a2e3..ad03a0e1fc7d 100644 --- a/drivers/gpu/drm/nouveau/nv40_mpeg.c +++ b/drivers/gpu/drm/nouveau/nv40_mpeg.c | |||
@@ -137,7 +137,7 @@ nv40_mpeg_init(struct drm_device *dev, int engine) | |||
137 | } | 137 | } |
138 | 138 | ||
139 | static int | 139 | static int |
140 | nv40_mpeg_fini(struct drm_device *dev, int engine) | 140 | nv40_mpeg_fini(struct drm_device *dev, int engine, bool suspend) |
141 | { | 141 | { |
142 | /*XXX: context save? */ | 142 | /*XXX: context save? */ |
143 | nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000); | 143 | nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000); |
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index e25cbb46789a..d43c46caa76e 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include "nouveau_grctx.h" | 31 | #include "nouveau_grctx.h" |
32 | #include "nouveau_dma.h" | 32 | #include "nouveau_dma.h" |
33 | #include "nouveau_vm.h" | 33 | #include "nouveau_vm.h" |
34 | #include "nouveau_ramht.h" | ||
35 | #include "nv50_evo.h" | 34 | #include "nv50_evo.h" |
36 | 35 | ||
37 | struct nv50_graph_engine { | 36 | struct nv50_graph_engine { |
@@ -125,7 +124,6 @@ static void | |||
125 | nv50_graph_init_reset(struct drm_device *dev) | 124 | nv50_graph_init_reset(struct drm_device *dev) |
126 | { | 125 | { |
127 | uint32_t pmc_e = NV_PMC_ENABLE_PGRAPH | (1 << 21); | 126 | uint32_t pmc_e = NV_PMC_ENABLE_PGRAPH | (1 << 21); |
128 | |||
129 | NV_DEBUG(dev, "\n"); | 127 | NV_DEBUG(dev, "\n"); |
130 | 128 | ||
131 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e); | 129 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e); |
@@ -255,9 +253,13 @@ nv50_graph_init(struct drm_device *dev, int engine) | |||
255 | } | 253 | } |
256 | 254 | ||
257 | static int | 255 | static int |
258 | nv50_graph_fini(struct drm_device *dev, int engine) | 256 | nv50_graph_fini(struct drm_device *dev, int engine, bool suspend) |
259 | { | 257 | { |
260 | NV_DEBUG(dev, "\n"); | 258 | nv_mask(dev, 0x400500, 0x00010001, 0x00000000); |
259 | if (!nv_wait(dev, 0x400700, ~0, 0) && suspend) { | ||
260 | nv_mask(dev, 0x400500, 0x00010001, 0x00010001); | ||
261 | return -EBUSY; | ||
262 | } | ||
261 | nv50_graph_unload_context(dev); | 263 | nv50_graph_unload_context(dev); |
262 | nv_wr32(dev, 0x40013c, 0x00000000); | 264 | nv_wr32(dev, 0x40013c, 0x00000000); |
263 | return 0; | 265 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/nv50_mpeg.c b/drivers/gpu/drm/nouveau/nv50_mpeg.c index 1dc5913f78c5..b57a2d180ad2 100644 --- a/drivers/gpu/drm/nouveau/nv50_mpeg.c +++ b/drivers/gpu/drm/nouveau/nv50_mpeg.c | |||
@@ -160,7 +160,7 @@ nv50_mpeg_init(struct drm_device *dev, int engine) | |||
160 | } | 160 | } |
161 | 161 | ||
162 | static int | 162 | static int |
163 | nv50_mpeg_fini(struct drm_device *dev, int engine) | 163 | nv50_mpeg_fini(struct drm_device *dev, int engine, bool suspend) |
164 | { | 164 | { |
165 | /*XXX: context save for s/r */ | 165 | /*XXX: context save for s/r */ |
166 | nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000); | 166 | nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000); |
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index c25c59386420..ffe8b483b7b0 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c | |||
@@ -318,6 +318,8 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry) | |||
318 | uint32_t tmp; | 318 | uint32_t tmp; |
319 | 319 | ||
320 | tmp = nv_rd32(dev, 0x61c700 + (or * 0x800)); | 320 | tmp = nv_rd32(dev, 0x61c700 + (or * 0x800)); |
321 | if (!tmp) | ||
322 | tmp = nv_rd32(dev, 0x610798 + (or * 8)); | ||
321 | 323 | ||
322 | switch ((tmp & 0x00000f00) >> 8) { | 324 | switch ((tmp & 0x00000f00) >> 8) { |
323 | case 8: | 325 | case 8: |
diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c index 75b809a51748..edece9c616eb 100644 --- a/drivers/gpu/drm/nouveau/nv84_crypt.c +++ b/drivers/gpu/drm/nouveau/nv84_crypt.c | |||
@@ -138,7 +138,7 @@ nv84_crypt_isr(struct drm_device *dev) | |||
138 | } | 138 | } |
139 | 139 | ||
140 | static int | 140 | static int |
141 | nv84_crypt_fini(struct drm_device *dev, int engine) | 141 | nv84_crypt_fini(struct drm_device *dev, int engine, bool suspend) |
142 | { | 142 | { |
143 | nv_wr32(dev, 0x102140, 0x00000000); | 143 | nv_wr32(dev, 0x102140, 0x00000000); |
144 | return 0; | 144 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/nva3_copy.c b/drivers/gpu/drm/nouveau/nva3_copy.c index b86820a61220..8f356d58e409 100644 --- a/drivers/gpu/drm/nouveau/nva3_copy.c +++ b/drivers/gpu/drm/nouveau/nva3_copy.c | |||
@@ -140,7 +140,7 @@ nva3_copy_init(struct drm_device *dev, int engine) | |||
140 | } | 140 | } |
141 | 141 | ||
142 | static int | 142 | static int |
143 | nva3_copy_fini(struct drm_device *dev, int engine) | 143 | nva3_copy_fini(struct drm_device *dev, int engine, bool suspend) |
144 | { | 144 | { |
145 | nv_mask(dev, 0x104048, 0x00000003, 0x00000000); | 145 | nv_mask(dev, 0x104048, 0x00000003, 0x00000000); |
146 | 146 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_copy.c b/drivers/gpu/drm/nouveau/nvc0_copy.c index 5ebcd74244db..dddf006f6d88 100644 --- a/drivers/gpu/drm/nouveau/nvc0_copy.c +++ b/drivers/gpu/drm/nouveau/nvc0_copy.c | |||
@@ -127,7 +127,7 @@ nvc0_copy_init(struct drm_device *dev, int engine) | |||
127 | } | 127 | } |
128 | 128 | ||
129 | static int | 129 | static int |
130 | nvc0_copy_fini(struct drm_device *dev, int engine) | 130 | nvc0_copy_fini(struct drm_device *dev, int engine, bool suspend) |
131 | { | 131 | { |
132 | struct nvc0_copy_engine *pcopy = nv_engine(dev, engine); | 132 | struct nvc0_copy_engine *pcopy = nv_engine(dev, engine); |
133 | 133 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c index 3a97431996c5..5b2f6f420468 100644 --- a/drivers/gpu/drm/nouveau/nvc0_graph.c +++ b/drivers/gpu/drm/nouveau/nvc0_graph.c | |||
@@ -304,7 +304,7 @@ nvc0_graph_object_new(struct nouveau_channel *chan, int engine, | |||
304 | } | 304 | } |
305 | 305 | ||
306 | static int | 306 | static int |
307 | nvc0_graph_fini(struct drm_device *dev, int engine) | 307 | nvc0_graph_fini(struct drm_device *dev, int engine, bool suspend) |
308 | { | 308 | { |
309 | return 0; | 309 | return 0; |
310 | } | 310 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 9541995e4b21..c742944d3805 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -764,7 +764,7 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc, | |||
764 | } | 764 | } |
765 | 765 | ||
766 | static void atombios_crtc_program_pll(struct drm_crtc *crtc, | 766 | static void atombios_crtc_program_pll(struct drm_crtc *crtc, |
767 | int crtc_id, | 767 | u32 crtc_id, |
768 | int pll_id, | 768 | int pll_id, |
769 | u32 encoder_mode, | 769 | u32 encoder_mode, |
770 | u32 encoder_id, | 770 | u32 encoder_id, |
@@ -851,8 +851,7 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc, | |||
851 | args.v5.ucPpll = pll_id; | 851 | args.v5.ucPpll = pll_id; |
852 | break; | 852 | break; |
853 | case 6: | 853 | case 6: |
854 | args.v6.ulCrtcPclkFreq.ucCRTC = crtc_id; | 854 | args.v6.ulDispEngClkFreq = cpu_to_le32(crtc_id << 24 | clock / 10); |
855 | args.v6.ulCrtcPclkFreq.ulPixelClock = cpu_to_le32(clock / 10); | ||
856 | args.v6.ucRefDiv = ref_div; | 855 | args.v6.ucRefDiv = ref_div; |
857 | args.v6.usFbDiv = cpu_to_le16(fb_div); | 856 | args.v6.usFbDiv = cpu_to_le16(fb_div); |
858 | args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); | 857 | args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 8c0f9e36ff8e..645b84b3d203 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -627,6 +627,7 @@ struct radeon_dp_link_train_info { | |||
627 | u8 train_set[4]; | 627 | u8 train_set[4]; |
628 | u8 link_status[DP_LINK_STATUS_SIZE]; | 628 | u8 link_status[DP_LINK_STATUS_SIZE]; |
629 | u8 tries; | 629 | u8 tries; |
630 | bool use_dpencoder; | ||
630 | }; | 631 | }; |
631 | 632 | ||
632 | static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info) | 633 | static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info) |
@@ -646,7 +647,7 @@ static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp) | |||
646 | int rtp = 0; | 647 | int rtp = 0; |
647 | 648 | ||
648 | /* set training pattern on the source */ | 649 | /* set training pattern on the source */ |
649 | if (ASIC_IS_DCE4(dp_info->rdev)) { | 650 | if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) { |
650 | switch (tp) { | 651 | switch (tp) { |
651 | case DP_TRAINING_PATTERN_1: | 652 | case DP_TRAINING_PATTERN_1: |
652 | rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1; | 653 | rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1; |
@@ -706,7 +707,7 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) | |||
706 | radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp); | 707 | radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp); |
707 | 708 | ||
708 | /* start training on the source */ | 709 | /* start training on the source */ |
709 | if (ASIC_IS_DCE4(dp_info->rdev)) | 710 | if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) |
710 | atombios_dig_encoder_setup(dp_info->encoder, | 711 | atombios_dig_encoder_setup(dp_info->encoder, |
711 | ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0); | 712 | ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0); |
712 | else | 713 | else |
@@ -731,7 +732,7 @@ static int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info | |||
731 | DP_TRAINING_PATTERN_DISABLE); | 732 | DP_TRAINING_PATTERN_DISABLE); |
732 | 733 | ||
733 | /* disable the training pattern on the source */ | 734 | /* disable the training pattern on the source */ |
734 | if (ASIC_IS_DCE4(dp_info->rdev)) | 735 | if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) |
735 | atombios_dig_encoder_setup(dp_info->encoder, | 736 | atombios_dig_encoder_setup(dp_info->encoder, |
736 | ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0); | 737 | ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0); |
737 | else | 738 | else |
@@ -869,7 +870,8 @@ void radeon_dp_link_train(struct drm_encoder *encoder, | |||
869 | struct radeon_connector *radeon_connector; | 870 | struct radeon_connector *radeon_connector; |
870 | struct radeon_connector_atom_dig *dig_connector; | 871 | struct radeon_connector_atom_dig *dig_connector; |
871 | struct radeon_dp_link_train_info dp_info; | 872 | struct radeon_dp_link_train_info dp_info; |
872 | u8 tmp; | 873 | int index; |
874 | u8 tmp, frev, crev; | ||
873 | 875 | ||
874 | if (!radeon_encoder->enc_priv) | 876 | if (!radeon_encoder->enc_priv) |
875 | return; | 877 | return; |
@@ -884,6 +886,18 @@ void radeon_dp_link_train(struct drm_encoder *encoder, | |||
884 | (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP)) | 886 | (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP)) |
885 | return; | 887 | return; |
886 | 888 | ||
889 | /* DPEncoderService newer than 1.1 can't program properly the | ||
890 | * training pattern. When facing such version use the | ||
891 | * DIGXEncoderControl (X== 1 | 2) | ||
892 | */ | ||
893 | dp_info.use_dpencoder = true; | ||
894 | index = GetIndexIntoMasterTable(COMMAND, DPEncoderService); | ||
895 | if (atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) { | ||
896 | if (crev > 1) { | ||
897 | dp_info.use_dpencoder = false; | ||
898 | } | ||
899 | } | ||
900 | |||
887 | dp_info.enc_id = 0; | 901 | dp_info.enc_id = 0; |
888 | if (dig->dig_encoder) | 902 | if (dig->dig_encoder) |
889 | dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; | 903 | dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 15bd0477a3e8..14dce9f22172 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -1382,9 +1382,6 @@ int evergreen_cp_resume(struct radeon_device *rdev) | |||
1382 | 1382 | ||
1383 | /* set the wb address wether it's enabled or not */ | 1383 | /* set the wb address wether it's enabled or not */ |
1384 | WREG32(CP_RB_RPTR_ADDR, | 1384 | WREG32(CP_RB_RPTR_ADDR, |
1385 | #ifdef __BIG_ENDIAN | ||
1386 | RB_RPTR_SWAP(2) | | ||
1387 | #endif | ||
1388 | ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); | 1385 | ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); |
1389 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); | 1386 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); |
1390 | WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); | 1387 | WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); |
@@ -2047,6 +2044,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
2047 | rdev->config.evergreen.tile_config |= | 2044 | rdev->config.evergreen.tile_config |= |
2048 | ((gb_addr_config & 0x30000000) >> 28) << 12; | 2045 | ((gb_addr_config & 0x30000000) >> 28) << 12; |
2049 | 2046 | ||
2047 | rdev->config.evergreen.backend_map = gb_backend_map; | ||
2050 | WREG32(GB_BACKEND_MAP, gb_backend_map); | 2048 | WREG32(GB_BACKEND_MAP, gb_backend_map); |
2051 | WREG32(GB_ADDR_CONFIG, gb_addr_config); | 2049 | WREG32(GB_ADDR_CONFIG, gb_addr_config); |
2052 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); | 2050 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); |
@@ -2761,6 +2759,9 @@ int evergreen_irq_process(struct radeon_device *rdev) | |||
2761 | return IRQ_NONE; | 2759 | return IRQ_NONE; |
2762 | } | 2760 | } |
2763 | restart_ih: | 2761 | restart_ih: |
2762 | /* Order reading of wptr vs. reading of IH ring data */ | ||
2763 | rmb(); | ||
2764 | |||
2764 | /* display interrupts */ | 2765 | /* display interrupts */ |
2765 | evergreen_irq_ack(rdev); | 2766 | evergreen_irq_ack(rdev); |
2766 | 2767 | ||
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 189e86522b5b..a134790903d3 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -428,7 +428,7 @@ static inline int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u3 | |||
428 | last_reg = ARRAY_SIZE(evergreen_reg_safe_bm); | 428 | last_reg = ARRAY_SIZE(evergreen_reg_safe_bm); |
429 | 429 | ||
430 | i = (reg >> 7); | 430 | i = (reg >> 7); |
431 | if (i > last_reg) { | 431 | if (i >= last_reg) { |
432 | dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); | 432 | dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); |
433 | return -EINVAL; | 433 | return -EINVAL; |
434 | } | 434 | } |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 559dbd412906..44c4750f4518 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -833,6 +833,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
833 | rdev->config.cayman.tile_config |= | 833 | rdev->config.cayman.tile_config |= |
834 | ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; | 834 | ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; |
835 | 835 | ||
836 | rdev->config.cayman.backend_map = gb_backend_map; | ||
836 | WREG32(GB_BACKEND_MAP, gb_backend_map); | 837 | WREG32(GB_BACKEND_MAP, gb_backend_map); |
837 | WREG32(GB_ADDR_CONFIG, gb_addr_config); | 838 | WREG32(GB_ADDR_CONFIG, gb_addr_config); |
838 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); | 839 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index bc54b26cb32f..aa5571b73aa0 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -1662,6 +1662,7 @@ void r600_gpu_init(struct radeon_device *rdev) | |||
1662 | R6XX_MAX_BACKENDS_MASK) >> 16)), | 1662 | R6XX_MAX_BACKENDS_MASK) >> 16)), |
1663 | (cc_rb_backend_disable >> 16)); | 1663 | (cc_rb_backend_disable >> 16)); |
1664 | rdev->config.r600.tile_config = tiling_config; | 1664 | rdev->config.r600.tile_config = tiling_config; |
1665 | rdev->config.r600.backend_map = backend_map; | ||
1665 | tiling_config |= BACKEND_MAP(backend_map); | 1666 | tiling_config |= BACKEND_MAP(backend_map); |
1666 | WREG32(GB_TILING_CONFIG, tiling_config); | 1667 | WREG32(GB_TILING_CONFIG, tiling_config); |
1667 | WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff); | 1668 | WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff); |
@@ -2212,9 +2213,6 @@ int r600_cp_resume(struct radeon_device *rdev) | |||
2212 | 2213 | ||
2213 | /* set the wb address whether it's enabled or not */ | 2214 | /* set the wb address whether it's enabled or not */ |
2214 | WREG32(CP_RB_RPTR_ADDR, | 2215 | WREG32(CP_RB_RPTR_ADDR, |
2215 | #ifdef __BIG_ENDIAN | ||
2216 | RB_RPTR_SWAP(2) | | ||
2217 | #endif | ||
2218 | ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); | 2216 | ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); |
2219 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); | 2217 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); |
2220 | WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); | 2218 | WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); |
@@ -2994,10 +2992,6 @@ int r600_irq_init(struct radeon_device *rdev) | |||
2994 | /* RPTR_REARM only works if msi's are enabled */ | 2992 | /* RPTR_REARM only works if msi's are enabled */ |
2995 | if (rdev->msi_enabled) | 2993 | if (rdev->msi_enabled) |
2996 | ih_cntl |= RPTR_REARM; | 2994 | ih_cntl |= RPTR_REARM; |
2997 | |||
2998 | #ifdef __BIG_ENDIAN | ||
2999 | ih_cntl |= IH_MC_SWAP(IH_MC_SWAP_32BIT); | ||
3000 | #endif | ||
3001 | WREG32(IH_CNTL, ih_cntl); | 2995 | WREG32(IH_CNTL, ih_cntl); |
3002 | 2996 | ||
3003 | /* force the active interrupt state to all disabled */ | 2997 | /* force the active interrupt state to all disabled */ |
@@ -3308,6 +3302,10 @@ int r600_irq_process(struct radeon_device *rdev) | |||
3308 | if (!rdev->ih.enabled || rdev->shutdown) | 3302 | if (!rdev->ih.enabled || rdev->shutdown) |
3309 | return IRQ_NONE; | 3303 | return IRQ_NONE; |
3310 | 3304 | ||
3305 | /* No MSIs, need a dummy read to flush PCI DMAs */ | ||
3306 | if (!rdev->msi_enabled) | ||
3307 | RREG32(IH_RB_WPTR); | ||
3308 | |||
3311 | wptr = r600_get_ih_wptr(rdev); | 3309 | wptr = r600_get_ih_wptr(rdev); |
3312 | rptr = rdev->ih.rptr; | 3310 | rptr = rdev->ih.rptr; |
3313 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | 3311 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); |
@@ -3320,6 +3318,9 @@ int r600_irq_process(struct radeon_device *rdev) | |||
3320 | } | 3318 | } |
3321 | 3319 | ||
3322 | restart_ih: | 3320 | restart_ih: |
3321 | /* Order reading of wptr vs. reading of IH ring data */ | ||
3322 | rmb(); | ||
3323 | |||
3323 | /* display interrupts */ | 3324 | /* display interrupts */ |
3324 | r600_irq_ack(rdev); | 3325 | r600_irq_ack(rdev); |
3325 | 3326 | ||
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c index c3ab959bdc7c..45fd592f9606 100644 --- a/drivers/gpu/drm/radeon/r600_cp.c +++ b/drivers/gpu/drm/radeon/r600_cp.c | |||
@@ -1802,8 +1802,8 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, | |||
1802 | /* Set ring buffer size */ | 1802 | /* Set ring buffer size */ |
1803 | #ifdef __BIG_ENDIAN | 1803 | #ifdef __BIG_ENDIAN |
1804 | RADEON_WRITE(R600_CP_RB_CNTL, | 1804 | RADEON_WRITE(R600_CP_RB_CNTL, |
1805 | RADEON_BUF_SWAP_32BIT | | 1805 | R600_BUF_SWAP_32BIT | |
1806 | RADEON_RB_NO_UPDATE | | 1806 | R600_RB_NO_UPDATE | |
1807 | (dev_priv->ring.rptr_update_l2qw << 8) | | 1807 | (dev_priv->ring.rptr_update_l2qw << 8) | |
1808 | dev_priv->ring.size_l2qw); | 1808 | dev_priv->ring.size_l2qw); |
1809 | #else | 1809 | #else |
@@ -1820,15 +1820,15 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, | |||
1820 | 1820 | ||
1821 | #ifdef __BIG_ENDIAN | 1821 | #ifdef __BIG_ENDIAN |
1822 | RADEON_WRITE(R600_CP_RB_CNTL, | 1822 | RADEON_WRITE(R600_CP_RB_CNTL, |
1823 | RADEON_BUF_SWAP_32BIT | | 1823 | R600_BUF_SWAP_32BIT | |
1824 | RADEON_RB_NO_UPDATE | | 1824 | R600_RB_NO_UPDATE | |
1825 | RADEON_RB_RPTR_WR_ENA | | 1825 | R600_RB_RPTR_WR_ENA | |
1826 | (dev_priv->ring.rptr_update_l2qw << 8) | | 1826 | (dev_priv->ring.rptr_update_l2qw << 8) | |
1827 | dev_priv->ring.size_l2qw); | 1827 | dev_priv->ring.size_l2qw); |
1828 | #else | 1828 | #else |
1829 | RADEON_WRITE(R600_CP_RB_CNTL, | 1829 | RADEON_WRITE(R600_CP_RB_CNTL, |
1830 | RADEON_RB_NO_UPDATE | | 1830 | R600_RB_NO_UPDATE | |
1831 | RADEON_RB_RPTR_WR_ENA | | 1831 | R600_RB_RPTR_WR_ENA | |
1832 | (dev_priv->ring.rptr_update_l2qw << 8) | | 1832 | (dev_priv->ring.rptr_update_l2qw << 8) | |
1833 | dev_priv->ring.size_l2qw); | 1833 | dev_priv->ring.size_l2qw); |
1834 | #endif | 1834 | #endif |
@@ -1851,13 +1851,8 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, | |||
1851 | - ((unsigned long) dev->sg->virtual) | 1851 | - ((unsigned long) dev->sg->virtual) |
1852 | + dev_priv->gart_vm_start; | 1852 | + dev_priv->gart_vm_start; |
1853 | } | 1853 | } |
1854 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR, | 1854 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR, (rptr_addr & 0xfffffffc)); |
1855 | #ifdef __BIG_ENDIAN | 1855 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, upper_32_bits(rptr_addr)); |
1856 | (2 << 0) | | ||
1857 | #endif | ||
1858 | (rptr_addr & 0xfffffffc)); | ||
1859 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, | ||
1860 | upper_32_bits(rptr_addr)); | ||
1861 | 1856 | ||
1862 | #ifdef __BIG_ENDIAN | 1857 | #ifdef __BIG_ENDIAN |
1863 | RADEON_WRITE(R600_CP_RB_CNTL, | 1858 | RADEON_WRITE(R600_CP_RB_CNTL, |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index db8ef1905d5f..cf83aa05a684 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -915,12 +915,11 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx | |||
915 | { | 915 | { |
916 | struct r600_cs_track *track = (struct r600_cs_track *)p->track; | 916 | struct r600_cs_track *track = (struct r600_cs_track *)p->track; |
917 | struct radeon_cs_reloc *reloc; | 917 | struct radeon_cs_reloc *reloc; |
918 | u32 last_reg = ARRAY_SIZE(r600_reg_safe_bm); | ||
919 | u32 m, i, tmp, *ib; | 918 | u32 m, i, tmp, *ib; |
920 | int r; | 919 | int r; |
921 | 920 | ||
922 | i = (reg >> 7); | 921 | i = (reg >> 7); |
923 | if (i > last_reg) { | 922 | if (i >= ARRAY_SIZE(r600_reg_safe_bm)) { |
924 | dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); | 923 | dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); |
925 | return -EINVAL; | 924 | return -EINVAL; |
926 | } | 925 | } |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index ef0e0e016914..32807baf55e2 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -60,7 +60,7 @@ | |||
60 | * are considered as fatal) | 60 | * are considered as fatal) |
61 | */ | 61 | */ |
62 | 62 | ||
63 | #include <asm/atomic.h> | 63 | #include <linux/atomic.h> |
64 | #include <linux/wait.h> | 64 | #include <linux/wait.h> |
65 | #include <linux/list.h> | 65 | #include <linux/list.h> |
66 | #include <linux/kref.h> | 66 | #include <linux/kref.h> |
@@ -1003,6 +1003,7 @@ struct r600_asic { | |||
1003 | unsigned tiling_npipes; | 1003 | unsigned tiling_npipes; |
1004 | unsigned tiling_group_size; | 1004 | unsigned tiling_group_size; |
1005 | unsigned tile_config; | 1005 | unsigned tile_config; |
1006 | unsigned backend_map; | ||
1006 | struct r100_gpu_lockup lockup; | 1007 | struct r100_gpu_lockup lockup; |
1007 | }; | 1008 | }; |
1008 | 1009 | ||
@@ -1028,6 +1029,7 @@ struct rv770_asic { | |||
1028 | unsigned tiling_npipes; | 1029 | unsigned tiling_npipes; |
1029 | unsigned tiling_group_size; | 1030 | unsigned tiling_group_size; |
1030 | unsigned tile_config; | 1031 | unsigned tile_config; |
1032 | unsigned backend_map; | ||
1031 | struct r100_gpu_lockup lockup; | 1033 | struct r100_gpu_lockup lockup; |
1032 | }; | 1034 | }; |
1033 | 1035 | ||
@@ -1054,6 +1056,7 @@ struct evergreen_asic { | |||
1054 | unsigned tiling_npipes; | 1056 | unsigned tiling_npipes; |
1055 | unsigned tiling_group_size; | 1057 | unsigned tiling_group_size; |
1056 | unsigned tile_config; | 1058 | unsigned tile_config; |
1059 | unsigned backend_map; | ||
1057 | struct r100_gpu_lockup lockup; | 1060 | struct r100_gpu_lockup lockup; |
1058 | }; | 1061 | }; |
1059 | 1062 | ||
@@ -1174,7 +1177,7 @@ struct radeon_device { | |||
1174 | /* Register mmio */ | 1177 | /* Register mmio */ |
1175 | resource_size_t rmmio_base; | 1178 | resource_size_t rmmio_base; |
1176 | resource_size_t rmmio_size; | 1179 | resource_size_t rmmio_size; |
1177 | void *rmmio; | 1180 | void __iomem *rmmio; |
1178 | radeon_rreg_t mc_rreg; | 1181 | radeon_rreg_t mc_rreg; |
1179 | radeon_wreg_t mc_wreg; | 1182 | radeon_wreg_t mc_wreg; |
1180 | radeon_rreg_t pll_rreg; | 1183 | radeon_rreg_t pll_rreg; |
@@ -1251,20 +1254,20 @@ int radeon_gpu_wait_for_idle(struct radeon_device *rdev); | |||
1251 | static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) | 1254 | static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) |
1252 | { | 1255 | { |
1253 | if (reg < rdev->rmmio_size) | 1256 | if (reg < rdev->rmmio_size) |
1254 | return readl(((void __iomem *)rdev->rmmio) + reg); | 1257 | return readl((rdev->rmmio) + reg); |
1255 | else { | 1258 | else { |
1256 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); | 1259 | writel(reg, (rdev->rmmio) + RADEON_MM_INDEX); |
1257 | return readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); | 1260 | return readl((rdev->rmmio) + RADEON_MM_DATA); |
1258 | } | 1261 | } |
1259 | } | 1262 | } |
1260 | 1263 | ||
1261 | static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | 1264 | static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) |
1262 | { | 1265 | { |
1263 | if (reg < rdev->rmmio_size) | 1266 | if (reg < rdev->rmmio_size) |
1264 | writel(v, ((void __iomem *)rdev->rmmio) + reg); | 1267 | writel(v, (rdev->rmmio) + reg); |
1265 | else { | 1268 | else { |
1266 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); | 1269 | writel(reg, (rdev->rmmio) + RADEON_MM_INDEX); |
1267 | writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); | 1270 | writel(v, (rdev->rmmio) + RADEON_MM_DATA); |
1268 | } | 1271 | } |
1269 | } | 1272 | } |
1270 | 1273 | ||
@@ -1296,10 +1299,10 @@ static inline void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v) | |||
1296 | /* | 1299 | /* |
1297 | * Registers read & write functions. | 1300 | * Registers read & write functions. |
1298 | */ | 1301 | */ |
1299 | #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) | 1302 | #define RREG8(reg) readb((rdev->rmmio) + (reg)) |
1300 | #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) | 1303 | #define WREG8(reg, v) writeb(v, (rdev->rmmio) + (reg)) |
1301 | #define RREG16(reg) readw(((void __iomem *)rdev->rmmio) + (reg)) | 1304 | #define RREG16(reg) readw((rdev->rmmio) + (reg)) |
1302 | #define WREG16(reg, v) writew(v, ((void __iomem *)rdev->rmmio) + (reg)) | 1305 | #define WREG16(reg, v) writew(v, (rdev->rmmio) + (reg)) |
1303 | #define RREG32(reg) r100_mm_rreg(rdev, (reg)) | 1306 | #define RREG32(reg) r100_mm_rreg(rdev, (reg)) |
1304 | #define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg))) | 1307 | #define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg))) |
1305 | #define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) | 1308 | #define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) |
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index 2d48e7a1474b..dcd0863e31ae 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c | |||
@@ -96,7 +96,7 @@ uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) | |||
96 | * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device | 96 | * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device |
97 | * tree. Hopefully, ATI OF driver is kind enough to fill these | 97 | * tree. Hopefully, ATI OF driver is kind enough to fill these |
98 | */ | 98 | */ |
99 | static bool __devinit radeon_read_clocks_OF(struct drm_device *dev) | 99 | static bool radeon_read_clocks_OF(struct drm_device *dev) |
100 | { | 100 | { |
101 | struct radeon_device *rdev = dev->dev_private; | 101 | struct radeon_device *rdev = dev->dev_private; |
102 | struct device_node *dp = rdev->pdev->dev.of_node; | 102 | struct device_node *dp = rdev->pdev->dev.of_node; |
@@ -166,7 +166,7 @@ static bool __devinit radeon_read_clocks_OF(struct drm_device *dev) | |||
166 | return true; | 166 | return true; |
167 | } | 167 | } |
168 | #else | 168 | #else |
169 | static bool __devinit radeon_read_clocks_OF(struct drm_device *dev) | 169 | static bool radeon_read_clocks_OF(struct drm_device *dev) |
170 | { | 170 | { |
171 | return false; | 171 | return false; |
172 | } | 172 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index e4594676a07c..e0138b674aca 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -779,7 +779,8 @@ void radeon_combios_i2c_init(struct radeon_device *rdev) | |||
779 | } | 779 | } |
780 | } | 780 | } |
781 | } | 781 | } |
782 | } else if (rdev->family >= CHIP_R200) { | 782 | } else if ((rdev->family == CHIP_R200) || |
783 | (rdev->family >= CHIP_R300)) { | ||
783 | /* 0x68 */ | 784 | /* 0x68 */ |
784 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); | 785 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); |
785 | rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); | 786 | rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); |
@@ -2556,6 +2557,7 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) | |||
2556 | u16 offset, misc, misc2 = 0; | 2557 | u16 offset, misc, misc2 = 0; |
2557 | u8 rev, blocks, tmp; | 2558 | u8 rev, blocks, tmp; |
2558 | int state_index = 0; | 2559 | int state_index = 0; |
2560 | struct radeon_i2c_bus_rec i2c_bus; | ||
2559 | 2561 | ||
2560 | rdev->pm.default_power_state_index = -1; | 2562 | rdev->pm.default_power_state_index = -1; |
2561 | 2563 | ||
@@ -2574,7 +2576,6 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) | |||
2574 | offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE); | 2576 | offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE); |
2575 | if (offset) { | 2577 | if (offset) { |
2576 | u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0; | 2578 | u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0; |
2577 | struct radeon_i2c_bus_rec i2c_bus; | ||
2578 | 2579 | ||
2579 | rev = RBIOS8(offset); | 2580 | rev = RBIOS8(offset); |
2580 | 2581 | ||
@@ -2616,6 +2617,25 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) | |||
2616 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); | 2617 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); |
2617 | } | 2618 | } |
2618 | } | 2619 | } |
2620 | } else { | ||
2621 | /* boards with a thermal chip, but no overdrive table */ | ||
2622 | |||
2623 | /* Asus 9600xt has an f75375 on the monid bus */ | ||
2624 | if ((dev->pdev->device == 0x4152) && | ||
2625 | (dev->pdev->subsystem_vendor == 0x1043) && | ||
2626 | (dev->pdev->subsystem_device == 0xc002)) { | ||
2627 | i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); | ||
2628 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); | ||
2629 | if (rdev->pm.i2c_bus) { | ||
2630 | struct i2c_board_info info = { }; | ||
2631 | const char *name = "f75375"; | ||
2632 | info.addr = 0x28; | ||
2633 | strlcpy(info.type, name, sizeof(info.type)); | ||
2634 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); | ||
2635 | DRM_INFO("Possible %s thermal controller at 0x%02x\n", | ||
2636 | name, info.addr); | ||
2637 | } | ||
2638 | } | ||
2619 | } | 2639 | } |
2620 | 2640 | ||
2621 | if (rdev->flags & RADEON_IS_MOBILITY) { | 2641 | if (rdev->flags & RADEON_IS_MOBILITY) { |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index cbb4584a4a23..e71d2ed7fa11 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -50,10 +50,11 @@ | |||
50 | * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs | 50 | * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs |
51 | * 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK, clock crystal query | 51 | * 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK, clock crystal query |
52 | * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query | 52 | * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query |
53 | * 2.10.0 - fusion 2D tiling, initial compute support for the CS checker | 53 | * 2.10.0 - fusion 2D tiling |
54 | * 2.11.0 - backend map, initial compute support for the CS checker | ||
54 | */ | 55 | */ |
55 | #define KMS_DRIVER_MAJOR 2 | 56 | #define KMS_DRIVER_MAJOR 2 |
56 | #define KMS_DRIVER_MINOR 10 | 57 | #define KMS_DRIVER_MINOR 11 |
57 | #define KMS_DRIVER_PATCHLEVEL 0 | 58 | #define KMS_DRIVER_PATCHLEVEL 0 |
58 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 59 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
59 | int radeon_driver_unload_kms(struct drm_device *dev); | 60 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 021d2b6b556f..7fd4e3e5ad5f 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -29,7 +29,7 @@ | |||
29 | * Dave Airlie | 29 | * Dave Airlie |
30 | */ | 30 | */ |
31 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
32 | #include <asm/atomic.h> | 32 | #include <linux/atomic.h> |
33 | #include <linux/wait.h> | 33 | #include <linux/wait.h> |
34 | #include <linux/list.h> | 34 | #include <linux/list.h> |
35 | #include <linux/kref.h> | 35 | #include <linux/kref.h> |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 6f80a216bb39..be2c1224e68a 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -237,6 +237,19 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
237 | case RADEON_INFO_FUSION_GART_WORKING: | 237 | case RADEON_INFO_FUSION_GART_WORKING: |
238 | value = 1; | 238 | value = 1; |
239 | break; | 239 | break; |
240 | case RADEON_INFO_BACKEND_MAP: | ||
241 | if (rdev->family >= CHIP_CAYMAN) | ||
242 | value = rdev->config.cayman.backend_map; | ||
243 | else if (rdev->family >= CHIP_CEDAR) | ||
244 | value = rdev->config.evergreen.backend_map; | ||
245 | else if (rdev->family >= CHIP_RV770) | ||
246 | value = rdev->config.rv770.backend_map; | ||
247 | else if (rdev->family >= CHIP_R600) | ||
248 | value = rdev->config.r600.backend_map; | ||
249 | else { | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | break; | ||
240 | default: | 253 | default: |
241 | DRM_DEBUG_KMS("Invalid request %d\n", info->request); | 254 | DRM_DEBUG_KMS("Invalid request %d\n", info->request); |
242 | return -EINVAL; | 255 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/radeon_mem.c b/drivers/gpu/drm/radeon/radeon_mem.c index ed95155c4b1d..988548efea92 100644 --- a/drivers/gpu/drm/radeon/radeon_mem.c +++ b/drivers/gpu/drm/radeon/radeon_mem.c | |||
@@ -139,7 +139,7 @@ static int init_heap(struct mem_block **heap, int start, int size) | |||
139 | if (!blocks) | 139 | if (!blocks) |
140 | return -ENOMEM; | 140 | return -ENOMEM; |
141 | 141 | ||
142 | *heap = kmalloc(sizeof(**heap), GFP_KERNEL); | 142 | *heap = kzalloc(sizeof(**heap), GFP_KERNEL); |
143 | if (!*heap) { | 143 | if (!*heap) { |
144 | kfree(blocks); | 144 | kfree(blocks); |
145 | return -ENOMEM; | 145 | return -ENOMEM; |
@@ -150,7 +150,6 @@ static int init_heap(struct mem_block **heap, int start, int size) | |||
150 | blocks->file_priv = NULL; | 150 | blocks->file_priv = NULL; |
151 | blocks->next = blocks->prev = *heap; | 151 | blocks->next = blocks->prev = *heap; |
152 | 152 | ||
153 | memset(*heap, 0, sizeof(**heap)); | ||
154 | (*heap)->file_priv = (struct drm_file *) - 1; | 153 | (*heap)->file_priv = (struct drm_file *) - 1; |
155 | (*heap)->next = (*heap)->prev = blocks; | 154 | (*heap)->next = (*heap)->prev = blocks; |
156 | return 0; | 155 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index aaa19dc418a0..6fabe89fa6a1 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -594,6 +594,9 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
594 | if (rdev->pm.default_vddc) | 594 | if (rdev->pm.default_vddc) |
595 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, | 595 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, |
596 | SET_VOLTAGE_TYPE_ASIC_VDDC); | 596 | SET_VOLTAGE_TYPE_ASIC_VDDC); |
597 | if (rdev->pm.default_vddci) | ||
598 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddci, | ||
599 | SET_VOLTAGE_TYPE_ASIC_VDDCI); | ||
597 | if (rdev->pm.default_sclk) | 600 | if (rdev->pm.default_sclk) |
598 | radeon_set_engine_clock(rdev, rdev->pm.default_sclk); | 601 | radeon_set_engine_clock(rdev, rdev->pm.default_sclk); |
599 | if (rdev->pm.default_mclk) | 602 | if (rdev->pm.default_mclk) |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index bc44a3d35ec6..b4ce86455707 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
@@ -3295,7 +3295,7 @@ | |||
3295 | # define RADEON_RB_BUFSZ_MASK (0x3f << 0) | 3295 | # define RADEON_RB_BUFSZ_MASK (0x3f << 0) |
3296 | # define RADEON_RB_BLKSZ_SHIFT 8 | 3296 | # define RADEON_RB_BLKSZ_SHIFT 8 |
3297 | # define RADEON_RB_BLKSZ_MASK (0x3f << 8) | 3297 | # define RADEON_RB_BLKSZ_MASK (0x3f << 8) |
3298 | # define RADEON_BUF_SWAP_32BIT (1 << 17) | 3298 | # define RADEON_BUF_SWAP_32BIT (2 << 16) |
3299 | # define RADEON_MAX_FETCH_SHIFT 18 | 3299 | # define RADEON_MAX_FETCH_SHIFT 18 |
3300 | # define RADEON_MAX_FETCH_MASK (0x3 << 18) | 3300 | # define RADEON_MAX_FETCH_MASK (0x3 << 18) |
3301 | # define RADEON_RB_NO_UPDATE (1 << 27) | 3301 | # define RADEON_RB_NO_UPDATE (1 << 27) |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 1f5850e473cc..4b5d0e6974a8 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -530,7 +530,7 @@ int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | |||
530 | addr = addr & 0xFFFFFFFFFFFFF000ULL; | 530 | addr = addr & 0xFFFFFFFFFFFFF000ULL; |
531 | addr |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED; | 531 | addr |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED; |
532 | addr |= R600_PTE_READABLE | R600_PTE_WRITEABLE; | 532 | addr |= R600_PTE_READABLE | R600_PTE_WRITEABLE; |
533 | writeq(addr, ((void __iomem *)ptr) + (i * 8)); | 533 | writeq(addr, ptr + (i * 8)); |
534 | return 0; | 534 | return 0; |
535 | } | 535 | } |
536 | 536 | ||
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 4de51891aa6d..4720d000d440 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -778,6 +778,7 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
778 | (cc_rb_backend_disable >> 16)); | 778 | (cc_rb_backend_disable >> 16)); |
779 | 779 | ||
780 | rdev->config.rv770.tile_config = gb_tiling_config; | 780 | rdev->config.rv770.tile_config = gb_tiling_config; |
781 | rdev->config.rv770.backend_map = backend_map; | ||
781 | gb_tiling_config |= BACKEND_MAP(backend_map); | 782 | gb_tiling_config |= BACKEND_MAP(backend_map); |
782 | 783 | ||
783 | WREG32(GB_TILING_CONFIG, gb_tiling_config); | 784 | WREG32(GB_TILING_CONFIG, gb_tiling_config); |
diff --git a/drivers/gpu/drm/sis/sis_drv.h b/drivers/gpu/drm/sis/sis_drv.h index ef940bad63f7..194303c177ad 100644 --- a/drivers/gpu/drm/sis/sis_drv.h +++ b/drivers/gpu/drm/sis/sis_drv.h | |||
@@ -48,8 +48,8 @@ enum sis_family { | |||
48 | 48 | ||
49 | 49 | ||
50 | #define SIS_BASE (dev_priv->mmio) | 50 | #define SIS_BASE (dev_priv->mmio) |
51 | #define SIS_READ(reg) DRM_READ32(SIS_BASE, reg); | 51 | #define SIS_READ(reg) DRM_READ32(SIS_BASE, reg) |
52 | #define SIS_WRITE(reg, val) DRM_WRITE32(SIS_BASE, reg, val); | 52 | #define SIS_WRITE(reg, val) DRM_WRITE32(SIS_BASE, reg, val) |
53 | 53 | ||
54 | typedef struct drm_sis_private { | 54 | typedef struct drm_sis_private { |
55 | drm_local_map_t *mmio; | 55 | drm_local_map_t *mmio; |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 2e618b5ac465..56619f64b6bf 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/mm.h> | 37 | #include <linux/mm.h> |
38 | #include <linux/file.h> | 38 | #include <linux/file.h> |
39 | #include <linux/module.h> | 39 | #include <linux/module.h> |
40 | #include <asm/atomic.h> | 40 | #include <linux/atomic.h> |
41 | 41 | ||
42 | #define TTM_ASSERT_LOCKED(param) | 42 | #define TTM_ASSERT_LOCKED(param) |
43 | #define TTM_DEBUG(fmt, arg...) | 43 | #define TTM_DEBUG(fmt, arg...) |
diff --git a/drivers/gpu/drm/ttm/ttm_lock.c b/drivers/gpu/drm/ttm/ttm_lock.c index de41e55a944a..075daf44bce4 100644 --- a/drivers/gpu/drm/ttm/ttm_lock.c +++ b/drivers/gpu/drm/ttm/ttm_lock.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #include "ttm/ttm_lock.h" | 31 | #include "ttm/ttm_lock.h" |
32 | #include "ttm/ttm_module.h" | 32 | #include "ttm/ttm_module.h" |
33 | #include <asm/atomic.h> | 33 | #include <linux/atomic.h> |
34 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
35 | #include <linux/wait.h> | 35 | #include <linux/wait.h> |
36 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c index ebddd443d91a..93577f2e2954 100644 --- a/drivers/gpu/drm/ttm/ttm_object.c +++ b/drivers/gpu/drm/ttm/ttm_object.c | |||
@@ -55,7 +55,7 @@ | |||
55 | #include <linux/spinlock.h> | 55 | #include <linux/spinlock.h> |
56 | #include <linux/slab.h> | 56 | #include <linux/slab.h> |
57 | #include <linux/module.h> | 57 | #include <linux/module.h> |
58 | #include <asm/atomic.h> | 58 | #include <linux/atomic.h> |
59 | 59 | ||
60 | struct ttm_object_file { | 60 | struct ttm_object_file { |
61 | struct ttm_object_device *tdev; | 61 | struct ttm_object_device *tdev; |
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 170e751c283e..727e93daac3b 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
41 | #include <linux/dma-mapping.h> | 41 | #include <linux/dma-mapping.h> |
42 | 42 | ||
43 | #include <asm/atomic.h> | 43 | #include <linux/atomic.h> |
44 | 44 | ||
45 | #include "ttm/ttm_bo_driver.h" | 45 | #include "ttm/ttm_bo_driver.h" |
46 | #include "ttm/ttm_page_alloc.h" | 46 | #include "ttm/ttm_page_alloc.h" |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c index f1a52f9e7298..07ce02da78a4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | |||
@@ -585,11 +585,10 @@ int vmw_overlay_init(struct vmw_private *dev_priv) | |||
585 | return -ENOSYS; | 585 | return -ENOSYS; |
586 | } | 586 | } |
587 | 587 | ||
588 | overlay = kmalloc(sizeof(*overlay), GFP_KERNEL); | 588 | overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); |
589 | if (!overlay) | 589 | if (!overlay) |
590 | return -ENOMEM; | 590 | return -ENOMEM; |
591 | 591 | ||
592 | memset(overlay, 0, sizeof(*overlay)); | ||
593 | mutex_init(&overlay->mutex); | 592 | mutex_init(&overlay->mutex); |
594 | for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) { | 593 | for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) { |
595 | overlay->stream[i].buf = NULL; | 594 | overlay->stream[i].buf = NULL; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 5408b1b7996f..bfe1bcce7f8a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -612,11 +612,9 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, | |||
612 | srf->sizes[0].height == 64 && | 612 | srf->sizes[0].height == 64 && |
613 | srf->format == SVGA3D_A8R8G8B8) { | 613 | srf->format == SVGA3D_A8R8G8B8) { |
614 | 614 | ||
615 | srf->snooper.image = kmalloc(64 * 64 * 4, GFP_KERNEL); | 615 | /* allocate image area and clear it */ |
616 | /* clear the image */ | 616 | srf->snooper.image = kzalloc(64 * 64 * 4, GFP_KERNEL); |
617 | if (srf->snooper.image) { | 617 | if (!srf->snooper.image) { |
618 | memset(srf->snooper.image, 0x00, 64 * 64 * 4); | ||
619 | } else { | ||
620 | DRM_ERROR("Failed to allocate cursor_image\n"); | 618 | DRM_ERROR("Failed to allocate cursor_image\n"); |
621 | ret = -ENOMEM; | 619 | ret = -ENOMEM; |
622 | goto out_err1; | 620 | goto out_err1; |
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index 8a1021f2e319..c72f1c0b5e63 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c | |||
@@ -1171,10 +1171,9 @@ static int vga_arb_open(struct inode *inode, struct file *file) | |||
1171 | 1171 | ||
1172 | pr_debug("%s\n", __func__); | 1172 | pr_debug("%s\n", __func__); |
1173 | 1173 | ||
1174 | priv = kmalloc(sizeof(struct vga_arb_private), GFP_KERNEL); | 1174 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
1175 | if (priv == NULL) | 1175 | if (priv == NULL) |
1176 | return -ENOMEM; | 1176 | return -ENOMEM; |
1177 | memset(priv, 0, sizeof(*priv)); | ||
1178 | spin_lock_init(&priv->lock); | 1177 | spin_lock_init(&priv->lock); |
1179 | file->private_data = priv; | 1178 | file->private_data = priv; |
1180 | 1179 | ||