diff options
Diffstat (limited to 'drivers/gpu')
188 files changed, 6664 insertions, 4906 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 88910e5a2c77..4cab0c6397e3 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -6,7 +6,7 @@ | |||
6 | # | 6 | # |
7 | menuconfig DRM | 7 | menuconfig DRM |
8 | tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" | 8 | tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" |
9 | depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && MMU | 9 | depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU |
10 | select I2C | 10 | select I2C |
11 | select I2C_ALGOBIT | 11 | select I2C_ALGOBIT |
12 | select SLOW_WORK | 12 | select SLOW_WORK |
@@ -17,7 +17,7 @@ menuconfig DRM | |||
17 | These modules provide support for synchronization, security, and | 17 | These modules provide support for synchronization, security, and |
18 | DMA transfers. Please see <http://dri.sourceforge.net/> for more | 18 | DMA transfers. Please see <http://dri.sourceforge.net/> for more |
19 | details. You should also select and configure AGP | 19 | details. You should also select and configure AGP |
20 | (/dev/agpgart) support. | 20 | (/dev/agpgart) support if it is available for your platform. |
21 | 21 | ||
22 | config DRM_KMS_HELPER | 22 | config DRM_KMS_HELPER |
23 | tristate | 23 | tristate |
@@ -61,6 +61,7 @@ config DRM_RADEON | |||
61 | select DRM_KMS_HELPER | 61 | select DRM_KMS_HELPER |
62 | select DRM_TTM | 62 | select DRM_TTM |
63 | select POWER_SUPPLY | 63 | select POWER_SUPPLY |
64 | select HWMON | ||
64 | help | 65 | help |
65 | Choose this option if you have an ATI Radeon graphics card. There | 66 | Choose this option if you have an ATI Radeon graphics card. There |
66 | are both PCI and AGP versions. You don't need to choose this to | 67 | are both PCI and AGP versions. You don't need to choose this to |
@@ -130,7 +131,7 @@ endchoice | |||
130 | 131 | ||
131 | config DRM_MGA | 132 | config DRM_MGA |
132 | tristate "Matrox g200/g400" | 133 | tristate "Matrox g200/g400" |
133 | depends on DRM | 134 | depends on DRM && PCI |
134 | select FW_LOADER | 135 | select FW_LOADER |
135 | help | 136 | help |
136 | Choose this option if you have a Matrox G200, G400 or G450 graphics | 137 | Choose this option if you have a Matrox G200, G400 or G450 graphics |
@@ -148,14 +149,14 @@ config DRM_SIS | |||
148 | 149 | ||
149 | config DRM_VIA | 150 | config DRM_VIA |
150 | tristate "Via unichrome video cards" | 151 | tristate "Via unichrome video cards" |
151 | depends on DRM | 152 | depends on DRM && PCI |
152 | help | 153 | help |
153 | Choose this option if you have a Via unichrome or compatible video | 154 | Choose this option if you have a Via unichrome or compatible video |
154 | chipset. If M is selected the module will be called via. | 155 | chipset. If M is selected the module will be called via. |
155 | 156 | ||
156 | config DRM_SAVAGE | 157 | config DRM_SAVAGE |
157 | tristate "Savage video cards" | 158 | tristate "Savage video cards" |
158 | depends on DRM | 159 | depends on DRM && PCI |
159 | help | 160 | help |
160 | Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister | 161 | Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister |
161 | chipset. If M is selected the module will be called savage. | 162 | chipset. If M is selected the module will be called savage. |
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index abe3f446ca48..f3a23a329f4e 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile | |||
@@ -9,9 +9,10 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ | |||
9 | drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ | 9 | drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ |
10 | drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ | 10 | drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ |
11 | drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ | 11 | drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ |
12 | drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ | 12 | drm_platform.o drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ |
13 | drm_crtc.o drm_modes.o drm_edid.o \ | 13 | drm_crtc.o drm_modes.o drm_edid.o \ |
14 | drm_info.o drm_debugfs.o drm_encoder_slave.o | 14 | drm_info.o drm_debugfs.o drm_encoder_slave.o \ |
15 | drm_trace_points.o drm_global.o | ||
15 | 16 | ||
16 | drm-$(CONFIG_COMPAT) += drm_ioc32.o | 17 | drm-$(CONFIG_COMPAT) += drm_ioc32.o |
17 | 18 | ||
@@ -19,6 +20,8 @@ drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_i2c_helper.o | |||
19 | 20 | ||
20 | obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o | 21 | obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o |
21 | 22 | ||
23 | CFLAGS_drm_trace_points.o := -I$(src) | ||
24 | |||
22 | obj-$(CONFIG_DRM) += drm.o | 25 | obj-$(CONFIG_DRM) += drm.o |
23 | obj-$(CONFIG_DRM_TTM) += ttm/ | 26 | obj-$(CONFIG_DRM_TTM) += ttm/ |
24 | obj-$(CONFIG_DRM_TDFX) += tdfx/ | 27 | obj-$(CONFIG_DRM_TDFX) += tdfx/ |
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 2092e7bb788f..a5c9ce93bbcb 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c | |||
@@ -39,19 +39,6 @@ | |||
39 | #include <asm/shmparam.h> | 39 | #include <asm/shmparam.h> |
40 | #include "drmP.h" | 40 | #include "drmP.h" |
41 | 41 | ||
42 | resource_size_t drm_get_resource_start(struct drm_device *dev, unsigned int resource) | ||
43 | { | ||
44 | return pci_resource_start(dev->pdev, resource); | ||
45 | } | ||
46 | EXPORT_SYMBOL(drm_get_resource_start); | ||
47 | |||
48 | resource_size_t drm_get_resource_len(struct drm_device *dev, unsigned int resource) | ||
49 | { | ||
50 | return pci_resource_len(dev->pdev, resource); | ||
51 | } | ||
52 | |||
53 | EXPORT_SYMBOL(drm_get_resource_len); | ||
54 | |||
55 | static struct drm_map_list *drm_find_matching_map(struct drm_device *dev, | 42 | static struct drm_map_list *drm_find_matching_map(struct drm_device *dev, |
56 | struct drm_local_map *map) | 43 | struct drm_local_map *map) |
57 | { | 44 | { |
@@ -189,7 +176,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
189 | switch (map->type) { | 176 | switch (map->type) { |
190 | case _DRM_REGISTERS: | 177 | case _DRM_REGISTERS: |
191 | case _DRM_FRAME_BUFFER: | 178 | case _DRM_FRAME_BUFFER: |
192 | #if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) | 179 | #if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__arm__) |
193 | if (map->offset + (map->size-1) < map->offset || | 180 | if (map->offset + (map->size-1) < map->offset || |
194 | map->offset < virt_to_phys(high_memory)) { | 181 | map->offset < virt_to_phys(high_memory)) { |
195 | kfree(map); | 182 | kfree(map); |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 57cea01c4ffb..4c68f76993d8 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -80,6 +80,7 @@ static struct drm_prop_enum_list drm_dithering_mode_enum_list[] = | |||
80 | { | 80 | { |
81 | { DRM_MODE_DITHERING_OFF, "Off" }, | 81 | { DRM_MODE_DITHERING_OFF, "Off" }, |
82 | { DRM_MODE_DITHERING_ON, "On" }, | 82 | { DRM_MODE_DITHERING_ON, "On" }, |
83 | { DRM_MODE_DITHERING_AUTO, "Automatic" }, | ||
83 | }; | 84 | }; |
84 | 85 | ||
85 | /* | 86 | /* |
@@ -1126,7 +1127,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, | |||
1126 | if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { | 1127 | if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { |
1127 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, | 1128 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, |
1128 | head) { | 1129 | head) { |
1129 | DRM_DEBUG_KMS("CRTC ID is %d\n", crtc->base.id); | 1130 | DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); |
1130 | if (put_user(crtc->base.id, crtc_id + copied)) { | 1131 | if (put_user(crtc->base.id, crtc_id + copied)) { |
1131 | ret = -EFAULT; | 1132 | ret = -EFAULT; |
1132 | goto out; | 1133 | goto out; |
@@ -1154,8 +1155,8 @@ int drm_mode_getresources(struct drm_device *dev, void *data, | |||
1154 | list_for_each_entry(encoder, | 1155 | list_for_each_entry(encoder, |
1155 | &dev->mode_config.encoder_list, | 1156 | &dev->mode_config.encoder_list, |
1156 | head) { | 1157 | head) { |
1157 | DRM_DEBUG_KMS("ENCODER ID is %d\n", | 1158 | DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id, |
1158 | encoder->base.id); | 1159 | drm_get_encoder_name(encoder)); |
1159 | if (put_user(encoder->base.id, encoder_id + | 1160 | if (put_user(encoder->base.id, encoder_id + |
1160 | copied)) { | 1161 | copied)) { |
1161 | ret = -EFAULT; | 1162 | ret = -EFAULT; |
@@ -1185,8 +1186,9 @@ int drm_mode_getresources(struct drm_device *dev, void *data, | |||
1185 | list_for_each_entry(connector, | 1186 | list_for_each_entry(connector, |
1186 | &dev->mode_config.connector_list, | 1187 | &dev->mode_config.connector_list, |
1187 | head) { | 1188 | head) { |
1188 | DRM_DEBUG_KMS("CONNECTOR ID is %d\n", | 1189 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
1189 | connector->base.id); | 1190 | connector->base.id, |
1191 | drm_get_connector_name(connector)); | ||
1190 | if (put_user(connector->base.id, | 1192 | if (put_user(connector->base.id, |
1191 | connector_id + copied)) { | 1193 | connector_id + copied)) { |
1192 | ret = -EFAULT; | 1194 | ret = -EFAULT; |
@@ -1209,7 +1211,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, | |||
1209 | } | 1211 | } |
1210 | card_res->count_connectors = connector_count; | 1212 | card_res->count_connectors = connector_count; |
1211 | 1213 | ||
1212 | DRM_DEBUG_KMS("Counted %d %d %d\n", card_res->count_crtcs, | 1214 | DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs, |
1213 | card_res->count_connectors, card_res->count_encoders); | 1215 | card_res->count_connectors, card_res->count_encoders); |
1214 | 1216 | ||
1215 | out: | 1217 | out: |
@@ -1312,7 +1314,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, | |||
1312 | 1314 | ||
1313 | memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); | 1315 | memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); |
1314 | 1316 | ||
1315 | DRM_DEBUG_KMS("connector id %d:\n", out_resp->connector_id); | 1317 | DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id); |
1316 | 1318 | ||
1317 | mutex_lock(&dev->mode_config.mutex); | 1319 | mutex_lock(&dev->mode_config.mutex); |
1318 | 1320 | ||
@@ -1493,6 +1495,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, | |||
1493 | goto out; | 1495 | goto out; |
1494 | } | 1496 | } |
1495 | crtc = obj_to_crtc(obj); | 1497 | crtc = obj_to_crtc(obj); |
1498 | DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); | ||
1496 | 1499 | ||
1497 | if (crtc_req->mode_valid) { | 1500 | if (crtc_req->mode_valid) { |
1498 | /* If we have a mode we need a framebuffer. */ | 1501 | /* If we have a mode we need a framebuffer. */ |
@@ -1569,6 +1572,9 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, | |||
1569 | goto out; | 1572 | goto out; |
1570 | } | 1573 | } |
1571 | connector = obj_to_connector(obj); | 1574 | connector = obj_to_connector(obj); |
1575 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", | ||
1576 | connector->base.id, | ||
1577 | drm_get_connector_name(connector)); | ||
1572 | 1578 | ||
1573 | connector_set[i] = connector; | 1579 | connector_set[i] = connector; |
1574 | } | 1580 | } |
@@ -1684,6 +1690,7 @@ int drm_mode_addfb(struct drm_device *dev, | |||
1684 | 1690 | ||
1685 | r->fb_id = fb->base.id; | 1691 | r->fb_id = fb->base.id; |
1686 | list_add(&fb->filp_head, &file_priv->fbs); | 1692 | list_add(&fb->filp_head, &file_priv->fbs); |
1693 | DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); | ||
1687 | 1694 | ||
1688 | out: | 1695 | out: |
1689 | mutex_unlock(&dev->mode_config.mutex); | 1696 | mutex_unlock(&dev->mode_config.mutex); |
@@ -2610,6 +2617,15 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, | |||
2610 | goto out; | 2617 | goto out; |
2611 | crtc = obj_to_crtc(obj); | 2618 | crtc = obj_to_crtc(obj); |
2612 | 2619 | ||
2620 | if (crtc->fb == NULL) { | ||
2621 | /* The framebuffer is currently unbound, presumably | ||
2622 | * due to a hotplug event, that userspace has not | ||
2623 | * yet discovered. | ||
2624 | */ | ||
2625 | ret = -EBUSY; | ||
2626 | goto out; | ||
2627 | } | ||
2628 | |||
2613 | if (crtc->funcs->page_flip == NULL) | 2629 | if (crtc->funcs->page_flip == NULL) |
2614 | goto out; | 2630 | goto out; |
2615 | 2631 | ||
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 9b2a54117c91..11fe9c870d17 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -86,7 +86,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
86 | int count = 0; | 86 | int count = 0; |
87 | int mode_flags = 0; | 87 | int mode_flags = 0; |
88 | 88 | ||
89 | DRM_DEBUG_KMS("%s\n", drm_get_connector_name(connector)); | 89 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, |
90 | drm_get_connector_name(connector)); | ||
90 | /* set all modes to the unverified state */ | 91 | /* set all modes to the unverified state */ |
91 | list_for_each_entry_safe(mode, t, &connector->modes, head) | 92 | list_for_each_entry_safe(mode, t, &connector->modes, head) |
92 | mode->status = MODE_UNVERIFIED; | 93 | mode->status = MODE_UNVERIFIED; |
@@ -102,8 +103,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
102 | connector->status = connector->funcs->detect(connector); | 103 | connector->status = connector->funcs->detect(connector); |
103 | 104 | ||
104 | if (connector->status == connector_status_disconnected) { | 105 | if (connector->status == connector_status_disconnected) { |
105 | DRM_DEBUG_KMS("%s is disconnected\n", | 106 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", |
106 | drm_get_connector_name(connector)); | 107 | connector->base.id, drm_get_connector_name(connector)); |
107 | drm_mode_connector_update_edid_property(connector, NULL); | 108 | drm_mode_connector_update_edid_property(connector, NULL); |
108 | goto prune; | 109 | goto prune; |
109 | } | 110 | } |
@@ -141,8 +142,8 @@ prune: | |||
141 | 142 | ||
142 | drm_mode_sort(&connector->modes); | 143 | drm_mode_sort(&connector->modes); |
143 | 144 | ||
144 | DRM_DEBUG_KMS("Probed modes for %s\n", | 145 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id, |
145 | drm_get_connector_name(connector)); | 146 | drm_get_connector_name(connector)); |
146 | list_for_each_entry_safe(mode, t, &connector->modes, head) { | 147 | list_for_each_entry_safe(mode, t, &connector->modes, head) { |
147 | mode->vrefresh = drm_mode_vrefresh(mode); | 148 | mode->vrefresh = drm_mode_vrefresh(mode); |
148 | 149 | ||
@@ -201,6 +202,17 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc) | |||
201 | } | 202 | } |
202 | EXPORT_SYMBOL(drm_helper_crtc_in_use); | 203 | EXPORT_SYMBOL(drm_helper_crtc_in_use); |
203 | 204 | ||
205 | static void | ||
206 | drm_encoder_disable(struct drm_encoder *encoder) | ||
207 | { | ||
208 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | ||
209 | |||
210 | if (encoder_funcs->disable) | ||
211 | (*encoder_funcs->disable)(encoder); | ||
212 | else | ||
213 | (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); | ||
214 | } | ||
215 | |||
204 | /** | 216 | /** |
205 | * drm_helper_disable_unused_functions - disable unused objects | 217 | * drm_helper_disable_unused_functions - disable unused objects |
206 | * @dev: DRM device | 218 | * @dev: DRM device |
@@ -215,7 +227,6 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) | |||
215 | { | 227 | { |
216 | struct drm_encoder *encoder; | 228 | struct drm_encoder *encoder; |
217 | struct drm_connector *connector; | 229 | struct drm_connector *connector; |
218 | struct drm_encoder_helper_funcs *encoder_funcs; | ||
219 | struct drm_crtc *crtc; | 230 | struct drm_crtc *crtc; |
220 | 231 | ||
221 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 232 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
@@ -226,12 +237,8 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) | |||
226 | } | 237 | } |
227 | 238 | ||
228 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 239 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
229 | encoder_funcs = encoder->helper_private; | ||
230 | if (!drm_helper_encoder_in_use(encoder)) { | 240 | if (!drm_helper_encoder_in_use(encoder)) { |
231 | if (encoder_funcs->disable) | 241 | drm_encoder_disable(encoder); |
232 | (*encoder_funcs->disable)(encoder); | ||
233 | else | ||
234 | (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); | ||
235 | /* disconnector encoder from any connector */ | 242 | /* disconnector encoder from any connector */ |
236 | encoder->crtc = NULL; | 243 | encoder->crtc = NULL; |
237 | } | 244 | } |
@@ -241,7 +248,10 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) | |||
241 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | 248 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; |
242 | crtc->enabled = drm_helper_crtc_in_use(crtc); | 249 | crtc->enabled = drm_helper_crtc_in_use(crtc); |
243 | if (!crtc->enabled) { | 250 | if (!crtc->enabled) { |
244 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); | 251 | if (crtc_funcs->disable) |
252 | (*crtc_funcs->disable)(crtc); | ||
253 | else | ||
254 | (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF); | ||
245 | crtc->fb = NULL; | 255 | crtc->fb = NULL; |
246 | } | 256 | } |
247 | } | 257 | } |
@@ -292,11 +302,11 @@ drm_crtc_prepare_encoders(struct drm_device *dev) | |||
292 | encoder_funcs = encoder->helper_private; | 302 | encoder_funcs = encoder->helper_private; |
293 | /* Disable unused encoders */ | 303 | /* Disable unused encoders */ |
294 | if (encoder->crtc == NULL) | 304 | if (encoder->crtc == NULL) |
295 | (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); | 305 | drm_encoder_disable(encoder); |
296 | /* Disable encoders whose CRTC is about to change */ | 306 | /* Disable encoders whose CRTC is about to change */ |
297 | if (encoder_funcs->get_crtc && | 307 | if (encoder_funcs->get_crtc && |
298 | encoder->crtc != (*encoder_funcs->get_crtc)(encoder)) | 308 | encoder->crtc != (*encoder_funcs->get_crtc)(encoder)) |
299 | (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); | 309 | drm_encoder_disable(encoder); |
300 | } | 310 | } |
301 | } | 311 | } |
302 | 312 | ||
@@ -365,6 +375,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, | |||
365 | if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) { | 375 | if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) { |
366 | goto done; | 376 | goto done; |
367 | } | 377 | } |
378 | DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); | ||
368 | 379 | ||
369 | /* Prepare the encoders and CRTCs before setting the mode. */ | 380 | /* Prepare the encoders and CRTCs before setting the mode. */ |
370 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 381 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
@@ -392,8 +403,9 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, | |||
392 | if (encoder->crtc != crtc) | 403 | if (encoder->crtc != crtc) |
393 | continue; | 404 | continue; |
394 | 405 | ||
395 | DRM_DEBUG("%s: set mode %s %x\n", drm_get_encoder_name(encoder), | 406 | DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n", |
396 | mode->name, mode->base.id); | 407 | encoder->base.id, drm_get_encoder_name(encoder), |
408 | mode->base.id, mode->name); | ||
397 | encoder_funcs = encoder->helper_private; | 409 | encoder_funcs = encoder->helper_private; |
398 | encoder_funcs->mode_set(encoder, mode, adjusted_mode); | 410 | encoder_funcs->mode_set(encoder, mode, adjusted_mode); |
399 | } | 411 | } |
@@ -469,10 +481,15 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
469 | 481 | ||
470 | crtc_funcs = set->crtc->helper_private; | 482 | crtc_funcs = set->crtc->helper_private; |
471 | 483 | ||
472 | DRM_DEBUG_KMS("crtc: %p %d fb: %p connectors: %p num_connectors:" | 484 | if (set->fb) { |
473 | " %d (x, y) (%i, %i)\n", | 485 | DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n", |
474 | set->crtc, set->crtc->base.id, set->fb, set->connectors, | 486 | set->crtc->base.id, set->fb->base.id, |
475 | (int)set->num_connectors, set->x, set->y); | 487 | (int)set->num_connectors, set->x, set->y); |
488 | } else { | ||
489 | DRM_DEBUG_KMS("[CRTC:%d] [NOFB] #connectors=%d (x y) (%i %i)\n", | ||
490 | set->crtc->base.id, (int)set->num_connectors, | ||
491 | set->x, set->y); | ||
492 | } | ||
476 | 493 | ||
477 | dev = set->crtc->dev; | 494 | dev = set->crtc->dev; |
478 | 495 | ||
@@ -601,8 +618,14 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
601 | mode_changed = true; | 618 | mode_changed = true; |
602 | connector->encoder->crtc = new_crtc; | 619 | connector->encoder->crtc = new_crtc; |
603 | } | 620 | } |
604 | DRM_DEBUG_KMS("setting connector %d crtc to %p\n", | 621 | if (new_crtc) { |
605 | connector->base.id, new_crtc); | 622 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n", |
623 | connector->base.id, drm_get_connector_name(connector), | ||
624 | new_crtc->base.id); | ||
625 | } else { | ||
626 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n", | ||
627 | connector->base.id, drm_get_connector_name(connector)); | ||
628 | } | ||
606 | } | 629 | } |
607 | 630 | ||
608 | /* mode_set_base is not a required function */ | 631 | /* mode_set_base is not a required function */ |
@@ -620,8 +643,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
620 | if (!drm_crtc_helper_set_mode(set->crtc, set->mode, | 643 | if (!drm_crtc_helper_set_mode(set->crtc, set->mode, |
621 | set->x, set->y, | 644 | set->x, set->y, |
622 | old_fb)) { | 645 | old_fb)) { |
623 | DRM_ERROR("failed to set mode on crtc %p\n", | 646 | DRM_ERROR("failed to set mode on [CRTC:%d]\n", |
624 | set->crtc); | 647 | set->crtc->base.id); |
625 | ret = -EINVAL; | 648 | ret = -EINVAL; |
626 | goto fail; | 649 | goto fail; |
627 | } | 650 | } |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 4a66201edaec..90288ec7c284 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -243,47 +243,20 @@ int drm_lastclose(struct drm_device * dev) | |||
243 | * | 243 | * |
244 | * Initializes an array of drm_device structures, and attempts to | 244 | * Initializes an array of drm_device structures, and attempts to |
245 | * initialize all available devices, using consecutive minors, registering the | 245 | * initialize all available devices, using consecutive minors, registering the |
246 | * stubs and initializing the AGP device. | 246 | * stubs and initializing the device. |
247 | * | 247 | * |
248 | * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and | 248 | * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and |
249 | * after the initialization for driver customization. | 249 | * after the initialization for driver customization. |
250 | */ | 250 | */ |
251 | int drm_init(struct drm_driver *driver) | 251 | int drm_init(struct drm_driver *driver) |
252 | { | 252 | { |
253 | struct pci_dev *pdev = NULL; | ||
254 | const struct pci_device_id *pid; | ||
255 | int i; | ||
256 | |||
257 | DRM_DEBUG("\n"); | 253 | DRM_DEBUG("\n"); |
258 | |||
259 | INIT_LIST_HEAD(&driver->device_list); | 254 | INIT_LIST_HEAD(&driver->device_list); |
260 | 255 | ||
261 | if (driver->driver_features & DRIVER_MODESET) | 256 | if (driver->driver_features & DRIVER_USE_PLATFORM_DEVICE) |
262 | return pci_register_driver(&driver->pci_driver); | 257 | return drm_platform_init(driver); |
263 | 258 | else | |
264 | /* If not using KMS, fall back to stealth mode manual scanning. */ | 259 | return drm_pci_init(driver); |
265 | for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { | ||
266 | pid = &driver->pci_driver.id_table[i]; | ||
267 | |||
268 | /* Loop around setting up a DRM device for each PCI device | ||
269 | * matching our ID and device class. If we had the internal | ||
270 | * function that pci_get_subsys and pci_get_class used, we'd | ||
271 | * be able to just pass pid in instead of doing a two-stage | ||
272 | * thing. | ||
273 | */ | ||
274 | pdev = NULL; | ||
275 | while ((pdev = | ||
276 | pci_get_subsys(pid->vendor, pid->device, pid->subvendor, | ||
277 | pid->subdevice, pdev)) != NULL) { | ||
278 | if ((pdev->class & pid->class_mask) != pid->class) | ||
279 | continue; | ||
280 | |||
281 | /* stealth mode requires a manual probe */ | ||
282 | pci_dev_get(pdev); | ||
283 | drm_get_dev(pdev, pid, driver); | ||
284 | } | ||
285 | } | ||
286 | return 0; | ||
287 | } | 260 | } |
288 | 261 | ||
289 | EXPORT_SYMBOL(drm_init); | 262 | EXPORT_SYMBOL(drm_init); |
@@ -315,6 +288,7 @@ static int __init drm_core_init(void) | |||
315 | { | 288 | { |
316 | int ret = -ENOMEM; | 289 | int ret = -ENOMEM; |
317 | 290 | ||
291 | drm_global_init(); | ||
318 | idr_init(&drm_minors_idr); | 292 | idr_init(&drm_minors_idr); |
319 | 293 | ||
320 | if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) | 294 | if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) |
@@ -362,6 +336,7 @@ static void __exit drm_core_exit(void) | |||
362 | 336 | ||
363 | unregister_chrdev(DRM_MAJOR, "drm"); | 337 | unregister_chrdev(DRM_MAJOR, "drm"); |
364 | 338 | ||
339 | idr_remove_all(&drm_minors_idr); | ||
365 | idr_destroy(&drm_minors_idr); | 340 | idr_destroy(&drm_minors_idr); |
366 | } | 341 | } |
367 | 342 | ||
@@ -506,9 +481,9 @@ long drm_ioctl(struct file *filp, | |||
506 | if (ioctl->flags & DRM_UNLOCKED) | 481 | if (ioctl->flags & DRM_UNLOCKED) |
507 | retcode = func(dev, kdata, file_priv); | 482 | retcode = func(dev, kdata, file_priv); |
508 | else { | 483 | else { |
509 | lock_kernel(); | 484 | mutex_lock(&drm_global_mutex); |
510 | retcode = func(dev, kdata, file_priv); | 485 | retcode = func(dev, kdata, file_priv); |
511 | unlock_kernel(); | 486 | mutex_unlock(&drm_global_mutex); |
512 | } | 487 | } |
513 | 488 | ||
514 | if (cmd & IOC_OUT) { | 489 | if (cmd & IOC_OUT) { |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 9585e531ac6b..dce5c4a97f8d 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -282,7 +282,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) | |||
282 | return block; | 282 | return block; |
283 | 283 | ||
284 | carp: | 284 | carp: |
285 | dev_warn(&connector->dev->pdev->dev, "%s: EDID block %d invalid.\n", | 285 | dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n", |
286 | drm_get_connector_name(connector), j); | 286 | drm_get_connector_name(connector), j); |
287 | 287 | ||
288 | out: | 288 | out: |
@@ -1623,7 +1623,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) | |||
1623 | return 0; | 1623 | return 0; |
1624 | } | 1624 | } |
1625 | if (!drm_edid_is_valid(edid)) { | 1625 | if (!drm_edid_is_valid(edid)) { |
1626 | dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n", | 1626 | dev_warn(connector->dev->dev, "%s: EDID invalid.\n", |
1627 | drm_get_connector_name(connector)); | 1627 | drm_get_connector_name(connector)); |
1628 | return 0; | 1628 | return 0; |
1629 | } | 1629 | } |
diff --git a/drivers/gpu/drm/drm_encoder_slave.c b/drivers/gpu/drm/drm_encoder_slave.c index f0184696edf3..d62c064fbaa0 100644 --- a/drivers/gpu/drm/drm_encoder_slave.c +++ b/drivers/gpu/drm/drm_encoder_slave.c | |||
@@ -41,6 +41,9 @@ | |||
41 | * &drm_encoder_slave. The @slave_funcs field will be initialized with | 41 | * &drm_encoder_slave. The @slave_funcs field will be initialized with |
42 | * the hooks provided by the slave driver. | 42 | * the hooks provided by the slave driver. |
43 | * | 43 | * |
44 | * If @info->platform_data is non-NULL it will be used as the initial | ||
45 | * slave config. | ||
46 | * | ||
44 | * Returns 0 on success or a negative errno on failure, in particular, | 47 | * Returns 0 on success or a negative errno on failure, in particular, |
45 | * -ENODEV is returned when no matching driver is found. | 48 | * -ENODEV is returned when no matching driver is found. |
46 | */ | 49 | */ |
@@ -85,6 +88,10 @@ int drm_i2c_encoder_init(struct drm_device *dev, | |||
85 | if (err) | 88 | if (err) |
86 | goto fail_unregister; | 89 | goto fail_unregister; |
87 | 90 | ||
91 | if (info->platform_data) | ||
92 | encoder->slave_funcs->set_config(&encoder->base, | ||
93 | info->platform_data); | ||
94 | |||
88 | return 0; | 95 | return 0; |
89 | 96 | ||
90 | fail_unregister: | 97 | fail_unregister: |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index e7aace20981f..2ca8df8b6102 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -39,6 +39,9 @@ | |||
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/smp_lock.h> | 40 | #include <linux/smp_lock.h> |
41 | 41 | ||
42 | /* from BKL pushdown: note that nothing else serializes idr_find() */ | ||
43 | DEFINE_MUTEX(drm_global_mutex); | ||
44 | |||
42 | static int drm_open_helper(struct inode *inode, struct file *filp, | 45 | static int drm_open_helper(struct inode *inode, struct file *filp, |
43 | struct drm_device * dev); | 46 | struct drm_device * dev); |
44 | 47 | ||
@@ -175,8 +178,7 @@ int drm_stub_open(struct inode *inode, struct file *filp) | |||
175 | 178 | ||
176 | DRM_DEBUG("\n"); | 179 | DRM_DEBUG("\n"); |
177 | 180 | ||
178 | /* BKL pushdown: note that nothing else serializes idr_find() */ | 181 | mutex_lock(&drm_global_mutex); |
179 | lock_kernel(); | ||
180 | minor = idr_find(&drm_minors_idr, minor_id); | 182 | minor = idr_find(&drm_minors_idr, minor_id); |
181 | if (!minor) | 183 | if (!minor) |
182 | goto out; | 184 | goto out; |
@@ -197,7 +199,7 @@ int drm_stub_open(struct inode *inode, struct file *filp) | |||
197 | fops_put(old_fops); | 199 | fops_put(old_fops); |
198 | 200 | ||
199 | out: | 201 | out: |
200 | unlock_kernel(); | 202 | mutex_unlock(&drm_global_mutex); |
201 | return err; | 203 | return err; |
202 | } | 204 | } |
203 | 205 | ||
@@ -472,7 +474,7 @@ int drm_release(struct inode *inode, struct file *filp) | |||
472 | struct drm_device *dev = file_priv->minor->dev; | 474 | struct drm_device *dev = file_priv->minor->dev; |
473 | int retcode = 0; | 475 | int retcode = 0; |
474 | 476 | ||
475 | lock_kernel(); | 477 | mutex_lock(&drm_global_mutex); |
476 | 478 | ||
477 | DRM_DEBUG("open_count = %d\n", dev->open_count); | 479 | DRM_DEBUG("open_count = %d\n", dev->open_count); |
478 | 480 | ||
@@ -573,17 +575,14 @@ int drm_release(struct inode *inode, struct file *filp) | |||
573 | if (atomic_read(&dev->ioctl_count)) { | 575 | if (atomic_read(&dev->ioctl_count)) { |
574 | DRM_ERROR("Device busy: %d\n", | 576 | DRM_ERROR("Device busy: %d\n", |
575 | atomic_read(&dev->ioctl_count)); | 577 | atomic_read(&dev->ioctl_count)); |
576 | spin_unlock(&dev->count_lock); | 578 | retcode = -EBUSY; |
577 | unlock_kernel(); | 579 | goto out; |
578 | return -EBUSY; | ||
579 | } | 580 | } |
580 | spin_unlock(&dev->count_lock); | 581 | retcode = drm_lastclose(dev); |
581 | unlock_kernel(); | ||
582 | return drm_lastclose(dev); | ||
583 | } | 582 | } |
583 | out: | ||
584 | spin_unlock(&dev->count_lock); | 584 | spin_unlock(&dev->count_lock); |
585 | 585 | mutex_unlock(&drm_global_mutex); | |
586 | unlock_kernel(); | ||
587 | 586 | ||
588 | return retcode; | 587 | return retcode; |
589 | } | 588 | } |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 33dad3fa6043..4f1b86714489 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -68,8 +68,18 @@ | |||
68 | * We make up offsets for buffer objects so we can recognize them at | 68 | * We make up offsets for buffer objects so we can recognize them at |
69 | * mmap time. | 69 | * mmap time. |
70 | */ | 70 | */ |
71 | |||
72 | /* pgoff in mmap is an unsigned long, so we need to make sure that | ||
73 | * the faked up offset will fit | ||
74 | */ | ||
75 | |||
76 | #if BITS_PER_LONG == 64 | ||
71 | #define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFFUL >> PAGE_SHIFT) + 1) | 77 | #define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFFUL >> PAGE_SHIFT) + 1) |
72 | #define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFFUL >> PAGE_SHIFT) * 16) | 78 | #define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFFUL >> PAGE_SHIFT) * 16) |
79 | #else | ||
80 | #define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFUL >> PAGE_SHIFT) + 1) | ||
81 | #define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFUL >> PAGE_SHIFT) * 16) | ||
82 | #endif | ||
73 | 83 | ||
74 | /** | 84 | /** |
75 | * Initialize the GEM device fields | 85 | * Initialize the GEM device fields |
@@ -419,6 +429,7 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private) | |||
419 | idr_for_each(&file_private->object_idr, | 429 | idr_for_each(&file_private->object_idr, |
420 | &drm_gem_object_release_handle, NULL); | 430 | &drm_gem_object_release_handle, NULL); |
421 | 431 | ||
432 | idr_remove_all(&file_private->object_idr); | ||
422 | idr_destroy(&file_private->object_idr); | 433 | idr_destroy(&file_private->object_idr); |
423 | } | 434 | } |
424 | 435 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_global.c b/drivers/gpu/drm/drm_global.c index b17007178a36..c87dc96444de 100644 --- a/drivers/gpu/drm/ttm/ttm_global.c +++ b/drivers/gpu/drm/drm_global.c | |||
@@ -28,45 +28,45 @@ | |||
28 | * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> | 28 | * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include "ttm/ttm_module.h" | ||
32 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
33 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
34 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include "drm_global.h" | ||
35 | 35 | ||
36 | struct ttm_global_item { | 36 | struct drm_global_item { |
37 | struct mutex mutex; | 37 | struct mutex mutex; |
38 | void *object; | 38 | void *object; |
39 | int refcount; | 39 | int refcount; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | static struct ttm_global_item glob[TTM_GLOBAL_NUM]; | 42 | static struct drm_global_item glob[DRM_GLOBAL_NUM]; |
43 | 43 | ||
44 | void ttm_global_init(void) | 44 | void drm_global_init(void) |
45 | { | 45 | { |
46 | int i; | 46 | int i; |
47 | 47 | ||
48 | for (i = 0; i < TTM_GLOBAL_NUM; ++i) { | 48 | for (i = 0; i < DRM_GLOBAL_NUM; ++i) { |
49 | struct ttm_global_item *item = &glob[i]; | 49 | struct drm_global_item *item = &glob[i]; |
50 | mutex_init(&item->mutex); | 50 | mutex_init(&item->mutex); |
51 | item->object = NULL; | 51 | item->object = NULL; |
52 | item->refcount = 0; | 52 | item->refcount = 0; |
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
56 | void ttm_global_release(void) | 56 | void drm_global_release(void) |
57 | { | 57 | { |
58 | int i; | 58 | int i; |
59 | for (i = 0; i < TTM_GLOBAL_NUM; ++i) { | 59 | for (i = 0; i < DRM_GLOBAL_NUM; ++i) { |
60 | struct ttm_global_item *item = &glob[i]; | 60 | struct drm_global_item *item = &glob[i]; |
61 | BUG_ON(item->object != NULL); | 61 | BUG_ON(item->object != NULL); |
62 | BUG_ON(item->refcount != 0); | 62 | BUG_ON(item->refcount != 0); |
63 | } | 63 | } |
64 | } | 64 | } |
65 | 65 | ||
66 | int ttm_global_item_ref(struct ttm_global_reference *ref) | 66 | int drm_global_item_ref(struct drm_global_reference *ref) |
67 | { | 67 | { |
68 | int ret; | 68 | int ret; |
69 | struct ttm_global_item *item = &glob[ref->global_type]; | 69 | struct drm_global_item *item = &glob[ref->global_type]; |
70 | void *object; | 70 | void *object; |
71 | 71 | ||
72 | mutex_lock(&item->mutex); | 72 | mutex_lock(&item->mutex); |
@@ -93,11 +93,11 @@ out_err: | |||
93 | item->object = NULL; | 93 | item->object = NULL; |
94 | return ret; | 94 | return ret; |
95 | } | 95 | } |
96 | EXPORT_SYMBOL(ttm_global_item_ref); | 96 | EXPORT_SYMBOL(drm_global_item_ref); |
97 | 97 | ||
98 | void ttm_global_item_unref(struct ttm_global_reference *ref) | 98 | void drm_global_item_unref(struct drm_global_reference *ref) |
99 | { | 99 | { |
100 | struct ttm_global_item *item = &glob[ref->global_type]; | 100 | struct drm_global_item *item = &glob[ref->global_type]; |
101 | 101 | ||
102 | mutex_lock(&item->mutex); | 102 | mutex_lock(&item->mutex); |
103 | BUG_ON(item->refcount == 0); | 103 | BUG_ON(item->refcount == 0); |
@@ -108,5 +108,5 @@ void ttm_global_item_unref(struct ttm_global_reference *ref) | |||
108 | } | 108 | } |
109 | mutex_unlock(&item->mutex); | 109 | mutex_unlock(&item->mutex); |
110 | } | 110 | } |
111 | EXPORT_SYMBOL(ttm_global_item_unref); | 111 | EXPORT_SYMBOL(drm_global_item_unref); |
112 | 112 | ||
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index f0f6c6b93f3a..2ef2c7827243 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c | |||
@@ -51,13 +51,24 @@ int drm_name_info(struct seq_file *m, void *data) | |||
51 | if (!master) | 51 | if (!master) |
52 | return 0; | 52 | return 0; |
53 | 53 | ||
54 | if (master->unique) { | 54 | if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) { |
55 | seq_printf(m, "%s %s %s\n", | 55 | if (master->unique) { |
56 | dev->driver->pci_driver.name, | 56 | seq_printf(m, "%s %s %s\n", |
57 | pci_name(dev->pdev), master->unique); | 57 | dev->driver->platform_device->name, |
58 | dev_name(dev->dev), master->unique); | ||
59 | } else { | ||
60 | seq_printf(m, "%s\n", | ||
61 | dev->driver->platform_device->name); | ||
62 | } | ||
58 | } else { | 63 | } else { |
59 | seq_printf(m, "%s %s\n", dev->driver->pci_driver.name, | 64 | if (master->unique) { |
60 | pci_name(dev->pdev)); | 65 | seq_printf(m, "%s %s %s\n", |
66 | dev->driver->pci_driver.name, | ||
67 | dev_name(dev->dev), master->unique); | ||
68 | } else { | ||
69 | seq_printf(m, "%s %s\n", dev->driver->pci_driver.name, | ||
70 | dev_name(dev->dev)); | ||
71 | } | ||
61 | } | 72 | } |
62 | 73 | ||
63 | return 0; | 74 | return 0; |
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 9b9ff46c2378..7b03b197fc00 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c | |||
@@ -64,6 +64,19 @@ int drm_getunique(struct drm_device *dev, void *data, | |||
64 | return 0; | 64 | return 0; |
65 | } | 65 | } |
66 | 66 | ||
67 | static void | ||
68 | drm_unset_busid(struct drm_device *dev, | ||
69 | struct drm_master *master) | ||
70 | { | ||
71 | kfree(dev->devname); | ||
72 | dev->devname = NULL; | ||
73 | |||
74 | kfree(master->unique); | ||
75 | master->unique = NULL; | ||
76 | master->unique_len = 0; | ||
77 | master->unique_size = 0; | ||
78 | } | ||
79 | |||
67 | /** | 80 | /** |
68 | * Set the bus id. | 81 | * Set the bus id. |
69 | * | 82 | * |
@@ -94,17 +107,24 @@ int drm_setunique(struct drm_device *dev, void *data, | |||
94 | master->unique_len = u->unique_len; | 107 | master->unique_len = u->unique_len; |
95 | master->unique_size = u->unique_len + 1; | 108 | master->unique_size = u->unique_len + 1; |
96 | master->unique = kmalloc(master->unique_size, GFP_KERNEL); | 109 | master->unique = kmalloc(master->unique_size, GFP_KERNEL); |
97 | if (!master->unique) | 110 | if (!master->unique) { |
98 | return -ENOMEM; | 111 | ret = -ENOMEM; |
99 | if (copy_from_user(master->unique, u->unique, master->unique_len)) | 112 | goto err; |
100 | return -EFAULT; | 113 | } |
114 | |||
115 | if (copy_from_user(master->unique, u->unique, master->unique_len)) { | ||
116 | ret = -EFAULT; | ||
117 | goto err; | ||
118 | } | ||
101 | 119 | ||
102 | master->unique[master->unique_len] = '\0'; | 120 | master->unique[master->unique_len] = '\0'; |
103 | 121 | ||
104 | dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) + | 122 | dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) + |
105 | strlen(master->unique) + 2, GFP_KERNEL); | 123 | strlen(master->unique) + 2, GFP_KERNEL); |
106 | if (!dev->devname) | 124 | if (!dev->devname) { |
107 | return -ENOMEM; | 125 | ret = -ENOMEM; |
126 | goto err; | ||
127 | } | ||
108 | 128 | ||
109 | sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, | 129 | sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, |
110 | master->unique); | 130 | master->unique); |
@@ -113,53 +133,103 @@ int drm_setunique(struct drm_device *dev, void *data, | |||
113 | * busid. | 133 | * busid. |
114 | */ | 134 | */ |
115 | ret = sscanf(master->unique, "PCI:%d:%d:%d", &bus, &slot, &func); | 135 | ret = sscanf(master->unique, "PCI:%d:%d:%d", &bus, &slot, &func); |
116 | if (ret != 3) | 136 | if (ret != 3) { |
117 | return -EINVAL; | 137 | ret = -EINVAL; |
138 | goto err; | ||
139 | } | ||
140 | |||
118 | domain = bus >> 8; | 141 | domain = bus >> 8; |
119 | bus &= 0xff; | 142 | bus &= 0xff; |
120 | 143 | ||
121 | if ((domain != drm_get_pci_domain(dev)) || | 144 | if ((domain != drm_get_pci_domain(dev)) || |
122 | (bus != dev->pdev->bus->number) || | 145 | (bus != dev->pdev->bus->number) || |
123 | (slot != PCI_SLOT(dev->pdev->devfn)) || | 146 | (slot != PCI_SLOT(dev->pdev->devfn)) || |
124 | (func != PCI_FUNC(dev->pdev->devfn))) | 147 | (func != PCI_FUNC(dev->pdev->devfn))) { |
125 | return -EINVAL; | 148 | ret = -EINVAL; |
149 | goto err; | ||
150 | } | ||
126 | 151 | ||
127 | return 0; | 152 | return 0; |
153 | |||
154 | err: | ||
155 | drm_unset_busid(dev, master); | ||
156 | return ret; | ||
128 | } | 157 | } |
129 | 158 | ||
130 | static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) | 159 | static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) |
131 | { | 160 | { |
132 | struct drm_master *master = file_priv->master; | 161 | struct drm_master *master = file_priv->master; |
133 | int len; | 162 | int len, ret; |
134 | 163 | ||
135 | if (master->unique != NULL) | 164 | if (master->unique != NULL) |
136 | return -EBUSY; | 165 | drm_unset_busid(dev, master); |
137 | 166 | ||
138 | master->unique_len = 40; | 167 | if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) { |
139 | master->unique_size = master->unique_len; | 168 | master->unique_len = 10 + strlen(dev->platformdev->name); |
140 | master->unique = kmalloc(master->unique_size, GFP_KERNEL); | 169 | master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL); |
141 | if (master->unique == NULL) | ||
142 | return -ENOMEM; | ||
143 | |||
144 | len = snprintf(master->unique, master->unique_len, "pci:%04x:%02x:%02x.%d", | ||
145 | drm_get_pci_domain(dev), | ||
146 | dev->pdev->bus->number, | ||
147 | PCI_SLOT(dev->pdev->devfn), | ||
148 | PCI_FUNC(dev->pdev->devfn)); | ||
149 | if (len >= master->unique_len) | ||
150 | DRM_ERROR("buffer overflow"); | ||
151 | else | ||
152 | master->unique_len = len; | ||
153 | 170 | ||
154 | dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) + | 171 | if (master->unique == NULL) |
155 | master->unique_len + 2, GFP_KERNEL); | 172 | return -ENOMEM; |
156 | if (dev->devname == NULL) | ||
157 | return -ENOMEM; | ||
158 | 173 | ||
159 | sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, | 174 | len = snprintf(master->unique, master->unique_len, |
160 | master->unique); | 175 | "platform:%s", dev->platformdev->name); |
176 | |||
177 | if (len > master->unique_len) { | ||
178 | DRM_ERROR("Unique buffer overflowed\n"); | ||
179 | ret = -EINVAL; | ||
180 | goto err; | ||
181 | } | ||
182 | |||
183 | dev->devname = | ||
184 | kmalloc(strlen(dev->platformdev->name) + | ||
185 | master->unique_len + 2, GFP_KERNEL); | ||
186 | |||
187 | if (dev->devname == NULL) { | ||
188 | ret = -ENOMEM; | ||
189 | goto err; | ||
190 | } | ||
191 | |||
192 | sprintf(dev->devname, "%s@%s", dev->platformdev->name, | ||
193 | master->unique); | ||
194 | |||
195 | } else { | ||
196 | master->unique_len = 40; | ||
197 | master->unique_size = master->unique_len; | ||
198 | master->unique = kmalloc(master->unique_size, GFP_KERNEL); | ||
199 | if (master->unique == NULL) | ||
200 | return -ENOMEM; | ||
201 | |||
202 | len = snprintf(master->unique, master->unique_len, | ||
203 | "pci:%04x:%02x:%02x.%d", | ||
204 | drm_get_pci_domain(dev), | ||
205 | dev->pdev->bus->number, | ||
206 | PCI_SLOT(dev->pdev->devfn), | ||
207 | PCI_FUNC(dev->pdev->devfn)); | ||
208 | if (len >= master->unique_len) { | ||
209 | DRM_ERROR("buffer overflow"); | ||
210 | ret = -EINVAL; | ||
211 | goto err; | ||
212 | } else | ||
213 | master->unique_len = len; | ||
214 | |||
215 | dev->devname = | ||
216 | kmalloc(strlen(dev->driver->pci_driver.name) + | ||
217 | master->unique_len + 2, GFP_KERNEL); | ||
218 | |||
219 | if (dev->devname == NULL) { | ||
220 | ret = -ENOMEM; | ||
221 | goto err; | ||
222 | } | ||
223 | |||
224 | sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, | ||
225 | master->unique); | ||
226 | } | ||
161 | 227 | ||
162 | return 0; | 228 | return 0; |
229 | |||
230 | err: | ||
231 | drm_unset_busid(dev, master); | ||
232 | return ret; | ||
163 | } | 233 | } |
164 | 234 | ||
165 | /** | 235 | /** |
@@ -323,7 +393,9 @@ int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_pri | |||
323 | /* | 393 | /* |
324 | * Version 1.1 includes tying of DRM to specific device | 394 | * Version 1.1 includes tying of DRM to specific device |
325 | */ | 395 | */ |
326 | drm_set_busid(dev, file_priv); | 396 | retcode = drm_set_busid(dev, file_priv); |
397 | if (retcode) | ||
398 | goto done; | ||
327 | } | 399 | } |
328 | } | 400 | } |
329 | 401 | ||
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index a263b7070fc6..9d3a5030b6e1 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -34,6 +34,7 @@ | |||
34 | */ | 34 | */ |
35 | 35 | ||
36 | #include "drmP.h" | 36 | #include "drmP.h" |
37 | #include "drm_trace.h" | ||
37 | 38 | ||
38 | #include <linux/interrupt.h> /* For task queue support */ | 39 | #include <linux/interrupt.h> /* For task queue support */ |
39 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
@@ -57,6 +58,9 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, | |||
57 | { | 58 | { |
58 | struct drm_irq_busid *p = data; | 59 | struct drm_irq_busid *p = data; |
59 | 60 | ||
61 | if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) | ||
62 | return -EINVAL; | ||
63 | |||
60 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) | 64 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) |
61 | return -EINVAL; | 65 | return -EINVAL; |
62 | 66 | ||
@@ -211,7 +215,7 @@ int drm_irq_install(struct drm_device *dev) | |||
211 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) | 215 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) |
212 | return -EINVAL; | 216 | return -EINVAL; |
213 | 217 | ||
214 | if (dev->pdev->irq == 0) | 218 | if (drm_dev_to_irq(dev) == 0) |
215 | return -EINVAL; | 219 | return -EINVAL; |
216 | 220 | ||
217 | mutex_lock(&dev->struct_mutex); | 221 | mutex_lock(&dev->struct_mutex); |
@@ -229,7 +233,7 @@ int drm_irq_install(struct drm_device *dev) | |||
229 | dev->irq_enabled = 1; | 233 | dev->irq_enabled = 1; |
230 | mutex_unlock(&dev->struct_mutex); | 234 | mutex_unlock(&dev->struct_mutex); |
231 | 235 | ||
232 | DRM_DEBUG("irq=%d\n", dev->pdev->irq); | 236 | DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev)); |
233 | 237 | ||
234 | /* Before installing handler */ | 238 | /* Before installing handler */ |
235 | dev->driver->irq_preinstall(dev); | 239 | dev->driver->irq_preinstall(dev); |
@@ -302,14 +306,14 @@ int drm_irq_uninstall(struct drm_device * dev) | |||
302 | if (!irq_enabled) | 306 | if (!irq_enabled) |
303 | return -EINVAL; | 307 | return -EINVAL; |
304 | 308 | ||
305 | DRM_DEBUG("irq=%d\n", dev->pdev->irq); | 309 | DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev)); |
306 | 310 | ||
307 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 311 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
308 | vga_client_register(dev->pdev, NULL, NULL, NULL); | 312 | vga_client_register(dev->pdev, NULL, NULL, NULL); |
309 | 313 | ||
310 | dev->driver->irq_uninstall(dev); | 314 | dev->driver->irq_uninstall(dev); |
311 | 315 | ||
312 | free_irq(dev->pdev->irq, dev); | 316 | free_irq(drm_dev_to_irq(dev), dev); |
313 | 317 | ||
314 | return 0; | 318 | return 0; |
315 | } | 319 | } |
@@ -341,7 +345,7 @@ int drm_control(struct drm_device *dev, void *data, | |||
341 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 345 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
342 | return 0; | 346 | return 0; |
343 | if (dev->if_version < DRM_IF_VERSION(1, 2) && | 347 | if (dev->if_version < DRM_IF_VERSION(1, 2) && |
344 | ctl->irq != dev->pdev->irq) | 348 | ctl->irq != drm_dev_to_irq(dev)) |
345 | return -EINVAL; | 349 | return -EINVAL; |
346 | return drm_irq_install(dev); | 350 | return drm_irq_install(dev); |
347 | case DRM_UNINST_HANDLER: | 351 | case DRM_UNINST_HANDLER: |
@@ -587,6 +591,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
587 | return -ENOMEM; | 591 | return -ENOMEM; |
588 | 592 | ||
589 | e->pipe = pipe; | 593 | e->pipe = pipe; |
594 | e->base.pid = current->pid; | ||
590 | e->event.base.type = DRM_EVENT_VBLANK; | 595 | e->event.base.type = DRM_EVENT_VBLANK; |
591 | e->event.base.length = sizeof e->event; | 596 | e->event.base.length = sizeof e->event; |
592 | e->event.user_data = vblwait->request.signal; | 597 | e->event.user_data = vblwait->request.signal; |
@@ -614,6 +619,9 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
614 | DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n", | 619 | DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n", |
615 | vblwait->request.sequence, seq, pipe); | 620 | vblwait->request.sequence, seq, pipe); |
616 | 621 | ||
622 | trace_drm_vblank_event_queued(current->pid, pipe, | ||
623 | vblwait->request.sequence); | ||
624 | |||
617 | e->event.sequence = vblwait->request.sequence; | 625 | e->event.sequence = vblwait->request.sequence; |
618 | if ((seq - vblwait->request.sequence) <= (1 << 23)) { | 626 | if ((seq - vblwait->request.sequence) <= (1 << 23)) { |
619 | e->event.tv_sec = now.tv_sec; | 627 | e->event.tv_sec = now.tv_sec; |
@@ -621,6 +629,8 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
621 | drm_vblank_put(dev, e->pipe); | 629 | drm_vblank_put(dev, e->pipe); |
622 | list_add_tail(&e->base.link, &e->base.file_priv->event_list); | 630 | list_add_tail(&e->base.link, &e->base.file_priv->event_list); |
623 | wake_up_interruptible(&e->base.file_priv->event_wait); | 631 | wake_up_interruptible(&e->base.file_priv->event_wait); |
632 | trace_drm_vblank_event_delivered(current->pid, pipe, | ||
633 | vblwait->request.sequence); | ||
624 | } else { | 634 | } else { |
625 | list_add_tail(&e->base.link, &dev->vblank_event_list); | 635 | list_add_tail(&e->base.link, &dev->vblank_event_list); |
626 | } | 636 | } |
@@ -651,7 +661,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, | |||
651 | int ret = 0; | 661 | int ret = 0; |
652 | unsigned int flags, seq, crtc; | 662 | unsigned int flags, seq, crtc; |
653 | 663 | ||
654 | if ((!dev->pdev->irq) || (!dev->irq_enabled)) | 664 | if ((!drm_dev_to_irq(dev)) || (!dev->irq_enabled)) |
655 | return -EINVAL; | 665 | return -EINVAL; |
656 | 666 | ||
657 | if (vblwait->request.type & _DRM_VBLANK_SIGNAL) | 667 | if (vblwait->request.type & _DRM_VBLANK_SIGNAL) |
@@ -751,9 +761,13 @@ void drm_handle_vblank_events(struct drm_device *dev, int crtc) | |||
751 | drm_vblank_put(dev, e->pipe); | 761 | drm_vblank_put(dev, e->pipe); |
752 | list_move_tail(&e->base.link, &e->base.file_priv->event_list); | 762 | list_move_tail(&e->base.link, &e->base.file_priv->event_list); |
753 | wake_up_interruptible(&e->base.file_priv->event_wait); | 763 | wake_up_interruptible(&e->base.file_priv->event_wait); |
764 | trace_drm_vblank_event_delivered(e->base.pid, e->pipe, | ||
765 | e->event.sequence); | ||
754 | } | 766 | } |
755 | 767 | ||
756 | spin_unlock_irqrestore(&dev->event_lock, flags); | 768 | spin_unlock_irqrestore(&dev->event_lock, flags); |
769 | |||
770 | trace_drm_vblank_event(crtc, seq); | ||
757 | } | 771 | } |
758 | 772 | ||
759 | /** | 773 | /** |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 2ac074c8f5d2..da99edc50888 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -48,44 +48,14 @@ | |||
48 | 48 | ||
49 | #define MM_UNUSED_TARGET 4 | 49 | #define MM_UNUSED_TARGET 4 |
50 | 50 | ||
51 | unsigned long drm_mm_tail_space(struct drm_mm *mm) | ||
52 | { | ||
53 | struct list_head *tail_node; | ||
54 | struct drm_mm_node *entry; | ||
55 | |||
56 | tail_node = mm->ml_entry.prev; | ||
57 | entry = list_entry(tail_node, struct drm_mm_node, ml_entry); | ||
58 | if (!entry->free) | ||
59 | return 0; | ||
60 | |||
61 | return entry->size; | ||
62 | } | ||
63 | |||
64 | int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size) | ||
65 | { | ||
66 | struct list_head *tail_node; | ||
67 | struct drm_mm_node *entry; | ||
68 | |||
69 | tail_node = mm->ml_entry.prev; | ||
70 | entry = list_entry(tail_node, struct drm_mm_node, ml_entry); | ||
71 | if (!entry->free) | ||
72 | return -ENOMEM; | ||
73 | |||
74 | if (entry->size <= size) | ||
75 | return -ENOMEM; | ||
76 | |||
77 | entry->size -= size; | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) | 51 | static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) |
82 | { | 52 | { |
83 | struct drm_mm_node *child; | 53 | struct drm_mm_node *child; |
84 | 54 | ||
85 | if (atomic) | 55 | if (atomic) |
86 | child = kmalloc(sizeof(*child), GFP_ATOMIC); | 56 | child = kzalloc(sizeof(*child), GFP_ATOMIC); |
87 | else | 57 | else |
88 | child = kmalloc(sizeof(*child), GFP_KERNEL); | 58 | child = kzalloc(sizeof(*child), GFP_KERNEL); |
89 | 59 | ||
90 | if (unlikely(child == NULL)) { | 60 | if (unlikely(child == NULL)) { |
91 | spin_lock(&mm->unused_lock); | 61 | spin_lock(&mm->unused_lock); |
@@ -94,8 +64,8 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) | |||
94 | else { | 64 | else { |
95 | child = | 65 | child = |
96 | list_entry(mm->unused_nodes.next, | 66 | list_entry(mm->unused_nodes.next, |
97 | struct drm_mm_node, fl_entry); | 67 | struct drm_mm_node, free_stack); |
98 | list_del(&child->fl_entry); | 68 | list_del(&child->free_stack); |
99 | --mm->num_unused; | 69 | --mm->num_unused; |
100 | } | 70 | } |
101 | spin_unlock(&mm->unused_lock); | 71 | spin_unlock(&mm->unused_lock); |
@@ -115,7 +85,7 @@ int drm_mm_pre_get(struct drm_mm *mm) | |||
115 | spin_lock(&mm->unused_lock); | 85 | spin_lock(&mm->unused_lock); |
116 | while (mm->num_unused < MM_UNUSED_TARGET) { | 86 | while (mm->num_unused < MM_UNUSED_TARGET) { |
117 | spin_unlock(&mm->unused_lock); | 87 | spin_unlock(&mm->unused_lock); |
118 | node = kmalloc(sizeof(*node), GFP_KERNEL); | 88 | node = kzalloc(sizeof(*node), GFP_KERNEL); |
119 | spin_lock(&mm->unused_lock); | 89 | spin_lock(&mm->unused_lock); |
120 | 90 | ||
121 | if (unlikely(node == NULL)) { | 91 | if (unlikely(node == NULL)) { |
@@ -124,7 +94,7 @@ int drm_mm_pre_get(struct drm_mm *mm) | |||
124 | return ret; | 94 | return ret; |
125 | } | 95 | } |
126 | ++mm->num_unused; | 96 | ++mm->num_unused; |
127 | list_add_tail(&node->fl_entry, &mm->unused_nodes); | 97 | list_add_tail(&node->free_stack, &mm->unused_nodes); |
128 | } | 98 | } |
129 | spin_unlock(&mm->unused_lock); | 99 | spin_unlock(&mm->unused_lock); |
130 | return 0; | 100 | return 0; |
@@ -146,27 +116,12 @@ static int drm_mm_create_tail_node(struct drm_mm *mm, | |||
146 | child->start = start; | 116 | child->start = start; |
147 | child->mm = mm; | 117 | child->mm = mm; |
148 | 118 | ||
149 | list_add_tail(&child->ml_entry, &mm->ml_entry); | 119 | list_add_tail(&child->node_list, &mm->node_list); |
150 | list_add_tail(&child->fl_entry, &mm->fl_entry); | 120 | list_add_tail(&child->free_stack, &mm->free_stack); |
151 | 121 | ||
152 | return 0; | 122 | return 0; |
153 | } | 123 | } |
154 | 124 | ||
155 | int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size, int atomic) | ||
156 | { | ||
157 | struct list_head *tail_node; | ||
158 | struct drm_mm_node *entry; | ||
159 | |||
160 | tail_node = mm->ml_entry.prev; | ||
161 | entry = list_entry(tail_node, struct drm_mm_node, ml_entry); | ||
162 | if (!entry->free) { | ||
163 | return drm_mm_create_tail_node(mm, entry->start + entry->size, | ||
164 | size, atomic); | ||
165 | } | ||
166 | entry->size += size; | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, | 125 | static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, |
171 | unsigned long size, | 126 | unsigned long size, |
172 | int atomic) | 127 | int atomic) |
@@ -177,15 +132,14 @@ static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, | |||
177 | if (unlikely(child == NULL)) | 132 | if (unlikely(child == NULL)) |
178 | return NULL; | 133 | return NULL; |
179 | 134 | ||
180 | INIT_LIST_HEAD(&child->fl_entry); | 135 | INIT_LIST_HEAD(&child->free_stack); |
181 | 136 | ||
182 | child->free = 0; | ||
183 | child->size = size; | 137 | child->size = size; |
184 | child->start = parent->start; | 138 | child->start = parent->start; |
185 | child->mm = parent->mm; | 139 | child->mm = parent->mm; |
186 | 140 | ||
187 | list_add_tail(&child->ml_entry, &parent->ml_entry); | 141 | list_add_tail(&child->node_list, &parent->node_list); |
188 | INIT_LIST_HEAD(&child->fl_entry); | 142 | INIT_LIST_HEAD(&child->free_stack); |
189 | 143 | ||
190 | parent->size -= size; | 144 | parent->size -= size; |
191 | parent->start += size; | 145 | parent->start += size; |
@@ -213,7 +167,7 @@ struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, | |||
213 | } | 167 | } |
214 | 168 | ||
215 | if (node->size == size) { | 169 | if (node->size == size) { |
216 | list_del_init(&node->fl_entry); | 170 | list_del_init(&node->free_stack); |
217 | node->free = 0; | 171 | node->free = 0; |
218 | } else { | 172 | } else { |
219 | node = drm_mm_split_at_start(node, size, atomic); | 173 | node = drm_mm_split_at_start(node, size, atomic); |
@@ -251,7 +205,7 @@ struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *node, | |||
251 | } | 205 | } |
252 | 206 | ||
253 | if (node->size == size) { | 207 | if (node->size == size) { |
254 | list_del_init(&node->fl_entry); | 208 | list_del_init(&node->free_stack); |
255 | node->free = 0; | 209 | node->free = 0; |
256 | } else { | 210 | } else { |
257 | node = drm_mm_split_at_start(node, size, atomic); | 211 | node = drm_mm_split_at_start(node, size, atomic); |
@@ -273,16 +227,19 @@ void drm_mm_put_block(struct drm_mm_node *cur) | |||
273 | { | 227 | { |
274 | 228 | ||
275 | struct drm_mm *mm = cur->mm; | 229 | struct drm_mm *mm = cur->mm; |
276 | struct list_head *cur_head = &cur->ml_entry; | 230 | struct list_head *cur_head = &cur->node_list; |
277 | struct list_head *root_head = &mm->ml_entry; | 231 | struct list_head *root_head = &mm->node_list; |
278 | struct drm_mm_node *prev_node = NULL; | 232 | struct drm_mm_node *prev_node = NULL; |
279 | struct drm_mm_node *next_node; | 233 | struct drm_mm_node *next_node; |
280 | 234 | ||
281 | int merged = 0; | 235 | int merged = 0; |
282 | 236 | ||
237 | BUG_ON(cur->scanned_block || cur->scanned_prev_free | ||
238 | || cur->scanned_next_free); | ||
239 | |||
283 | if (cur_head->prev != root_head) { | 240 | if (cur_head->prev != root_head) { |
284 | prev_node = | 241 | prev_node = |
285 | list_entry(cur_head->prev, struct drm_mm_node, ml_entry); | 242 | list_entry(cur_head->prev, struct drm_mm_node, node_list); |
286 | if (prev_node->free) { | 243 | if (prev_node->free) { |
287 | prev_node->size += cur->size; | 244 | prev_node->size += cur->size; |
288 | merged = 1; | 245 | merged = 1; |
@@ -290,15 +247,15 @@ void drm_mm_put_block(struct drm_mm_node *cur) | |||
290 | } | 247 | } |
291 | if (cur_head->next != root_head) { | 248 | if (cur_head->next != root_head) { |
292 | next_node = | 249 | next_node = |
293 | list_entry(cur_head->next, struct drm_mm_node, ml_entry); | 250 | list_entry(cur_head->next, struct drm_mm_node, node_list); |
294 | if (next_node->free) { | 251 | if (next_node->free) { |
295 | if (merged) { | 252 | if (merged) { |
296 | prev_node->size += next_node->size; | 253 | prev_node->size += next_node->size; |
297 | list_del(&next_node->ml_entry); | 254 | list_del(&next_node->node_list); |
298 | list_del(&next_node->fl_entry); | 255 | list_del(&next_node->free_stack); |
299 | spin_lock(&mm->unused_lock); | 256 | spin_lock(&mm->unused_lock); |
300 | if (mm->num_unused < MM_UNUSED_TARGET) { | 257 | if (mm->num_unused < MM_UNUSED_TARGET) { |
301 | list_add(&next_node->fl_entry, | 258 | list_add(&next_node->free_stack, |
302 | &mm->unused_nodes); | 259 | &mm->unused_nodes); |
303 | ++mm->num_unused; | 260 | ++mm->num_unused; |
304 | } else | 261 | } else |
@@ -313,12 +270,12 @@ void drm_mm_put_block(struct drm_mm_node *cur) | |||
313 | } | 270 | } |
314 | if (!merged) { | 271 | if (!merged) { |
315 | cur->free = 1; | 272 | cur->free = 1; |
316 | list_add(&cur->fl_entry, &mm->fl_entry); | 273 | list_add(&cur->free_stack, &mm->free_stack); |
317 | } else { | 274 | } else { |
318 | list_del(&cur->ml_entry); | 275 | list_del(&cur->node_list); |
319 | spin_lock(&mm->unused_lock); | 276 | spin_lock(&mm->unused_lock); |
320 | if (mm->num_unused < MM_UNUSED_TARGET) { | 277 | if (mm->num_unused < MM_UNUSED_TARGET) { |
321 | list_add(&cur->fl_entry, &mm->unused_nodes); | 278 | list_add(&cur->free_stack, &mm->unused_nodes); |
322 | ++mm->num_unused; | 279 | ++mm->num_unused; |
323 | } else | 280 | } else |
324 | kfree(cur); | 281 | kfree(cur); |
@@ -328,40 +285,50 @@ void drm_mm_put_block(struct drm_mm_node *cur) | |||
328 | 285 | ||
329 | EXPORT_SYMBOL(drm_mm_put_block); | 286 | EXPORT_SYMBOL(drm_mm_put_block); |
330 | 287 | ||
288 | static int check_free_mm_node(struct drm_mm_node *entry, unsigned long size, | ||
289 | unsigned alignment) | ||
290 | { | ||
291 | unsigned wasted = 0; | ||
292 | |||
293 | if (entry->size < size) | ||
294 | return 0; | ||
295 | |||
296 | if (alignment) { | ||
297 | register unsigned tmp = entry->start % alignment; | ||
298 | if (tmp) | ||
299 | wasted = alignment - tmp; | ||
300 | } | ||
301 | |||
302 | if (entry->size >= size + wasted) { | ||
303 | return 1; | ||
304 | } | ||
305 | |||
306 | return 0; | ||
307 | } | ||
308 | |||
331 | struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, | 309 | struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, |
332 | unsigned long size, | 310 | unsigned long size, |
333 | unsigned alignment, int best_match) | 311 | unsigned alignment, int best_match) |
334 | { | 312 | { |
335 | struct list_head *list; | ||
336 | const struct list_head *free_stack = &mm->fl_entry; | ||
337 | struct drm_mm_node *entry; | 313 | struct drm_mm_node *entry; |
338 | struct drm_mm_node *best; | 314 | struct drm_mm_node *best; |
339 | unsigned long best_size; | 315 | unsigned long best_size; |
340 | unsigned wasted; | 316 | |
317 | BUG_ON(mm->scanned_blocks); | ||
341 | 318 | ||
342 | best = NULL; | 319 | best = NULL; |
343 | best_size = ~0UL; | 320 | best_size = ~0UL; |
344 | 321 | ||
345 | list_for_each(list, free_stack) { | 322 | list_for_each_entry(entry, &mm->free_stack, free_stack) { |
346 | entry = list_entry(list, struct drm_mm_node, fl_entry); | 323 | if (!check_free_mm_node(entry, size, alignment)) |
347 | wasted = 0; | ||
348 | |||
349 | if (entry->size < size) | ||
350 | continue; | 324 | continue; |
351 | 325 | ||
352 | if (alignment) { | 326 | if (!best_match) |
353 | register unsigned tmp = entry->start % alignment; | 327 | return entry; |
354 | if (tmp) | ||
355 | wasted += alignment - tmp; | ||
356 | } | ||
357 | 328 | ||
358 | if (entry->size >= size + wasted) { | 329 | if (entry->size < best_size) { |
359 | if (!best_match) | 330 | best = entry; |
360 | return entry; | 331 | best_size = entry->size; |
361 | if (entry->size < best_size) { | ||
362 | best = entry; | ||
363 | best_size = entry->size; | ||
364 | } | ||
365 | } | 332 | } |
366 | } | 333 | } |
367 | 334 | ||
@@ -376,43 +343,28 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, | |||
376 | unsigned long end, | 343 | unsigned long end, |
377 | int best_match) | 344 | int best_match) |
378 | { | 345 | { |
379 | struct list_head *list; | ||
380 | const struct list_head *free_stack = &mm->fl_entry; | ||
381 | struct drm_mm_node *entry; | 346 | struct drm_mm_node *entry; |
382 | struct drm_mm_node *best; | 347 | struct drm_mm_node *best; |
383 | unsigned long best_size; | 348 | unsigned long best_size; |
384 | unsigned wasted; | 349 | |
350 | BUG_ON(mm->scanned_blocks); | ||
385 | 351 | ||
386 | best = NULL; | 352 | best = NULL; |
387 | best_size = ~0UL; | 353 | best_size = ~0UL; |
388 | 354 | ||
389 | list_for_each(list, free_stack) { | 355 | list_for_each_entry(entry, &mm->free_stack, free_stack) { |
390 | entry = list_entry(list, struct drm_mm_node, fl_entry); | ||
391 | wasted = 0; | ||
392 | |||
393 | if (entry->size < size) | ||
394 | continue; | ||
395 | |||
396 | if (entry->start > end || (entry->start+entry->size) < start) | 356 | if (entry->start > end || (entry->start+entry->size) < start) |
397 | continue; | 357 | continue; |
398 | 358 | ||
399 | if (entry->start < start) | 359 | if (!check_free_mm_node(entry, size, alignment)) |
400 | wasted += start - entry->start; | 360 | continue; |
401 | 361 | ||
402 | if (alignment) { | 362 | if (!best_match) |
403 | register unsigned tmp = (entry->start + wasted) % alignment; | 363 | return entry; |
404 | if (tmp) | ||
405 | wasted += alignment - tmp; | ||
406 | } | ||
407 | 364 | ||
408 | if (entry->size >= size + wasted && | 365 | if (entry->size < best_size) { |
409 | (entry->start + wasted + size) <= end) { | 366 | best = entry; |
410 | if (!best_match) | 367 | best_size = entry->size; |
411 | return entry; | ||
412 | if (entry->size < best_size) { | ||
413 | best = entry; | ||
414 | best_size = entry->size; | ||
415 | } | ||
416 | } | 368 | } |
417 | } | 369 | } |
418 | 370 | ||
@@ -420,9 +372,161 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, | |||
420 | } | 372 | } |
421 | EXPORT_SYMBOL(drm_mm_search_free_in_range); | 373 | EXPORT_SYMBOL(drm_mm_search_free_in_range); |
422 | 374 | ||
375 | /** | ||
376 | * Initializa lru scanning. | ||
377 | * | ||
378 | * This simply sets up the scanning routines with the parameters for the desired | ||
379 | * hole. | ||
380 | * | ||
381 | * Warning: As long as the scan list is non-empty, no other operations than | ||
382 | * adding/removing nodes to/from the scan list are allowed. | ||
383 | */ | ||
384 | void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, | ||
385 | unsigned alignment) | ||
386 | { | ||
387 | mm->scan_alignment = alignment; | ||
388 | mm->scan_size = size; | ||
389 | mm->scanned_blocks = 0; | ||
390 | mm->scan_hit_start = 0; | ||
391 | mm->scan_hit_size = 0; | ||
392 | } | ||
393 | EXPORT_SYMBOL(drm_mm_init_scan); | ||
394 | |||
395 | /** | ||
396 | * Add a node to the scan list that might be freed to make space for the desired | ||
397 | * hole. | ||
398 | * | ||
399 | * Returns non-zero, if a hole has been found, zero otherwise. | ||
400 | */ | ||
401 | int drm_mm_scan_add_block(struct drm_mm_node *node) | ||
402 | { | ||
403 | struct drm_mm *mm = node->mm; | ||
404 | struct list_head *prev_free, *next_free; | ||
405 | struct drm_mm_node *prev_node, *next_node; | ||
406 | |||
407 | mm->scanned_blocks++; | ||
408 | |||
409 | prev_free = next_free = NULL; | ||
410 | |||
411 | BUG_ON(node->free); | ||
412 | node->scanned_block = 1; | ||
413 | node->free = 1; | ||
414 | |||
415 | if (node->node_list.prev != &mm->node_list) { | ||
416 | prev_node = list_entry(node->node_list.prev, struct drm_mm_node, | ||
417 | node_list); | ||
418 | |||
419 | if (prev_node->free) { | ||
420 | list_del(&prev_node->node_list); | ||
421 | |||
422 | node->start = prev_node->start; | ||
423 | node->size += prev_node->size; | ||
424 | |||
425 | prev_node->scanned_prev_free = 1; | ||
426 | |||
427 | prev_free = &prev_node->free_stack; | ||
428 | } | ||
429 | } | ||
430 | |||
431 | if (node->node_list.next != &mm->node_list) { | ||
432 | next_node = list_entry(node->node_list.next, struct drm_mm_node, | ||
433 | node_list); | ||
434 | |||
435 | if (next_node->free) { | ||
436 | list_del(&next_node->node_list); | ||
437 | |||
438 | node->size += next_node->size; | ||
439 | |||
440 | next_node->scanned_next_free = 1; | ||
441 | |||
442 | next_free = &next_node->free_stack; | ||
443 | } | ||
444 | } | ||
445 | |||
446 | /* The free_stack list is not used for allocated objects, so these two | ||
447 | * pointers can be abused (as long as no allocations in this memory | ||
448 | * manager happens). */ | ||
449 | node->free_stack.prev = prev_free; | ||
450 | node->free_stack.next = next_free; | ||
451 | |||
452 | if (check_free_mm_node(node, mm->scan_size, mm->scan_alignment)) { | ||
453 | mm->scan_hit_start = node->start; | ||
454 | mm->scan_hit_size = node->size; | ||
455 | |||
456 | return 1; | ||
457 | } | ||
458 | |||
459 | return 0; | ||
460 | } | ||
461 | EXPORT_SYMBOL(drm_mm_scan_add_block); | ||
462 | |||
463 | /** | ||
464 | * Remove a node from the scan list. | ||
465 | * | ||
466 | * Nodes _must_ be removed in the exact same order from the scan list as they | ||
467 | * have been added, otherwise the internal state of the memory manager will be | ||
468 | * corrupted. | ||
469 | * | ||
470 | * When the scan list is empty, the selected memory nodes can be freed. An | ||
471 | * immediatly following drm_mm_search_free with best_match = 0 will then return | ||
472 | * the just freed block (because its at the top of the free_stack list). | ||
473 | * | ||
474 | * Returns one if this block should be evicted, zero otherwise. Will always | ||
475 | * return zero when no hole has been found. | ||
476 | */ | ||
477 | int drm_mm_scan_remove_block(struct drm_mm_node *node) | ||
478 | { | ||
479 | struct drm_mm *mm = node->mm; | ||
480 | struct drm_mm_node *prev_node, *next_node; | ||
481 | |||
482 | mm->scanned_blocks--; | ||
483 | |||
484 | BUG_ON(!node->scanned_block); | ||
485 | node->scanned_block = 0; | ||
486 | node->free = 0; | ||
487 | |||
488 | prev_node = list_entry(node->free_stack.prev, struct drm_mm_node, | ||
489 | free_stack); | ||
490 | next_node = list_entry(node->free_stack.next, struct drm_mm_node, | ||
491 | free_stack); | ||
492 | |||
493 | if (prev_node) { | ||
494 | BUG_ON(!prev_node->scanned_prev_free); | ||
495 | prev_node->scanned_prev_free = 0; | ||
496 | |||
497 | list_add_tail(&prev_node->node_list, &node->node_list); | ||
498 | |||
499 | node->start = prev_node->start + prev_node->size; | ||
500 | node->size -= prev_node->size; | ||
501 | } | ||
502 | |||
503 | if (next_node) { | ||
504 | BUG_ON(!next_node->scanned_next_free); | ||
505 | next_node->scanned_next_free = 0; | ||
506 | |||
507 | list_add(&next_node->node_list, &node->node_list); | ||
508 | |||
509 | node->size -= next_node->size; | ||
510 | } | ||
511 | |||
512 | INIT_LIST_HEAD(&node->free_stack); | ||
513 | |||
514 | /* Only need to check for containement because start&size for the | ||
515 | * complete resulting free block (not just the desired part) is | ||
516 | * stored. */ | ||
517 | if (node->start >= mm->scan_hit_start && | ||
518 | node->start + node->size | ||
519 | <= mm->scan_hit_start + mm->scan_hit_size) { | ||
520 | return 1; | ||
521 | } | ||
522 | |||
523 | return 0; | ||
524 | } | ||
525 | EXPORT_SYMBOL(drm_mm_scan_remove_block); | ||
526 | |||
423 | int drm_mm_clean(struct drm_mm * mm) | 527 | int drm_mm_clean(struct drm_mm * mm) |
424 | { | 528 | { |
425 | struct list_head *head = &mm->ml_entry; | 529 | struct list_head *head = &mm->node_list; |
426 | 530 | ||
427 | return (head->next->next == head); | 531 | return (head->next->next == head); |
428 | } | 532 | } |
@@ -430,10 +534,11 @@ EXPORT_SYMBOL(drm_mm_clean); | |||
430 | 534 | ||
431 | int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) | 535 | int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) |
432 | { | 536 | { |
433 | INIT_LIST_HEAD(&mm->ml_entry); | 537 | INIT_LIST_HEAD(&mm->node_list); |
434 | INIT_LIST_HEAD(&mm->fl_entry); | 538 | INIT_LIST_HEAD(&mm->free_stack); |
435 | INIT_LIST_HEAD(&mm->unused_nodes); | 539 | INIT_LIST_HEAD(&mm->unused_nodes); |
436 | mm->num_unused = 0; | 540 | mm->num_unused = 0; |
541 | mm->scanned_blocks = 0; | ||
437 | spin_lock_init(&mm->unused_lock); | 542 | spin_lock_init(&mm->unused_lock); |
438 | 543 | ||
439 | return drm_mm_create_tail_node(mm, start, size, 0); | 544 | return drm_mm_create_tail_node(mm, start, size, 0); |
@@ -442,25 +547,25 @@ EXPORT_SYMBOL(drm_mm_init); | |||
442 | 547 | ||
443 | void drm_mm_takedown(struct drm_mm * mm) | 548 | void drm_mm_takedown(struct drm_mm * mm) |
444 | { | 549 | { |
445 | struct list_head *bnode = mm->fl_entry.next; | 550 | struct list_head *bnode = mm->free_stack.next; |
446 | struct drm_mm_node *entry; | 551 | struct drm_mm_node *entry; |
447 | struct drm_mm_node *next; | 552 | struct drm_mm_node *next; |
448 | 553 | ||
449 | entry = list_entry(bnode, struct drm_mm_node, fl_entry); | 554 | entry = list_entry(bnode, struct drm_mm_node, free_stack); |
450 | 555 | ||
451 | if (entry->ml_entry.next != &mm->ml_entry || | 556 | if (entry->node_list.next != &mm->node_list || |
452 | entry->fl_entry.next != &mm->fl_entry) { | 557 | entry->free_stack.next != &mm->free_stack) { |
453 | DRM_ERROR("Memory manager not clean. Delaying takedown\n"); | 558 | DRM_ERROR("Memory manager not clean. Delaying takedown\n"); |
454 | return; | 559 | return; |
455 | } | 560 | } |
456 | 561 | ||
457 | list_del(&entry->fl_entry); | 562 | list_del(&entry->free_stack); |
458 | list_del(&entry->ml_entry); | 563 | list_del(&entry->node_list); |
459 | kfree(entry); | 564 | kfree(entry); |
460 | 565 | ||
461 | spin_lock(&mm->unused_lock); | 566 | spin_lock(&mm->unused_lock); |
462 | list_for_each_entry_safe(entry, next, &mm->unused_nodes, fl_entry) { | 567 | list_for_each_entry_safe(entry, next, &mm->unused_nodes, free_stack) { |
463 | list_del(&entry->fl_entry); | 568 | list_del(&entry->free_stack); |
464 | kfree(entry); | 569 | kfree(entry); |
465 | --mm->num_unused; | 570 | --mm->num_unused; |
466 | } | 571 | } |
@@ -475,7 +580,7 @@ void drm_mm_debug_table(struct drm_mm *mm, const char *prefix) | |||
475 | struct drm_mm_node *entry; | 580 | struct drm_mm_node *entry; |
476 | int total_used = 0, total_free = 0, total = 0; | 581 | int total_used = 0, total_free = 0, total = 0; |
477 | 582 | ||
478 | list_for_each_entry(entry, &mm->ml_entry, ml_entry) { | 583 | list_for_each_entry(entry, &mm->node_list, node_list) { |
479 | printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8ld: %s\n", | 584 | printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8ld: %s\n", |
480 | prefix, entry->start, entry->start + entry->size, | 585 | prefix, entry->start, entry->start + entry->size, |
481 | entry->size, entry->free ? "free" : "used"); | 586 | entry->size, entry->free ? "free" : "used"); |
@@ -496,7 +601,7 @@ int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) | |||
496 | struct drm_mm_node *entry; | 601 | struct drm_mm_node *entry; |
497 | int total_used = 0, total_free = 0, total = 0; | 602 | int total_used = 0, total_free = 0, total = 0; |
498 | 603 | ||
499 | list_for_each_entry(entry, &mm->ml_entry, ml_entry) { | 604 | list_for_each_entry(entry, &mm->node_list, node_list) { |
500 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: %s\n", entry->start, entry->start + entry->size, entry->size, entry->free ? "free" : "used"); | 605 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: %s\n", entry->start, entry->start + entry->size, entry->size, entry->free ? "free" : "used"); |
501 | total += entry->size; | 606 | total += entry->size; |
502 | if (entry->free) | 607 | if (entry->free) |
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 2ea9ad4a8d69..e20f78b542a7 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c | |||
@@ -124,4 +124,147 @@ void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah) | |||
124 | 124 | ||
125 | EXPORT_SYMBOL(drm_pci_free); | 125 | EXPORT_SYMBOL(drm_pci_free); |
126 | 126 | ||
127 | #ifdef CONFIG_PCI | ||
128 | /** | ||
129 | * Register. | ||
130 | * | ||
131 | * \param pdev - PCI device structure | ||
132 | * \param ent entry from the PCI ID table with device type flags | ||
133 | * \return zero on success or a negative number on failure. | ||
134 | * | ||
135 | * Attempt to gets inter module "drm" information. If we are first | ||
136 | * then register the character device and inter module information. | ||
137 | * Try and register, if we fail to register, backout previous work. | ||
138 | */ | ||
139 | int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | ||
140 | struct drm_driver *driver) | ||
141 | { | ||
142 | struct drm_device *dev; | ||
143 | int ret; | ||
144 | |||
145 | DRM_DEBUG("\n"); | ||
146 | |||
147 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
148 | if (!dev) | ||
149 | return -ENOMEM; | ||
150 | |||
151 | ret = pci_enable_device(pdev); | ||
152 | if (ret) | ||
153 | goto err_g1; | ||
154 | |||
155 | pci_set_master(pdev); | ||
156 | |||
157 | dev->pdev = pdev; | ||
158 | dev->dev = &pdev->dev; | ||
159 | |||
160 | dev->pci_device = pdev->device; | ||
161 | dev->pci_vendor = pdev->vendor; | ||
162 | |||
163 | #ifdef __alpha__ | ||
164 | dev->hose = pdev->sysdata; | ||
165 | #endif | ||
166 | |||
167 | if ((ret = drm_fill_in_dev(dev, ent, driver))) { | ||
168 | printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); | ||
169 | goto err_g2; | ||
170 | } | ||
171 | |||
172 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
173 | pci_set_drvdata(pdev, dev); | ||
174 | ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); | ||
175 | if (ret) | ||
176 | goto err_g2; | ||
177 | } | ||
178 | |||
179 | if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) | ||
180 | goto err_g3; | ||
181 | |||
182 | if (dev->driver->load) { | ||
183 | ret = dev->driver->load(dev, ent->driver_data); | ||
184 | if (ret) | ||
185 | goto err_g4; | ||
186 | } | ||
187 | |||
188 | /* setup the grouping for the legacy output */ | ||
189 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
190 | ret = drm_mode_group_init_legacy_group(dev, | ||
191 | &dev->primary->mode_group); | ||
192 | if (ret) | ||
193 | goto err_g4; | ||
194 | } | ||
195 | |||
196 | list_add_tail(&dev->driver_item, &driver->device_list); | ||
197 | |||
198 | DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", | ||
199 | driver->name, driver->major, driver->minor, driver->patchlevel, | ||
200 | driver->date, pci_name(pdev), dev->primary->index); | ||
201 | |||
202 | return 0; | ||
203 | |||
204 | err_g4: | ||
205 | drm_put_minor(&dev->primary); | ||
206 | err_g3: | ||
207 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
208 | drm_put_minor(&dev->control); | ||
209 | err_g2: | ||
210 | pci_disable_device(pdev); | ||
211 | err_g1: | ||
212 | kfree(dev); | ||
213 | return ret; | ||
214 | } | ||
215 | EXPORT_SYMBOL(drm_get_pci_dev); | ||
216 | |||
217 | /** | ||
218 | * PCI device initialization. Called via drm_init at module load time, | ||
219 | * | ||
220 | * \return zero on success or a negative number on failure. | ||
221 | * | ||
222 | * Initializes a drm_device structures,registering the | ||
223 | * stubs and initializing the AGP device. | ||
224 | * | ||
225 | * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and | ||
226 | * after the initialization for driver customization. | ||
227 | */ | ||
228 | int drm_pci_init(struct drm_driver *driver) | ||
229 | { | ||
230 | struct pci_dev *pdev = NULL; | ||
231 | const struct pci_device_id *pid; | ||
232 | int i; | ||
233 | |||
234 | if (driver->driver_features & DRIVER_MODESET) | ||
235 | return pci_register_driver(&driver->pci_driver); | ||
236 | |||
237 | /* If not using KMS, fall back to stealth mode manual scanning. */ | ||
238 | for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { | ||
239 | pid = &driver->pci_driver.id_table[i]; | ||
240 | |||
241 | /* Loop around setting up a DRM device for each PCI device | ||
242 | * matching our ID and device class. If we had the internal | ||
243 | * function that pci_get_subsys and pci_get_class used, we'd | ||
244 | * be able to just pass pid in instead of doing a two-stage | ||
245 | * thing. | ||
246 | */ | ||
247 | pdev = NULL; | ||
248 | while ((pdev = | ||
249 | pci_get_subsys(pid->vendor, pid->device, pid->subvendor, | ||
250 | pid->subdevice, pdev)) != NULL) { | ||
251 | if ((pdev->class & pid->class_mask) != pid->class) | ||
252 | continue; | ||
253 | |||
254 | /* stealth mode requires a manual probe */ | ||
255 | pci_dev_get(pdev); | ||
256 | drm_get_pci_dev(pdev, pid, driver); | ||
257 | } | ||
258 | } | ||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | #else | ||
263 | |||
264 | int drm_pci_init(struct drm_driver *driver) | ||
265 | { | ||
266 | return -1; | ||
267 | } | ||
268 | |||
269 | #endif | ||
127 | /*@}*/ | 270 | /*@}*/ |
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c new file mode 100644 index 000000000000..460e9a3afa8d --- /dev/null +++ b/drivers/gpu/drm/drm_platform.c | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * Derived from drm_pci.c | ||
3 | * | ||
4 | * Copyright 2003 José Fonseca. | ||
5 | * Copyright 2003 Leif Delgass. | ||
6 | * Copyright (c) 2009, Code Aurora Forum. | ||
7 | * All Rights Reserved. | ||
8 | * | ||
9 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
10 | * copy of this software and associated documentation files (the "Software"), | ||
11 | * to deal in the Software without restriction, including without limitation | ||
12 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
13 | * and/or sell copies of the Software, and to permit persons to whom the | ||
14 | * Software is furnished to do so, subject to the following conditions: | ||
15 | * | ||
16 | * The above copyright notice and this permission notice (including the next | ||
17 | * paragraph) shall be included in all copies or substantial portions of the | ||
18 | * Software. | ||
19 | * | ||
20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
23 | * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
24 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
25 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
26 | */ | ||
27 | |||
28 | #include "drmP.h" | ||
29 | |||
30 | /** | ||
31 | * Register. | ||
32 | * | ||
33 | * \param platdev - Platform device struture | ||
34 | * \return zero on success or a negative number on failure. | ||
35 | * | ||
36 | * Attempt to gets inter module "drm" information. If we are first | ||
37 | * then register the character device and inter module information. | ||
38 | * Try and register, if we fail to register, backout previous work. | ||
39 | */ | ||
40 | |||
41 | int drm_get_platform_dev(struct platform_device *platdev, | ||
42 | struct drm_driver *driver) | ||
43 | { | ||
44 | struct drm_device *dev; | ||
45 | int ret; | ||
46 | |||
47 | DRM_DEBUG("\n"); | ||
48 | |||
49 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
50 | if (!dev) | ||
51 | return -ENOMEM; | ||
52 | |||
53 | dev->platformdev = platdev; | ||
54 | dev->dev = &platdev->dev; | ||
55 | |||
56 | ret = drm_fill_in_dev(dev, NULL, driver); | ||
57 | |||
58 | if (ret) { | ||
59 | printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); | ||
60 | goto err_g1; | ||
61 | } | ||
62 | |||
63 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
64 | dev_set_drvdata(&platdev->dev, dev); | ||
65 | ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); | ||
66 | if (ret) | ||
67 | goto err_g1; | ||
68 | } | ||
69 | |||
70 | ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); | ||
71 | if (ret) | ||
72 | goto err_g2; | ||
73 | |||
74 | if (dev->driver->load) { | ||
75 | ret = dev->driver->load(dev, 0); | ||
76 | if (ret) | ||
77 | goto err_g3; | ||
78 | } | ||
79 | |||
80 | /* setup the grouping for the legacy output */ | ||
81 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
82 | ret = drm_mode_group_init_legacy_group(dev, | ||
83 | &dev->primary->mode_group); | ||
84 | if (ret) | ||
85 | goto err_g3; | ||
86 | } | ||
87 | |||
88 | list_add_tail(&dev->driver_item, &driver->device_list); | ||
89 | |||
90 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", | ||
91 | driver->name, driver->major, driver->minor, driver->patchlevel, | ||
92 | driver->date, dev->primary->index); | ||
93 | |||
94 | return 0; | ||
95 | |||
96 | err_g3: | ||
97 | drm_put_minor(&dev->primary); | ||
98 | err_g2: | ||
99 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
100 | drm_put_minor(&dev->control); | ||
101 | err_g1: | ||
102 | kfree(dev); | ||
103 | return ret; | ||
104 | } | ||
105 | EXPORT_SYMBOL(drm_get_platform_dev); | ||
106 | |||
107 | /** | ||
108 | * Platform device initialization. Called via drm_init at module load time, | ||
109 | * | ||
110 | * \return zero on success or a negative number on failure. | ||
111 | * | ||
112 | * Initializes a drm_device structures,registering the | ||
113 | * stubs | ||
114 | * | ||
115 | * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and | ||
116 | * after the initialization for driver customization. | ||
117 | */ | ||
118 | |||
119 | int drm_platform_init(struct drm_driver *driver) | ||
120 | { | ||
121 | return drm_get_platform_dev(driver->platform_device, driver); | ||
122 | } | ||
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index a0c365f2e521..d1ad57450df1 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -156,6 +156,9 @@ static void drm_master_destroy(struct kref *kref) | |||
156 | master->unique_len = 0; | 156 | master->unique_len = 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | kfree(dev->devname); | ||
160 | dev->devname = NULL; | ||
161 | |||
159 | list_for_each_entry_safe(pt, next, &master->magicfree, head) { | 162 | list_for_each_entry_safe(pt, next, &master->magicfree, head) { |
160 | list_del(&pt->head); | 163 | list_del(&pt->head); |
161 | drm_ht_remove_item(&master->magiclist, &pt->hash_item); | 164 | drm_ht_remove_item(&master->magiclist, &pt->hash_item); |
@@ -224,7 +227,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data, | |||
224 | return 0; | 227 | return 0; |
225 | } | 228 | } |
226 | 229 | ||
227 | static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, | 230 | int drm_fill_in_dev(struct drm_device *dev, |
228 | const struct pci_device_id *ent, | 231 | const struct pci_device_id *ent, |
229 | struct drm_driver *driver) | 232 | struct drm_driver *driver) |
230 | { | 233 | { |
@@ -245,14 +248,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, | |||
245 | 248 | ||
246 | idr_init(&dev->drw_idr); | 249 | idr_init(&dev->drw_idr); |
247 | 250 | ||
248 | dev->pdev = pdev; | ||
249 | dev->pci_device = pdev->device; | ||
250 | dev->pci_vendor = pdev->vendor; | ||
251 | |||
252 | #ifdef __alpha__ | ||
253 | dev->hose = pdev->sysdata; | ||
254 | #endif | ||
255 | |||
256 | if (drm_ht_create(&dev->map_hash, 12)) { | 251 | if (drm_ht_create(&dev->map_hash, 12)) { |
257 | return -ENOMEM; | 252 | return -ENOMEM; |
258 | } | 253 | } |
@@ -321,7 +316,7 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, | |||
321 | * create the proc init entry via proc_init(). This routines assigns | 316 | * create the proc init entry via proc_init(). This routines assigns |
322 | * minor numbers to secondary heads of multi-headed cards | 317 | * minor numbers to secondary heads of multi-headed cards |
323 | */ | 318 | */ |
324 | static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) | 319 | int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) |
325 | { | 320 | { |
326 | struct drm_minor *new_minor; | 321 | struct drm_minor *new_minor; |
327 | int ret; | 322 | int ret; |
@@ -388,83 +383,6 @@ err_idr: | |||
388 | } | 383 | } |
389 | 384 | ||
390 | /** | 385 | /** |
391 | * Register. | ||
392 | * | ||
393 | * \param pdev - PCI device structure | ||
394 | * \param ent entry from the PCI ID table with device type flags | ||
395 | * \return zero on success or a negative number on failure. | ||
396 | * | ||
397 | * Attempt to gets inter module "drm" information. If we are first | ||
398 | * then register the character device and inter module information. | ||
399 | * Try and register, if we fail to register, backout previous work. | ||
400 | */ | ||
401 | int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | ||
402 | struct drm_driver *driver) | ||
403 | { | ||
404 | struct drm_device *dev; | ||
405 | int ret; | ||
406 | |||
407 | DRM_DEBUG("\n"); | ||
408 | |||
409 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
410 | if (!dev) | ||
411 | return -ENOMEM; | ||
412 | |||
413 | ret = pci_enable_device(pdev); | ||
414 | if (ret) | ||
415 | goto err_g1; | ||
416 | |||
417 | pci_set_master(pdev); | ||
418 | if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) { | ||
419 | printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); | ||
420 | goto err_g2; | ||
421 | } | ||
422 | |||
423 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
424 | pci_set_drvdata(pdev, dev); | ||
425 | ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); | ||
426 | if (ret) | ||
427 | goto err_g2; | ||
428 | } | ||
429 | |||
430 | if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) | ||
431 | goto err_g3; | ||
432 | |||
433 | if (dev->driver->load) { | ||
434 | ret = dev->driver->load(dev, ent->driver_data); | ||
435 | if (ret) | ||
436 | goto err_g4; | ||
437 | } | ||
438 | |||
439 | /* setup the grouping for the legacy output */ | ||
440 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
441 | ret = drm_mode_group_init_legacy_group(dev, &dev->primary->mode_group); | ||
442 | if (ret) | ||
443 | goto err_g4; | ||
444 | } | ||
445 | |||
446 | list_add_tail(&dev->driver_item, &driver->device_list); | ||
447 | |||
448 | DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", | ||
449 | driver->name, driver->major, driver->minor, driver->patchlevel, | ||
450 | driver->date, pci_name(pdev), dev->primary->index); | ||
451 | |||
452 | return 0; | ||
453 | |||
454 | err_g4: | ||
455 | drm_put_minor(&dev->primary); | ||
456 | err_g3: | ||
457 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
458 | drm_put_minor(&dev->control); | ||
459 | err_g2: | ||
460 | pci_disable_device(pdev); | ||
461 | err_g1: | ||
462 | kfree(dev); | ||
463 | return ret; | ||
464 | } | ||
465 | EXPORT_SYMBOL(drm_get_dev); | ||
466 | |||
467 | /** | ||
468 | * Put a secondary minor number. | 386 | * Put a secondary minor number. |
469 | * | 387 | * |
470 | * \param sec_minor - structure to be released | 388 | * \param sec_minor - structure to be released |
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 101d381e9d86..86118a742231 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -489,7 +489,8 @@ int drm_sysfs_device_add(struct drm_minor *minor) | |||
489 | int err; | 489 | int err; |
490 | char *minor_str; | 490 | char *minor_str; |
491 | 491 | ||
492 | minor->kdev.parent = &minor->dev->pdev->dev; | 492 | minor->kdev.parent = minor->dev->dev; |
493 | |||
493 | minor->kdev.class = drm_class; | 494 | minor->kdev.class = drm_class; |
494 | minor->kdev.release = drm_sysfs_device_release; | 495 | minor->kdev.release = drm_sysfs_device_release; |
495 | minor->kdev.devt = minor->device; | 496 | minor->kdev.devt = minor->device; |
diff --git a/drivers/gpu/drm/drm_trace.h b/drivers/gpu/drm/drm_trace.h new file mode 100644 index 000000000000..03ea964aa604 --- /dev/null +++ b/drivers/gpu/drm/drm_trace.h | |||
@@ -0,0 +1,66 @@ | |||
1 | #if !defined(_DRM_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) | ||
2 | #define _DRM_TRACE_H_ | ||
3 | |||
4 | #include <linux/stringify.h> | ||
5 | #include <linux/types.h> | ||
6 | #include <linux/tracepoint.h> | ||
7 | |||
8 | #undef TRACE_SYSTEM | ||
9 | #define TRACE_SYSTEM drm | ||
10 | #define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) | ||
11 | #define TRACE_INCLUDE_FILE drm_trace | ||
12 | |||
13 | TRACE_EVENT(drm_vblank_event, | ||
14 | TP_PROTO(int crtc, unsigned int seq), | ||
15 | TP_ARGS(crtc, seq), | ||
16 | TP_STRUCT__entry( | ||
17 | __field(int, crtc) | ||
18 | __field(unsigned int, seq) | ||
19 | ), | ||
20 | TP_fast_assign( | ||
21 | __entry->crtc = crtc; | ||
22 | __entry->seq = seq; | ||
23 | ), | ||
24 | TP_printk("crtc=%d, seq=%d", __entry->crtc, __entry->seq) | ||
25 | ); | ||
26 | |||
27 | TRACE_EVENT(drm_vblank_event_queued, | ||
28 | TP_PROTO(pid_t pid, int crtc, unsigned int seq), | ||
29 | TP_ARGS(pid, crtc, seq), | ||
30 | TP_STRUCT__entry( | ||
31 | __field(pid_t, pid) | ||
32 | __field(int, crtc) | ||
33 | __field(unsigned int, seq) | ||
34 | ), | ||
35 | TP_fast_assign( | ||
36 | __entry->pid = pid; | ||
37 | __entry->crtc = crtc; | ||
38 | __entry->seq = seq; | ||
39 | ), | ||
40 | TP_printk("pid=%d, crtc=%d, seq=%d", __entry->pid, __entry->crtc, \ | ||
41 | __entry->seq) | ||
42 | ); | ||
43 | |||
44 | TRACE_EVENT(drm_vblank_event_delivered, | ||
45 | TP_PROTO(pid_t pid, int crtc, unsigned int seq), | ||
46 | TP_ARGS(pid, crtc, seq), | ||
47 | TP_STRUCT__entry( | ||
48 | __field(pid_t, pid) | ||
49 | __field(int, crtc) | ||
50 | __field(unsigned int, seq) | ||
51 | ), | ||
52 | TP_fast_assign( | ||
53 | __entry->pid = pid; | ||
54 | __entry->crtc = crtc; | ||
55 | __entry->seq = seq; | ||
56 | ), | ||
57 | TP_printk("pid=%d, crtc=%d, seq=%d", __entry->pid, __entry->crtc, \ | ||
58 | __entry->seq) | ||
59 | ); | ||
60 | |||
61 | #endif /* _DRM_TRACE_H_ */ | ||
62 | |||
63 | /* This part must be outside protection */ | ||
64 | #undef TRACE_INCLUDE_PATH | ||
65 | #define TRACE_INCLUDE_PATH . | ||
66 | #include <trace/define_trace.h> | ||
diff --git a/drivers/gpu/drm/drm_trace_points.c b/drivers/gpu/drm/drm_trace_points.c new file mode 100644 index 000000000000..0d0eb90864ae --- /dev/null +++ b/drivers/gpu/drm/drm_trace_points.c | |||
@@ -0,0 +1,4 @@ | |||
1 | #include "drmP.h" | ||
2 | |||
3 | #define CREATE_TRACE_POINTS | ||
4 | #include "drm_trace.h" | ||
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index c3b13fb41d0c..3778360eceea 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c | |||
@@ -61,7 +61,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) | |||
61 | tmp = pgprot_writecombine(tmp); | 61 | tmp = pgprot_writecombine(tmp); |
62 | else | 62 | else |
63 | tmp = pgprot_noncached(tmp); | 63 | tmp = pgprot_noncached(tmp); |
64 | #elif defined(__sparc__) | 64 | #elif defined(__sparc__) || defined(__arm__) |
65 | tmp = pgprot_noncached(tmp); | 65 | tmp = pgprot_noncached(tmp); |
66 | #endif | 66 | #endif |
67 | return tmp; | 67 | return tmp; |
@@ -601,6 +601,7 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) | |||
601 | } | 601 | } |
602 | 602 | ||
603 | switch (map->type) { | 603 | switch (map->type) { |
604 | #if !defined(__arm__) | ||
604 | case _DRM_AGP: | 605 | case _DRM_AGP: |
605 | if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) { | 606 | if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) { |
606 | /* | 607 | /* |
@@ -615,20 +616,31 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) | |||
615 | break; | 616 | break; |
616 | } | 617 | } |
617 | /* fall through to _DRM_FRAME_BUFFER... */ | 618 | /* fall through to _DRM_FRAME_BUFFER... */ |
619 | #endif | ||
618 | case _DRM_FRAME_BUFFER: | 620 | case _DRM_FRAME_BUFFER: |
619 | case _DRM_REGISTERS: | 621 | case _DRM_REGISTERS: |
620 | offset = dev->driver->get_reg_ofs(dev); | 622 | offset = dev->driver->get_reg_ofs(dev); |
621 | vma->vm_flags |= VM_IO; /* not in core dump */ | 623 | vma->vm_flags |= VM_IO; /* not in core dump */ |
622 | vma->vm_page_prot = drm_io_prot(map->type, vma); | 624 | vma->vm_page_prot = drm_io_prot(map->type, vma); |
625 | #if !defined(__arm__) | ||
623 | if (io_remap_pfn_range(vma, vma->vm_start, | 626 | if (io_remap_pfn_range(vma, vma->vm_start, |
624 | (map->offset + offset) >> PAGE_SHIFT, | 627 | (map->offset + offset) >> PAGE_SHIFT, |
625 | vma->vm_end - vma->vm_start, | 628 | vma->vm_end - vma->vm_start, |
626 | vma->vm_page_prot)) | 629 | vma->vm_page_prot)) |
627 | return -EAGAIN; | 630 | return -EAGAIN; |
631 | #else | ||
632 | if (remap_pfn_range(vma, vma->vm_start, | ||
633 | (map->offset + offset) >> PAGE_SHIFT, | ||
634 | vma->vm_end - vma->vm_start, | ||
635 | vma->vm_page_prot)) | ||
636 | return -EAGAIN; | ||
637 | #endif | ||
638 | |||
628 | DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," | 639 | DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," |
629 | " offset = 0x%llx\n", | 640 | " offset = 0x%llx\n", |
630 | map->type, | 641 | map->type, |
631 | vma->vm_start, vma->vm_end, (unsigned long long)(map->offset + offset)); | 642 | vma->vm_start, vma->vm_end, (unsigned long long)(map->offset + offset)); |
643 | |||
632 | vma->vm_ops = &drm_vm_ops; | 644 | vma->vm_ops = &drm_vm_ops; |
633 | break; | 645 | break; |
634 | case _DRM_CONSISTENT: | 646 | case _DRM_CONSISTENT: |
diff --git a/drivers/gpu/drm/i2c/Makefile b/drivers/gpu/drm/i2c/Makefile index 6d2abaf35ba2..92862563e7ee 100644 --- a/drivers/gpu/drm/i2c/Makefile +++ b/drivers/gpu/drm/i2c/Makefile | |||
@@ -2,3 +2,6 @@ ccflags-y := -Iinclude/drm | |||
2 | 2 | ||
3 | ch7006-y := ch7006_drv.o ch7006_mode.o | 3 | ch7006-y := ch7006_drv.o ch7006_mode.o |
4 | obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o | 4 | obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o |
5 | |||
6 | sil164-y := sil164_drv.o | ||
7 | obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o | ||
diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c index 81681a07a806..833b35f44a77 100644 --- a/drivers/gpu/drm/i2c/ch7006_drv.c +++ b/drivers/gpu/drm/i2c/ch7006_drv.c | |||
@@ -33,7 +33,7 @@ static void ch7006_encoder_set_config(struct drm_encoder *encoder, | |||
33 | { | 33 | { |
34 | struct ch7006_priv *priv = to_ch7006_priv(encoder); | 34 | struct ch7006_priv *priv = to_ch7006_priv(encoder); |
35 | 35 | ||
36 | priv->params = params; | 36 | priv->params = *(struct ch7006_encoder_params *)params; |
37 | } | 37 | } |
38 | 38 | ||
39 | static void ch7006_encoder_destroy(struct drm_encoder *encoder) | 39 | static void ch7006_encoder_destroy(struct drm_encoder *encoder) |
@@ -114,7 +114,7 @@ static void ch7006_encoder_mode_set(struct drm_encoder *encoder, | |||
114 | { | 114 | { |
115 | struct i2c_client *client = drm_i2c_encoder_get_client(encoder); | 115 | struct i2c_client *client = drm_i2c_encoder_get_client(encoder); |
116 | struct ch7006_priv *priv = to_ch7006_priv(encoder); | 116 | struct ch7006_priv *priv = to_ch7006_priv(encoder); |
117 | struct ch7006_encoder_params *params = priv->params; | 117 | struct ch7006_encoder_params *params = &priv->params; |
118 | struct ch7006_state *state = &priv->state; | 118 | struct ch7006_state *state = &priv->state; |
119 | uint8_t *regs = state->regs; | 119 | uint8_t *regs = state->regs; |
120 | struct ch7006_mode *mode = priv->mode; | 120 | struct ch7006_mode *mode = priv->mode; |
@@ -428,6 +428,22 @@ static int ch7006_remove(struct i2c_client *client) | |||
428 | return 0; | 428 | return 0; |
429 | } | 429 | } |
430 | 430 | ||
431 | static int ch7006_suspend(struct i2c_client *client, pm_message_t mesg) | ||
432 | { | ||
433 | ch7006_dbg(client, "\n"); | ||
434 | |||
435 | return 0; | ||
436 | } | ||
437 | |||
438 | static int ch7006_resume(struct i2c_client *client) | ||
439 | { | ||
440 | ch7006_dbg(client, "\n"); | ||
441 | |||
442 | ch7006_write(client, 0x3d, 0x0); | ||
443 | |||
444 | return 0; | ||
445 | } | ||
446 | |||
431 | static int ch7006_encoder_init(struct i2c_client *client, | 447 | static int ch7006_encoder_init(struct i2c_client *client, |
432 | struct drm_device *dev, | 448 | struct drm_device *dev, |
433 | struct drm_encoder_slave *encoder) | 449 | struct drm_encoder_slave *encoder) |
@@ -487,6 +503,8 @@ static struct drm_i2c_encoder_driver ch7006_driver = { | |||
487 | .i2c_driver = { | 503 | .i2c_driver = { |
488 | .probe = ch7006_probe, | 504 | .probe = ch7006_probe, |
489 | .remove = ch7006_remove, | 505 | .remove = ch7006_remove, |
506 | .suspend = ch7006_suspend, | ||
507 | .resume = ch7006_resume, | ||
490 | 508 | ||
491 | .driver = { | 509 | .driver = { |
492 | .name = "ch7006", | 510 | .name = "ch7006", |
diff --git a/drivers/gpu/drm/i2c/ch7006_priv.h b/drivers/gpu/drm/i2c/ch7006_priv.h index b06d3d93d8ac..1c6d2e3bd96f 100644 --- a/drivers/gpu/drm/i2c/ch7006_priv.h +++ b/drivers/gpu/drm/i2c/ch7006_priv.h | |||
@@ -77,7 +77,7 @@ struct ch7006_state { | |||
77 | }; | 77 | }; |
78 | 78 | ||
79 | struct ch7006_priv { | 79 | struct ch7006_priv { |
80 | struct ch7006_encoder_params *params; | 80 | struct ch7006_encoder_params params; |
81 | struct ch7006_mode *mode; | 81 | struct ch7006_mode *mode; |
82 | 82 | ||
83 | struct ch7006_state state; | 83 | struct ch7006_state state; |
diff --git a/drivers/gpu/drm/i2c/sil164_drv.c b/drivers/gpu/drm/i2c/sil164_drv.c new file mode 100644 index 000000000000..0b6773290c08 --- /dev/null +++ b/drivers/gpu/drm/i2c/sil164_drv.c | |||
@@ -0,0 +1,462 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Francisco Jerez. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining | ||
6 | * a copy of this software and associated documentation files (the | ||
7 | * "Software"), to deal in the Software without restriction, including | ||
8 | * without limitation the rights to use, copy, modify, merge, publish, | ||
9 | * distribute, sublicense, and/or sell copies of the Software, and to | ||
10 | * permit persons to whom the Software is furnished to do so, subject to | ||
11 | * the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice (including the | ||
14 | * next paragraph) shall be included in all copies or substantial | ||
15 | * portions of the Software. | ||
16 | * | ||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
20 | * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||
21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include "drmP.h" | ||
28 | #include "drm_crtc_helper.h" | ||
29 | #include "drm_encoder_slave.h" | ||
30 | #include "i2c/sil164.h" | ||
31 | |||
32 | struct sil164_priv { | ||
33 | struct sil164_encoder_params config; | ||
34 | struct i2c_client *duallink_slave; | ||
35 | |||
36 | uint8_t saved_state[0x10]; | ||
37 | uint8_t saved_slave_state[0x10]; | ||
38 | }; | ||
39 | |||
40 | #define to_sil164_priv(x) \ | ||
41 | ((struct sil164_priv *)to_encoder_slave(x)->slave_priv) | ||
42 | |||
43 | #define sil164_dbg(client, format, ...) do { \ | ||
44 | if (drm_debug & DRM_UT_KMS) \ | ||
45 | dev_printk(KERN_DEBUG, &client->dev, \ | ||
46 | "%s: " format, __func__, ## __VA_ARGS__); \ | ||
47 | } while (0) | ||
48 | #define sil164_info(client, format, ...) \ | ||
49 | dev_info(&client->dev, format, __VA_ARGS__) | ||
50 | #define sil164_err(client, format, ...) \ | ||
51 | dev_err(&client->dev, format, __VA_ARGS__) | ||
52 | |||
53 | #define SIL164_I2C_ADDR_MASTER 0x38 | ||
54 | #define SIL164_I2C_ADDR_SLAVE 0x39 | ||
55 | |||
56 | /* HW register definitions */ | ||
57 | |||
58 | #define SIL164_VENDOR_LO 0x0 | ||
59 | #define SIL164_VENDOR_HI 0x1 | ||
60 | #define SIL164_DEVICE_LO 0x2 | ||
61 | #define SIL164_DEVICE_HI 0x3 | ||
62 | #define SIL164_REVISION 0x4 | ||
63 | #define SIL164_FREQ_MIN 0x6 | ||
64 | #define SIL164_FREQ_MAX 0x7 | ||
65 | #define SIL164_CONTROL0 0x8 | ||
66 | # define SIL164_CONTROL0_POWER_ON 0x01 | ||
67 | # define SIL164_CONTROL0_EDGE_RISING 0x02 | ||
68 | # define SIL164_CONTROL0_INPUT_24BIT 0x04 | ||
69 | # define SIL164_CONTROL0_DUAL_EDGE 0x08 | ||
70 | # define SIL164_CONTROL0_HSYNC_ON 0x10 | ||
71 | # define SIL164_CONTROL0_VSYNC_ON 0x20 | ||
72 | #define SIL164_DETECT 0x9 | ||
73 | # define SIL164_DETECT_INTR_STAT 0x01 | ||
74 | # define SIL164_DETECT_HOTPLUG_STAT 0x02 | ||
75 | # define SIL164_DETECT_RECEIVER_STAT 0x04 | ||
76 | # define SIL164_DETECT_INTR_MODE_RECEIVER 0x00 | ||
77 | # define SIL164_DETECT_INTR_MODE_HOTPLUG 0x08 | ||
78 | # define SIL164_DETECT_OUT_MODE_HIGH 0x00 | ||
79 | # define SIL164_DETECT_OUT_MODE_INTR 0x10 | ||
80 | # define SIL164_DETECT_OUT_MODE_RECEIVER 0x20 | ||
81 | # define SIL164_DETECT_OUT_MODE_HOTPLUG 0x30 | ||
82 | # define SIL164_DETECT_VSWING_STAT 0x80 | ||
83 | #define SIL164_CONTROL1 0xa | ||
84 | # define SIL164_CONTROL1_DESKEW_ENABLE 0x10 | ||
85 | # define SIL164_CONTROL1_DESKEW_INCR_SHIFT 5 | ||
86 | #define SIL164_GPIO 0xb | ||
87 | #define SIL164_CONTROL2 0xc | ||
88 | # define SIL164_CONTROL2_FILTER_ENABLE 0x01 | ||
89 | # define SIL164_CONTROL2_FILTER_SETTING_SHIFT 1 | ||
90 | # define SIL164_CONTROL2_DUALLINK_MASTER 0x40 | ||
91 | # define SIL164_CONTROL2_SYNC_CONT 0x80 | ||
92 | #define SIL164_DUALLINK 0xd | ||
93 | # define SIL164_DUALLINK_ENABLE 0x10 | ||
94 | # define SIL164_DUALLINK_SKEW_SHIFT 5 | ||
95 | #define SIL164_PLLZONE 0xe | ||
96 | # define SIL164_PLLZONE_STAT 0x08 | ||
97 | # define SIL164_PLLZONE_FORCE_ON 0x10 | ||
98 | # define SIL164_PLLZONE_FORCE_HIGH 0x20 | ||
99 | |||
100 | /* HW access functions */ | ||
101 | |||
102 | static void | ||
103 | sil164_write(struct i2c_client *client, uint8_t addr, uint8_t val) | ||
104 | { | ||
105 | uint8_t buf[] = {addr, val}; | ||
106 | int ret; | ||
107 | |||
108 | ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); | ||
109 | if (ret < 0) | ||
110 | sil164_err(client, "Error %d writing to subaddress 0x%x\n", | ||
111 | ret, addr); | ||
112 | } | ||
113 | |||
114 | static uint8_t | ||
115 | sil164_read(struct i2c_client *client, uint8_t addr) | ||
116 | { | ||
117 | uint8_t val; | ||
118 | int ret; | ||
119 | |||
120 | ret = i2c_master_send(client, &addr, sizeof(addr)); | ||
121 | if (ret < 0) | ||
122 | goto fail; | ||
123 | |||
124 | ret = i2c_master_recv(client, &val, sizeof(val)); | ||
125 | if (ret < 0) | ||
126 | goto fail; | ||
127 | |||
128 | return val; | ||
129 | |||
130 | fail: | ||
131 | sil164_err(client, "Error %d reading from subaddress 0x%x\n", | ||
132 | ret, addr); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static void | ||
137 | sil164_save_state(struct i2c_client *client, uint8_t *state) | ||
138 | { | ||
139 | int i; | ||
140 | |||
141 | for (i = 0x8; i <= 0xe; i++) | ||
142 | state[i] = sil164_read(client, i); | ||
143 | } | ||
144 | |||
145 | static void | ||
146 | sil164_restore_state(struct i2c_client *client, uint8_t *state) | ||
147 | { | ||
148 | int i; | ||
149 | |||
150 | for (i = 0x8; i <= 0xe; i++) | ||
151 | sil164_write(client, i, state[i]); | ||
152 | } | ||
153 | |||
154 | static void | ||
155 | sil164_set_power_state(struct i2c_client *client, bool on) | ||
156 | { | ||
157 | uint8_t control0 = sil164_read(client, SIL164_CONTROL0); | ||
158 | |||
159 | if (on) | ||
160 | control0 |= SIL164_CONTROL0_POWER_ON; | ||
161 | else | ||
162 | control0 &= ~SIL164_CONTROL0_POWER_ON; | ||
163 | |||
164 | sil164_write(client, SIL164_CONTROL0, control0); | ||
165 | } | ||
166 | |||
167 | static void | ||
168 | sil164_init_state(struct i2c_client *client, | ||
169 | struct sil164_encoder_params *config, | ||
170 | bool duallink) | ||
171 | { | ||
172 | sil164_write(client, SIL164_CONTROL0, | ||
173 | SIL164_CONTROL0_HSYNC_ON | | ||
174 | SIL164_CONTROL0_VSYNC_ON | | ||
175 | (config->input_edge ? SIL164_CONTROL0_EDGE_RISING : 0) | | ||
176 | (config->input_width ? SIL164_CONTROL0_INPUT_24BIT : 0) | | ||
177 | (config->input_dual ? SIL164_CONTROL0_DUAL_EDGE : 0)); | ||
178 | |||
179 | sil164_write(client, SIL164_DETECT, | ||
180 | SIL164_DETECT_INTR_STAT | | ||
181 | SIL164_DETECT_OUT_MODE_RECEIVER); | ||
182 | |||
183 | sil164_write(client, SIL164_CONTROL1, | ||
184 | (config->input_skew ? SIL164_CONTROL1_DESKEW_ENABLE : 0) | | ||
185 | (((config->input_skew + 4) & 0x7) | ||
186 | << SIL164_CONTROL1_DESKEW_INCR_SHIFT)); | ||
187 | |||
188 | sil164_write(client, SIL164_CONTROL2, | ||
189 | SIL164_CONTROL2_SYNC_CONT | | ||
190 | (config->pll_filter ? 0 : SIL164_CONTROL2_FILTER_ENABLE) | | ||
191 | (4 << SIL164_CONTROL2_FILTER_SETTING_SHIFT)); | ||
192 | |||
193 | sil164_write(client, SIL164_PLLZONE, 0); | ||
194 | |||
195 | if (duallink) | ||
196 | sil164_write(client, SIL164_DUALLINK, | ||
197 | SIL164_DUALLINK_ENABLE | | ||
198 | (((config->duallink_skew + 4) & 0x7) | ||
199 | << SIL164_DUALLINK_SKEW_SHIFT)); | ||
200 | else | ||
201 | sil164_write(client, SIL164_DUALLINK, 0); | ||
202 | } | ||
203 | |||
204 | /* DRM encoder functions */ | ||
205 | |||
206 | static void | ||
207 | sil164_encoder_set_config(struct drm_encoder *encoder, void *params) | ||
208 | { | ||
209 | struct sil164_priv *priv = to_sil164_priv(encoder); | ||
210 | |||
211 | priv->config = *(struct sil164_encoder_params *)params; | ||
212 | } | ||
213 | |||
214 | static void | ||
215 | sil164_encoder_dpms(struct drm_encoder *encoder, int mode) | ||
216 | { | ||
217 | struct sil164_priv *priv = to_sil164_priv(encoder); | ||
218 | bool on = (mode == DRM_MODE_DPMS_ON); | ||
219 | bool duallink = (on && encoder->crtc->mode.clock > 165000); | ||
220 | |||
221 | sil164_set_power_state(drm_i2c_encoder_get_client(encoder), on); | ||
222 | |||
223 | if (priv->duallink_slave) | ||
224 | sil164_set_power_state(priv->duallink_slave, duallink); | ||
225 | } | ||
226 | |||
227 | static void | ||
228 | sil164_encoder_save(struct drm_encoder *encoder) | ||
229 | { | ||
230 | struct sil164_priv *priv = to_sil164_priv(encoder); | ||
231 | |||
232 | sil164_save_state(drm_i2c_encoder_get_client(encoder), | ||
233 | priv->saved_state); | ||
234 | |||
235 | if (priv->duallink_slave) | ||
236 | sil164_save_state(priv->duallink_slave, | ||
237 | priv->saved_slave_state); | ||
238 | } | ||
239 | |||
240 | static void | ||
241 | sil164_encoder_restore(struct drm_encoder *encoder) | ||
242 | { | ||
243 | struct sil164_priv *priv = to_sil164_priv(encoder); | ||
244 | |||
245 | sil164_restore_state(drm_i2c_encoder_get_client(encoder), | ||
246 | priv->saved_state); | ||
247 | |||
248 | if (priv->duallink_slave) | ||
249 | sil164_restore_state(priv->duallink_slave, | ||
250 | priv->saved_slave_state); | ||
251 | } | ||
252 | |||
253 | static bool | ||
254 | sil164_encoder_mode_fixup(struct drm_encoder *encoder, | ||
255 | struct drm_display_mode *mode, | ||
256 | struct drm_display_mode *adjusted_mode) | ||
257 | { | ||
258 | return true; | ||
259 | } | ||
260 | |||
261 | static int | ||
262 | sil164_encoder_mode_valid(struct drm_encoder *encoder, | ||
263 | struct drm_display_mode *mode) | ||
264 | { | ||
265 | struct sil164_priv *priv = to_sil164_priv(encoder); | ||
266 | |||
267 | if (mode->clock < 32000) | ||
268 | return MODE_CLOCK_LOW; | ||
269 | |||
270 | if (mode->clock > 330000 || | ||
271 | (mode->clock > 165000 && !priv->duallink_slave)) | ||
272 | return MODE_CLOCK_HIGH; | ||
273 | |||
274 | return MODE_OK; | ||
275 | } | ||
276 | |||
277 | static void | ||
278 | sil164_encoder_mode_set(struct drm_encoder *encoder, | ||
279 | struct drm_display_mode *mode, | ||
280 | struct drm_display_mode *adjusted_mode) | ||
281 | { | ||
282 | struct sil164_priv *priv = to_sil164_priv(encoder); | ||
283 | bool duallink = adjusted_mode->clock > 165000; | ||
284 | |||
285 | sil164_init_state(drm_i2c_encoder_get_client(encoder), | ||
286 | &priv->config, duallink); | ||
287 | |||
288 | if (priv->duallink_slave) | ||
289 | sil164_init_state(priv->duallink_slave, | ||
290 | &priv->config, duallink); | ||
291 | |||
292 | sil164_encoder_dpms(encoder, DRM_MODE_DPMS_ON); | ||
293 | } | ||
294 | |||
295 | static enum drm_connector_status | ||
296 | sil164_encoder_detect(struct drm_encoder *encoder, | ||
297 | struct drm_connector *connector) | ||
298 | { | ||
299 | struct i2c_client *client = drm_i2c_encoder_get_client(encoder); | ||
300 | |||
301 | if (sil164_read(client, SIL164_DETECT) & SIL164_DETECT_HOTPLUG_STAT) | ||
302 | return connector_status_connected; | ||
303 | else | ||
304 | return connector_status_disconnected; | ||
305 | } | ||
306 | |||
307 | static int | ||
308 | sil164_encoder_get_modes(struct drm_encoder *encoder, | ||
309 | struct drm_connector *connector) | ||
310 | { | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static int | ||
315 | sil164_encoder_create_resources(struct drm_encoder *encoder, | ||
316 | struct drm_connector *connector) | ||
317 | { | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static int | ||
322 | sil164_encoder_set_property(struct drm_encoder *encoder, | ||
323 | struct drm_connector *connector, | ||
324 | struct drm_property *property, | ||
325 | uint64_t val) | ||
326 | { | ||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static void | ||
331 | sil164_encoder_destroy(struct drm_encoder *encoder) | ||
332 | { | ||
333 | struct sil164_priv *priv = to_sil164_priv(encoder); | ||
334 | |||
335 | if (priv->duallink_slave) | ||
336 | i2c_unregister_device(priv->duallink_slave); | ||
337 | |||
338 | kfree(priv); | ||
339 | drm_i2c_encoder_destroy(encoder); | ||
340 | } | ||
341 | |||
342 | static struct drm_encoder_slave_funcs sil164_encoder_funcs = { | ||
343 | .set_config = sil164_encoder_set_config, | ||
344 | .destroy = sil164_encoder_destroy, | ||
345 | .dpms = sil164_encoder_dpms, | ||
346 | .save = sil164_encoder_save, | ||
347 | .restore = sil164_encoder_restore, | ||
348 | .mode_fixup = sil164_encoder_mode_fixup, | ||
349 | .mode_valid = sil164_encoder_mode_valid, | ||
350 | .mode_set = sil164_encoder_mode_set, | ||
351 | .detect = sil164_encoder_detect, | ||
352 | .get_modes = sil164_encoder_get_modes, | ||
353 | .create_resources = sil164_encoder_create_resources, | ||
354 | .set_property = sil164_encoder_set_property, | ||
355 | }; | ||
356 | |||
357 | /* I2C driver functions */ | ||
358 | |||
359 | static int | ||
360 | sil164_probe(struct i2c_client *client, const struct i2c_device_id *id) | ||
361 | { | ||
362 | int vendor = sil164_read(client, SIL164_VENDOR_HI) << 8 | | ||
363 | sil164_read(client, SIL164_VENDOR_LO); | ||
364 | int device = sil164_read(client, SIL164_DEVICE_HI) << 8 | | ||
365 | sil164_read(client, SIL164_DEVICE_LO); | ||
366 | int rev = sil164_read(client, SIL164_REVISION); | ||
367 | |||
368 | if (vendor != 0x1 || device != 0x6) { | ||
369 | sil164_dbg(client, "Unknown device %x:%x.%x\n", | ||
370 | vendor, device, rev); | ||
371 | return -ENODEV; | ||
372 | } | ||
373 | |||
374 | sil164_info(client, "Detected device %x:%x.%x\n", | ||
375 | vendor, device, rev); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | static int | ||
381 | sil164_remove(struct i2c_client *client) | ||
382 | { | ||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static struct i2c_client * | ||
387 | sil164_detect_slave(struct i2c_client *client) | ||
388 | { | ||
389 | struct i2c_adapter *adap = client->adapter; | ||
390 | struct i2c_msg msg = { | ||
391 | .addr = SIL164_I2C_ADDR_SLAVE, | ||
392 | .len = 0, | ||
393 | }; | ||
394 | const struct i2c_board_info info = { | ||
395 | I2C_BOARD_INFO("sil164", SIL164_I2C_ADDR_SLAVE) | ||
396 | }; | ||
397 | |||
398 | if (i2c_transfer(adap, &msg, 1) != 1) { | ||
399 | sil164_dbg(adap, "No dual-link slave found."); | ||
400 | return NULL; | ||
401 | } | ||
402 | |||
403 | return i2c_new_device(adap, &info); | ||
404 | } | ||
405 | |||
406 | static int | ||
407 | sil164_encoder_init(struct i2c_client *client, | ||
408 | struct drm_device *dev, | ||
409 | struct drm_encoder_slave *encoder) | ||
410 | { | ||
411 | struct sil164_priv *priv; | ||
412 | |||
413 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
414 | if (!priv) | ||
415 | return -ENOMEM; | ||
416 | |||
417 | encoder->slave_priv = priv; | ||
418 | encoder->slave_funcs = &sil164_encoder_funcs; | ||
419 | |||
420 | priv->duallink_slave = sil164_detect_slave(client); | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | static struct i2c_device_id sil164_ids[] = { | ||
426 | { "sil164", 0 }, | ||
427 | { } | ||
428 | }; | ||
429 | MODULE_DEVICE_TABLE(i2c, sil164_ids); | ||
430 | |||
431 | static struct drm_i2c_encoder_driver sil164_driver = { | ||
432 | .i2c_driver = { | ||
433 | .probe = sil164_probe, | ||
434 | .remove = sil164_remove, | ||
435 | .driver = { | ||
436 | .name = "sil164", | ||
437 | }, | ||
438 | .id_table = sil164_ids, | ||
439 | }, | ||
440 | .encoder_init = sil164_encoder_init, | ||
441 | }; | ||
442 | |||
443 | /* Module initialization */ | ||
444 | |||
445 | static int __init | ||
446 | sil164_init(void) | ||
447 | { | ||
448 | return drm_i2c_encoder_register(THIS_MODULE, &sil164_driver); | ||
449 | } | ||
450 | |||
451 | static void __exit | ||
452 | sil164_exit(void) | ||
453 | { | ||
454 | drm_i2c_encoder_unregister(&sil164_driver); | ||
455 | } | ||
456 | |||
457 | MODULE_AUTHOR("Francisco Jerez <currojerez@riseup.net>"); | ||
458 | MODULE_DESCRIPTION("Silicon Image sil164 TMDS transmitter driver"); | ||
459 | MODULE_LICENSE("GPL and additional rights"); | ||
460 | |||
461 | module_init(sil164_init); | ||
462 | module_exit(sil164_exit); | ||
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 997d91707ad2..0e6c131313d9 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/interrupt.h> /* For task queue support */ | 37 | #include <linux/interrupt.h> /* For task queue support */ |
38 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/smp_lock.h> | ||
40 | #include <linux/pagemap.h> | 41 | #include <linux/pagemap.h> |
41 | 42 | ||
42 | #define I810_BUF_FREE 2 | 43 | #define I810_BUF_FREE 2 |
@@ -60,9 +61,8 @@ static struct drm_buf *i810_freelist_get(struct drm_device * dev) | |||
60 | /* In use is already a pointer */ | 61 | /* In use is already a pointer */ |
61 | used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, | 62 | used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, |
62 | I810_BUF_CLIENT); | 63 | I810_BUF_CLIENT); |
63 | if (used == I810_BUF_FREE) { | 64 | if (used == I810_BUF_FREE) |
64 | return buf; | 65 | return buf; |
65 | } | ||
66 | } | 66 | } |
67 | return NULL; | 67 | return NULL; |
68 | } | 68 | } |
@@ -71,7 +71,7 @@ static struct drm_buf *i810_freelist_get(struct drm_device * dev) | |||
71 | * yet, the hardware updates in use for us once its on the ring buffer. | 71 | * yet, the hardware updates in use for us once its on the ring buffer. |
72 | */ | 72 | */ |
73 | 73 | ||
74 | static int i810_freelist_put(struct drm_device * dev, struct drm_buf * buf) | 74 | static int i810_freelist_put(struct drm_device *dev, struct drm_buf *buf) |
75 | { | 75 | { |
76 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; | 76 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; |
77 | int used; | 77 | int used; |
@@ -121,7 +121,7 @@ static const struct file_operations i810_buffer_fops = { | |||
121 | .fasync = drm_fasync, | 121 | .fasync = drm_fasync, |
122 | }; | 122 | }; |
123 | 123 | ||
124 | static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) | 124 | static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) |
125 | { | 125 | { |
126 | struct drm_device *dev = file_priv->minor->dev; | 126 | struct drm_device *dev = file_priv->minor->dev; |
127 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; | 127 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; |
@@ -152,7 +152,7 @@ static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) | |||
152 | return retcode; | 152 | return retcode; |
153 | } | 153 | } |
154 | 154 | ||
155 | static int i810_unmap_buffer(struct drm_buf * buf) | 155 | static int i810_unmap_buffer(struct drm_buf *buf) |
156 | { | 156 | { |
157 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; | 157 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; |
158 | int retcode = 0; | 158 | int retcode = 0; |
@@ -172,7 +172,7 @@ static int i810_unmap_buffer(struct drm_buf * buf) | |||
172 | return retcode; | 172 | return retcode; |
173 | } | 173 | } |
174 | 174 | ||
175 | static int i810_dma_get_buffer(struct drm_device * dev, drm_i810_dma_t * d, | 175 | static int i810_dma_get_buffer(struct drm_device *dev, drm_i810_dma_t *d, |
176 | struct drm_file *file_priv) | 176 | struct drm_file *file_priv) |
177 | { | 177 | { |
178 | struct drm_buf *buf; | 178 | struct drm_buf *buf; |
@@ -202,7 +202,7 @@ static int i810_dma_get_buffer(struct drm_device * dev, drm_i810_dma_t * d, | |||
202 | return retcode; | 202 | return retcode; |
203 | } | 203 | } |
204 | 204 | ||
205 | static int i810_dma_cleanup(struct drm_device * dev) | 205 | static int i810_dma_cleanup(struct drm_device *dev) |
206 | { | 206 | { |
207 | struct drm_device_dma *dma = dev->dma; | 207 | struct drm_device_dma *dma = dev->dma; |
208 | 208 | ||
@@ -218,9 +218,8 @@ static int i810_dma_cleanup(struct drm_device * dev) | |||
218 | drm_i810_private_t *dev_priv = | 218 | drm_i810_private_t *dev_priv = |
219 | (drm_i810_private_t *) dev->dev_private; | 219 | (drm_i810_private_t *) dev->dev_private; |
220 | 220 | ||
221 | if (dev_priv->ring.virtual_start) { | 221 | if (dev_priv->ring.virtual_start) |
222 | drm_core_ioremapfree(&dev_priv->ring.map, dev); | 222 | drm_core_ioremapfree(&dev_priv->ring.map, dev); |
223 | } | ||
224 | if (dev_priv->hw_status_page) { | 223 | if (dev_priv->hw_status_page) { |
225 | pci_free_consistent(dev->pdev, PAGE_SIZE, | 224 | pci_free_consistent(dev->pdev, PAGE_SIZE, |
226 | dev_priv->hw_status_page, | 225 | dev_priv->hw_status_page, |
@@ -242,7 +241,7 @@ static int i810_dma_cleanup(struct drm_device * dev) | |||
242 | return 0; | 241 | return 0; |
243 | } | 242 | } |
244 | 243 | ||
245 | static int i810_wait_ring(struct drm_device * dev, int n) | 244 | static int i810_wait_ring(struct drm_device *dev, int n) |
246 | { | 245 | { |
247 | drm_i810_private_t *dev_priv = dev->dev_private; | 246 | drm_i810_private_t *dev_priv = dev->dev_private; |
248 | drm_i810_ring_buffer_t *ring = &(dev_priv->ring); | 247 | drm_i810_ring_buffer_t *ring = &(dev_priv->ring); |
@@ -271,11 +270,11 @@ static int i810_wait_ring(struct drm_device * dev, int n) | |||
271 | udelay(1); | 270 | udelay(1); |
272 | } | 271 | } |
273 | 272 | ||
274 | out_wait_ring: | 273 | out_wait_ring: |
275 | return iters; | 274 | return iters; |
276 | } | 275 | } |
277 | 276 | ||
278 | static void i810_kernel_lost_context(struct drm_device * dev) | 277 | static void i810_kernel_lost_context(struct drm_device *dev) |
279 | { | 278 | { |
280 | drm_i810_private_t *dev_priv = dev->dev_private; | 279 | drm_i810_private_t *dev_priv = dev->dev_private; |
281 | drm_i810_ring_buffer_t *ring = &(dev_priv->ring); | 280 | drm_i810_ring_buffer_t *ring = &(dev_priv->ring); |
@@ -287,7 +286,7 @@ static void i810_kernel_lost_context(struct drm_device * dev) | |||
287 | ring->space += ring->Size; | 286 | ring->space += ring->Size; |
288 | } | 287 | } |
289 | 288 | ||
290 | static int i810_freelist_init(struct drm_device * dev, drm_i810_private_t * dev_priv) | 289 | static int i810_freelist_init(struct drm_device *dev, drm_i810_private_t *dev_priv) |
291 | { | 290 | { |
292 | struct drm_device_dma *dma = dev->dma; | 291 | struct drm_device_dma *dma = dev->dma; |
293 | int my_idx = 24; | 292 | int my_idx = 24; |
@@ -322,9 +321,9 @@ static int i810_freelist_init(struct drm_device * dev, drm_i810_private_t * dev_ | |||
322 | return 0; | 321 | return 0; |
323 | } | 322 | } |
324 | 323 | ||
325 | static int i810_dma_initialize(struct drm_device * dev, | 324 | static int i810_dma_initialize(struct drm_device *dev, |
326 | drm_i810_private_t * dev_priv, | 325 | drm_i810_private_t *dev_priv, |
327 | drm_i810_init_t * init) | 326 | drm_i810_init_t *init) |
328 | { | 327 | { |
329 | struct drm_map_list *r_list; | 328 | struct drm_map_list *r_list; |
330 | memset(dev_priv, 0, sizeof(drm_i810_private_t)); | 329 | memset(dev_priv, 0, sizeof(drm_i810_private_t)); |
@@ -462,7 +461,7 @@ static int i810_dma_init(struct drm_device *dev, void *data, | |||
462 | * Use 'volatile' & local var tmp to force the emitted values to be | 461 | * Use 'volatile' & local var tmp to force the emitted values to be |
463 | * identical to the verified ones. | 462 | * identical to the verified ones. |
464 | */ | 463 | */ |
465 | static void i810EmitContextVerified(struct drm_device * dev, | 464 | static void i810EmitContextVerified(struct drm_device *dev, |
466 | volatile unsigned int *code) | 465 | volatile unsigned int *code) |
467 | { | 466 | { |
468 | drm_i810_private_t *dev_priv = dev->dev_private; | 467 | drm_i810_private_t *dev_priv = dev->dev_private; |
@@ -495,7 +494,7 @@ static void i810EmitContextVerified(struct drm_device * dev, | |||
495 | ADVANCE_LP_RING(); | 494 | ADVANCE_LP_RING(); |
496 | } | 495 | } |
497 | 496 | ||
498 | static void i810EmitTexVerified(struct drm_device * dev, volatile unsigned int *code) | 497 | static void i810EmitTexVerified(struct drm_device *dev, volatile unsigned int *code) |
499 | { | 498 | { |
500 | drm_i810_private_t *dev_priv = dev->dev_private; | 499 | drm_i810_private_t *dev_priv = dev->dev_private; |
501 | int i, j = 0; | 500 | int i, j = 0; |
@@ -528,7 +527,7 @@ static void i810EmitTexVerified(struct drm_device * dev, volatile unsigned int * | |||
528 | 527 | ||
529 | /* Need to do some additional checking when setting the dest buffer. | 528 | /* Need to do some additional checking when setting the dest buffer. |
530 | */ | 529 | */ |
531 | static void i810EmitDestVerified(struct drm_device * dev, | 530 | static void i810EmitDestVerified(struct drm_device *dev, |
532 | volatile unsigned int *code) | 531 | volatile unsigned int *code) |
533 | { | 532 | { |
534 | drm_i810_private_t *dev_priv = dev->dev_private; | 533 | drm_i810_private_t *dev_priv = dev->dev_private; |
@@ -563,7 +562,7 @@ static void i810EmitDestVerified(struct drm_device * dev, | |||
563 | ADVANCE_LP_RING(); | 562 | ADVANCE_LP_RING(); |
564 | } | 563 | } |
565 | 564 | ||
566 | static void i810EmitState(struct drm_device * dev) | 565 | static void i810EmitState(struct drm_device *dev) |
567 | { | 566 | { |
568 | drm_i810_private_t *dev_priv = dev->dev_private; | 567 | drm_i810_private_t *dev_priv = dev->dev_private; |
569 | drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; | 568 | drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; |
@@ -594,7 +593,7 @@ static void i810EmitState(struct drm_device * dev) | |||
594 | 593 | ||
595 | /* need to verify | 594 | /* need to verify |
596 | */ | 595 | */ |
597 | static void i810_dma_dispatch_clear(struct drm_device * dev, int flags, | 596 | static void i810_dma_dispatch_clear(struct drm_device *dev, int flags, |
598 | unsigned int clear_color, | 597 | unsigned int clear_color, |
599 | unsigned int clear_zval) | 598 | unsigned int clear_zval) |
600 | { | 599 | { |
@@ -669,7 +668,7 @@ static void i810_dma_dispatch_clear(struct drm_device * dev, int flags, | |||
669 | } | 668 | } |
670 | } | 669 | } |
671 | 670 | ||
672 | static void i810_dma_dispatch_swap(struct drm_device * dev) | 671 | static void i810_dma_dispatch_swap(struct drm_device *dev) |
673 | { | 672 | { |
674 | drm_i810_private_t *dev_priv = dev->dev_private; | 673 | drm_i810_private_t *dev_priv = dev->dev_private; |
675 | drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; | 674 | drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; |
@@ -715,8 +714,8 @@ static void i810_dma_dispatch_swap(struct drm_device * dev) | |||
715 | } | 714 | } |
716 | } | 715 | } |
717 | 716 | ||
718 | static void i810_dma_dispatch_vertex(struct drm_device * dev, | 717 | static void i810_dma_dispatch_vertex(struct drm_device *dev, |
719 | struct drm_buf * buf, int discard, int used) | 718 | struct drm_buf *buf, int discard, int used) |
720 | { | 719 | { |
721 | drm_i810_private_t *dev_priv = dev->dev_private; | 720 | drm_i810_private_t *dev_priv = dev->dev_private; |
722 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; | 721 | drm_i810_buf_priv_t *buf_priv = buf->dev_private; |
@@ -795,7 +794,7 @@ static void i810_dma_dispatch_vertex(struct drm_device * dev, | |||
795 | } | 794 | } |
796 | } | 795 | } |
797 | 796 | ||
798 | static void i810_dma_dispatch_flip(struct drm_device * dev) | 797 | static void i810_dma_dispatch_flip(struct drm_device *dev) |
799 | { | 798 | { |
800 | drm_i810_private_t *dev_priv = dev->dev_private; | 799 | drm_i810_private_t *dev_priv = dev->dev_private; |
801 | int pitch = dev_priv->pitch; | 800 | int pitch = dev_priv->pitch; |
@@ -841,7 +840,7 @@ static void i810_dma_dispatch_flip(struct drm_device * dev) | |||
841 | 840 | ||
842 | } | 841 | } |
843 | 842 | ||
844 | static void i810_dma_quiescent(struct drm_device * dev) | 843 | static void i810_dma_quiescent(struct drm_device *dev) |
845 | { | 844 | { |
846 | drm_i810_private_t *dev_priv = dev->dev_private; | 845 | drm_i810_private_t *dev_priv = dev->dev_private; |
847 | RING_LOCALS; | 846 | RING_LOCALS; |
@@ -858,7 +857,7 @@ static void i810_dma_quiescent(struct drm_device * dev) | |||
858 | i810_wait_ring(dev, dev_priv->ring.Size - 8); | 857 | i810_wait_ring(dev, dev_priv->ring.Size - 8); |
859 | } | 858 | } |
860 | 859 | ||
861 | static int i810_flush_queue(struct drm_device * dev) | 860 | static int i810_flush_queue(struct drm_device *dev) |
862 | { | 861 | { |
863 | drm_i810_private_t *dev_priv = dev->dev_private; | 862 | drm_i810_private_t *dev_priv = dev->dev_private; |
864 | struct drm_device_dma *dma = dev->dma; | 863 | struct drm_device_dma *dma = dev->dma; |
@@ -891,7 +890,7 @@ static int i810_flush_queue(struct drm_device * dev) | |||
891 | } | 890 | } |
892 | 891 | ||
893 | /* Must be called with the lock held */ | 892 | /* Must be called with the lock held */ |
894 | static void i810_reclaim_buffers(struct drm_device * dev, | 893 | static void i810_reclaim_buffers(struct drm_device *dev, |
895 | struct drm_file *file_priv) | 894 | struct drm_file *file_priv) |
896 | { | 895 | { |
897 | struct drm_device_dma *dma = dev->dma; | 896 | struct drm_device_dma *dma = dev->dma; |
@@ -969,9 +968,8 @@ static int i810_clear_bufs(struct drm_device *dev, void *data, | |||
969 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 968 | LOCK_TEST_WITH_RETURN(dev, file_priv); |
970 | 969 | ||
971 | /* GH: Someone's doing nasty things... */ | 970 | /* GH: Someone's doing nasty things... */ |
972 | if (!dev->dev_private) { | 971 | if (!dev->dev_private) |
973 | return -EINVAL; | 972 | return -EINVAL; |
974 | } | ||
975 | 973 | ||
976 | i810_dma_dispatch_clear(dev, clear->flags, | 974 | i810_dma_dispatch_clear(dev, clear->flags, |
977 | clear->clear_color, clear->clear_depth); | 975 | clear->clear_color, clear->clear_depth); |
@@ -1039,7 +1037,7 @@ static int i810_docopy(struct drm_device *dev, void *data, | |||
1039 | return 0; | 1037 | return 0; |
1040 | } | 1038 | } |
1041 | 1039 | ||
1042 | static void i810_dma_dispatch_mc(struct drm_device * dev, struct drm_buf * buf, int used, | 1040 | static void i810_dma_dispatch_mc(struct drm_device *dev, struct drm_buf *buf, int used, |
1043 | unsigned int last_render) | 1041 | unsigned int last_render) |
1044 | { | 1042 | { |
1045 | drm_i810_private_t *dev_priv = dev->dev_private; | 1043 | drm_i810_private_t *dev_priv = dev->dev_private; |
@@ -1053,9 +1051,8 @@ static void i810_dma_dispatch_mc(struct drm_device * dev, struct drm_buf * buf, | |||
1053 | i810_kernel_lost_context(dev); | 1051 | i810_kernel_lost_context(dev); |
1054 | 1052 | ||
1055 | u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE); | 1053 | u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE); |
1056 | if (u != I810_BUF_CLIENT) { | 1054 | if (u != I810_BUF_CLIENT) |
1057 | DRM_DEBUG("MC found buffer that isn't mine!\n"); | 1055 | DRM_DEBUG("MC found buffer that isn't mine!\n"); |
1058 | } | ||
1059 | 1056 | ||
1060 | if (used > 4 * 1024) | 1057 | if (used > 4 * 1024) |
1061 | used = 0; | 1058 | used = 0; |
@@ -1160,7 +1157,7 @@ static int i810_ov0_flip(struct drm_device *dev, void *data, | |||
1160 | 1157 | ||
1161 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 1158 | LOCK_TEST_WITH_RETURN(dev, file_priv); |
1162 | 1159 | ||
1163 | //Tell the overlay to update | 1160 | /* Tell the overlay to update */ |
1164 | I810_WRITE(0x30000, dev_priv->overlay_physical | 0x80000000); | 1161 | I810_WRITE(0x30000, dev_priv->overlay_physical | 0x80000000); |
1165 | 1162 | ||
1166 | return 0; | 1163 | return 0; |
@@ -1168,7 +1165,7 @@ static int i810_ov0_flip(struct drm_device *dev, void *data, | |||
1168 | 1165 | ||
1169 | /* Not sure why this isn't set all the time: | 1166 | /* Not sure why this isn't set all the time: |
1170 | */ | 1167 | */ |
1171 | static void i810_do_init_pageflip(struct drm_device * dev) | 1168 | static void i810_do_init_pageflip(struct drm_device *dev) |
1172 | { | 1169 | { |
1173 | drm_i810_private_t *dev_priv = dev->dev_private; | 1170 | drm_i810_private_t *dev_priv = dev->dev_private; |
1174 | 1171 | ||
@@ -1178,7 +1175,7 @@ static void i810_do_init_pageflip(struct drm_device * dev) | |||
1178 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; | 1175 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; |
1179 | } | 1176 | } |
1180 | 1177 | ||
1181 | static int i810_do_cleanup_pageflip(struct drm_device * dev) | 1178 | static int i810_do_cleanup_pageflip(struct drm_device *dev) |
1182 | { | 1179 | { |
1183 | drm_i810_private_t *dev_priv = dev->dev_private; | 1180 | drm_i810_private_t *dev_priv = dev->dev_private; |
1184 | 1181 | ||
@@ -1218,49 +1215,61 @@ int i810_driver_load(struct drm_device *dev, unsigned long flags) | |||
1218 | return 0; | 1215 | return 0; |
1219 | } | 1216 | } |
1220 | 1217 | ||
1221 | void i810_driver_lastclose(struct drm_device * dev) | 1218 | void i810_driver_lastclose(struct drm_device *dev) |
1222 | { | 1219 | { |
1223 | i810_dma_cleanup(dev); | 1220 | i810_dma_cleanup(dev); |
1224 | } | 1221 | } |
1225 | 1222 | ||
1226 | void i810_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) | 1223 | void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) |
1227 | { | 1224 | { |
1228 | if (dev->dev_private) { | 1225 | if (dev->dev_private) { |
1229 | drm_i810_private_t *dev_priv = dev->dev_private; | 1226 | drm_i810_private_t *dev_priv = dev->dev_private; |
1230 | if (dev_priv->page_flipping) { | 1227 | if (dev_priv->page_flipping) |
1231 | i810_do_cleanup_pageflip(dev); | 1228 | i810_do_cleanup_pageflip(dev); |
1232 | } | ||
1233 | } | 1229 | } |
1234 | } | 1230 | } |
1235 | 1231 | ||
1236 | void i810_driver_reclaim_buffers_locked(struct drm_device * dev, | 1232 | void i810_driver_reclaim_buffers_locked(struct drm_device *dev, |
1237 | struct drm_file *file_priv) | 1233 | struct drm_file *file_priv) |
1238 | { | 1234 | { |
1239 | i810_reclaim_buffers(dev, file_priv); | 1235 | i810_reclaim_buffers(dev, file_priv); |
1240 | } | 1236 | } |
1241 | 1237 | ||
1242 | int i810_driver_dma_quiescent(struct drm_device * dev) | 1238 | int i810_driver_dma_quiescent(struct drm_device *dev) |
1243 | { | 1239 | { |
1244 | i810_dma_quiescent(dev); | 1240 | i810_dma_quiescent(dev); |
1245 | return 0; | 1241 | return 0; |
1246 | } | 1242 | } |
1247 | 1243 | ||
1244 | /* | ||
1245 | * call the drm_ioctl under the big kernel lock because | ||
1246 | * to lock against the i810_mmap_buffers function. | ||
1247 | */ | ||
1248 | long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
1249 | { | ||
1250 | int ret; | ||
1251 | lock_kernel(); | ||
1252 | ret = drm_ioctl(file, cmd, arg); | ||
1253 | unlock_kernel(); | ||
1254 | return ret; | ||
1255 | } | ||
1256 | |||
1248 | struct drm_ioctl_desc i810_ioctls[] = { | 1257 | struct drm_ioctl_desc i810_ioctls[] = { |
1249 | DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1258 | DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
1250 | DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH), | 1259 | DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED), |
1251 | DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH), | 1260 | DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED), |
1252 | DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH), | 1261 | DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), |
1253 | DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH), | 1262 | DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED), |
1254 | DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH), | 1263 | DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED), |
1255 | DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH), | 1264 | DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED), |
1256 | DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH), | 1265 | DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED), |
1257 | DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH), | 1266 | DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED), |
1258 | DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH), | 1267 | DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED), |
1259 | DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH), | 1268 | DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED), |
1260 | DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH), | 1269 | DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED), |
1261 | DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1270 | DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
1262 | DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH), | 1271 | DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED), |
1263 | DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH) | 1272 | DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED), |
1264 | }; | 1273 | }; |
1265 | 1274 | ||
1266 | int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); | 1275 | int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); |
@@ -1276,7 +1285,7 @@ int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); | |||
1276 | * \returns | 1285 | * \returns |
1277 | * A value of 1 is always retured to indictate every i810 is AGP. | 1286 | * A value of 1 is always retured to indictate every i810 is AGP. |
1278 | */ | 1287 | */ |
1279 | int i810_driver_device_is_agp(struct drm_device * dev) | 1288 | int i810_driver_device_is_agp(struct drm_device *dev) |
1280 | { | 1289 | { |
1281 | return 1; | 1290 | return 1; |
1282 | } | 1291 | } |
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index c1e02752e023..b4250b2cac1f 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c | |||
@@ -59,7 +59,7 @@ static struct drm_driver driver = { | |||
59 | .owner = THIS_MODULE, | 59 | .owner = THIS_MODULE, |
60 | .open = drm_open, | 60 | .open = drm_open, |
61 | .release = drm_release, | 61 | .release = drm_release, |
62 | .unlocked_ioctl = drm_ioctl, | 62 | .unlocked_ioctl = i810_ioctl, |
63 | .mmap = drm_mmap, | 63 | .mmap = drm_mmap, |
64 | .poll = drm_poll, | 64 | .poll = drm_poll, |
65 | .fasync = drm_fasync, | 65 | .fasync = drm_fasync, |
diff --git a/drivers/gpu/drm/i810/i810_drv.h b/drivers/gpu/drm/i810/i810_drv.h index 21e2691f28f9..c9339f481795 100644 --- a/drivers/gpu/drm/i810/i810_drv.h +++ b/drivers/gpu/drm/i810/i810_drv.h | |||
@@ -115,56 +115,59 @@ typedef struct drm_i810_private { | |||
115 | } drm_i810_private_t; | 115 | } drm_i810_private_t; |
116 | 116 | ||
117 | /* i810_dma.c */ | 117 | /* i810_dma.c */ |
118 | extern int i810_driver_dma_quiescent(struct drm_device * dev); | 118 | extern int i810_driver_dma_quiescent(struct drm_device *dev); |
119 | extern void i810_driver_reclaim_buffers_locked(struct drm_device * dev, | 119 | extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, |
120 | struct drm_file *file_priv); | 120 | struct drm_file *file_priv); |
121 | extern int i810_driver_load(struct drm_device *, unsigned long flags); | 121 | extern int i810_driver_load(struct drm_device *, unsigned long flags); |
122 | extern void i810_driver_lastclose(struct drm_device * dev); | 122 | extern void i810_driver_lastclose(struct drm_device *dev); |
123 | extern void i810_driver_preclose(struct drm_device * dev, | 123 | extern void i810_driver_preclose(struct drm_device *dev, |
124 | struct drm_file *file_priv); | 124 | struct drm_file *file_priv); |
125 | extern void i810_driver_reclaim_buffers_locked(struct drm_device * dev, | 125 | extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, |
126 | struct drm_file *file_priv); | 126 | struct drm_file *file_priv); |
127 | extern int i810_driver_device_is_agp(struct drm_device * dev); | 127 | extern int i810_driver_device_is_agp(struct drm_device *dev); |
128 | 128 | ||
129 | extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | ||
129 | extern struct drm_ioctl_desc i810_ioctls[]; | 130 | extern struct drm_ioctl_desc i810_ioctls[]; |
130 | extern int i810_max_ioctl; | 131 | extern int i810_max_ioctl; |
131 | 132 | ||
132 | #define I810_BASE(reg) ((unsigned long) \ | 133 | #define I810_BASE(reg) ((unsigned long) \ |
133 | dev_priv->mmio_map->handle) | 134 | dev_priv->mmio_map->handle) |
134 | #define I810_ADDR(reg) (I810_BASE(reg) + reg) | 135 | #define I810_ADDR(reg) (I810_BASE(reg) + reg) |
135 | #define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg) | 136 | #define I810_DEREF(reg) (*(__volatile__ int *)I810_ADDR(reg)) |
136 | #define I810_READ(reg) I810_DEREF(reg) | 137 | #define I810_READ(reg) I810_DEREF(reg) |
137 | #define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0) | 138 | #define I810_WRITE(reg, val) do { I810_DEREF(reg) = val; } while (0) |
138 | #define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg) | 139 | #define I810_DEREF16(reg) (*(__volatile__ u16 *)I810_ADDR(reg)) |
139 | #define I810_READ16(reg) I810_DEREF16(reg) | 140 | #define I810_READ16(reg) I810_DEREF16(reg) |
140 | #define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0) | 141 | #define I810_WRITE16(reg, val) do { I810_DEREF16(reg) = val; } while (0) |
141 | 142 | ||
142 | #define I810_VERBOSE 0 | 143 | #define I810_VERBOSE 0 |
143 | #define RING_LOCALS unsigned int outring, ringmask; \ | 144 | #define RING_LOCALS unsigned int outring, ringmask; \ |
144 | volatile char *virt; | 145 | volatile char *virt; |
145 | 146 | ||
146 | #define BEGIN_LP_RING(n) do { \ | 147 | #define BEGIN_LP_RING(n) do { \ |
147 | if (I810_VERBOSE) \ | 148 | if (I810_VERBOSE) \ |
148 | DRM_DEBUG("BEGIN_LP_RING(%d)\n", n); \ | 149 | DRM_DEBUG("BEGIN_LP_RING(%d)\n", n); \ |
149 | if (dev_priv->ring.space < n*4) \ | 150 | if (dev_priv->ring.space < n*4) \ |
150 | i810_wait_ring(dev, n*4); \ | 151 | i810_wait_ring(dev, n*4); \ |
151 | dev_priv->ring.space -= n*4; \ | 152 | dev_priv->ring.space -= n*4; \ |
152 | outring = dev_priv->ring.tail; \ | 153 | outring = dev_priv->ring.tail; \ |
153 | ringmask = dev_priv->ring.tail_mask; \ | 154 | ringmask = dev_priv->ring.tail_mask; \ |
154 | virt = dev_priv->ring.virtual_start; \ | 155 | virt = dev_priv->ring.virtual_start; \ |
155 | } while (0) | 156 | } while (0) |
156 | 157 | ||
157 | #define ADVANCE_LP_RING() do { \ | 158 | #define ADVANCE_LP_RING() do { \ |
158 | if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ | 159 | if (I810_VERBOSE) \ |
160 | DRM_DEBUG("ADVANCE_LP_RING\n"); \ | ||
159 | dev_priv->ring.tail = outring; \ | 161 | dev_priv->ring.tail = outring; \ |
160 | I810_WRITE(LP_RING + RING_TAIL, outring); \ | 162 | I810_WRITE(LP_RING + RING_TAIL, outring); \ |
161 | } while(0) | 163 | } while (0) |
162 | 164 | ||
163 | #define OUT_RING(n) do { \ | 165 | #define OUT_RING(n) do { \ |
164 | if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ | 166 | if (I810_VERBOSE) \ |
165 | *(volatile unsigned int *)(virt + outring) = n; \ | 167 | DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ |
166 | outring += 4; \ | 168 | *(volatile unsigned int *)(virt + outring) = n; \ |
167 | outring &= ringmask; \ | 169 | outring += 4; \ |
170 | outring &= ringmask; \ | ||
168 | } while (0) | 171 | } while (0) |
169 | 172 | ||
170 | #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) | 173 | #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) |
diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 65759a9a85c8..5168862c9227 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "i830_drm.h" | 36 | #include "i830_drm.h" |
37 | #include "i830_drv.h" | 37 | #include "i830_drv.h" |
38 | #include <linux/interrupt.h> /* For task queue support */ | 38 | #include <linux/interrupt.h> /* For task queue support */ |
39 | #include <linux/smp_lock.h> | ||
39 | #include <linux/pagemap.h> | 40 | #include <linux/pagemap.h> |
40 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
41 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
@@ -62,9 +63,8 @@ static struct drm_buf *i830_freelist_get(struct drm_device * dev) | |||
62 | /* In use is already a pointer */ | 63 | /* In use is already a pointer */ |
63 | used = cmpxchg(buf_priv->in_use, I830_BUF_FREE, | 64 | used = cmpxchg(buf_priv->in_use, I830_BUF_FREE, |
64 | I830_BUF_CLIENT); | 65 | I830_BUF_CLIENT); |
65 | if (used == I830_BUF_FREE) { | 66 | if (used == I830_BUF_FREE) |
66 | return buf; | 67 | return buf; |
67 | } | ||
68 | } | 68 | } |
69 | return NULL; | 69 | return NULL; |
70 | } | 70 | } |
@@ -73,7 +73,7 @@ static struct drm_buf *i830_freelist_get(struct drm_device * dev) | |||
73 | * yet, the hardware updates in use for us once its on the ring buffer. | 73 | * yet, the hardware updates in use for us once its on the ring buffer. |
74 | */ | 74 | */ |
75 | 75 | ||
76 | static int i830_freelist_put(struct drm_device * dev, struct drm_buf * buf) | 76 | static int i830_freelist_put(struct drm_device *dev, struct drm_buf *buf) |
77 | { | 77 | { |
78 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; | 78 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; |
79 | int used; | 79 | int used; |
@@ -123,7 +123,7 @@ static const struct file_operations i830_buffer_fops = { | |||
123 | .fasync = drm_fasync, | 123 | .fasync = drm_fasync, |
124 | }; | 124 | }; |
125 | 125 | ||
126 | static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) | 126 | static int i830_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) |
127 | { | 127 | { |
128 | struct drm_device *dev = file_priv->minor->dev; | 128 | struct drm_device *dev = file_priv->minor->dev; |
129 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; | 129 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; |
@@ -156,7 +156,7 @@ static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) | |||
156 | return retcode; | 156 | return retcode; |
157 | } | 157 | } |
158 | 158 | ||
159 | static int i830_unmap_buffer(struct drm_buf * buf) | 159 | static int i830_unmap_buffer(struct drm_buf *buf) |
160 | { | 160 | { |
161 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; | 161 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; |
162 | int retcode = 0; | 162 | int retcode = 0; |
@@ -176,7 +176,7 @@ static int i830_unmap_buffer(struct drm_buf * buf) | |||
176 | return retcode; | 176 | return retcode; |
177 | } | 177 | } |
178 | 178 | ||
179 | static int i830_dma_get_buffer(struct drm_device * dev, drm_i830_dma_t * d, | 179 | static int i830_dma_get_buffer(struct drm_device *dev, drm_i830_dma_t *d, |
180 | struct drm_file *file_priv) | 180 | struct drm_file *file_priv) |
181 | { | 181 | { |
182 | struct drm_buf *buf; | 182 | struct drm_buf *buf; |
@@ -206,7 +206,7 @@ static int i830_dma_get_buffer(struct drm_device * dev, drm_i830_dma_t * d, | |||
206 | return retcode; | 206 | return retcode; |
207 | } | 207 | } |
208 | 208 | ||
209 | static int i830_dma_cleanup(struct drm_device * dev) | 209 | static int i830_dma_cleanup(struct drm_device *dev) |
210 | { | 210 | { |
211 | struct drm_device_dma *dma = dev->dma; | 211 | struct drm_device_dma *dma = dev->dma; |
212 | 212 | ||
@@ -222,9 +222,8 @@ static int i830_dma_cleanup(struct drm_device * dev) | |||
222 | drm_i830_private_t *dev_priv = | 222 | drm_i830_private_t *dev_priv = |
223 | (drm_i830_private_t *) dev->dev_private; | 223 | (drm_i830_private_t *) dev->dev_private; |
224 | 224 | ||
225 | if (dev_priv->ring.virtual_start) { | 225 | if (dev_priv->ring.virtual_start) |
226 | drm_core_ioremapfree(&dev_priv->ring.map, dev); | 226 | drm_core_ioremapfree(&dev_priv->ring.map, dev); |
227 | } | ||
228 | if (dev_priv->hw_status_page) { | 227 | if (dev_priv->hw_status_page) { |
229 | pci_free_consistent(dev->pdev, PAGE_SIZE, | 228 | pci_free_consistent(dev->pdev, PAGE_SIZE, |
230 | dev_priv->hw_status_page, | 229 | dev_priv->hw_status_page, |
@@ -246,7 +245,7 @@ static int i830_dma_cleanup(struct drm_device * dev) | |||
246 | return 0; | 245 | return 0; |
247 | } | 246 | } |
248 | 247 | ||
249 | int i830_wait_ring(struct drm_device * dev, int n, const char *caller) | 248 | int i830_wait_ring(struct drm_device *dev, int n, const char *caller) |
250 | { | 249 | { |
251 | drm_i830_private_t *dev_priv = dev->dev_private; | 250 | drm_i830_private_t *dev_priv = dev->dev_private; |
252 | drm_i830_ring_buffer_t *ring = &(dev_priv->ring); | 251 | drm_i830_ring_buffer_t *ring = &(dev_priv->ring); |
@@ -276,11 +275,11 @@ int i830_wait_ring(struct drm_device * dev, int n, const char *caller) | |||
276 | dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; | 275 | dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; |
277 | } | 276 | } |
278 | 277 | ||
279 | out_wait_ring: | 278 | out_wait_ring: |
280 | return iters; | 279 | return iters; |
281 | } | 280 | } |
282 | 281 | ||
283 | static void i830_kernel_lost_context(struct drm_device * dev) | 282 | static void i830_kernel_lost_context(struct drm_device *dev) |
284 | { | 283 | { |
285 | drm_i830_private_t *dev_priv = dev->dev_private; | 284 | drm_i830_private_t *dev_priv = dev->dev_private; |
286 | drm_i830_ring_buffer_t *ring = &(dev_priv->ring); | 285 | drm_i830_ring_buffer_t *ring = &(dev_priv->ring); |
@@ -295,7 +294,7 @@ static void i830_kernel_lost_context(struct drm_device * dev) | |||
295 | dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY; | 294 | dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY; |
296 | } | 295 | } |
297 | 296 | ||
298 | static int i830_freelist_init(struct drm_device * dev, drm_i830_private_t * dev_priv) | 297 | static int i830_freelist_init(struct drm_device *dev, drm_i830_private_t *dev_priv) |
299 | { | 298 | { |
300 | struct drm_device_dma *dma = dev->dma; | 299 | struct drm_device_dma *dma = dev->dma; |
301 | int my_idx = 36; | 300 | int my_idx = 36; |
@@ -329,9 +328,9 @@ static int i830_freelist_init(struct drm_device * dev, drm_i830_private_t * dev_ | |||
329 | return 0; | 328 | return 0; |
330 | } | 329 | } |
331 | 330 | ||
332 | static int i830_dma_initialize(struct drm_device * dev, | 331 | static int i830_dma_initialize(struct drm_device *dev, |
333 | drm_i830_private_t * dev_priv, | 332 | drm_i830_private_t *dev_priv, |
334 | drm_i830_init_t * init) | 333 | drm_i830_init_t *init) |
335 | { | 334 | { |
336 | struct drm_map_list *r_list; | 335 | struct drm_map_list *r_list; |
337 | 336 | ||
@@ -482,7 +481,7 @@ static int i830_dma_init(struct drm_device *dev, void *data, | |||
482 | /* Most efficient way to verify state for the i830 is as it is | 481 | /* Most efficient way to verify state for the i830 is as it is |
483 | * emitted. Non-conformant state is silently dropped. | 482 | * emitted. Non-conformant state is silently dropped. |
484 | */ | 483 | */ |
485 | static void i830EmitContextVerified(struct drm_device * dev, unsigned int *code) | 484 | static void i830EmitContextVerified(struct drm_device *dev, unsigned int *code) |
486 | { | 485 | { |
487 | drm_i830_private_t *dev_priv = dev->dev_private; | 486 | drm_i830_private_t *dev_priv = dev->dev_private; |
488 | int i, j = 0; | 487 | int i, j = 0; |
@@ -527,7 +526,7 @@ static void i830EmitContextVerified(struct drm_device * dev, unsigned int *code) | |||
527 | ADVANCE_LP_RING(); | 526 | ADVANCE_LP_RING(); |
528 | } | 527 | } |
529 | 528 | ||
530 | static void i830EmitTexVerified(struct drm_device * dev, unsigned int *code) | 529 | static void i830EmitTexVerified(struct drm_device *dev, unsigned int *code) |
531 | { | 530 | { |
532 | drm_i830_private_t *dev_priv = dev->dev_private; | 531 | drm_i830_private_t *dev_priv = dev->dev_private; |
533 | int i, j = 0; | 532 | int i, j = 0; |
@@ -561,7 +560,7 @@ static void i830EmitTexVerified(struct drm_device * dev, unsigned int *code) | |||
561 | printk("rejected packet %x\n", code[0]); | 560 | printk("rejected packet %x\n", code[0]); |
562 | } | 561 | } |
563 | 562 | ||
564 | static void i830EmitTexBlendVerified(struct drm_device * dev, | 563 | static void i830EmitTexBlendVerified(struct drm_device *dev, |
565 | unsigned int *code, unsigned int num) | 564 | unsigned int *code, unsigned int num) |
566 | { | 565 | { |
567 | drm_i830_private_t *dev_priv = dev->dev_private; | 566 | drm_i830_private_t *dev_priv = dev->dev_private; |
@@ -586,7 +585,7 @@ static void i830EmitTexBlendVerified(struct drm_device * dev, | |||
586 | ADVANCE_LP_RING(); | 585 | ADVANCE_LP_RING(); |
587 | } | 586 | } |
588 | 587 | ||
589 | static void i830EmitTexPalette(struct drm_device * dev, | 588 | static void i830EmitTexPalette(struct drm_device *dev, |
590 | unsigned int *palette, int number, int is_shared) | 589 | unsigned int *palette, int number, int is_shared) |
591 | { | 590 | { |
592 | drm_i830_private_t *dev_priv = dev->dev_private; | 591 | drm_i830_private_t *dev_priv = dev->dev_private; |
@@ -603,9 +602,8 @@ static void i830EmitTexPalette(struct drm_device * dev, | |||
603 | } else { | 602 | } else { |
604 | OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number)); | 603 | OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number)); |
605 | } | 604 | } |
606 | for (i = 0; i < 256; i++) { | 605 | for (i = 0; i < 256; i++) |
607 | OUT_RING(palette[i]); | 606 | OUT_RING(palette[i]); |
608 | } | ||
609 | OUT_RING(0); | 607 | OUT_RING(0); |
610 | /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop! | 608 | /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop! |
611 | */ | 609 | */ |
@@ -613,7 +611,7 @@ static void i830EmitTexPalette(struct drm_device * dev, | |||
613 | 611 | ||
614 | /* Need to do some additional checking when setting the dest buffer. | 612 | /* Need to do some additional checking when setting the dest buffer. |
615 | */ | 613 | */ |
616 | static void i830EmitDestVerified(struct drm_device * dev, unsigned int *code) | 614 | static void i830EmitDestVerified(struct drm_device *dev, unsigned int *code) |
617 | { | 615 | { |
618 | drm_i830_private_t *dev_priv = dev->dev_private; | 616 | drm_i830_private_t *dev_priv = dev->dev_private; |
619 | unsigned int tmp; | 617 | unsigned int tmp; |
@@ -674,7 +672,7 @@ static void i830EmitDestVerified(struct drm_device * dev, unsigned int *code) | |||
674 | ADVANCE_LP_RING(); | 672 | ADVANCE_LP_RING(); |
675 | } | 673 | } |
676 | 674 | ||
677 | static void i830EmitStippleVerified(struct drm_device * dev, unsigned int *code) | 675 | static void i830EmitStippleVerified(struct drm_device *dev, unsigned int *code) |
678 | { | 676 | { |
679 | drm_i830_private_t *dev_priv = dev->dev_private; | 677 | drm_i830_private_t *dev_priv = dev->dev_private; |
680 | RING_LOCALS; | 678 | RING_LOCALS; |
@@ -685,7 +683,7 @@ static void i830EmitStippleVerified(struct drm_device * dev, unsigned int *code) | |||
685 | ADVANCE_LP_RING(); | 683 | ADVANCE_LP_RING(); |
686 | } | 684 | } |
687 | 685 | ||
688 | static void i830EmitState(struct drm_device * dev) | 686 | static void i830EmitState(struct drm_device *dev) |
689 | { | 687 | { |
690 | drm_i830_private_t *dev_priv = dev->dev_private; | 688 | drm_i830_private_t *dev_priv = dev->dev_private; |
691 | drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; | 689 | drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; |
@@ -788,7 +786,7 @@ static void i830EmitState(struct drm_device * dev) | |||
788 | * Performance monitoring functions | 786 | * Performance monitoring functions |
789 | */ | 787 | */ |
790 | 788 | ||
791 | static void i830_fill_box(struct drm_device * dev, | 789 | static void i830_fill_box(struct drm_device *dev, |
792 | int x, int y, int w, int h, int r, int g, int b) | 790 | int x, int y, int w, int h, int r, int g, int b) |
793 | { | 791 | { |
794 | drm_i830_private_t *dev_priv = dev->dev_private; | 792 | drm_i830_private_t *dev_priv = dev->dev_private; |
@@ -816,17 +814,16 @@ static void i830_fill_box(struct drm_device * dev, | |||
816 | OUT_RING((y << 16) | x); | 814 | OUT_RING((y << 16) | x); |
817 | OUT_RING(((y + h) << 16) | (x + w)); | 815 | OUT_RING(((y + h) << 16) | (x + w)); |
818 | 816 | ||
819 | if (dev_priv->current_page == 1) { | 817 | if (dev_priv->current_page == 1) |
820 | OUT_RING(dev_priv->front_offset); | 818 | OUT_RING(dev_priv->front_offset); |
821 | } else { | 819 | else |
822 | OUT_RING(dev_priv->back_offset); | 820 | OUT_RING(dev_priv->back_offset); |
823 | } | ||
824 | 821 | ||
825 | OUT_RING(color); | 822 | OUT_RING(color); |
826 | ADVANCE_LP_RING(); | 823 | ADVANCE_LP_RING(); |
827 | } | 824 | } |
828 | 825 | ||
829 | static void i830_cp_performance_boxes(struct drm_device * dev) | 826 | static void i830_cp_performance_boxes(struct drm_device *dev) |
830 | { | 827 | { |
831 | drm_i830_private_t *dev_priv = dev->dev_private; | 828 | drm_i830_private_t *dev_priv = dev->dev_private; |
832 | 829 | ||
@@ -871,7 +868,7 @@ static void i830_cp_performance_boxes(struct drm_device * dev) | |||
871 | dev_priv->sarea_priv->perf_boxes = 0; | 868 | dev_priv->sarea_priv->perf_boxes = 0; |
872 | } | 869 | } |
873 | 870 | ||
874 | static void i830_dma_dispatch_clear(struct drm_device * dev, int flags, | 871 | static void i830_dma_dispatch_clear(struct drm_device *dev, int flags, |
875 | unsigned int clear_color, | 872 | unsigned int clear_color, |
876 | unsigned int clear_zval, | 873 | unsigned int clear_zval, |
877 | unsigned int clear_depthmask) | 874 | unsigned int clear_depthmask) |
@@ -966,7 +963,7 @@ static void i830_dma_dispatch_clear(struct drm_device * dev, int flags, | |||
966 | } | 963 | } |
967 | } | 964 | } |
968 | 965 | ||
969 | static void i830_dma_dispatch_swap(struct drm_device * dev) | 966 | static void i830_dma_dispatch_swap(struct drm_device *dev) |
970 | { | 967 | { |
971 | drm_i830_private_t *dev_priv = dev->dev_private; | 968 | drm_i830_private_t *dev_priv = dev->dev_private; |
972 | drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; | 969 | drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; |
@@ -1036,7 +1033,7 @@ static void i830_dma_dispatch_swap(struct drm_device * dev) | |||
1036 | } | 1033 | } |
1037 | } | 1034 | } |
1038 | 1035 | ||
1039 | static void i830_dma_dispatch_flip(struct drm_device * dev) | 1036 | static void i830_dma_dispatch_flip(struct drm_device *dev) |
1040 | { | 1037 | { |
1041 | drm_i830_private_t *dev_priv = dev->dev_private; | 1038 | drm_i830_private_t *dev_priv = dev->dev_private; |
1042 | RING_LOCALS; | 1039 | RING_LOCALS; |
@@ -1079,8 +1076,8 @@ static void i830_dma_dispatch_flip(struct drm_device * dev) | |||
1079 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; | 1076 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; |
1080 | } | 1077 | } |
1081 | 1078 | ||
1082 | static void i830_dma_dispatch_vertex(struct drm_device * dev, | 1079 | static void i830_dma_dispatch_vertex(struct drm_device *dev, |
1083 | struct drm_buf * buf, int discard, int used) | 1080 | struct drm_buf *buf, int discard, int used) |
1084 | { | 1081 | { |
1085 | drm_i830_private_t *dev_priv = dev->dev_private; | 1082 | drm_i830_private_t *dev_priv = dev->dev_private; |
1086 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; | 1083 | drm_i830_buf_priv_t *buf_priv = buf->dev_private; |
@@ -1100,9 +1097,8 @@ static void i830_dma_dispatch_vertex(struct drm_device * dev, | |||
1100 | if (discard) { | 1097 | if (discard) { |
1101 | u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, | 1098 | u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, |
1102 | I830_BUF_HARDWARE); | 1099 | I830_BUF_HARDWARE); |
1103 | if (u != I830_BUF_CLIENT) { | 1100 | if (u != I830_BUF_CLIENT) |
1104 | DRM_DEBUG("xxxx 2\n"); | 1101 | DRM_DEBUG("xxxx 2\n"); |
1105 | } | ||
1106 | } | 1102 | } |
1107 | 1103 | ||
1108 | if (used > 4 * 1023) | 1104 | if (used > 4 * 1023) |
@@ -1191,7 +1187,7 @@ static void i830_dma_dispatch_vertex(struct drm_device * dev, | |||
1191 | } | 1187 | } |
1192 | } | 1188 | } |
1193 | 1189 | ||
1194 | static void i830_dma_quiescent(struct drm_device * dev) | 1190 | static void i830_dma_quiescent(struct drm_device *dev) |
1195 | { | 1191 | { |
1196 | drm_i830_private_t *dev_priv = dev->dev_private; | 1192 | drm_i830_private_t *dev_priv = dev->dev_private; |
1197 | RING_LOCALS; | 1193 | RING_LOCALS; |
@@ -1208,7 +1204,7 @@ static void i830_dma_quiescent(struct drm_device * dev) | |||
1208 | i830_wait_ring(dev, dev_priv->ring.Size - 8, __func__); | 1204 | i830_wait_ring(dev, dev_priv->ring.Size - 8, __func__); |
1209 | } | 1205 | } |
1210 | 1206 | ||
1211 | static int i830_flush_queue(struct drm_device * dev) | 1207 | static int i830_flush_queue(struct drm_device *dev) |
1212 | { | 1208 | { |
1213 | drm_i830_private_t *dev_priv = dev->dev_private; | 1209 | drm_i830_private_t *dev_priv = dev->dev_private; |
1214 | struct drm_device_dma *dma = dev->dma; | 1210 | struct drm_device_dma *dma = dev->dma; |
@@ -1241,7 +1237,7 @@ static int i830_flush_queue(struct drm_device * dev) | |||
1241 | } | 1237 | } |
1242 | 1238 | ||
1243 | /* Must be called with the lock held */ | 1239 | /* Must be called with the lock held */ |
1244 | static void i830_reclaim_buffers(struct drm_device * dev, struct drm_file *file_priv) | 1240 | static void i830_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) |
1245 | { | 1241 | { |
1246 | struct drm_device_dma *dma = dev->dma; | 1242 | struct drm_device_dma *dma = dev->dma; |
1247 | int i; | 1243 | int i; |
@@ -1316,9 +1312,8 @@ static int i830_clear_bufs(struct drm_device *dev, void *data, | |||
1316 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 1312 | LOCK_TEST_WITH_RETURN(dev, file_priv); |
1317 | 1313 | ||
1318 | /* GH: Someone's doing nasty things... */ | 1314 | /* GH: Someone's doing nasty things... */ |
1319 | if (!dev->dev_private) { | 1315 | if (!dev->dev_private) |
1320 | return -EINVAL; | 1316 | return -EINVAL; |
1321 | } | ||
1322 | 1317 | ||
1323 | i830_dma_dispatch_clear(dev, clear->flags, | 1318 | i830_dma_dispatch_clear(dev, clear->flags, |
1324 | clear->clear_color, | 1319 | clear->clear_color, |
@@ -1339,7 +1334,7 @@ static int i830_swap_bufs(struct drm_device *dev, void *data, | |||
1339 | 1334 | ||
1340 | /* Not sure why this isn't set all the time: | 1335 | /* Not sure why this isn't set all the time: |
1341 | */ | 1336 | */ |
1342 | static void i830_do_init_pageflip(struct drm_device * dev) | 1337 | static void i830_do_init_pageflip(struct drm_device *dev) |
1343 | { | 1338 | { |
1344 | drm_i830_private_t *dev_priv = dev->dev_private; | 1339 | drm_i830_private_t *dev_priv = dev->dev_private; |
1345 | 1340 | ||
@@ -1349,7 +1344,7 @@ static void i830_do_init_pageflip(struct drm_device * dev) | |||
1349 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; | 1344 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; |
1350 | } | 1345 | } |
1351 | 1346 | ||
1352 | static int i830_do_cleanup_pageflip(struct drm_device * dev) | 1347 | static int i830_do_cleanup_pageflip(struct drm_device *dev) |
1353 | { | 1348 | { |
1354 | drm_i830_private_t *dev_priv = dev->dev_private; | 1349 | drm_i830_private_t *dev_priv = dev->dev_private; |
1355 | 1350 | ||
@@ -1490,47 +1485,59 @@ int i830_driver_load(struct drm_device *dev, unsigned long flags) | |||
1490 | return 0; | 1485 | return 0; |
1491 | } | 1486 | } |
1492 | 1487 | ||
1493 | void i830_driver_lastclose(struct drm_device * dev) | 1488 | void i830_driver_lastclose(struct drm_device *dev) |
1494 | { | 1489 | { |
1495 | i830_dma_cleanup(dev); | 1490 | i830_dma_cleanup(dev); |
1496 | } | 1491 | } |
1497 | 1492 | ||
1498 | void i830_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) | 1493 | void i830_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) |
1499 | { | 1494 | { |
1500 | if (dev->dev_private) { | 1495 | if (dev->dev_private) { |
1501 | drm_i830_private_t *dev_priv = dev->dev_private; | 1496 | drm_i830_private_t *dev_priv = dev->dev_private; |
1502 | if (dev_priv->page_flipping) { | 1497 | if (dev_priv->page_flipping) |
1503 | i830_do_cleanup_pageflip(dev); | 1498 | i830_do_cleanup_pageflip(dev); |
1504 | } | ||
1505 | } | 1499 | } |
1506 | } | 1500 | } |
1507 | 1501 | ||
1508 | void i830_driver_reclaim_buffers_locked(struct drm_device * dev, struct drm_file *file_priv) | 1502 | void i830_driver_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv) |
1509 | { | 1503 | { |
1510 | i830_reclaim_buffers(dev, file_priv); | 1504 | i830_reclaim_buffers(dev, file_priv); |
1511 | } | 1505 | } |
1512 | 1506 | ||
1513 | int i830_driver_dma_quiescent(struct drm_device * dev) | 1507 | int i830_driver_dma_quiescent(struct drm_device *dev) |
1514 | { | 1508 | { |
1515 | i830_dma_quiescent(dev); | 1509 | i830_dma_quiescent(dev); |
1516 | return 0; | 1510 | return 0; |
1517 | } | 1511 | } |
1518 | 1512 | ||
1513 | /* | ||
1514 | * call the drm_ioctl under the big kernel lock because | ||
1515 | * to lock against the i830_mmap_buffers function. | ||
1516 | */ | ||
1517 | long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
1518 | { | ||
1519 | int ret; | ||
1520 | lock_kernel(); | ||
1521 | ret = drm_ioctl(file, cmd, arg); | ||
1522 | unlock_kernel(); | ||
1523 | return ret; | ||
1524 | } | ||
1525 | |||
1519 | struct drm_ioctl_desc i830_ioctls[] = { | 1526 | struct drm_ioctl_desc i830_ioctls[] = { |
1520 | DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1527 | DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
1521 | DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH), | 1528 | DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED), |
1522 | DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH), | 1529 | DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED), |
1523 | DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH), | 1530 | DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), |
1524 | DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH), | 1531 | DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED), |
1525 | DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH), | 1532 | DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED), |
1526 | DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH), | 1533 | DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED), |
1527 | DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH), | 1534 | DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED), |
1528 | DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH), | 1535 | DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED), |
1529 | DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH), | 1536 | DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED), |
1530 | DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH), | 1537 | DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED), |
1531 | DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH), | 1538 | DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED), |
1532 | DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH), | 1539 | DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED), |
1533 | DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH) | 1540 | DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED), |
1534 | }; | 1541 | }; |
1535 | 1542 | ||
1536 | int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); | 1543 | int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); |
@@ -1546,7 +1553,7 @@ int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); | |||
1546 | * \returns | 1553 | * \returns |
1547 | * A value of 1 is always retured to indictate every i8xx is AGP. | 1554 | * A value of 1 is always retured to indictate every i8xx is AGP. |
1548 | */ | 1555 | */ |
1549 | int i830_driver_device_is_agp(struct drm_device * dev) | 1556 | int i830_driver_device_is_agp(struct drm_device *dev) |
1550 | { | 1557 | { |
1551 | return 1; | 1558 | return 1; |
1552 | } | 1559 | } |
diff --git a/drivers/gpu/drm/i830/i830_drv.c b/drivers/gpu/drm/i830/i830_drv.c index 44f990bed8f4..a5c66aa82f0c 100644 --- a/drivers/gpu/drm/i830/i830_drv.c +++ b/drivers/gpu/drm/i830/i830_drv.c | |||
@@ -70,7 +70,7 @@ static struct drm_driver driver = { | |||
70 | .owner = THIS_MODULE, | 70 | .owner = THIS_MODULE, |
71 | .open = drm_open, | 71 | .open = drm_open, |
72 | .release = drm_release, | 72 | .release = drm_release, |
73 | .unlocked_ioctl = drm_ioctl, | 73 | .unlocked_ioctl = i830_ioctl, |
74 | .mmap = drm_mmap, | 74 | .mmap = drm_mmap, |
75 | .poll = drm_poll, | 75 | .poll = drm_poll, |
76 | .fasync = drm_fasync, | 76 | .fasync = drm_fasync, |
diff --git a/drivers/gpu/drm/i830/i830_drv.h b/drivers/gpu/drm/i830/i830_drv.h index da82afe4ded5..0df1c720560b 100644 --- a/drivers/gpu/drm/i830/i830_drv.h +++ b/drivers/gpu/drm/i830/i830_drv.h | |||
@@ -122,6 +122,7 @@ typedef struct drm_i830_private { | |||
122 | 122 | ||
123 | } drm_i830_private_t; | 123 | } drm_i830_private_t; |
124 | 124 | ||
125 | long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | ||
125 | extern struct drm_ioctl_desc i830_ioctls[]; | 126 | extern struct drm_ioctl_desc i830_ioctls[]; |
126 | extern int i830_max_ioctl; | 127 | extern int i830_max_ioctl; |
127 | 128 | ||
@@ -132,33 +133,33 @@ extern int i830_irq_wait(struct drm_device *dev, void *data, | |||
132 | struct drm_file *file_priv); | 133 | struct drm_file *file_priv); |
133 | 134 | ||
134 | extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS); | 135 | extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS); |
135 | extern void i830_driver_irq_preinstall(struct drm_device * dev); | 136 | extern void i830_driver_irq_preinstall(struct drm_device *dev); |
136 | extern void i830_driver_irq_postinstall(struct drm_device * dev); | 137 | extern void i830_driver_irq_postinstall(struct drm_device *dev); |
137 | extern void i830_driver_irq_uninstall(struct drm_device * dev); | 138 | extern void i830_driver_irq_uninstall(struct drm_device *dev); |
138 | extern int i830_driver_load(struct drm_device *, unsigned long flags); | 139 | extern int i830_driver_load(struct drm_device *, unsigned long flags); |
139 | extern void i830_driver_preclose(struct drm_device * dev, | 140 | extern void i830_driver_preclose(struct drm_device *dev, |
140 | struct drm_file *file_priv); | 141 | struct drm_file *file_priv); |
141 | extern void i830_driver_lastclose(struct drm_device * dev); | 142 | extern void i830_driver_lastclose(struct drm_device *dev); |
142 | extern void i830_driver_reclaim_buffers_locked(struct drm_device * dev, | 143 | extern void i830_driver_reclaim_buffers_locked(struct drm_device *dev, |
143 | struct drm_file *file_priv); | 144 | struct drm_file *file_priv); |
144 | extern int i830_driver_dma_quiescent(struct drm_device * dev); | 145 | extern int i830_driver_dma_quiescent(struct drm_device *dev); |
145 | extern int i830_driver_device_is_agp(struct drm_device * dev); | 146 | extern int i830_driver_device_is_agp(struct drm_device *dev); |
146 | 147 | ||
147 | #define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) | 148 | #define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) |
148 | #define I830_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val) | 149 | #define I830_WRITE(reg, val) DRM_WRITE32(dev_priv->mmio_map, reg, val) |
149 | #define I830_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg) | 150 | #define I830_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg) |
150 | #define I830_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, reg, val) | 151 | #define I830_WRITE16(reg, val) DRM_WRITE16(dev_priv->mmio_map, reg, val) |
151 | 152 | ||
152 | #define I830_VERBOSE 0 | 153 | #define I830_VERBOSE 0 |
153 | 154 | ||
154 | #define RING_LOCALS unsigned int outring, ringmask, outcount; \ | 155 | #define RING_LOCALS unsigned int outring, ringmask, outcount; \ |
155 | volatile char *virt; | 156 | volatile char *virt; |
156 | 157 | ||
157 | #define BEGIN_LP_RING(n) do { \ | 158 | #define BEGIN_LP_RING(n) do { \ |
158 | if (I830_VERBOSE) \ | 159 | if (I830_VERBOSE) \ |
159 | printk("BEGIN_LP_RING(%d)\n", (n)); \ | 160 | printk("BEGIN_LP_RING(%d)\n", (n)); \ |
160 | if (dev_priv->ring.space < n*4) \ | 161 | if (dev_priv->ring.space < n*4) \ |
161 | i830_wait_ring(dev, n*4, __func__); \ | 162 | i830_wait_ring(dev, n*4, __func__); \ |
162 | outcount = 0; \ | 163 | outcount = 0; \ |
163 | outring = dev_priv->ring.tail; \ | 164 | outring = dev_priv->ring.tail; \ |
164 | ringmask = dev_priv->ring.tail_mask; \ | 165 | ringmask = dev_priv->ring.tail_mask; \ |
@@ -166,21 +167,23 @@ extern int i830_driver_device_is_agp(struct drm_device * dev); | |||
166 | } while (0) | 167 | } while (0) |
167 | 168 | ||
168 | #define OUT_RING(n) do { \ | 169 | #define OUT_RING(n) do { \ |
169 | if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \ | 170 | if (I830_VERBOSE) \ |
171 | printk(" OUT_RING %x\n", (int)(n)); \ | ||
170 | *(volatile unsigned int *)(virt + outring) = n; \ | 172 | *(volatile unsigned int *)(virt + outring) = n; \ |
171 | outcount++; \ | 173 | outcount++; \ |
172 | outring += 4; \ | 174 | outring += 4; \ |
173 | outring &= ringmask; \ | 175 | outring &= ringmask; \ |
174 | } while (0) | 176 | } while (0) |
175 | 177 | ||
176 | #define ADVANCE_LP_RING() do { \ | 178 | #define ADVANCE_LP_RING() do { \ |
177 | if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \ | 179 | if (I830_VERBOSE) \ |
178 | dev_priv->ring.tail = outring; \ | 180 | printk("ADVANCE_LP_RING %x\n", outring); \ |
179 | dev_priv->ring.space -= outcount * 4; \ | 181 | dev_priv->ring.tail = outring; \ |
180 | I830_WRITE(LP_RING + RING_TAIL, outring); \ | 182 | dev_priv->ring.space -= outcount * 4; \ |
181 | } while(0) | 183 | I830_WRITE(LP_RING + RING_TAIL, outring); \ |
184 | } while (0) | ||
182 | 185 | ||
183 | extern int i830_wait_ring(struct drm_device * dev, int n, const char *caller); | 186 | extern int i830_wait_ring(struct drm_device *dev, int n, const char *caller); |
184 | 187 | ||
185 | #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) | 188 | #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) |
186 | #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) | 189 | #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) |
diff --git a/drivers/gpu/drm/i830/i830_irq.c b/drivers/gpu/drm/i830/i830_irq.c index 91ec2bb497e9..d1a6b95d631d 100644 --- a/drivers/gpu/drm/i830/i830_irq.c +++ b/drivers/gpu/drm/i830/i830_irq.c | |||
@@ -53,7 +53,7 @@ irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS) | |||
53 | return IRQ_HANDLED; | 53 | return IRQ_HANDLED; |
54 | } | 54 | } |
55 | 55 | ||
56 | static int i830_emit_irq(struct drm_device * dev) | 56 | static int i830_emit_irq(struct drm_device *dev) |
57 | { | 57 | { |
58 | drm_i830_private_t *dev_priv = dev->dev_private; | 58 | drm_i830_private_t *dev_priv = dev->dev_private; |
59 | RING_LOCALS; | 59 | RING_LOCALS; |
@@ -70,7 +70,7 @@ static int i830_emit_irq(struct drm_device * dev) | |||
70 | return atomic_read(&dev_priv->irq_emitted); | 70 | return atomic_read(&dev_priv->irq_emitted); |
71 | } | 71 | } |
72 | 72 | ||
73 | static int i830_wait_irq(struct drm_device * dev, int irq_nr) | 73 | static int i830_wait_irq(struct drm_device *dev, int irq_nr) |
74 | { | 74 | { |
75 | drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; | 75 | drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; |
76 | DECLARE_WAITQUEUE(entry, current); | 76 | DECLARE_WAITQUEUE(entry, current); |
@@ -156,7 +156,7 @@ int i830_irq_wait(struct drm_device *dev, void *data, | |||
156 | 156 | ||
157 | /* drm_dma.h hooks | 157 | /* drm_dma.h hooks |
158 | */ | 158 | */ |
159 | void i830_driver_irq_preinstall(struct drm_device * dev) | 159 | void i830_driver_irq_preinstall(struct drm_device *dev) |
160 | { | 160 | { |
161 | drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; | 161 | drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; |
162 | 162 | ||
@@ -168,14 +168,14 @@ void i830_driver_irq_preinstall(struct drm_device * dev) | |||
168 | init_waitqueue_head(&dev_priv->irq_queue); | 168 | init_waitqueue_head(&dev_priv->irq_queue); |
169 | } | 169 | } |
170 | 170 | ||
171 | void i830_driver_irq_postinstall(struct drm_device * dev) | 171 | void i830_driver_irq_postinstall(struct drm_device *dev) |
172 | { | 172 | { |
173 | drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; | 173 | drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; |
174 | 174 | ||
175 | I830_WRITE16(I830REG_INT_ENABLE_R, 0x2); | 175 | I830_WRITE16(I830REG_INT_ENABLE_R, 0x2); |
176 | } | 176 | } |
177 | 177 | ||
178 | void i830_driver_irq_uninstall(struct drm_device * dev) | 178 | void i830_driver_irq_uninstall(struct drm_device *dev) |
179 | { | 179 | { |
180 | drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; | 180 | drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; |
181 | if (!dev_priv) | 181 | if (!dev_priv) |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2305a1234f1e..f19ffe87af3c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -34,12 +34,15 @@ | |||
34 | #include "i915_drm.h" | 34 | #include "i915_drm.h" |
35 | #include "i915_drv.h" | 35 | #include "i915_drv.h" |
36 | #include "i915_trace.h" | 36 | #include "i915_trace.h" |
37 | #include <linux/pci.h> | ||
37 | #include <linux/vgaarb.h> | 38 | #include <linux/vgaarb.h> |
38 | #include <linux/acpi.h> | 39 | #include <linux/acpi.h> |
39 | #include <linux/pnp.h> | 40 | #include <linux/pnp.h> |
40 | #include <linux/vga_switcheroo.h> | 41 | #include <linux/vga_switcheroo.h> |
41 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
42 | 43 | ||
44 | extern int intel_max_stolen; /* from AGP driver */ | ||
45 | |||
43 | /** | 46 | /** |
44 | * Sets up the hardware status page for devices that need a physical address | 47 | * Sets up the hardware status page for devices that need a physical address |
45 | * in the register. | 48 | * in the register. |
@@ -1256,7 +1259,7 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1256 | drm_mm_put_block(compressed_fb); | 1259 | drm_mm_put_block(compressed_fb); |
1257 | } | 1260 | } |
1258 | 1261 | ||
1259 | if (!IS_GM45(dev)) { | 1262 | if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) { |
1260 | compressed_llb = drm_mm_search_free(&dev_priv->vram, 4096, | 1263 | compressed_llb = drm_mm_search_free(&dev_priv->vram, 4096, |
1261 | 4096, 0); | 1264 | 4096, 0); |
1262 | if (!compressed_llb) { | 1265 | if (!compressed_llb) { |
@@ -1282,8 +1285,9 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1282 | 1285 | ||
1283 | intel_disable_fbc(dev); | 1286 | intel_disable_fbc(dev); |
1284 | dev_priv->compressed_fb = compressed_fb; | 1287 | dev_priv->compressed_fb = compressed_fb; |
1285 | 1288 | if (IS_IRONLAKE_M(dev)) | |
1286 | if (IS_GM45(dev)) { | 1289 | I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start); |
1290 | else if (IS_GM45(dev)) { | ||
1287 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); | 1291 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); |
1288 | } else { | 1292 | } else { |
1289 | I915_WRITE(FBC_CFB_BASE, cfb_base); | 1293 | I915_WRITE(FBC_CFB_BASE, cfb_base); |
@@ -1291,7 +1295,7 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1291 | dev_priv->compressed_llb = compressed_llb; | 1295 | dev_priv->compressed_llb = compressed_llb; |
1292 | } | 1296 | } |
1293 | 1297 | ||
1294 | DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, | 1298 | DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, |
1295 | ll_base, size >> 20); | 1299 | ll_base, size >> 20); |
1296 | } | 1300 | } |
1297 | 1301 | ||
@@ -1354,7 +1358,7 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1354 | int fb_bar = IS_I9XX(dev) ? 2 : 0; | 1358 | int fb_bar = IS_I9XX(dev) ? 2 : 0; |
1355 | int ret = 0; | 1359 | int ret = 0; |
1356 | 1360 | ||
1357 | dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) & | 1361 | dev->mode_config.fb_base = pci_resource_start(dev->pdev, fb_bar) & |
1358 | 0xff000000; | 1362 | 0xff000000; |
1359 | 1363 | ||
1360 | /* Basic memrange allocator for stolen space (aka vram) */ | 1364 | /* Basic memrange allocator for stolen space (aka vram) */ |
@@ -2063,8 +2067,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2063 | 2067 | ||
2064 | /* Add register map (needed for suspend/resume) */ | 2068 | /* Add register map (needed for suspend/resume) */ |
2065 | mmio_bar = IS_I9XX(dev) ? 0 : 1; | 2069 | mmio_bar = IS_I9XX(dev) ? 0 : 1; |
2066 | base = drm_get_resource_start(dev, mmio_bar); | 2070 | base = pci_resource_start(dev->pdev, mmio_bar); |
2067 | size = drm_get_resource_len(dev, mmio_bar); | 2071 | size = pci_resource_len(dev->pdev, mmio_bar); |
2068 | 2072 | ||
2069 | if (i915_get_bridge_dev(dev)) { | 2073 | if (i915_get_bridge_dev(dev)) { |
2070 | ret = -EIO; | 2074 | ret = -EIO; |
@@ -2104,6 +2108,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2104 | if (ret) | 2108 | if (ret) |
2105 | goto out_iomapfree; | 2109 | goto out_iomapfree; |
2106 | 2110 | ||
2111 | if (prealloc_size > intel_max_stolen) { | ||
2112 | DRM_INFO("detected %dM stolen memory, trimming to %dM\n", | ||
2113 | prealloc_size >> 20, intel_max_stolen >> 20); | ||
2114 | prealloc_size = intel_max_stolen; | ||
2115 | } | ||
2116 | |||
2107 | dev_priv->wq = create_singlethread_workqueue("i915"); | 2117 | dev_priv->wq = create_singlethread_workqueue("i915"); |
2108 | if (dev_priv->wq == NULL) { | 2118 | if (dev_priv->wq == NULL) { |
2109 | DRM_ERROR("Failed to create our workqueue.\n"); | 2119 | DRM_ERROR("Failed to create our workqueue.\n"); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 423dc90c1e20..5044f653e8ea 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -93,11 +93,11 @@ static const struct intel_device_info intel_i945gm_info = { | |||
93 | }; | 93 | }; |
94 | 94 | ||
95 | static const struct intel_device_info intel_i965g_info = { | 95 | static const struct intel_device_info intel_i965g_info = { |
96 | .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, | 96 | .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, |
97 | }; | 97 | }; |
98 | 98 | ||
99 | static const struct intel_device_info intel_i965gm_info = { | 99 | static const struct intel_device_info intel_i965gm_info = { |
100 | .is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1, | 100 | .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, |
101 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, | 101 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, |
102 | .has_hotplug = 1, | 102 | .has_hotplug = 1, |
103 | }; | 103 | }; |
@@ -114,7 +114,7 @@ static const struct intel_device_info intel_g45_info = { | |||
114 | }; | 114 | }; |
115 | 115 | ||
116 | static const struct intel_device_info intel_gm45_info = { | 116 | static const struct intel_device_info intel_gm45_info = { |
117 | .is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1, | 117 | .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, |
118 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, | 118 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, |
119 | .has_pipe_cxsr = 1, | 119 | .has_pipe_cxsr = 1, |
120 | .has_hotplug = 1, | 120 | .has_hotplug = 1, |
@@ -134,7 +134,7 @@ static const struct intel_device_info intel_ironlake_d_info = { | |||
134 | 134 | ||
135 | static const struct intel_device_info intel_ironlake_m_info = { | 135 | static const struct intel_device_info intel_ironlake_m_info = { |
136 | .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, | 136 | .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, |
137 | .need_gfx_hws = 1, .has_rc6 = 1, | 137 | .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, |
138 | .has_hotplug = 1, | 138 | .has_hotplug = 1, |
139 | }; | 139 | }; |
140 | 140 | ||
@@ -148,33 +148,33 @@ static const struct intel_device_info intel_sandybridge_m_info = { | |||
148 | .has_hotplug = 1, .is_gen6 = 1, | 148 | .has_hotplug = 1, .is_gen6 = 1, |
149 | }; | 149 | }; |
150 | 150 | ||
151 | static const struct pci_device_id pciidlist[] = { | 151 | static const struct pci_device_id pciidlist[] = { /* aka */ |
152 | INTEL_VGA_DEVICE(0x3577, &intel_i830_info), | 152 | INTEL_VGA_DEVICE(0x3577, &intel_i830_info), /* I830_M */ |
153 | INTEL_VGA_DEVICE(0x2562, &intel_845g_info), | 153 | INTEL_VGA_DEVICE(0x2562, &intel_845g_info), /* 845_G */ |
154 | INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), | 154 | INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), /* I855_GM */ |
155 | INTEL_VGA_DEVICE(0x358e, &intel_i85x_info), | 155 | INTEL_VGA_DEVICE(0x358e, &intel_i85x_info), |
156 | INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), | 156 | INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), /* I865_G */ |
157 | INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), | 157 | INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), /* I915_G */ |
158 | INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), | 158 | INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), /* E7221_G */ |
159 | INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info), | 159 | INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info), /* I915_GM */ |
160 | INTEL_VGA_DEVICE(0x2772, &intel_i945g_info), | 160 | INTEL_VGA_DEVICE(0x2772, &intel_i945g_info), /* I945_G */ |
161 | INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info), | 161 | INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info), /* I945_GM */ |
162 | INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info), | 162 | INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info), /* I945_GME */ |
163 | INTEL_VGA_DEVICE(0x2972, &intel_i965g_info), | 163 | INTEL_VGA_DEVICE(0x2972, &intel_i965g_info), /* I946_GZ */ |
164 | INTEL_VGA_DEVICE(0x2982, &intel_i965g_info), | 164 | INTEL_VGA_DEVICE(0x2982, &intel_i965g_info), /* G35_G */ |
165 | INTEL_VGA_DEVICE(0x2992, &intel_i965g_info), | 165 | INTEL_VGA_DEVICE(0x2992, &intel_i965g_info), /* I965_Q */ |
166 | INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info), | 166 | INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info), /* I965_G */ |
167 | INTEL_VGA_DEVICE(0x29b2, &intel_g33_info), | 167 | INTEL_VGA_DEVICE(0x29b2, &intel_g33_info), /* Q35_G */ |
168 | INTEL_VGA_DEVICE(0x29c2, &intel_g33_info), | 168 | INTEL_VGA_DEVICE(0x29c2, &intel_g33_info), /* G33_G */ |
169 | INTEL_VGA_DEVICE(0x29d2, &intel_g33_info), | 169 | INTEL_VGA_DEVICE(0x29d2, &intel_g33_info), /* Q33_G */ |
170 | INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info), | 170 | INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info), /* I965_GM */ |
171 | INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info), | 171 | INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info), /* I965_GME */ |
172 | INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info), | 172 | INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info), /* GM45_G */ |
173 | INTEL_VGA_DEVICE(0x2e02, &intel_g45_info), | 173 | INTEL_VGA_DEVICE(0x2e02, &intel_g45_info), /* IGD_E_G */ |
174 | INTEL_VGA_DEVICE(0x2e12, &intel_g45_info), | 174 | INTEL_VGA_DEVICE(0x2e12, &intel_g45_info), /* Q45_G */ |
175 | INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), | 175 | INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */ |
176 | INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), | 176 | INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */ |
177 | INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), | 177 | INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */ |
178 | INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), | 178 | INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), |
179 | INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), | 179 | INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), |
180 | INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), | 180 | INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), |
@@ -340,7 +340,7 @@ int i965_reset(struct drm_device *dev, u8 flags) | |||
340 | /* | 340 | /* |
341 | * Clear request list | 341 | * Clear request list |
342 | */ | 342 | */ |
343 | i915_gem_retire_requests(dev, &dev_priv->render_ring); | 343 | i915_gem_retire_requests(dev); |
344 | 344 | ||
345 | if (need_display) | 345 | if (need_display) |
346 | i915_save_display(dev); | 346 | i915_save_display(dev); |
@@ -413,7 +413,7 @@ int i965_reset(struct drm_device *dev, u8 flags) | |||
413 | static int __devinit | 413 | static int __devinit |
414 | i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 414 | i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
415 | { | 415 | { |
416 | return drm_get_dev(pdev, ent, &driver); | 416 | return drm_get_pci_dev(pdev, ent, &driver); |
417 | } | 417 | } |
418 | 418 | ||
419 | static void | 419 | static void |
@@ -482,7 +482,7 @@ static int i915_pm_poweroff(struct device *dev) | |||
482 | return i915_drm_freeze(drm_dev); | 482 | return i915_drm_freeze(drm_dev); |
483 | } | 483 | } |
484 | 484 | ||
485 | const struct dev_pm_ops i915_pm_ops = { | 485 | static const struct dev_pm_ops i915_pm_ops = { |
486 | .suspend = i915_pm_suspend, | 486 | .suspend = i915_pm_suspend, |
487 | .resume = i915_pm_resume, | 487 | .resume = i915_pm_resume, |
488 | .freeze = i915_pm_freeze, | 488 | .freeze = i915_pm_freeze, |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2e1744d37ad5..906663b9929e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -176,7 +176,8 @@ struct drm_i915_display_funcs { | |||
176 | int (*get_display_clock_speed)(struct drm_device *dev); | 176 | int (*get_display_clock_speed)(struct drm_device *dev); |
177 | int (*get_fifo_size)(struct drm_device *dev, int plane); | 177 | int (*get_fifo_size)(struct drm_device *dev, int plane); |
178 | void (*update_wm)(struct drm_device *dev, int planea_clock, | 178 | void (*update_wm)(struct drm_device *dev, int planea_clock, |
179 | int planeb_clock, int sr_hdisplay, int pixel_size); | 179 | int planeb_clock, int sr_hdisplay, int sr_htotal, |
180 | int pixel_size); | ||
180 | /* clock updates for mode set */ | 181 | /* clock updates for mode set */ |
181 | /* cursor updates */ | 182 | /* cursor updates */ |
182 | /* render clock increase/decrease */ | 183 | /* render clock increase/decrease */ |
@@ -200,6 +201,8 @@ struct intel_device_info { | |||
200 | u8 need_gfx_hws : 1; | 201 | u8 need_gfx_hws : 1; |
201 | u8 is_g4x : 1; | 202 | u8 is_g4x : 1; |
202 | u8 is_pineview : 1; | 203 | u8 is_pineview : 1; |
204 | u8 is_broadwater : 1; | ||
205 | u8 is_crestline : 1; | ||
203 | u8 is_ironlake : 1; | 206 | u8 is_ironlake : 1; |
204 | u8 is_gen6 : 1; | 207 | u8 is_gen6 : 1; |
205 | u8 has_fbc : 1; | 208 | u8 has_fbc : 1; |
@@ -288,6 +291,8 @@ typedef struct drm_i915_private { | |||
288 | struct timer_list hangcheck_timer; | 291 | struct timer_list hangcheck_timer; |
289 | int hangcheck_count; | 292 | int hangcheck_count; |
290 | uint32_t last_acthd; | 293 | uint32_t last_acthd; |
294 | uint32_t last_instdone; | ||
295 | uint32_t last_instdone1; | ||
291 | 296 | ||
292 | struct drm_mm vram; | 297 | struct drm_mm vram; |
293 | 298 | ||
@@ -547,6 +552,14 @@ typedef struct drm_i915_private { | |||
547 | struct list_head fence_list; | 552 | struct list_head fence_list; |
548 | 553 | ||
549 | /** | 554 | /** |
555 | * List of objects currently pending being freed. | ||
556 | * | ||
557 | * These objects are no longer in use, but due to a signal | ||
558 | * we were prevented from freeing them at the appointed time. | ||
559 | */ | ||
560 | struct list_head deferred_free_list; | ||
561 | |||
562 | /** | ||
550 | * We leave the user IRQ off as much as possible, | 563 | * We leave the user IRQ off as much as possible, |
551 | * but this means that requests will finish and never | 564 | * but this means that requests will finish and never |
552 | * be retired once the system goes idle. Set a timer to | 565 | * be retired once the system goes idle. Set a timer to |
@@ -677,7 +690,7 @@ struct drm_i915_gem_object { | |||
677 | * | 690 | * |
678 | * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE) | 691 | * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE) |
679 | */ | 692 | */ |
680 | int fence_reg : 5; | 693 | signed int fence_reg : 5; |
681 | 694 | ||
682 | /** | 695 | /** |
683 | * Used for checking the object doesn't appear more than once | 696 | * Used for checking the object doesn't appear more than once |
@@ -713,7 +726,7 @@ struct drm_i915_gem_object { | |||
713 | * | 726 | * |
714 | * In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3 | 727 | * In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3 |
715 | * bits with absolutely no headroom. So use 4 bits. */ | 728 | * bits with absolutely no headroom. So use 4 bits. */ |
716 | int pin_count : 4; | 729 | unsigned int pin_count : 4; |
717 | #define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf | 730 | #define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf |
718 | 731 | ||
719 | /** AGP memory structure for our GTT binding. */ | 732 | /** AGP memory structure for our GTT binding. */ |
@@ -743,7 +756,7 @@ struct drm_i915_gem_object { | |||
743 | uint32_t stride; | 756 | uint32_t stride; |
744 | 757 | ||
745 | /** Record of address bit 17 of each page at last unbind. */ | 758 | /** Record of address bit 17 of each page at last unbind. */ |
746 | long *bit_17; | 759 | unsigned long *bit_17; |
747 | 760 | ||
748 | /** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */ | 761 | /** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */ |
749 | uint32_t agp_type; | 762 | uint32_t agp_type; |
@@ -955,8 +968,7 @@ uint32_t i915_get_gem_seqno(struct drm_device *dev, | |||
955 | bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); | 968 | bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); |
956 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); | 969 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); |
957 | int i915_gem_object_put_fence_reg(struct drm_gem_object *obj); | 970 | int i915_gem_object_put_fence_reg(struct drm_gem_object *obj); |
958 | void i915_gem_retire_requests(struct drm_device *dev, | 971 | void i915_gem_retire_requests(struct drm_device *dev); |
959 | struct intel_ring_buffer *ring); | ||
960 | void i915_gem_retire_work_handler(struct work_struct *work); | 972 | void i915_gem_retire_work_handler(struct work_struct *work); |
961 | void i915_gem_clflush_object(struct drm_gem_object *obj); | 973 | void i915_gem_clflush_object(struct drm_gem_object *obj); |
962 | int i915_gem_object_set_domain(struct drm_gem_object *obj, | 974 | int i915_gem_object_set_domain(struct drm_gem_object *obj, |
@@ -986,7 +998,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev); | |||
986 | int i915_gem_object_get_pages(struct drm_gem_object *obj, gfp_t gfpmask); | 998 | int i915_gem_object_get_pages(struct drm_gem_object *obj, gfp_t gfpmask); |
987 | void i915_gem_object_put_pages(struct drm_gem_object *obj); | 999 | void i915_gem_object_put_pages(struct drm_gem_object *obj); |
988 | void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); | 1000 | void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); |
989 | void i915_gem_object_flush_write_domain(struct drm_gem_object *obj); | 1001 | int i915_gem_object_flush_write_domain(struct drm_gem_object *obj); |
990 | 1002 | ||
991 | void i915_gem_shrinker_init(void); | 1003 | void i915_gem_shrinker_init(void); |
992 | void i915_gem_shrinker_exit(void); | 1004 | void i915_gem_shrinker_exit(void); |
@@ -1046,6 +1058,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev); | |||
1046 | extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); | 1058 | extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); |
1047 | extern void i8xx_disable_fbc(struct drm_device *dev); | 1059 | extern void i8xx_disable_fbc(struct drm_device *dev); |
1048 | extern void g4x_disable_fbc(struct drm_device *dev); | 1060 | extern void g4x_disable_fbc(struct drm_device *dev); |
1061 | extern void ironlake_disable_fbc(struct drm_device *dev); | ||
1049 | extern void intel_disable_fbc(struct drm_device *dev); | 1062 | extern void intel_disable_fbc(struct drm_device *dev); |
1050 | extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); | 1063 | extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); |
1051 | extern bool intel_fbc_enabled(struct drm_device *dev); | 1064 | extern bool intel_fbc_enabled(struct drm_device *dev); |
@@ -1135,6 +1148,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
1135 | #define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm) | 1148 | #define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm) |
1136 | #define IS_I965G(dev) (INTEL_INFO(dev)->is_i965g) | 1149 | #define IS_I965G(dev) (INTEL_INFO(dev)->is_i965g) |
1137 | #define IS_I965GM(dev) (INTEL_INFO(dev)->is_i965gm) | 1150 | #define IS_I965GM(dev) (INTEL_INFO(dev)->is_i965gm) |
1151 | #define IS_BROADWATER(dev) (INTEL_INFO(dev)->is_broadwater) | ||
1152 | #define IS_CRESTLINE(dev) (INTEL_INFO(dev)->is_crestline) | ||
1138 | #define IS_GM45(dev) ((dev)->pci_device == 0x2A42) | 1153 | #define IS_GM45(dev) ((dev)->pci_device == 0x2A42) |
1139 | #define IS_G4X(dev) (INTEL_INFO(dev)->is_g4x) | 1154 | #define IS_G4X(dev) (INTEL_INFO(dev)->is_g4x) |
1140 | #define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001) | 1155 | #define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001) |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5aa747fc25a9..2a4ed7ca8b4e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/swap.h> | 35 | #include <linux/swap.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | 37 | ||
38 | static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); | 38 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); |
39 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); | 39 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); |
40 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); | 40 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); |
41 | static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, | 41 | static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, |
@@ -53,6 +53,7 @@ static int i915_gem_evict_from_inactive_list(struct drm_device *dev); | |||
53 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | 53 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, |
54 | struct drm_i915_gem_pwrite *args, | 54 | struct drm_i915_gem_pwrite *args, |
55 | struct drm_file *file_priv); | 55 | struct drm_file *file_priv); |
56 | static void i915_gem_free_object_tail(struct drm_gem_object *obj); | ||
56 | 57 | ||
57 | static LIST_HEAD(shrink_list); | 58 | static LIST_HEAD(shrink_list); |
58 | static DEFINE_SPINLOCK(shrink_list_lock); | 59 | static DEFINE_SPINLOCK(shrink_list_lock); |
@@ -127,8 +128,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
127 | return -ENOMEM; | 128 | return -ENOMEM; |
128 | 129 | ||
129 | ret = drm_gem_handle_create(file_priv, obj, &handle); | 130 | ret = drm_gem_handle_create(file_priv, obj, &handle); |
130 | drm_gem_object_handle_unreference_unlocked(obj); | 131 | drm_gem_object_unreference_unlocked(obj); |
131 | |||
132 | if (ret) | 132 | if (ret) |
133 | return ret; | 133 | return ret; |
134 | 134 | ||
@@ -496,10 +496,10 @@ fast_user_write(struct io_mapping *mapping, | |||
496 | char *vaddr_atomic; | 496 | char *vaddr_atomic; |
497 | unsigned long unwritten; | 497 | unsigned long unwritten; |
498 | 498 | ||
499 | vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base); | 499 | vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base, KM_USER0); |
500 | unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + page_offset, | 500 | unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + page_offset, |
501 | user_data, length); | 501 | user_data, length); |
502 | io_mapping_unmap_atomic(vaddr_atomic); | 502 | io_mapping_unmap_atomic(vaddr_atomic, KM_USER0); |
503 | if (unwritten) | 503 | if (unwritten) |
504 | return -EFAULT; | 504 | return -EFAULT; |
505 | return 0; | 505 | return 0; |
@@ -1709,9 +1709,9 @@ i915_get_gem_seqno(struct drm_device *dev, | |||
1709 | /** | 1709 | /** |
1710 | * This function clears the request list as sequence numbers are passed. | 1710 | * This function clears the request list as sequence numbers are passed. |
1711 | */ | 1711 | */ |
1712 | void | 1712 | static void |
1713 | i915_gem_retire_requests(struct drm_device *dev, | 1713 | i915_gem_retire_requests_ring(struct drm_device *dev, |
1714 | struct intel_ring_buffer *ring) | 1714 | struct intel_ring_buffer *ring) |
1715 | { | 1715 | { |
1716 | drm_i915_private_t *dev_priv = dev->dev_private; | 1716 | drm_i915_private_t *dev_priv = dev->dev_private; |
1717 | uint32_t seqno; | 1717 | uint32_t seqno; |
@@ -1751,6 +1751,30 @@ i915_gem_retire_requests(struct drm_device *dev, | |||
1751 | } | 1751 | } |
1752 | 1752 | ||
1753 | void | 1753 | void |
1754 | i915_gem_retire_requests(struct drm_device *dev) | ||
1755 | { | ||
1756 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1757 | |||
1758 | if (!list_empty(&dev_priv->mm.deferred_free_list)) { | ||
1759 | struct drm_i915_gem_object *obj_priv, *tmp; | ||
1760 | |||
1761 | /* We must be careful that during unbind() we do not | ||
1762 | * accidentally infinitely recurse into retire requests. | ||
1763 | * Currently: | ||
1764 | * retire -> free -> unbind -> wait -> retire_ring | ||
1765 | */ | ||
1766 | list_for_each_entry_safe(obj_priv, tmp, | ||
1767 | &dev_priv->mm.deferred_free_list, | ||
1768 | list) | ||
1769 | i915_gem_free_object_tail(&obj_priv->base); | ||
1770 | } | ||
1771 | |||
1772 | i915_gem_retire_requests_ring(dev, &dev_priv->render_ring); | ||
1773 | if (HAS_BSD(dev)) | ||
1774 | i915_gem_retire_requests_ring(dev, &dev_priv->bsd_ring); | ||
1775 | } | ||
1776 | |||
1777 | void | ||
1754 | i915_gem_retire_work_handler(struct work_struct *work) | 1778 | i915_gem_retire_work_handler(struct work_struct *work) |
1755 | { | 1779 | { |
1756 | drm_i915_private_t *dev_priv; | 1780 | drm_i915_private_t *dev_priv; |
@@ -1761,10 +1785,7 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
1761 | dev = dev_priv->dev; | 1785 | dev = dev_priv->dev; |
1762 | 1786 | ||
1763 | mutex_lock(&dev->struct_mutex); | 1787 | mutex_lock(&dev->struct_mutex); |
1764 | i915_gem_retire_requests(dev, &dev_priv->render_ring); | 1788 | i915_gem_retire_requests(dev); |
1765 | |||
1766 | if (HAS_BSD(dev)) | ||
1767 | i915_gem_retire_requests(dev, &dev_priv->bsd_ring); | ||
1768 | 1789 | ||
1769 | if (!dev_priv->mm.suspended && | 1790 | if (!dev_priv->mm.suspended && |
1770 | (!list_empty(&dev_priv->render_ring.request_list) || | 1791 | (!list_empty(&dev_priv->render_ring.request_list) || |
@@ -1832,7 +1853,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, | |||
1832 | * a separate wait queue to handle that. | 1853 | * a separate wait queue to handle that. |
1833 | */ | 1854 | */ |
1834 | if (ret == 0) | 1855 | if (ret == 0) |
1835 | i915_gem_retire_requests(dev, ring); | 1856 | i915_gem_retire_requests_ring(dev, ring); |
1836 | 1857 | ||
1837 | return ret; | 1858 | return ret; |
1838 | } | 1859 | } |
@@ -1945,11 +1966,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
1945 | * before we unbind. | 1966 | * before we unbind. |
1946 | */ | 1967 | */ |
1947 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); | 1968 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); |
1948 | if (ret) { | 1969 | if (ret == -ERESTARTSYS) |
1949 | if (ret != -ERESTARTSYS) | ||
1950 | DRM_ERROR("set_domain failed: %d\n", ret); | ||
1951 | return ret; | 1970 | return ret; |
1952 | } | 1971 | /* Continue on if we fail due to EIO, the GPU is hung so we |
1972 | * should be safe and we need to cleanup or else we might | ||
1973 | * cause memory corruption through use-after-free. | ||
1974 | */ | ||
1953 | 1975 | ||
1954 | BUG_ON(obj_priv->active); | 1976 | BUG_ON(obj_priv->active); |
1955 | 1977 | ||
@@ -1985,7 +2007,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
1985 | 2007 | ||
1986 | trace_i915_gem_object_unbind(obj); | 2008 | trace_i915_gem_object_unbind(obj); |
1987 | 2009 | ||
1988 | return 0; | 2010 | return ret; |
1989 | } | 2011 | } |
1990 | 2012 | ||
1991 | static struct drm_gem_object * | 2013 | static struct drm_gem_object * |
@@ -2107,10 +2129,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) | |||
2107 | struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | 2129 | struct intel_ring_buffer *render_ring = &dev_priv->render_ring; |
2108 | struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring; | 2130 | struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring; |
2109 | for (;;) { | 2131 | for (;;) { |
2110 | i915_gem_retire_requests(dev, render_ring); | 2132 | i915_gem_retire_requests(dev); |
2111 | |||
2112 | if (HAS_BSD(dev)) | ||
2113 | i915_gem_retire_requests(dev, bsd_ring); | ||
2114 | 2133 | ||
2115 | /* If there's an inactive buffer available now, grab it | 2134 | /* If there's an inactive buffer available now, grab it |
2116 | * and be done. | 2135 | * and be done. |
@@ -2583,7 +2602,10 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj) | |||
2583 | if (!IS_I965G(dev)) { | 2602 | if (!IS_I965G(dev)) { |
2584 | int ret; | 2603 | int ret; |
2585 | 2604 | ||
2586 | i915_gem_object_flush_gpu_write_domain(obj); | 2605 | ret = i915_gem_object_flush_gpu_write_domain(obj); |
2606 | if (ret != 0) | ||
2607 | return ret; | ||
2608 | |||
2587 | ret = i915_gem_object_wait_rendering(obj); | 2609 | ret = i915_gem_object_wait_rendering(obj); |
2588 | if (ret != 0) | 2610 | if (ret != 0) |
2589 | return ret; | 2611 | return ret; |
@@ -2634,10 +2656,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2634 | if (free_space != NULL) { | 2656 | if (free_space != NULL) { |
2635 | obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size, | 2657 | obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size, |
2636 | alignment); | 2658 | alignment); |
2637 | if (obj_priv->gtt_space != NULL) { | 2659 | if (obj_priv->gtt_space != NULL) |
2638 | obj_priv->gtt_space->private = obj; | ||
2639 | obj_priv->gtt_offset = obj_priv->gtt_space->start; | 2660 | obj_priv->gtt_offset = obj_priv->gtt_space->start; |
2640 | } | ||
2641 | } | 2661 | } |
2642 | if (obj_priv->gtt_space == NULL) { | 2662 | if (obj_priv->gtt_space == NULL) { |
2643 | /* If the gtt is empty and we're still having trouble | 2663 | /* If the gtt is empty and we're still having trouble |
@@ -2733,7 +2753,7 @@ i915_gem_clflush_object(struct drm_gem_object *obj) | |||
2733 | } | 2753 | } |
2734 | 2754 | ||
2735 | /** Flushes any GPU write domain for the object if it's dirty. */ | 2755 | /** Flushes any GPU write domain for the object if it's dirty. */ |
2736 | static void | 2756 | static int |
2737 | i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) | 2757 | i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) |
2738 | { | 2758 | { |
2739 | struct drm_device *dev = obj->dev; | 2759 | struct drm_device *dev = obj->dev; |
@@ -2741,17 +2761,18 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) | |||
2741 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2761 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2742 | 2762 | ||
2743 | if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) | 2763 | if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) |
2744 | return; | 2764 | return 0; |
2745 | 2765 | ||
2746 | /* Queue the GPU write cache flushing we need. */ | 2766 | /* Queue the GPU write cache flushing we need. */ |
2747 | old_write_domain = obj->write_domain; | 2767 | old_write_domain = obj->write_domain; |
2748 | i915_gem_flush(dev, 0, obj->write_domain); | 2768 | i915_gem_flush(dev, 0, obj->write_domain); |
2749 | (void) i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring); | 2769 | if (i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring) == 0) |
2750 | BUG_ON(obj->write_domain); | 2770 | return -ENOMEM; |
2751 | 2771 | ||
2752 | trace_i915_gem_object_change_domain(obj, | 2772 | trace_i915_gem_object_change_domain(obj, |
2753 | obj->read_domains, | 2773 | obj->read_domains, |
2754 | old_write_domain); | 2774 | old_write_domain); |
2775 | return 0; | ||
2755 | } | 2776 | } |
2756 | 2777 | ||
2757 | /** Flushes the GTT write domain for the object if it's dirty. */ | 2778 | /** Flushes the GTT write domain for the object if it's dirty. */ |
@@ -2795,9 +2816,11 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj) | |||
2795 | old_write_domain); | 2816 | old_write_domain); |
2796 | } | 2817 | } |
2797 | 2818 | ||
2798 | void | 2819 | int |
2799 | i915_gem_object_flush_write_domain(struct drm_gem_object *obj) | 2820 | i915_gem_object_flush_write_domain(struct drm_gem_object *obj) |
2800 | { | 2821 | { |
2822 | int ret = 0; | ||
2823 | |||
2801 | switch (obj->write_domain) { | 2824 | switch (obj->write_domain) { |
2802 | case I915_GEM_DOMAIN_GTT: | 2825 | case I915_GEM_DOMAIN_GTT: |
2803 | i915_gem_object_flush_gtt_write_domain(obj); | 2826 | i915_gem_object_flush_gtt_write_domain(obj); |
@@ -2806,9 +2829,11 @@ i915_gem_object_flush_write_domain(struct drm_gem_object *obj) | |||
2806 | i915_gem_object_flush_cpu_write_domain(obj); | 2829 | i915_gem_object_flush_cpu_write_domain(obj); |
2807 | break; | 2830 | break; |
2808 | default: | 2831 | default: |
2809 | i915_gem_object_flush_gpu_write_domain(obj); | 2832 | ret = i915_gem_object_flush_gpu_write_domain(obj); |
2810 | break; | 2833 | break; |
2811 | } | 2834 | } |
2835 | |||
2836 | return ret; | ||
2812 | } | 2837 | } |
2813 | 2838 | ||
2814 | /** | 2839 | /** |
@@ -2828,7 +2853,10 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) | |||
2828 | if (obj_priv->gtt_space == NULL) | 2853 | if (obj_priv->gtt_space == NULL) |
2829 | return -EINVAL; | 2854 | return -EINVAL; |
2830 | 2855 | ||
2831 | i915_gem_object_flush_gpu_write_domain(obj); | 2856 | ret = i915_gem_object_flush_gpu_write_domain(obj); |
2857 | if (ret != 0) | ||
2858 | return ret; | ||
2859 | |||
2832 | /* Wait on any GPU rendering and flushing to occur. */ | 2860 | /* Wait on any GPU rendering and flushing to occur. */ |
2833 | ret = i915_gem_object_wait_rendering(obj); | 2861 | ret = i915_gem_object_wait_rendering(obj); |
2834 | if (ret != 0) | 2862 | if (ret != 0) |
@@ -2878,7 +2906,9 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) | |||
2878 | if (obj_priv->gtt_space == NULL) | 2906 | if (obj_priv->gtt_space == NULL) |
2879 | return -EINVAL; | 2907 | return -EINVAL; |
2880 | 2908 | ||
2881 | i915_gem_object_flush_gpu_write_domain(obj); | 2909 | ret = i915_gem_object_flush_gpu_write_domain(obj); |
2910 | if (ret) | ||
2911 | return ret; | ||
2882 | 2912 | ||
2883 | /* Wait on any GPU rendering and flushing to occur. */ | 2913 | /* Wait on any GPU rendering and flushing to occur. */ |
2884 | if (obj_priv->active) { | 2914 | if (obj_priv->active) { |
@@ -2926,7 +2956,10 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) | |||
2926 | uint32_t old_write_domain, old_read_domains; | 2956 | uint32_t old_write_domain, old_read_domains; |
2927 | int ret; | 2957 | int ret; |
2928 | 2958 | ||
2929 | i915_gem_object_flush_gpu_write_domain(obj); | 2959 | ret = i915_gem_object_flush_gpu_write_domain(obj); |
2960 | if (ret) | ||
2961 | return ret; | ||
2962 | |||
2930 | /* Wait on any GPU rendering and flushing to occur. */ | 2963 | /* Wait on any GPU rendering and flushing to occur. */ |
2931 | ret = i915_gem_object_wait_rendering(obj); | 2964 | ret = i915_gem_object_wait_rendering(obj); |
2932 | if (ret != 0) | 2965 | if (ret != 0) |
@@ -3216,7 +3249,10 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, | |||
3216 | if (offset == 0 && size == obj->size) | 3249 | if (offset == 0 && size == obj->size) |
3217 | return i915_gem_object_set_to_cpu_domain(obj, 0); | 3250 | return i915_gem_object_set_to_cpu_domain(obj, 0); |
3218 | 3251 | ||
3219 | i915_gem_object_flush_gpu_write_domain(obj); | 3252 | ret = i915_gem_object_flush_gpu_write_domain(obj); |
3253 | if (ret) | ||
3254 | return ret; | ||
3255 | |||
3220 | /* Wait on any GPU rendering and flushing to occur. */ | 3256 | /* Wait on any GPU rendering and flushing to occur. */ |
3221 | ret = i915_gem_object_wait_rendering(obj); | 3257 | ret = i915_gem_object_wait_rendering(obj); |
3222 | if (ret != 0) | 3258 | if (ret != 0) |
@@ -3451,7 +3487,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3451 | reloc_offset = obj_priv->gtt_offset + reloc->offset; | 3487 | reloc_offset = obj_priv->gtt_offset + reloc->offset; |
3452 | reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, | 3488 | reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, |
3453 | (reloc_offset & | 3489 | (reloc_offset & |
3454 | ~(PAGE_SIZE - 1))); | 3490 | ~(PAGE_SIZE - 1)), |
3491 | KM_USER0); | ||
3455 | reloc_entry = (uint32_t __iomem *)(reloc_page + | 3492 | reloc_entry = (uint32_t __iomem *)(reloc_page + |
3456 | (reloc_offset & (PAGE_SIZE - 1))); | 3493 | (reloc_offset & (PAGE_SIZE - 1))); |
3457 | reloc_val = target_obj_priv->gtt_offset + reloc->delta; | 3494 | reloc_val = target_obj_priv->gtt_offset + reloc->delta; |
@@ -3462,7 +3499,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3462 | readl(reloc_entry), reloc_val); | 3499 | readl(reloc_entry), reloc_val); |
3463 | #endif | 3500 | #endif |
3464 | writel(reloc_val, reloc_entry); | 3501 | writel(reloc_val, reloc_entry); |
3465 | io_mapping_unmap_atomic(reloc_page); | 3502 | io_mapping_unmap_atomic(reloc_page, KM_USER0); |
3466 | 3503 | ||
3467 | /* The updated presumed offset for this entry will be | 3504 | /* The updated presumed offset for this entry will be |
3468 | * copied back out to the user. | 3505 | * copied back out to the user. |
@@ -4313,7 +4350,6 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
4313 | struct drm_i915_gem_busy *args = data; | 4350 | struct drm_i915_gem_busy *args = data; |
4314 | struct drm_gem_object *obj; | 4351 | struct drm_gem_object *obj; |
4315 | struct drm_i915_gem_object *obj_priv; | 4352 | struct drm_i915_gem_object *obj_priv; |
4316 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
4317 | 4353 | ||
4318 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 4354 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
4319 | if (obj == NULL) { | 4355 | if (obj == NULL) { |
@@ -4328,10 +4364,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
4328 | * actually unmasked, and our working set ends up being larger than | 4364 | * actually unmasked, and our working set ends up being larger than |
4329 | * required. | 4365 | * required. |
4330 | */ | 4366 | */ |
4331 | i915_gem_retire_requests(dev, &dev_priv->render_ring); | 4367 | i915_gem_retire_requests(dev); |
4332 | |||
4333 | if (HAS_BSD(dev)) | ||
4334 | i915_gem_retire_requests(dev, &dev_priv->bsd_ring); | ||
4335 | 4368 | ||
4336 | obj_priv = to_intel_bo(obj); | 4369 | obj_priv = to_intel_bo(obj); |
4337 | /* Don't count being on the flushing list against the object being | 4370 | /* Don't count being on the flushing list against the object being |
@@ -4441,20 +4474,19 @@ int i915_gem_init_object(struct drm_gem_object *obj) | |||
4441 | return 0; | 4474 | return 0; |
4442 | } | 4475 | } |
4443 | 4476 | ||
4444 | void i915_gem_free_object(struct drm_gem_object *obj) | 4477 | static void i915_gem_free_object_tail(struct drm_gem_object *obj) |
4445 | { | 4478 | { |
4446 | struct drm_device *dev = obj->dev; | 4479 | struct drm_device *dev = obj->dev; |
4480 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
4447 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 4481 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
4482 | int ret; | ||
4448 | 4483 | ||
4449 | trace_i915_gem_object_destroy(obj); | 4484 | ret = i915_gem_object_unbind(obj); |
4450 | 4485 | if (ret == -ERESTARTSYS) { | |
4451 | while (obj_priv->pin_count > 0) | 4486 | list_move(&obj_priv->list, |
4452 | i915_gem_object_unpin(obj); | 4487 | &dev_priv->mm.deferred_free_list); |
4453 | 4488 | return; | |
4454 | if (obj_priv->phys_obj) | 4489 | } |
4455 | i915_gem_detach_phys_object(dev, obj); | ||
4456 | |||
4457 | i915_gem_object_unbind(obj); | ||
4458 | 4490 | ||
4459 | if (obj_priv->mmap_offset) | 4491 | if (obj_priv->mmap_offset) |
4460 | i915_gem_free_mmap_offset(obj); | 4492 | i915_gem_free_mmap_offset(obj); |
@@ -4466,6 +4498,22 @@ void i915_gem_free_object(struct drm_gem_object *obj) | |||
4466 | kfree(obj_priv); | 4498 | kfree(obj_priv); |
4467 | } | 4499 | } |
4468 | 4500 | ||
4501 | void i915_gem_free_object(struct drm_gem_object *obj) | ||
4502 | { | ||
4503 | struct drm_device *dev = obj->dev; | ||
4504 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
4505 | |||
4506 | trace_i915_gem_object_destroy(obj); | ||
4507 | |||
4508 | while (obj_priv->pin_count > 0) | ||
4509 | i915_gem_object_unpin(obj); | ||
4510 | |||
4511 | if (obj_priv->phys_obj) | ||
4512 | i915_gem_detach_phys_object(dev, obj); | ||
4513 | |||
4514 | i915_gem_free_object_tail(obj); | ||
4515 | } | ||
4516 | |||
4469 | /** Unbinds all inactive objects. */ | 4517 | /** Unbinds all inactive objects. */ |
4470 | static int | 4518 | static int |
4471 | i915_gem_evict_from_inactive_list(struct drm_device *dev) | 4519 | i915_gem_evict_from_inactive_list(struct drm_device *dev) |
@@ -4689,9 +4737,19 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, | |||
4689 | BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.request_list)); | 4737 | BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.request_list)); |
4690 | mutex_unlock(&dev->struct_mutex); | 4738 | mutex_unlock(&dev->struct_mutex); |
4691 | 4739 | ||
4692 | drm_irq_install(dev); | 4740 | ret = drm_irq_install(dev); |
4741 | if (ret) | ||
4742 | goto cleanup_ringbuffer; | ||
4693 | 4743 | ||
4694 | return 0; | 4744 | return 0; |
4745 | |||
4746 | cleanup_ringbuffer: | ||
4747 | mutex_lock(&dev->struct_mutex); | ||
4748 | i915_gem_cleanup_ringbuffer(dev); | ||
4749 | dev_priv->mm.suspended = 1; | ||
4750 | mutex_unlock(&dev->struct_mutex); | ||
4751 | |||
4752 | return ret; | ||
4695 | } | 4753 | } |
4696 | 4754 | ||
4697 | int | 4755 | int |
@@ -4729,6 +4787,7 @@ i915_gem_load(struct drm_device *dev) | |||
4729 | INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); | 4787 | INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); |
4730 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); | 4788 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); |
4731 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); | 4789 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); |
4790 | INIT_LIST_HEAD(&dev_priv->mm.deferred_free_list); | ||
4732 | INIT_LIST_HEAD(&dev_priv->render_ring.active_list); | 4791 | INIT_LIST_HEAD(&dev_priv->render_ring.active_list); |
4733 | INIT_LIST_HEAD(&dev_priv->render_ring.request_list); | 4792 | INIT_LIST_HEAD(&dev_priv->render_ring.request_list); |
4734 | if (HAS_BSD(dev)) { | 4793 | if (HAS_BSD(dev)) { |
@@ -5027,10 +5086,7 @@ rescan: | |||
5027 | continue; | 5086 | continue; |
5028 | 5087 | ||
5029 | spin_unlock(&shrink_list_lock); | 5088 | spin_unlock(&shrink_list_lock); |
5030 | i915_gem_retire_requests(dev, &dev_priv->render_ring); | 5089 | i915_gem_retire_requests(dev); |
5031 | |||
5032 | if (HAS_BSD(dev)) | ||
5033 | i915_gem_retire_requests(dev, &dev_priv->bsd_ring); | ||
5034 | 5090 | ||
5035 | list_for_each_entry_safe(obj_priv, next_obj, | 5091 | list_for_each_entry_safe(obj_priv, next_obj, |
5036 | &dev_priv->mm.inactive_list, | 5092 | &dev_priv->mm.inactive_list, |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 4b7c49d4257d..155719e4d16f 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -333,8 +333,6 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
333 | i915_gem_release_mmap(obj); | 333 | i915_gem_release_mmap(obj); |
334 | 334 | ||
335 | if (ret != 0) { | 335 | if (ret != 0) { |
336 | WARN(ret != -ERESTARTSYS, | ||
337 | "failed to reset object for tiling switch"); | ||
338 | args->tiling_mode = obj_priv->tiling_mode; | 336 | args->tiling_mode = obj_priv->tiling_mode; |
339 | args->stride = obj_priv->stride; | 337 | args->stride = obj_priv->stride; |
340 | goto err; | 338 | goto err; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index dba53d4b9fb3..85785a8844ed 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -171,10 +171,10 @@ void intel_enable_asle (struct drm_device *dev) | |||
171 | ironlake_enable_display_irq(dev_priv, DE_GSE); | 171 | ironlake_enable_display_irq(dev_priv, DE_GSE); |
172 | else { | 172 | else { |
173 | i915_enable_pipestat(dev_priv, 1, | 173 | i915_enable_pipestat(dev_priv, 1, |
174 | I915_LEGACY_BLC_EVENT_ENABLE); | 174 | PIPE_LEGACY_BLC_EVENT_ENABLE); |
175 | if (IS_I965G(dev)) | 175 | if (IS_I965G(dev)) |
176 | i915_enable_pipestat(dev_priv, 0, | 176 | i915_enable_pipestat(dev_priv, 0, |
177 | I915_LEGACY_BLC_EVENT_ENABLE); | 177 | PIPE_LEGACY_BLC_EVENT_ENABLE); |
178 | } | 178 | } |
179 | } | 179 | } |
180 | 180 | ||
@@ -842,7 +842,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
842 | u32 iir, new_iir; | 842 | u32 iir, new_iir; |
843 | u32 pipea_stats, pipeb_stats; | 843 | u32 pipea_stats, pipeb_stats; |
844 | u32 vblank_status; | 844 | u32 vblank_status; |
845 | u32 vblank_enable; | ||
846 | int vblank = 0; | 845 | int vblank = 0; |
847 | unsigned long irqflags; | 846 | unsigned long irqflags; |
848 | int irq_received; | 847 | int irq_received; |
@@ -856,13 +855,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
856 | 855 | ||
857 | iir = I915_READ(IIR); | 856 | iir = I915_READ(IIR); |
858 | 857 | ||
859 | if (IS_I965G(dev)) { | 858 | if (IS_I965G(dev)) |
860 | vblank_status = I915_START_VBLANK_INTERRUPT_STATUS; | 859 | vblank_status = PIPE_START_VBLANK_INTERRUPT_STATUS; |
861 | vblank_enable = PIPE_START_VBLANK_INTERRUPT_ENABLE; | 860 | else |
862 | } else { | 861 | vblank_status = PIPE_VBLANK_INTERRUPT_STATUS; |
863 | vblank_status = I915_VBLANK_INTERRUPT_STATUS; | ||
864 | vblank_enable = I915_VBLANK_INTERRUPT_ENABLE; | ||
865 | } | ||
866 | 862 | ||
867 | for (;;) { | 863 | for (;;) { |
868 | irq_received = iir != 0; | 864 | irq_received = iir != 0; |
@@ -966,8 +962,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
966 | intel_finish_page_flip(dev, 1); | 962 | intel_finish_page_flip(dev, 1); |
967 | } | 963 | } |
968 | 964 | ||
969 | if ((pipea_stats & I915_LEGACY_BLC_EVENT_STATUS) || | 965 | if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || |
970 | (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) || | 966 | (pipeb_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || |
971 | (iir & I915_ASLE_INTERRUPT)) | 967 | (iir & I915_ASLE_INTERRUPT)) |
972 | opregion_asle_intr(dev); | 968 | opregion_asle_intr(dev); |
973 | 969 | ||
@@ -1233,16 +1229,21 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1233 | { | 1229 | { |
1234 | struct drm_device *dev = (struct drm_device *)data; | 1230 | struct drm_device *dev = (struct drm_device *)data; |
1235 | drm_i915_private_t *dev_priv = dev->dev_private; | 1231 | drm_i915_private_t *dev_priv = dev->dev_private; |
1236 | uint32_t acthd; | 1232 | uint32_t acthd, instdone, instdone1; |
1237 | 1233 | ||
1238 | /* No reset support on this chip yet. */ | 1234 | /* No reset support on this chip yet. */ |
1239 | if (IS_GEN6(dev)) | 1235 | if (IS_GEN6(dev)) |
1240 | return; | 1236 | return; |
1241 | 1237 | ||
1242 | if (!IS_I965G(dev)) | 1238 | if (!IS_I965G(dev)) { |
1243 | acthd = I915_READ(ACTHD); | 1239 | acthd = I915_READ(ACTHD); |
1244 | else | 1240 | instdone = I915_READ(INSTDONE); |
1241 | instdone1 = 0; | ||
1242 | } else { | ||
1245 | acthd = I915_READ(ACTHD_I965); | 1243 | acthd = I915_READ(ACTHD_I965); |
1244 | instdone = I915_READ(INSTDONE_I965); | ||
1245 | instdone1 = I915_READ(INSTDONE1); | ||
1246 | } | ||
1246 | 1247 | ||
1247 | /* If all work is done then ACTHD clearly hasn't advanced. */ | 1248 | /* If all work is done then ACTHD clearly hasn't advanced. */ |
1248 | if (list_empty(&dev_priv->render_ring.request_list) || | 1249 | if (list_empty(&dev_priv->render_ring.request_list) || |
@@ -1253,21 +1254,24 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1253 | return; | 1254 | return; |
1254 | } | 1255 | } |
1255 | 1256 | ||
1256 | if (dev_priv->last_acthd == acthd && dev_priv->hangcheck_count > 0) { | 1257 | if (dev_priv->last_acthd == acthd && |
1257 | DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); | 1258 | dev_priv->last_instdone == instdone && |
1258 | i915_handle_error(dev, true); | 1259 | dev_priv->last_instdone1 == instdone1) { |
1259 | return; | 1260 | if (dev_priv->hangcheck_count++ > 1) { |
1260 | } | 1261 | DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); |
1262 | i915_handle_error(dev, true); | ||
1263 | return; | ||
1264 | } | ||
1265 | } else { | ||
1266 | dev_priv->hangcheck_count = 0; | ||
1267 | |||
1268 | dev_priv->last_acthd = acthd; | ||
1269 | dev_priv->last_instdone = instdone; | ||
1270 | dev_priv->last_instdone1 = instdone1; | ||
1271 | } | ||
1261 | 1272 | ||
1262 | /* Reset timer case chip hangs without another request being added */ | 1273 | /* Reset timer case chip hangs without another request being added */ |
1263 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); | 1274 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); |
1264 | |||
1265 | if (acthd != dev_priv->last_acthd) | ||
1266 | dev_priv->hangcheck_count = 0; | ||
1267 | else | ||
1268 | dev_priv->hangcheck_count++; | ||
1269 | |||
1270 | dev_priv->last_acthd = acthd; | ||
1271 | } | 1275 | } |
1272 | 1276 | ||
1273 | /* drm_dma.h hooks | 1277 | /* drm_dma.h hooks |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index cf41c672defe..281db6e5403a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -442,7 +442,7 @@ | |||
442 | #define GEN6_RENDER_IMR 0x20a8 | 442 | #define GEN6_RENDER_IMR 0x20a8 |
443 | #define GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT (1 << 8) | 443 | #define GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT (1 << 8) |
444 | #define GEN6_RENDER_PPGTT_PAGE_FAULT (1 << 7) | 444 | #define GEN6_RENDER_PPGTT_PAGE_FAULT (1 << 7) |
445 | #define GEN6_RENDER TIMEOUT_COUNTER_EXPIRED (1 << 6) | 445 | #define GEN6_RENDER_TIMEOUT_COUNTER_EXPIRED (1 << 6) |
446 | #define GEN6_RENDER_L3_PARITY_ERROR (1 << 5) | 446 | #define GEN6_RENDER_L3_PARITY_ERROR (1 << 5) |
447 | #define GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT (1 << 4) | 447 | #define GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT (1 << 4) |
448 | #define GEN6_RENDER_COMMAND_PARSER_MASTER_ERROR (1 << 3) | 448 | #define GEN6_RENDER_COMMAND_PARSER_MASTER_ERROR (1 << 3) |
@@ -530,6 +530,21 @@ | |||
530 | #define DPFC_CHICKEN 0x3224 | 530 | #define DPFC_CHICKEN 0x3224 |
531 | #define DPFC_HT_MODIFY (1<<31) | 531 | #define DPFC_HT_MODIFY (1<<31) |
532 | 532 | ||
533 | /* Framebuffer compression for Ironlake */ | ||
534 | #define ILK_DPFC_CB_BASE 0x43200 | ||
535 | #define ILK_DPFC_CONTROL 0x43208 | ||
536 | /* The bit 28-8 is reserved */ | ||
537 | #define DPFC_RESERVED (0x1FFFFF00) | ||
538 | #define ILK_DPFC_RECOMP_CTL 0x4320c | ||
539 | #define ILK_DPFC_STATUS 0x43210 | ||
540 | #define ILK_DPFC_FENCE_YOFF 0x43218 | ||
541 | #define ILK_DPFC_CHICKEN 0x43224 | ||
542 | #define ILK_FBC_RT_BASE 0x2128 | ||
543 | #define ILK_FBC_RT_VALID (1<<0) | ||
544 | |||
545 | #define ILK_DISPLAY_CHICKEN1 0x42000 | ||
546 | #define ILK_FBCQ_DIS (1<<22) | ||
547 | |||
533 | /* | 548 | /* |
534 | * GPIO regs | 549 | * GPIO regs |
535 | */ | 550 | */ |
@@ -595,32 +610,6 @@ | |||
595 | #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ | 610 | #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ |
596 | #define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */ | 611 | #define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */ |
597 | 612 | ||
598 | #define I915_FIFO_UNDERRUN_STATUS (1UL<<31) | ||
599 | #define I915_CRC_ERROR_ENABLE (1UL<<29) | ||
600 | #define I915_CRC_DONE_ENABLE (1UL<<28) | ||
601 | #define I915_GMBUS_EVENT_ENABLE (1UL<<27) | ||
602 | #define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25) | ||
603 | #define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24) | ||
604 | #define I915_DPST_EVENT_ENABLE (1UL<<23) | ||
605 | #define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22) | ||
606 | #define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) | ||
607 | #define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) | ||
608 | #define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ | ||
609 | #define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) | ||
610 | #define I915_OVERLAY_UPDATED_ENABLE (1UL<<16) | ||
611 | #define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13) | ||
612 | #define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12) | ||
613 | #define I915_GMBUS_INTERRUPT_STATUS (1UL<<11) | ||
614 | #define I915_VSYNC_INTERRUPT_STATUS (1UL<<9) | ||
615 | #define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) | ||
616 | #define I915_DPST_EVENT_STATUS (1UL<<7) | ||
617 | #define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6) | ||
618 | #define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) | ||
619 | #define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) | ||
620 | #define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ | ||
621 | #define I915_VBLANK_INTERRUPT_STATUS (1UL<<1) | ||
622 | #define I915_OVERLAY_UPDATED_STATUS (1UL<<0) | ||
623 | |||
624 | #define SRX_INDEX 0x3c4 | 613 | #define SRX_INDEX 0x3c4 |
625 | #define SRX_DATA 0x3c5 | 614 | #define SRX_DATA 0x3c5 |
626 | #define SR01 1 | 615 | #define SR01 1 |
@@ -2166,7 +2155,8 @@ | |||
2166 | #define I830_FIFO_LINE_SIZE 32 | 2155 | #define I830_FIFO_LINE_SIZE 32 |
2167 | 2156 | ||
2168 | #define G4X_FIFO_SIZE 127 | 2157 | #define G4X_FIFO_SIZE 127 |
2169 | #define I945_FIFO_SIZE 127 /* 945 & 965 */ | 2158 | #define I965_FIFO_SIZE 512 |
2159 | #define I945_FIFO_SIZE 127 | ||
2170 | #define I915_FIFO_SIZE 95 | 2160 | #define I915_FIFO_SIZE 95 |
2171 | #define I855GM_FIFO_SIZE 127 /* In cachelines */ | 2161 | #define I855GM_FIFO_SIZE 127 /* In cachelines */ |
2172 | #define I830_FIFO_SIZE 95 | 2162 | #define I830_FIFO_SIZE 95 |
@@ -2185,6 +2175,9 @@ | |||
2185 | #define PINEVIEW_CURSOR_DFT_WM 0 | 2175 | #define PINEVIEW_CURSOR_DFT_WM 0 |
2186 | #define PINEVIEW_CURSOR_GUARD_WM 5 | 2176 | #define PINEVIEW_CURSOR_GUARD_WM 5 |
2187 | 2177 | ||
2178 | #define I965_CURSOR_FIFO 64 | ||
2179 | #define I965_CURSOR_MAX_WM 32 | ||
2180 | #define I965_CURSOR_DFT_WM 8 | ||
2188 | 2181 | ||
2189 | /* define the Watermark register on Ironlake */ | 2182 | /* define the Watermark register on Ironlake */ |
2190 | #define WM0_PIPEA_ILK 0x45100 | 2183 | #define WM0_PIPEA_ILK 0x45100 |
@@ -2212,6 +2205,9 @@ | |||
2212 | #define ILK_DISPLAY_FIFO 128 | 2205 | #define ILK_DISPLAY_FIFO 128 |
2213 | #define ILK_DISPLAY_MAXWM 64 | 2206 | #define ILK_DISPLAY_MAXWM 64 |
2214 | #define ILK_DISPLAY_DFTWM 8 | 2207 | #define ILK_DISPLAY_DFTWM 8 |
2208 | #define ILK_CURSOR_FIFO 32 | ||
2209 | #define ILK_CURSOR_MAXWM 16 | ||
2210 | #define ILK_CURSOR_DFTWM 8 | ||
2215 | 2211 | ||
2216 | #define ILK_DISPLAY_SR_FIFO 512 | 2212 | #define ILK_DISPLAY_SR_FIFO 512 |
2217 | #define ILK_DISPLAY_MAX_SRWM 0x1ff | 2213 | #define ILK_DISPLAY_MAX_SRWM 0x1ff |
@@ -2510,6 +2506,10 @@ | |||
2510 | #define ILK_VSDPFD_FULL (1<<21) | 2506 | #define ILK_VSDPFD_FULL (1<<21) |
2511 | #define ILK_DSPCLK_GATE 0x42020 | 2507 | #define ILK_DSPCLK_GATE 0x42020 |
2512 | #define ILK_DPARB_CLK_GATE (1<<5) | 2508 | #define ILK_DPARB_CLK_GATE (1<<5) |
2509 | /* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */ | ||
2510 | #define ILK_CLK_FBC (1<<7) | ||
2511 | #define ILK_DPFC_DIS1 (1<<8) | ||
2512 | #define ILK_DPFC_DIS2 (1<<9) | ||
2513 | 2513 | ||
2514 | #define DISP_ARB_CTL 0x45000 | 2514 | #define DISP_ARB_CTL 0x45000 |
2515 | #define DISP_TILE_SURFACE_SWIZZLING (1<<13) | 2515 | #define DISP_TILE_SURFACE_SWIZZLING (1<<13) |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 60a5800fba6e..6e2025274db5 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -602,7 +602,9 @@ void i915_save_display(struct drm_device *dev) | |||
602 | 602 | ||
603 | /* Only save FBC state on the platform that supports FBC */ | 603 | /* Only save FBC state on the platform that supports FBC */ |
604 | if (I915_HAS_FBC(dev)) { | 604 | if (I915_HAS_FBC(dev)) { |
605 | if (IS_GM45(dev)) { | 605 | if (IS_IRONLAKE_M(dev)) { |
606 | dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE); | ||
607 | } else if (IS_GM45(dev)) { | ||
606 | dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); | 608 | dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); |
607 | } else { | 609 | } else { |
608 | dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); | 610 | dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); |
@@ -706,7 +708,10 @@ void i915_restore_display(struct drm_device *dev) | |||
706 | 708 | ||
707 | /* only restore FBC info on the platform that supports FBC*/ | 709 | /* only restore FBC info on the platform that supports FBC*/ |
708 | if (I915_HAS_FBC(dev)) { | 710 | if (I915_HAS_FBC(dev)) { |
709 | if (IS_GM45(dev)) { | 711 | if (IS_IRONLAKE_M(dev)) { |
712 | ironlake_disable_fbc(dev); | ||
713 | I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); | ||
714 | } else if (IS_GM45(dev)) { | ||
710 | g4x_disable_fbc(dev); | 715 | g4x_disable_fbc(dev); |
711 | I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); | 716 | I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); |
712 | } else { | 717 | } else { |
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index fab21760dd57..fea97a21cc14 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h | |||
@@ -262,6 +262,42 @@ DEFINE_EVENT(i915_ring, i915_ring_wait_end, | |||
262 | TP_ARGS(dev) | 262 | TP_ARGS(dev) |
263 | ); | 263 | ); |
264 | 264 | ||
265 | TRACE_EVENT(i915_flip_request, | ||
266 | TP_PROTO(int plane, struct drm_gem_object *obj), | ||
267 | |||
268 | TP_ARGS(plane, obj), | ||
269 | |||
270 | TP_STRUCT__entry( | ||
271 | __field(int, plane) | ||
272 | __field(struct drm_gem_object *, obj) | ||
273 | ), | ||
274 | |||
275 | TP_fast_assign( | ||
276 | __entry->plane = plane; | ||
277 | __entry->obj = obj; | ||
278 | ), | ||
279 | |||
280 | TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj) | ||
281 | ); | ||
282 | |||
283 | TRACE_EVENT(i915_flip_complete, | ||
284 | TP_PROTO(int plane, struct drm_gem_object *obj), | ||
285 | |||
286 | TP_ARGS(plane, obj), | ||
287 | |||
288 | TP_STRUCT__entry( | ||
289 | __field(int, plane) | ||
290 | __field(struct drm_gem_object *, obj) | ||
291 | ), | ||
292 | |||
293 | TP_fast_assign( | ||
294 | __entry->plane = plane; | ||
295 | __entry->obj = obj; | ||
296 | ), | ||
297 | |||
298 | TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj) | ||
299 | ); | ||
300 | |||
265 | #endif /* _I915_TRACE_H_ */ | 301 | #endif /* _I915_TRACE_H_ */ |
266 | 302 | ||
267 | /* This part must be outside protection */ | 303 | /* This part must be outside protection */ |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 714bf539918b..1e5e0d379fa9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "intel_drv.h" | 33 | #include "intel_drv.h" |
34 | #include "i915_drm.h" | 34 | #include "i915_drm.h" |
35 | #include "i915_drv.h" | 35 | #include "i915_drv.h" |
36 | #include "i915_trace.h" | ||
36 | #include "drm_dp_helper.h" | 37 | #include "drm_dp_helper.h" |
37 | 38 | ||
38 | #include "drm_crtc_helper.h" | 39 | #include "drm_crtc_helper.h" |
@@ -42,6 +43,7 @@ | |||
42 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); | 43 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); |
43 | static void intel_update_watermarks(struct drm_device *dev); | 44 | static void intel_update_watermarks(struct drm_device *dev); |
44 | static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule); | 45 | static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule); |
46 | static void intel_crtc_update_cursor(struct drm_crtc *crtc); | ||
45 | 47 | ||
46 | typedef struct { | 48 | typedef struct { |
47 | /* given values */ | 49 | /* given values */ |
@@ -322,6 +324,9 @@ struct intel_limit { | |||
322 | #define IRONLAKE_DP_P1_MIN 1 | 324 | #define IRONLAKE_DP_P1_MIN 1 |
323 | #define IRONLAKE_DP_P1_MAX 2 | 325 | #define IRONLAKE_DP_P1_MAX 2 |
324 | 326 | ||
327 | /* FDI */ | ||
328 | #define IRONLAKE_FDI_FREQ 2700000 /* in kHz for mode->clock */ | ||
329 | |||
325 | static bool | 330 | static bool |
326 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 331 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
327 | int target, int refclk, intel_clock_t *best_clock); | 332 | int target, int refclk, intel_clock_t *best_clock); |
@@ -1125,6 +1130,67 @@ static bool g4x_fbc_enabled(struct drm_device *dev) | |||
1125 | return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; | 1130 | return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; |
1126 | } | 1131 | } |
1127 | 1132 | ||
1133 | static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | ||
1134 | { | ||
1135 | struct drm_device *dev = crtc->dev; | ||
1136 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1137 | struct drm_framebuffer *fb = crtc->fb; | ||
1138 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | ||
1139 | struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); | ||
1140 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
1141 | int plane = (intel_crtc->plane == 0) ? DPFC_CTL_PLANEA : | ||
1142 | DPFC_CTL_PLANEB; | ||
1143 | unsigned long stall_watermark = 200; | ||
1144 | u32 dpfc_ctl; | ||
1145 | |||
1146 | dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; | ||
1147 | dev_priv->cfb_fence = obj_priv->fence_reg; | ||
1148 | dev_priv->cfb_plane = intel_crtc->plane; | ||
1149 | |||
1150 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | ||
1151 | dpfc_ctl &= DPFC_RESERVED; | ||
1152 | dpfc_ctl |= (plane | DPFC_CTL_LIMIT_1X); | ||
1153 | if (obj_priv->tiling_mode != I915_TILING_NONE) { | ||
1154 | dpfc_ctl |= (DPFC_CTL_FENCE_EN | dev_priv->cfb_fence); | ||
1155 | I915_WRITE(ILK_DPFC_CHICKEN, DPFC_HT_MODIFY); | ||
1156 | } else { | ||
1157 | I915_WRITE(ILK_DPFC_CHICKEN, ~DPFC_HT_MODIFY); | ||
1158 | } | ||
1159 | |||
1160 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); | ||
1161 | I915_WRITE(ILK_DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | | ||
1162 | (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | | ||
1163 | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); | ||
1164 | I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); | ||
1165 | I915_WRITE(ILK_FBC_RT_BASE, obj_priv->gtt_offset | ILK_FBC_RT_VALID); | ||
1166 | /* enable it... */ | ||
1167 | I915_WRITE(ILK_DPFC_CONTROL, I915_READ(ILK_DPFC_CONTROL) | | ||
1168 | DPFC_CTL_EN); | ||
1169 | |||
1170 | DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); | ||
1171 | } | ||
1172 | |||
1173 | void ironlake_disable_fbc(struct drm_device *dev) | ||
1174 | { | ||
1175 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1176 | u32 dpfc_ctl; | ||
1177 | |||
1178 | /* Disable compression */ | ||
1179 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | ||
1180 | dpfc_ctl &= ~DPFC_CTL_EN; | ||
1181 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); | ||
1182 | intel_wait_for_vblank(dev); | ||
1183 | |||
1184 | DRM_DEBUG_KMS("disabled FBC\n"); | ||
1185 | } | ||
1186 | |||
1187 | static bool ironlake_fbc_enabled(struct drm_device *dev) | ||
1188 | { | ||
1189 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1190 | |||
1191 | return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN; | ||
1192 | } | ||
1193 | |||
1128 | bool intel_fbc_enabled(struct drm_device *dev) | 1194 | bool intel_fbc_enabled(struct drm_device *dev) |
1129 | { | 1195 | { |
1130 | struct drm_i915_private *dev_priv = dev->dev_private; | 1196 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -1286,7 +1352,12 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) | |||
1286 | 1352 | ||
1287 | switch (obj_priv->tiling_mode) { | 1353 | switch (obj_priv->tiling_mode) { |
1288 | case I915_TILING_NONE: | 1354 | case I915_TILING_NONE: |
1289 | alignment = 64 * 1024; | 1355 | if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) |
1356 | alignment = 128 * 1024; | ||
1357 | else if (IS_I965G(dev)) | ||
1358 | alignment = 4 * 1024; | ||
1359 | else | ||
1360 | alignment = 64 * 1024; | ||
1290 | break; | 1361 | break; |
1291 | case I915_TILING_X: | 1362 | case I915_TILING_X: |
1292 | /* pin() will align the object as required by fence */ | 1363 | /* pin() will align the object as required by fence */ |
@@ -1653,6 +1724,15 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) | |||
1653 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; | 1724 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; |
1654 | u32 temp, tries = 0; | 1725 | u32 temp, tries = 0; |
1655 | 1726 | ||
1727 | /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit | ||
1728 | for train result */ | ||
1729 | temp = I915_READ(fdi_rx_imr_reg); | ||
1730 | temp &= ~FDI_RX_SYMBOL_LOCK; | ||
1731 | temp &= ~FDI_RX_BIT_LOCK; | ||
1732 | I915_WRITE(fdi_rx_imr_reg, temp); | ||
1733 | I915_READ(fdi_rx_imr_reg); | ||
1734 | udelay(150); | ||
1735 | |||
1656 | /* enable CPU FDI TX and PCH FDI RX */ | 1736 | /* enable CPU FDI TX and PCH FDI RX */ |
1657 | temp = I915_READ(fdi_tx_reg); | 1737 | temp = I915_READ(fdi_tx_reg); |
1658 | temp |= FDI_TX_ENABLE; | 1738 | temp |= FDI_TX_ENABLE; |
@@ -1670,16 +1750,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) | |||
1670 | I915_READ(fdi_rx_reg); | 1750 | I915_READ(fdi_rx_reg); |
1671 | udelay(150); | 1751 | udelay(150); |
1672 | 1752 | ||
1673 | /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit | 1753 | for (tries = 0; tries < 5; tries++) { |
1674 | for train result */ | ||
1675 | temp = I915_READ(fdi_rx_imr_reg); | ||
1676 | temp &= ~FDI_RX_SYMBOL_LOCK; | ||
1677 | temp &= ~FDI_RX_BIT_LOCK; | ||
1678 | I915_WRITE(fdi_rx_imr_reg, temp); | ||
1679 | I915_READ(fdi_rx_imr_reg); | ||
1680 | udelay(150); | ||
1681 | |||
1682 | for (;;) { | ||
1683 | temp = I915_READ(fdi_rx_iir_reg); | 1754 | temp = I915_READ(fdi_rx_iir_reg); |
1684 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); | 1755 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); |
1685 | 1756 | ||
@@ -1689,14 +1760,9 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) | |||
1689 | temp | FDI_RX_BIT_LOCK); | 1760 | temp | FDI_RX_BIT_LOCK); |
1690 | break; | 1761 | break; |
1691 | } | 1762 | } |
1692 | |||
1693 | tries++; | ||
1694 | |||
1695 | if (tries > 5) { | ||
1696 | DRM_DEBUG_KMS("FDI train 1 fail!\n"); | ||
1697 | break; | ||
1698 | } | ||
1699 | } | 1763 | } |
1764 | if (tries == 5) | ||
1765 | DRM_DEBUG_KMS("FDI train 1 fail!\n"); | ||
1700 | 1766 | ||
1701 | /* Train 2 */ | 1767 | /* Train 2 */ |
1702 | temp = I915_READ(fdi_tx_reg); | 1768 | temp = I915_READ(fdi_tx_reg); |
@@ -1712,7 +1778,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) | |||
1712 | 1778 | ||
1713 | tries = 0; | 1779 | tries = 0; |
1714 | 1780 | ||
1715 | for (;;) { | 1781 | for (tries = 0; tries < 5; tries++) { |
1716 | temp = I915_READ(fdi_rx_iir_reg); | 1782 | temp = I915_READ(fdi_rx_iir_reg); |
1717 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); | 1783 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); |
1718 | 1784 | ||
@@ -1722,14 +1788,9 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) | |||
1722 | DRM_DEBUG_KMS("FDI train 2 done.\n"); | 1788 | DRM_DEBUG_KMS("FDI train 2 done.\n"); |
1723 | break; | 1789 | break; |
1724 | } | 1790 | } |
1725 | |||
1726 | tries++; | ||
1727 | |||
1728 | if (tries > 5) { | ||
1729 | DRM_DEBUG_KMS("FDI train 2 fail!\n"); | ||
1730 | break; | ||
1731 | } | ||
1732 | } | 1791 | } |
1792 | if (tries == 5) | ||
1793 | DRM_DEBUG_KMS("FDI train 2 fail!\n"); | ||
1733 | 1794 | ||
1734 | DRM_DEBUG_KMS("FDI train done\n"); | 1795 | DRM_DEBUG_KMS("FDI train done\n"); |
1735 | } | 1796 | } |
@@ -1754,6 +1815,15 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) | |||
1754 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; | 1815 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; |
1755 | u32 temp, i; | 1816 | u32 temp, i; |
1756 | 1817 | ||
1818 | /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit | ||
1819 | for train result */ | ||
1820 | temp = I915_READ(fdi_rx_imr_reg); | ||
1821 | temp &= ~FDI_RX_SYMBOL_LOCK; | ||
1822 | temp &= ~FDI_RX_BIT_LOCK; | ||
1823 | I915_WRITE(fdi_rx_imr_reg, temp); | ||
1824 | I915_READ(fdi_rx_imr_reg); | ||
1825 | udelay(150); | ||
1826 | |||
1757 | /* enable CPU FDI TX and PCH FDI RX */ | 1827 | /* enable CPU FDI TX and PCH FDI RX */ |
1758 | temp = I915_READ(fdi_tx_reg); | 1828 | temp = I915_READ(fdi_tx_reg); |
1759 | temp |= FDI_TX_ENABLE; | 1829 | temp |= FDI_TX_ENABLE; |
@@ -1779,15 +1849,6 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) | |||
1779 | I915_READ(fdi_rx_reg); | 1849 | I915_READ(fdi_rx_reg); |
1780 | udelay(150); | 1850 | udelay(150); |
1781 | 1851 | ||
1782 | /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit | ||
1783 | for train result */ | ||
1784 | temp = I915_READ(fdi_rx_imr_reg); | ||
1785 | temp &= ~FDI_RX_SYMBOL_LOCK; | ||
1786 | temp &= ~FDI_RX_BIT_LOCK; | ||
1787 | I915_WRITE(fdi_rx_imr_reg, temp); | ||
1788 | I915_READ(fdi_rx_imr_reg); | ||
1789 | udelay(150); | ||
1790 | |||
1791 | for (i = 0; i < 4; i++ ) { | 1852 | for (i = 0; i < 4; i++ ) { |
1792 | temp = I915_READ(fdi_tx_reg); | 1853 | temp = I915_READ(fdi_tx_reg); |
1793 | temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; | 1854 | temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; |
@@ -1942,7 +2003,8 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1942 | } | 2003 | } |
1943 | 2004 | ||
1944 | /* Enable panel fitting for LVDS */ | 2005 | /* Enable panel fitting for LVDS */ |
1945 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 2006 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) |
2007 | || HAS_eDP || intel_pch_has_edp(crtc)) { | ||
1946 | temp = I915_READ(pf_ctl_reg); | 2008 | temp = I915_READ(pf_ctl_reg); |
1947 | I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); | 2009 | I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); |
1948 | 2010 | ||
@@ -2037,9 +2099,12 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2037 | reg = I915_READ(trans_dp_ctl); | 2099 | reg = I915_READ(trans_dp_ctl); |
2038 | reg &= ~TRANS_DP_PORT_SEL_MASK; | 2100 | reg &= ~TRANS_DP_PORT_SEL_MASK; |
2039 | reg = TRANS_DP_OUTPUT_ENABLE | | 2101 | reg = TRANS_DP_OUTPUT_ENABLE | |
2040 | TRANS_DP_ENH_FRAMING | | 2102 | TRANS_DP_ENH_FRAMING; |
2041 | TRANS_DP_VSYNC_ACTIVE_HIGH | | 2103 | |
2042 | TRANS_DP_HSYNC_ACTIVE_HIGH; | 2104 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
2105 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; | ||
2106 | if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) | ||
2107 | reg |= TRANS_DP_VSYNC_ACTIVE_HIGH; | ||
2043 | 2108 | ||
2044 | switch (intel_trans_dp_port_sel(crtc)) { | 2109 | switch (intel_trans_dp_port_sel(crtc)) { |
2045 | case PCH_DP_B: | 2110 | case PCH_DP_B: |
@@ -2079,6 +2144,8 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2079 | 2144 | ||
2080 | intel_crtc_load_lut(crtc); | 2145 | intel_crtc_load_lut(crtc); |
2081 | 2146 | ||
2147 | intel_update_fbc(crtc, &crtc->mode); | ||
2148 | |||
2082 | break; | 2149 | break; |
2083 | case DRM_MODE_DPMS_OFF: | 2150 | case DRM_MODE_DPMS_OFF: |
2084 | DRM_DEBUG_KMS("crtc %d dpms off\n", pipe); | 2151 | DRM_DEBUG_KMS("crtc %d dpms off\n", pipe); |
@@ -2093,6 +2160,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2093 | I915_READ(dspbase_reg); | 2160 | I915_READ(dspbase_reg); |
2094 | } | 2161 | } |
2095 | 2162 | ||
2163 | if (dev_priv->cfb_plane == plane && | ||
2164 | dev_priv->display.disable_fbc) | ||
2165 | dev_priv->display.disable_fbc(dev); | ||
2166 | |||
2096 | i915_disable_vga(dev); | 2167 | i915_disable_vga(dev); |
2097 | 2168 | ||
2098 | /* disable cpu pipe, disable after all planes disabled */ | 2169 | /* disable cpu pipe, disable after all planes disabled */ |
@@ -2472,8 +2543,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | |||
2472 | struct drm_device *dev = crtc->dev; | 2543 | struct drm_device *dev = crtc->dev; |
2473 | if (HAS_PCH_SPLIT(dev)) { | 2544 | if (HAS_PCH_SPLIT(dev)) { |
2474 | /* FDI link clock is fixed at 2.7G */ | 2545 | /* FDI link clock is fixed at 2.7G */ |
2475 | if (mode->clock * 3 > 27000 * 4) | 2546 | if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4) |
2476 | return MODE_CLOCK_HIGH; | 2547 | return false; |
2477 | } | 2548 | } |
2478 | return true; | 2549 | return true; |
2479 | } | 2550 | } |
@@ -2655,6 +2726,20 @@ static struct intel_watermark_params g4x_wm_info = { | |||
2655 | 2, | 2726 | 2, |
2656 | G4X_FIFO_LINE_SIZE, | 2727 | G4X_FIFO_LINE_SIZE, |
2657 | }; | 2728 | }; |
2729 | static struct intel_watermark_params g4x_cursor_wm_info = { | ||
2730 | I965_CURSOR_FIFO, | ||
2731 | I965_CURSOR_MAX_WM, | ||
2732 | I965_CURSOR_DFT_WM, | ||
2733 | 2, | ||
2734 | G4X_FIFO_LINE_SIZE, | ||
2735 | }; | ||
2736 | static struct intel_watermark_params i965_cursor_wm_info = { | ||
2737 | I965_CURSOR_FIFO, | ||
2738 | I965_CURSOR_MAX_WM, | ||
2739 | I965_CURSOR_DFT_WM, | ||
2740 | 2, | ||
2741 | I915_FIFO_LINE_SIZE, | ||
2742 | }; | ||
2658 | static struct intel_watermark_params i945_wm_info = { | 2743 | static struct intel_watermark_params i945_wm_info = { |
2659 | I945_FIFO_SIZE, | 2744 | I945_FIFO_SIZE, |
2660 | I915_MAX_WM, | 2745 | I915_MAX_WM, |
@@ -2692,6 +2777,14 @@ static struct intel_watermark_params ironlake_display_wm_info = { | |||
2692 | ILK_FIFO_LINE_SIZE | 2777 | ILK_FIFO_LINE_SIZE |
2693 | }; | 2778 | }; |
2694 | 2779 | ||
2780 | static struct intel_watermark_params ironlake_cursor_wm_info = { | ||
2781 | ILK_CURSOR_FIFO, | ||
2782 | ILK_CURSOR_MAXWM, | ||
2783 | ILK_CURSOR_DFTWM, | ||
2784 | 2, | ||
2785 | ILK_FIFO_LINE_SIZE | ||
2786 | }; | ||
2787 | |||
2695 | static struct intel_watermark_params ironlake_display_srwm_info = { | 2788 | static struct intel_watermark_params ironlake_display_srwm_info = { |
2696 | ILK_DISPLAY_SR_FIFO, | 2789 | ILK_DISPLAY_SR_FIFO, |
2697 | ILK_DISPLAY_MAX_SRWM, | 2790 | ILK_DISPLAY_MAX_SRWM, |
@@ -2741,7 +2834,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | |||
2741 | */ | 2834 | */ |
2742 | entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) / | 2835 | entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) / |
2743 | 1000; | 2836 | 1000; |
2744 | entries_required /= wm->cacheline_size; | 2837 | entries_required = DIV_ROUND_UP(entries_required, wm->cacheline_size); |
2745 | 2838 | ||
2746 | DRM_DEBUG_KMS("FIFO entries required for mode: %d\n", entries_required); | 2839 | DRM_DEBUG_KMS("FIFO entries required for mode: %d\n", entries_required); |
2747 | 2840 | ||
@@ -2752,8 +2845,14 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | |||
2752 | /* Don't promote wm_size to unsigned... */ | 2845 | /* Don't promote wm_size to unsigned... */ |
2753 | if (wm_size > (long)wm->max_wm) | 2846 | if (wm_size > (long)wm->max_wm) |
2754 | wm_size = wm->max_wm; | 2847 | wm_size = wm->max_wm; |
2755 | if (wm_size <= 0) | 2848 | if (wm_size <= 0) { |
2756 | wm_size = wm->default_wm; | 2849 | wm_size = wm->default_wm; |
2850 | DRM_ERROR("Insufficient FIFO for plane, expect flickering:" | ||
2851 | " entries required = %ld, available = %lu.\n", | ||
2852 | entries_required + wm->guard_size, | ||
2853 | wm->fifo_size); | ||
2854 | } | ||
2855 | |||
2757 | return wm_size; | 2856 | return wm_size; |
2758 | } | 2857 | } |
2759 | 2858 | ||
@@ -2862,11 +2961,9 @@ static int i9xx_get_fifo_size(struct drm_device *dev, int plane) | |||
2862 | uint32_t dsparb = I915_READ(DSPARB); | 2961 | uint32_t dsparb = I915_READ(DSPARB); |
2863 | int size; | 2962 | int size; |
2864 | 2963 | ||
2865 | if (plane == 0) | 2964 | size = dsparb & 0x7f; |
2866 | size = dsparb & 0x7f; | 2965 | if (plane) |
2867 | else | 2966 | size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - size; |
2868 | size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - | ||
2869 | (dsparb & 0x7f); | ||
2870 | 2967 | ||
2871 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | 2968 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, |
2872 | plane ? "B" : "A", size); | 2969 | plane ? "B" : "A", size); |
@@ -2880,11 +2977,9 @@ static int i85x_get_fifo_size(struct drm_device *dev, int plane) | |||
2880 | uint32_t dsparb = I915_READ(DSPARB); | 2977 | uint32_t dsparb = I915_READ(DSPARB); |
2881 | int size; | 2978 | int size; |
2882 | 2979 | ||
2883 | if (plane == 0) | 2980 | size = dsparb & 0x1ff; |
2884 | size = dsparb & 0x1ff; | 2981 | if (plane) |
2885 | else | 2982 | size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - size; |
2886 | size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - | ||
2887 | (dsparb & 0x1ff); | ||
2888 | size >>= 1; /* Convert to cachelines */ | 2983 | size >>= 1; /* Convert to cachelines */ |
2889 | 2984 | ||
2890 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | 2985 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, |
@@ -2925,7 +3020,8 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane) | |||
2925 | } | 3020 | } |
2926 | 3021 | ||
2927 | static void pineview_update_wm(struct drm_device *dev, int planea_clock, | 3022 | static void pineview_update_wm(struct drm_device *dev, int planea_clock, |
2928 | int planeb_clock, int sr_hdisplay, int pixel_size) | 3023 | int planeb_clock, int sr_hdisplay, int unused, |
3024 | int pixel_size) | ||
2929 | { | 3025 | { |
2930 | struct drm_i915_private *dev_priv = dev->dev_private; | 3026 | struct drm_i915_private *dev_priv = dev->dev_private; |
2931 | u32 reg; | 3027 | u32 reg; |
@@ -2990,7 +3086,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
2990 | } | 3086 | } |
2991 | 3087 | ||
2992 | static void g4x_update_wm(struct drm_device *dev, int planea_clock, | 3088 | static void g4x_update_wm(struct drm_device *dev, int planea_clock, |
2993 | int planeb_clock, int sr_hdisplay, int pixel_size) | 3089 | int planeb_clock, int sr_hdisplay, int sr_htotal, |
3090 | int pixel_size) | ||
2994 | { | 3091 | { |
2995 | struct drm_i915_private *dev_priv = dev->dev_private; | 3092 | struct drm_i915_private *dev_priv = dev->dev_private; |
2996 | int total_size, cacheline_size; | 3093 | int total_size, cacheline_size; |
@@ -3014,12 +3111,12 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock, | |||
3014 | */ | 3111 | */ |
3015 | entries_required = ((planea_clock / 1000) * pixel_size * latency_ns) / | 3112 | entries_required = ((planea_clock / 1000) * pixel_size * latency_ns) / |
3016 | 1000; | 3113 | 1000; |
3017 | entries_required /= G4X_FIFO_LINE_SIZE; | 3114 | entries_required = DIV_ROUND_UP(entries_required, G4X_FIFO_LINE_SIZE); |
3018 | planea_wm = entries_required + planea_params.guard_size; | 3115 | planea_wm = entries_required + planea_params.guard_size; |
3019 | 3116 | ||
3020 | entries_required = ((planeb_clock / 1000) * pixel_size * latency_ns) / | 3117 | entries_required = ((planeb_clock / 1000) * pixel_size * latency_ns) / |
3021 | 1000; | 3118 | 1000; |
3022 | entries_required /= G4X_FIFO_LINE_SIZE; | 3119 | entries_required = DIV_ROUND_UP(entries_required, G4X_FIFO_LINE_SIZE); |
3023 | planeb_wm = entries_required + planeb_params.guard_size; | 3120 | planeb_wm = entries_required + planeb_params.guard_size; |
3024 | 3121 | ||
3025 | cursora_wm = cursorb_wm = 16; | 3122 | cursora_wm = cursorb_wm = 16; |
@@ -3033,13 +3130,24 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock, | |||
3033 | static const int sr_latency_ns = 12000; | 3130 | static const int sr_latency_ns = 12000; |
3034 | 3131 | ||
3035 | sr_clock = planea_clock ? planea_clock : planeb_clock; | 3132 | sr_clock = planea_clock ? planea_clock : planeb_clock; |
3036 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); | 3133 | line_time_us = ((sr_htotal * 1000) / sr_clock); |
3037 | 3134 | ||
3038 | /* Use ns/us then divide to preserve precision */ | 3135 | /* Use ns/us then divide to preserve precision */ |
3039 | sr_entries = (((sr_latency_ns / line_time_us) + 1) * | 3136 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
3040 | pixel_size * sr_hdisplay) / 1000; | 3137 | pixel_size * sr_hdisplay; |
3041 | sr_entries = roundup(sr_entries / cacheline_size, 1); | 3138 | sr_entries = DIV_ROUND_UP(sr_entries, cacheline_size); |
3042 | DRM_DEBUG("self-refresh entries: %d\n", sr_entries); | 3139 | |
3140 | entries_required = (((sr_latency_ns / line_time_us) + | ||
3141 | 1000) / 1000) * pixel_size * 64; | ||
3142 | entries_required = DIV_ROUND_UP(entries_required, | ||
3143 | g4x_cursor_wm_info.cacheline_size); | ||
3144 | cursor_sr = entries_required + g4x_cursor_wm_info.guard_size; | ||
3145 | |||
3146 | if (cursor_sr > g4x_cursor_wm_info.max_wm) | ||
3147 | cursor_sr = g4x_cursor_wm_info.max_wm; | ||
3148 | DRM_DEBUG_KMS("self-refresh watermark: display plane %d " | ||
3149 | "cursor %d\n", sr_entries, cursor_sr); | ||
3150 | |||
3043 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | 3151 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); |
3044 | } else { | 3152 | } else { |
3045 | /* Turn off self refresh if both pipes are enabled */ | 3153 | /* Turn off self refresh if both pipes are enabled */ |
@@ -3064,11 +3172,13 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock, | |||
3064 | } | 3172 | } |
3065 | 3173 | ||
3066 | static void i965_update_wm(struct drm_device *dev, int planea_clock, | 3174 | static void i965_update_wm(struct drm_device *dev, int planea_clock, |
3067 | int planeb_clock, int sr_hdisplay, int pixel_size) | 3175 | int planeb_clock, int sr_hdisplay, int sr_htotal, |
3176 | int pixel_size) | ||
3068 | { | 3177 | { |
3069 | struct drm_i915_private *dev_priv = dev->dev_private; | 3178 | struct drm_i915_private *dev_priv = dev->dev_private; |
3070 | unsigned long line_time_us; | 3179 | unsigned long line_time_us; |
3071 | int sr_clock, sr_entries, srwm = 1; | 3180 | int sr_clock, sr_entries, srwm = 1; |
3181 | int cursor_sr = 16; | ||
3072 | 3182 | ||
3073 | /* Calc sr entries for one plane configs */ | 3183 | /* Calc sr entries for one plane configs */ |
3074 | if (sr_hdisplay && (!planea_clock || !planeb_clock)) { | 3184 | if (sr_hdisplay && (!planea_clock || !planeb_clock)) { |
@@ -3076,17 +3186,31 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, | |||
3076 | static const int sr_latency_ns = 12000; | 3186 | static const int sr_latency_ns = 12000; |
3077 | 3187 | ||
3078 | sr_clock = planea_clock ? planea_clock : planeb_clock; | 3188 | sr_clock = planea_clock ? planea_clock : planeb_clock; |
3079 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); | 3189 | line_time_us = ((sr_htotal * 1000) / sr_clock); |
3080 | 3190 | ||
3081 | /* Use ns/us then divide to preserve precision */ | 3191 | /* Use ns/us then divide to preserve precision */ |
3082 | sr_entries = (((sr_latency_ns / line_time_us) + 1) * | 3192 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
3083 | pixel_size * sr_hdisplay) / 1000; | 3193 | pixel_size * sr_hdisplay; |
3084 | sr_entries = roundup(sr_entries / I915_FIFO_LINE_SIZE, 1); | 3194 | sr_entries = DIV_ROUND_UP(sr_entries, I915_FIFO_LINE_SIZE); |
3085 | DRM_DEBUG("self-refresh entries: %d\n", sr_entries); | 3195 | DRM_DEBUG("self-refresh entries: %d\n", sr_entries); |
3086 | srwm = I945_FIFO_SIZE - sr_entries; | 3196 | srwm = I965_FIFO_SIZE - sr_entries; |
3087 | if (srwm < 0) | 3197 | if (srwm < 0) |
3088 | srwm = 1; | 3198 | srwm = 1; |
3089 | srwm &= 0x3f; | 3199 | srwm &= 0x1ff; |
3200 | |||
3201 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | ||
3202 | pixel_size * 64; | ||
3203 | sr_entries = DIV_ROUND_UP(sr_entries, | ||
3204 | i965_cursor_wm_info.cacheline_size); | ||
3205 | cursor_sr = i965_cursor_wm_info.fifo_size - | ||
3206 | (sr_entries + i965_cursor_wm_info.guard_size); | ||
3207 | |||
3208 | if (cursor_sr > i965_cursor_wm_info.max_wm) | ||
3209 | cursor_sr = i965_cursor_wm_info.max_wm; | ||
3210 | |||
3211 | DRM_DEBUG_KMS("self-refresh watermark: display plane %d " | ||
3212 | "cursor %d\n", srwm, cursor_sr); | ||
3213 | |||
3090 | if (IS_I965GM(dev)) | 3214 | if (IS_I965GM(dev)) |
3091 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | 3215 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); |
3092 | } else { | 3216 | } else { |
@@ -3103,10 +3227,13 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, | |||
3103 | I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | (8 << 16) | (8 << 8) | | 3227 | I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | (8 << 16) | (8 << 8) | |
3104 | (8 << 0)); | 3228 | (8 << 0)); |
3105 | I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); | 3229 | I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); |
3230 | /* update cursor SR watermark */ | ||
3231 | I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | ||
3106 | } | 3232 | } |
3107 | 3233 | ||
3108 | static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | 3234 | static void i9xx_update_wm(struct drm_device *dev, int planea_clock, |
3109 | int planeb_clock, int sr_hdisplay, int pixel_size) | 3235 | int planeb_clock, int sr_hdisplay, int sr_htotal, |
3236 | int pixel_size) | ||
3110 | { | 3237 | { |
3111 | struct drm_i915_private *dev_priv = dev->dev_private; | 3238 | struct drm_i915_private *dev_priv = dev->dev_private; |
3112 | uint32_t fwater_lo; | 3239 | uint32_t fwater_lo; |
@@ -3151,12 +3278,12 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
3151 | static const int sr_latency_ns = 6000; | 3278 | static const int sr_latency_ns = 6000; |
3152 | 3279 | ||
3153 | sr_clock = planea_clock ? planea_clock : planeb_clock; | 3280 | sr_clock = planea_clock ? planea_clock : planeb_clock; |
3154 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); | 3281 | line_time_us = ((sr_htotal * 1000) / sr_clock); |
3155 | 3282 | ||
3156 | /* Use ns/us then divide to preserve precision */ | 3283 | /* Use ns/us then divide to preserve precision */ |
3157 | sr_entries = (((sr_latency_ns / line_time_us) + 1) * | 3284 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
3158 | pixel_size * sr_hdisplay) / 1000; | 3285 | pixel_size * sr_hdisplay; |
3159 | sr_entries = roundup(sr_entries / cacheline_size, 1); | 3286 | sr_entries = DIV_ROUND_UP(sr_entries, cacheline_size); |
3160 | DRM_DEBUG_KMS("self-refresh entries: %d\n", sr_entries); | 3287 | DRM_DEBUG_KMS("self-refresh entries: %d\n", sr_entries); |
3161 | srwm = total_size - sr_entries; | 3288 | srwm = total_size - sr_entries; |
3162 | if (srwm < 0) | 3289 | if (srwm < 0) |
@@ -3194,7 +3321,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
3194 | } | 3321 | } |
3195 | 3322 | ||
3196 | static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, | 3323 | static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, |
3197 | int unused2, int pixel_size) | 3324 | int unused2, int unused3, int pixel_size) |
3198 | { | 3325 | { |
3199 | struct drm_i915_private *dev_priv = dev->dev_private; | 3326 | struct drm_i915_private *dev_priv = dev->dev_private; |
3200 | uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff; | 3327 | uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff; |
@@ -3212,9 +3339,11 @@ static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, | |||
3212 | } | 3339 | } |
3213 | 3340 | ||
3214 | #define ILK_LP0_PLANE_LATENCY 700 | 3341 | #define ILK_LP0_PLANE_LATENCY 700 |
3342 | #define ILK_LP0_CURSOR_LATENCY 1300 | ||
3215 | 3343 | ||
3216 | static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | 3344 | static void ironlake_update_wm(struct drm_device *dev, int planea_clock, |
3217 | int planeb_clock, int sr_hdisplay, int pixel_size) | 3345 | int planeb_clock, int sr_hdisplay, int sr_htotal, |
3346 | int pixel_size) | ||
3218 | { | 3347 | { |
3219 | struct drm_i915_private *dev_priv = dev->dev_private; | 3348 | struct drm_i915_private *dev_priv = dev->dev_private; |
3220 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; | 3349 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; |
@@ -3222,20 +3351,48 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | |||
3222 | unsigned long line_time_us; | 3351 | unsigned long line_time_us; |
3223 | int sr_clock, entries_required; | 3352 | int sr_clock, entries_required; |
3224 | u32 reg_value; | 3353 | u32 reg_value; |
3354 | int line_count; | ||
3355 | int planea_htotal = 0, planeb_htotal = 0; | ||
3356 | struct drm_crtc *crtc; | ||
3357 | struct intel_crtc *intel_crtc; | ||
3358 | |||
3359 | /* Need htotal for all active display plane */ | ||
3360 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
3361 | intel_crtc = to_intel_crtc(crtc); | ||
3362 | if (crtc->enabled) { | ||
3363 | if (intel_crtc->plane == 0) | ||
3364 | planea_htotal = crtc->mode.htotal; | ||
3365 | else | ||
3366 | planeb_htotal = crtc->mode.htotal; | ||
3367 | } | ||
3368 | } | ||
3225 | 3369 | ||
3226 | /* Calculate and update the watermark for plane A */ | 3370 | /* Calculate and update the watermark for plane A */ |
3227 | if (planea_clock) { | 3371 | if (planea_clock) { |
3228 | entries_required = ((planea_clock / 1000) * pixel_size * | 3372 | entries_required = ((planea_clock / 1000) * pixel_size * |
3229 | ILK_LP0_PLANE_LATENCY) / 1000; | 3373 | ILK_LP0_PLANE_LATENCY) / 1000; |
3230 | entries_required = DIV_ROUND_UP(entries_required, | 3374 | entries_required = DIV_ROUND_UP(entries_required, |
3231 | ironlake_display_wm_info.cacheline_size); | 3375 | ironlake_display_wm_info.cacheline_size); |
3232 | planea_wm = entries_required + | 3376 | planea_wm = entries_required + |
3233 | ironlake_display_wm_info.guard_size; | 3377 | ironlake_display_wm_info.guard_size; |
3234 | 3378 | ||
3235 | if (planea_wm > (int)ironlake_display_wm_info.max_wm) | 3379 | if (planea_wm > (int)ironlake_display_wm_info.max_wm) |
3236 | planea_wm = ironlake_display_wm_info.max_wm; | 3380 | planea_wm = ironlake_display_wm_info.max_wm; |
3237 | 3381 | ||
3238 | cursora_wm = 16; | 3382 | /* Use the large buffer method to calculate cursor watermark */ |
3383 | line_time_us = (planea_htotal * 1000) / planea_clock; | ||
3384 | |||
3385 | /* Use ns/us then divide to preserve precision */ | ||
3386 | line_count = (ILK_LP0_CURSOR_LATENCY / line_time_us + 1000) / 1000; | ||
3387 | |||
3388 | /* calculate the cursor watermark for cursor A */ | ||
3389 | entries_required = line_count * 64 * pixel_size; | ||
3390 | entries_required = DIV_ROUND_UP(entries_required, | ||
3391 | ironlake_cursor_wm_info.cacheline_size); | ||
3392 | cursora_wm = entries_required + ironlake_cursor_wm_info.guard_size; | ||
3393 | if (cursora_wm > ironlake_cursor_wm_info.max_wm) | ||
3394 | cursora_wm = ironlake_cursor_wm_info.max_wm; | ||
3395 | |||
3239 | reg_value = I915_READ(WM0_PIPEA_ILK); | 3396 | reg_value = I915_READ(WM0_PIPEA_ILK); |
3240 | reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | 3397 | reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); |
3241 | reg_value |= (planea_wm << WM0_PIPE_PLANE_SHIFT) | | 3398 | reg_value |= (planea_wm << WM0_PIPE_PLANE_SHIFT) | |
@@ -3249,14 +3406,27 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | |||
3249 | entries_required = ((planeb_clock / 1000) * pixel_size * | 3406 | entries_required = ((planeb_clock / 1000) * pixel_size * |
3250 | ILK_LP0_PLANE_LATENCY) / 1000; | 3407 | ILK_LP0_PLANE_LATENCY) / 1000; |
3251 | entries_required = DIV_ROUND_UP(entries_required, | 3408 | entries_required = DIV_ROUND_UP(entries_required, |
3252 | ironlake_display_wm_info.cacheline_size); | 3409 | ironlake_display_wm_info.cacheline_size); |
3253 | planeb_wm = entries_required + | 3410 | planeb_wm = entries_required + |
3254 | ironlake_display_wm_info.guard_size; | 3411 | ironlake_display_wm_info.guard_size; |
3255 | 3412 | ||
3256 | if (planeb_wm > (int)ironlake_display_wm_info.max_wm) | 3413 | if (planeb_wm > (int)ironlake_display_wm_info.max_wm) |
3257 | planeb_wm = ironlake_display_wm_info.max_wm; | 3414 | planeb_wm = ironlake_display_wm_info.max_wm; |
3258 | 3415 | ||
3259 | cursorb_wm = 16; | 3416 | /* Use the large buffer method to calculate cursor watermark */ |
3417 | line_time_us = (planeb_htotal * 1000) / planeb_clock; | ||
3418 | |||
3419 | /* Use ns/us then divide to preserve precision */ | ||
3420 | line_count = (ILK_LP0_CURSOR_LATENCY / line_time_us + 1000) / 1000; | ||
3421 | |||
3422 | /* calculate the cursor watermark for cursor B */ | ||
3423 | entries_required = line_count * 64 * pixel_size; | ||
3424 | entries_required = DIV_ROUND_UP(entries_required, | ||
3425 | ironlake_cursor_wm_info.cacheline_size); | ||
3426 | cursorb_wm = entries_required + ironlake_cursor_wm_info.guard_size; | ||
3427 | if (cursorb_wm > ironlake_cursor_wm_info.max_wm) | ||
3428 | cursorb_wm = ironlake_cursor_wm_info.max_wm; | ||
3429 | |||
3260 | reg_value = I915_READ(WM0_PIPEB_ILK); | 3430 | reg_value = I915_READ(WM0_PIPEB_ILK); |
3261 | reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | 3431 | reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); |
3262 | reg_value |= (planeb_wm << WM0_PIPE_PLANE_SHIFT) | | 3432 | reg_value |= (planeb_wm << WM0_PIPE_PLANE_SHIFT) | |
@@ -3271,12 +3441,12 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | |||
3271 | * display plane is used. | 3441 | * display plane is used. |
3272 | */ | 3442 | */ |
3273 | if (!planea_clock || !planeb_clock) { | 3443 | if (!planea_clock || !planeb_clock) { |
3274 | int line_count; | 3444 | |
3275 | /* Read the self-refresh latency. The unit is 0.5us */ | 3445 | /* Read the self-refresh latency. The unit is 0.5us */ |
3276 | int ilk_sr_latency = I915_READ(MLTR_ILK) & ILK_SRLT_MASK; | 3446 | int ilk_sr_latency = I915_READ(MLTR_ILK) & ILK_SRLT_MASK; |
3277 | 3447 | ||
3278 | sr_clock = planea_clock ? planea_clock : planeb_clock; | 3448 | sr_clock = planea_clock ? planea_clock : planeb_clock; |
3279 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); | 3449 | line_time_us = ((sr_htotal * 1000) / sr_clock); |
3280 | 3450 | ||
3281 | /* Use ns/us then divide to preserve precision */ | 3451 | /* Use ns/us then divide to preserve precision */ |
3282 | line_count = ((ilk_sr_latency * 500) / line_time_us + 1000) | 3452 | line_count = ((ilk_sr_latency * 500) / line_time_us + 1000) |
@@ -3285,14 +3455,14 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | |||
3285 | /* calculate the self-refresh watermark for display plane */ | 3455 | /* calculate the self-refresh watermark for display plane */ |
3286 | entries_required = line_count * sr_hdisplay * pixel_size; | 3456 | entries_required = line_count * sr_hdisplay * pixel_size; |
3287 | entries_required = DIV_ROUND_UP(entries_required, | 3457 | entries_required = DIV_ROUND_UP(entries_required, |
3288 | ironlake_display_srwm_info.cacheline_size); | 3458 | ironlake_display_srwm_info.cacheline_size); |
3289 | sr_wm = entries_required + | 3459 | sr_wm = entries_required + |
3290 | ironlake_display_srwm_info.guard_size; | 3460 | ironlake_display_srwm_info.guard_size; |
3291 | 3461 | ||
3292 | /* calculate the self-refresh watermark for display cursor */ | 3462 | /* calculate the self-refresh watermark for display cursor */ |
3293 | entries_required = line_count * pixel_size * 64; | 3463 | entries_required = line_count * pixel_size * 64; |
3294 | entries_required = DIV_ROUND_UP(entries_required, | 3464 | entries_required = DIV_ROUND_UP(entries_required, |
3295 | ironlake_cursor_srwm_info.cacheline_size); | 3465 | ironlake_cursor_srwm_info.cacheline_size); |
3296 | cursor_wm = entries_required + | 3466 | cursor_wm = entries_required + |
3297 | ironlake_cursor_srwm_info.guard_size; | 3467 | ironlake_cursor_srwm_info.guard_size; |
3298 | 3468 | ||
@@ -3336,6 +3506,7 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | |||
3336 | * bytes per pixel | 3506 | * bytes per pixel |
3337 | * where | 3507 | * where |
3338 | * line time = htotal / dotclock | 3508 | * line time = htotal / dotclock |
3509 | * surface width = hdisplay for normal plane and 64 for cursor | ||
3339 | * and latency is assumed to be high, as above. | 3510 | * and latency is assumed to be high, as above. |
3340 | * | 3511 | * |
3341 | * The final value programmed to the register should always be rounded up, | 3512 | * The final value programmed to the register should always be rounded up, |
@@ -3352,6 +3523,7 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
3352 | int sr_hdisplay = 0; | 3523 | int sr_hdisplay = 0; |
3353 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; | 3524 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; |
3354 | int enabled = 0, pixel_size = 0; | 3525 | int enabled = 0, pixel_size = 0; |
3526 | int sr_htotal = 0; | ||
3355 | 3527 | ||
3356 | if (!dev_priv->display.update_wm) | 3528 | if (!dev_priv->display.update_wm) |
3357 | return; | 3529 | return; |
@@ -3372,6 +3544,7 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
3372 | } | 3544 | } |
3373 | sr_hdisplay = crtc->mode.hdisplay; | 3545 | sr_hdisplay = crtc->mode.hdisplay; |
3374 | sr_clock = crtc->mode.clock; | 3546 | sr_clock = crtc->mode.clock; |
3547 | sr_htotal = crtc->mode.htotal; | ||
3375 | if (crtc->fb) | 3548 | if (crtc->fb) |
3376 | pixel_size = crtc->fb->bits_per_pixel / 8; | 3549 | pixel_size = crtc->fb->bits_per_pixel / 8; |
3377 | else | 3550 | else |
@@ -3383,7 +3556,7 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
3383 | return; | 3556 | return; |
3384 | 3557 | ||
3385 | dev_priv->display.update_wm(dev, planea_clock, planeb_clock, | 3558 | dev_priv->display.update_wm(dev, planea_clock, planeb_clock, |
3386 | sr_hdisplay, pixel_size); | 3559 | sr_hdisplay, sr_htotal, pixel_size); |
3387 | } | 3560 | } |
3388 | 3561 | ||
3389 | static int intel_crtc_mode_set(struct drm_crtc *crtc, | 3562 | static int intel_crtc_mode_set(struct drm_crtc *crtc, |
@@ -3502,6 +3675,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3502 | return -EINVAL; | 3675 | return -EINVAL; |
3503 | } | 3676 | } |
3504 | 3677 | ||
3678 | /* Ensure that the cursor is valid for the new mode before changing... */ | ||
3679 | intel_crtc_update_cursor(crtc); | ||
3680 | |||
3505 | if (is_lvds && dev_priv->lvds_downclock_avail) { | 3681 | if (is_lvds && dev_priv->lvds_downclock_avail) { |
3506 | has_reduced_clock = limit->find_pll(limit, crtc, | 3682 | has_reduced_clock = limit->find_pll(limit, crtc, |
3507 | dev_priv->lvds_downclock, | 3683 | dev_priv->lvds_downclock, |
@@ -3568,7 +3744,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3568 | temp |= PIPE_8BPC; | 3744 | temp |= PIPE_8BPC; |
3569 | else | 3745 | else |
3570 | temp |= PIPE_6BPC; | 3746 | temp |= PIPE_6BPC; |
3571 | } else if (is_edp) { | 3747 | } else if (is_edp || (is_dp && intel_pch_has_edp(crtc))) { |
3572 | switch (dev_priv->edp_bpp/3) { | 3748 | switch (dev_priv->edp_bpp/3) { |
3573 | case 8: | 3749 | case 8: |
3574 | temp |= PIPE_8BPC; | 3750 | temp |= PIPE_8BPC; |
@@ -3811,6 +3987,11 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3811 | udelay(150); | 3987 | udelay(150); |
3812 | } | 3988 | } |
3813 | 3989 | ||
3990 | if (HAS_PCH_SPLIT(dev)) { | ||
3991 | pipeconf &= ~PIPE_ENABLE_DITHER; | ||
3992 | pipeconf &= ~PIPE_DITHER_TYPE_MASK; | ||
3993 | } | ||
3994 | |||
3814 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. | 3995 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
3815 | * This is an exception to the general rule that mode_set doesn't turn | 3996 | * This is an exception to the general rule that mode_set doesn't turn |
3816 | * things on. | 3997 | * things on. |
@@ -3853,16 +4034,13 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3853 | if (dev_priv->lvds_dither) { | 4034 | if (dev_priv->lvds_dither) { |
3854 | if (HAS_PCH_SPLIT(dev)) { | 4035 | if (HAS_PCH_SPLIT(dev)) { |
3855 | pipeconf |= PIPE_ENABLE_DITHER; | 4036 | pipeconf |= PIPE_ENABLE_DITHER; |
3856 | pipeconf &= ~PIPE_DITHER_TYPE_MASK; | ||
3857 | pipeconf |= PIPE_DITHER_TYPE_ST01; | 4037 | pipeconf |= PIPE_DITHER_TYPE_ST01; |
3858 | } else | 4038 | } else |
3859 | lvds |= LVDS_ENABLE_DITHER; | 4039 | lvds |= LVDS_ENABLE_DITHER; |
3860 | } else { | 4040 | } else { |
3861 | if (HAS_PCH_SPLIT(dev)) { | 4041 | if (!HAS_PCH_SPLIT(dev)) { |
3862 | pipeconf &= ~PIPE_ENABLE_DITHER; | ||
3863 | pipeconf &= ~PIPE_DITHER_TYPE_MASK; | ||
3864 | } else | ||
3865 | lvds &= ~LVDS_ENABLE_DITHER; | 4042 | lvds &= ~LVDS_ENABLE_DITHER; |
4043 | } | ||
3866 | } | 4044 | } |
3867 | } | 4045 | } |
3868 | I915_WRITE(lvds_reg, lvds); | 4046 | I915_WRITE(lvds_reg, lvds); |
@@ -4038,6 +4216,85 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) | |||
4038 | } | 4216 | } |
4039 | } | 4217 | } |
4040 | 4218 | ||
4219 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ | ||
4220 | static void intel_crtc_update_cursor(struct drm_crtc *crtc) | ||
4221 | { | ||
4222 | struct drm_device *dev = crtc->dev; | ||
4223 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4224 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
4225 | int pipe = intel_crtc->pipe; | ||
4226 | int x = intel_crtc->cursor_x; | ||
4227 | int y = intel_crtc->cursor_y; | ||
4228 | uint32_t base, pos; | ||
4229 | bool visible; | ||
4230 | |||
4231 | pos = 0; | ||
4232 | |||
4233 | if (crtc->fb) { | ||
4234 | base = intel_crtc->cursor_addr; | ||
4235 | if (x > (int) crtc->fb->width) | ||
4236 | base = 0; | ||
4237 | |||
4238 | if (y > (int) crtc->fb->height) | ||
4239 | base = 0; | ||
4240 | } else | ||
4241 | base = 0; | ||
4242 | |||
4243 | if (x < 0) { | ||
4244 | if (x + intel_crtc->cursor_width < 0) | ||
4245 | base = 0; | ||
4246 | |||
4247 | pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; | ||
4248 | x = -x; | ||
4249 | } | ||
4250 | pos |= x << CURSOR_X_SHIFT; | ||
4251 | |||
4252 | if (y < 0) { | ||
4253 | if (y + intel_crtc->cursor_height < 0) | ||
4254 | base = 0; | ||
4255 | |||
4256 | pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; | ||
4257 | y = -y; | ||
4258 | } | ||
4259 | pos |= y << CURSOR_Y_SHIFT; | ||
4260 | |||
4261 | visible = base != 0; | ||
4262 | if (!visible && !intel_crtc->cursor_visble) | ||
4263 | return; | ||
4264 | |||
4265 | I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); | ||
4266 | if (intel_crtc->cursor_visble != visible) { | ||
4267 | uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); | ||
4268 | if (base) { | ||
4269 | /* Hooray for CUR*CNTR differences */ | ||
4270 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
4271 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); | ||
4272 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | ||
4273 | cntl |= pipe << 28; /* Connect to correct pipe */ | ||
4274 | } else { | ||
4275 | cntl &= ~(CURSOR_FORMAT_MASK); | ||
4276 | cntl |= CURSOR_ENABLE; | ||
4277 | cntl |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; | ||
4278 | } | ||
4279 | } else { | ||
4280 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
4281 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | ||
4282 | cntl |= CURSOR_MODE_DISABLE; | ||
4283 | } else { | ||
4284 | cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); | ||
4285 | } | ||
4286 | } | ||
4287 | I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl); | ||
4288 | |||
4289 | intel_crtc->cursor_visble = visible; | ||
4290 | } | ||
4291 | /* and commit changes on next vblank */ | ||
4292 | I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base); | ||
4293 | |||
4294 | if (visible) | ||
4295 | intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); | ||
4296 | } | ||
4297 | |||
4041 | static int intel_crtc_cursor_set(struct drm_crtc *crtc, | 4298 | static int intel_crtc_cursor_set(struct drm_crtc *crtc, |
4042 | struct drm_file *file_priv, | 4299 | struct drm_file *file_priv, |
4043 | uint32_t handle, | 4300 | uint32_t handle, |
@@ -4048,11 +4305,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4048 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 4305 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
4049 | struct drm_gem_object *bo; | 4306 | struct drm_gem_object *bo; |
4050 | struct drm_i915_gem_object *obj_priv; | 4307 | struct drm_i915_gem_object *obj_priv; |
4051 | int pipe = intel_crtc->pipe; | 4308 | uint32_t addr; |
4052 | uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; | ||
4053 | uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; | ||
4054 | uint32_t temp = I915_READ(control); | ||
4055 | size_t addr; | ||
4056 | int ret; | 4309 | int ret; |
4057 | 4310 | ||
4058 | DRM_DEBUG_KMS("\n"); | 4311 | DRM_DEBUG_KMS("\n"); |
@@ -4060,12 +4313,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4060 | /* if we want to turn off the cursor ignore width and height */ | 4313 | /* if we want to turn off the cursor ignore width and height */ |
4061 | if (!handle) { | 4314 | if (!handle) { |
4062 | DRM_DEBUG_KMS("cursor off\n"); | 4315 | DRM_DEBUG_KMS("cursor off\n"); |
4063 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
4064 | temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | ||
4065 | temp |= CURSOR_MODE_DISABLE; | ||
4066 | } else { | ||
4067 | temp &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); | ||
4068 | } | ||
4069 | addr = 0; | 4316 | addr = 0; |
4070 | bo = NULL; | 4317 | bo = NULL; |
4071 | mutex_lock(&dev->struct_mutex); | 4318 | mutex_lock(&dev->struct_mutex); |
@@ -4107,7 +4354,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4107 | 4354 | ||
4108 | addr = obj_priv->gtt_offset; | 4355 | addr = obj_priv->gtt_offset; |
4109 | } else { | 4356 | } else { |
4110 | ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); | 4357 | ret = i915_gem_attach_phys_object(dev, bo, |
4358 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); | ||
4111 | if (ret) { | 4359 | if (ret) { |
4112 | DRM_ERROR("failed to attach phys object\n"); | 4360 | DRM_ERROR("failed to attach phys object\n"); |
4113 | goto fail_locked; | 4361 | goto fail_locked; |
@@ -4118,21 +4366,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4118 | if (!IS_I9XX(dev)) | 4366 | if (!IS_I9XX(dev)) |
4119 | I915_WRITE(CURSIZE, (height << 12) | width); | 4367 | I915_WRITE(CURSIZE, (height << 12) | width); |
4120 | 4368 | ||
4121 | /* Hooray for CUR*CNTR differences */ | ||
4122 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
4123 | temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); | ||
4124 | temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | ||
4125 | temp |= (pipe << 28); /* Connect to correct pipe */ | ||
4126 | } else { | ||
4127 | temp &= ~(CURSOR_FORMAT_MASK); | ||
4128 | temp |= CURSOR_ENABLE; | ||
4129 | temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; | ||
4130 | } | ||
4131 | |||
4132 | finish: | 4369 | finish: |
4133 | I915_WRITE(control, temp); | ||
4134 | I915_WRITE(base, addr); | ||
4135 | |||
4136 | if (intel_crtc->cursor_bo) { | 4370 | if (intel_crtc->cursor_bo) { |
4137 | if (dev_priv->info->cursor_needs_physical) { | 4371 | if (dev_priv->info->cursor_needs_physical) { |
4138 | if (intel_crtc->cursor_bo != bo) | 4372 | if (intel_crtc->cursor_bo != bo) |
@@ -4146,6 +4380,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4146 | 4380 | ||
4147 | intel_crtc->cursor_addr = addr; | 4381 | intel_crtc->cursor_addr = addr; |
4148 | intel_crtc->cursor_bo = bo; | 4382 | intel_crtc->cursor_bo = bo; |
4383 | intel_crtc->cursor_width = width; | ||
4384 | intel_crtc->cursor_height = height; | ||
4385 | |||
4386 | intel_crtc_update_cursor(crtc); | ||
4149 | 4387 | ||
4150 | return 0; | 4388 | return 0; |
4151 | fail_unpin: | 4389 | fail_unpin: |
@@ -4159,34 +4397,12 @@ fail: | |||
4159 | 4397 | ||
4160 | static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | 4398 | static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) |
4161 | { | 4399 | { |
4162 | struct drm_device *dev = crtc->dev; | ||
4163 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4164 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 4400 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
4165 | struct intel_framebuffer *intel_fb; | ||
4166 | int pipe = intel_crtc->pipe; | ||
4167 | uint32_t temp = 0; | ||
4168 | uint32_t adder; | ||
4169 | 4401 | ||
4170 | if (crtc->fb) { | 4402 | intel_crtc->cursor_x = x; |
4171 | intel_fb = to_intel_framebuffer(crtc->fb); | 4403 | intel_crtc->cursor_y = y; |
4172 | intel_mark_busy(dev, intel_fb->obj); | ||
4173 | } | ||
4174 | 4404 | ||
4175 | if (x < 0) { | 4405 | intel_crtc_update_cursor(crtc); |
4176 | temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; | ||
4177 | x = -x; | ||
4178 | } | ||
4179 | if (y < 0) { | ||
4180 | temp |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; | ||
4181 | y = -y; | ||
4182 | } | ||
4183 | |||
4184 | temp |= x << CURSOR_X_SHIFT; | ||
4185 | temp |= y << CURSOR_Y_SHIFT; | ||
4186 | |||
4187 | adder = intel_crtc->cursor_addr; | ||
4188 | I915_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp); | ||
4189 | I915_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder); | ||
4190 | 4406 | ||
4191 | return 0; | 4407 | return 0; |
4192 | } | 4408 | } |
@@ -4770,6 +4986,8 @@ static void do_intel_finish_page_flip(struct drm_device *dev, | |||
4770 | atomic_dec_and_test(&obj_priv->pending_flip)) | 4986 | atomic_dec_and_test(&obj_priv->pending_flip)) |
4771 | DRM_WAKEUP(&dev_priv->pending_flip_queue); | 4987 | DRM_WAKEUP(&dev_priv->pending_flip_queue); |
4772 | schedule_work(&work->work); | 4988 | schedule_work(&work->work); |
4989 | |||
4990 | trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj); | ||
4773 | } | 4991 | } |
4774 | 4992 | ||
4775 | void intel_finish_page_flip(struct drm_device *dev, int pipe) | 4993 | void intel_finish_page_flip(struct drm_device *dev, int pipe) |
@@ -4847,27 +5065,22 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4847 | 5065 | ||
4848 | mutex_lock(&dev->struct_mutex); | 5066 | mutex_lock(&dev->struct_mutex); |
4849 | ret = intel_pin_and_fence_fb_obj(dev, obj); | 5067 | ret = intel_pin_and_fence_fb_obj(dev, obj); |
4850 | if (ret != 0) { | 5068 | if (ret) |
4851 | mutex_unlock(&dev->struct_mutex); | 5069 | goto cleanup_work; |
4852 | |||
4853 | spin_lock_irqsave(&dev->event_lock, flags); | ||
4854 | intel_crtc->unpin_work = NULL; | ||
4855 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
4856 | |||
4857 | kfree(work); | ||
4858 | |||
4859 | DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", | ||
4860 | to_intel_bo(obj)); | ||
4861 | return ret; | ||
4862 | } | ||
4863 | 5070 | ||
4864 | /* Reference the objects for the scheduled work. */ | 5071 | /* Reference the objects for the scheduled work. */ |
4865 | drm_gem_object_reference(work->old_fb_obj); | 5072 | drm_gem_object_reference(work->old_fb_obj); |
4866 | drm_gem_object_reference(obj); | 5073 | drm_gem_object_reference(obj); |
4867 | 5074 | ||
4868 | crtc->fb = fb; | 5075 | crtc->fb = fb; |
4869 | i915_gem_object_flush_write_domain(obj); | 5076 | ret = i915_gem_object_flush_write_domain(obj); |
4870 | drm_vblank_get(dev, intel_crtc->pipe); | 5077 | if (ret) |
5078 | goto cleanup_objs; | ||
5079 | |||
5080 | ret = drm_vblank_get(dev, intel_crtc->pipe); | ||
5081 | if (ret) | ||
5082 | goto cleanup_objs; | ||
5083 | |||
4871 | obj_priv = to_intel_bo(obj); | 5084 | obj_priv = to_intel_bo(obj); |
4872 | atomic_inc(&obj_priv->pending_flip); | 5085 | atomic_inc(&obj_priv->pending_flip); |
4873 | work->pending_flip_obj = obj; | 5086 | work->pending_flip_obj = obj; |
@@ -4905,7 +5118,23 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4905 | 5118 | ||
4906 | mutex_unlock(&dev->struct_mutex); | 5119 | mutex_unlock(&dev->struct_mutex); |
4907 | 5120 | ||
5121 | trace_i915_flip_request(intel_crtc->plane, obj); | ||
5122 | |||
4908 | return 0; | 5123 | return 0; |
5124 | |||
5125 | cleanup_objs: | ||
5126 | drm_gem_object_unreference(work->old_fb_obj); | ||
5127 | drm_gem_object_unreference(obj); | ||
5128 | cleanup_work: | ||
5129 | mutex_unlock(&dev->struct_mutex); | ||
5130 | |||
5131 | spin_lock_irqsave(&dev->event_lock, flags); | ||
5132 | intel_crtc->unpin_work = NULL; | ||
5133 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
5134 | |||
5135 | kfree(work); | ||
5136 | |||
5137 | return ret; | ||
4909 | } | 5138 | } |
4910 | 5139 | ||
4911 | static const struct drm_crtc_helper_funcs intel_helper_funcs = { | 5140 | static const struct drm_crtc_helper_funcs intel_helper_funcs = { |
@@ -5032,19 +5261,26 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
5032 | { | 5261 | { |
5033 | struct drm_i915_private *dev_priv = dev->dev_private; | 5262 | struct drm_i915_private *dev_priv = dev->dev_private; |
5034 | struct drm_encoder *encoder; | 5263 | struct drm_encoder *encoder; |
5264 | bool dpd_is_edp = false; | ||
5035 | 5265 | ||
5036 | intel_crt_init(dev); | ||
5037 | |||
5038 | /* Set up integrated LVDS */ | ||
5039 | if (IS_MOBILE(dev) && !IS_I830(dev)) | 5266 | if (IS_MOBILE(dev) && !IS_I830(dev)) |
5040 | intel_lvds_init(dev); | 5267 | intel_lvds_init(dev); |
5041 | 5268 | ||
5042 | if (HAS_PCH_SPLIT(dev)) { | 5269 | if (HAS_PCH_SPLIT(dev)) { |
5043 | int found; | 5270 | dpd_is_edp = intel_dpd_is_edp(dev); |
5044 | 5271 | ||
5045 | if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED)) | 5272 | if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED)) |
5046 | intel_dp_init(dev, DP_A); | 5273 | intel_dp_init(dev, DP_A); |
5047 | 5274 | ||
5275 | if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) | ||
5276 | intel_dp_init(dev, PCH_DP_D); | ||
5277 | } | ||
5278 | |||
5279 | intel_crt_init(dev); | ||
5280 | |||
5281 | if (HAS_PCH_SPLIT(dev)) { | ||
5282 | int found; | ||
5283 | |||
5048 | if (I915_READ(HDMIB) & PORT_DETECTED) { | 5284 | if (I915_READ(HDMIB) & PORT_DETECTED) { |
5049 | /* PCH SDVOB multiplex with HDMIB */ | 5285 | /* PCH SDVOB multiplex with HDMIB */ |
5050 | found = intel_sdvo_init(dev, PCH_SDVOB); | 5286 | found = intel_sdvo_init(dev, PCH_SDVOB); |
@@ -5063,7 +5299,7 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
5063 | if (I915_READ(PCH_DP_C) & DP_DETECTED) | 5299 | if (I915_READ(PCH_DP_C) & DP_DETECTED) |
5064 | intel_dp_init(dev, PCH_DP_C); | 5300 | intel_dp_init(dev, PCH_DP_C); |
5065 | 5301 | ||
5066 | if (I915_READ(PCH_DP_D) & DP_DETECTED) | 5302 | if (!dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) |
5067 | intel_dp_init(dev, PCH_DP_D); | 5303 | intel_dp_init(dev, PCH_DP_D); |
5068 | 5304 | ||
5069 | } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { | 5305 | } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { |
@@ -5472,6 +5708,26 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5472 | (I915_READ(DISP_ARB_CTL) | | 5708 | (I915_READ(DISP_ARB_CTL) | |
5473 | DISP_FBC_WM_DIS)); | 5709 | DISP_FBC_WM_DIS)); |
5474 | } | 5710 | } |
5711 | /* | ||
5712 | * Based on the document from hardware guys the following bits | ||
5713 | * should be set unconditionally in order to enable FBC. | ||
5714 | * The bit 22 of 0x42000 | ||
5715 | * The bit 22 of 0x42004 | ||
5716 | * The bit 7,8,9 of 0x42020. | ||
5717 | */ | ||
5718 | if (IS_IRONLAKE_M(dev)) { | ||
5719 | I915_WRITE(ILK_DISPLAY_CHICKEN1, | ||
5720 | I915_READ(ILK_DISPLAY_CHICKEN1) | | ||
5721 | ILK_FBCQ_DIS); | ||
5722 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
5723 | I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
5724 | ILK_DPARB_GATE); | ||
5725 | I915_WRITE(ILK_DSPCLK_GATE, | ||
5726 | I915_READ(ILK_DSPCLK_GATE) | | ||
5727 | ILK_DPFC_DIS1 | | ||
5728 | ILK_DPFC_DIS2 | | ||
5729 | ILK_CLK_FBC); | ||
5730 | } | ||
5475 | return; | 5731 | return; |
5476 | } else if (IS_G4X(dev)) { | 5732 | } else if (IS_G4X(dev)) { |
5477 | uint32_t dspclk_gate; | 5733 | uint32_t dspclk_gate; |
@@ -5550,7 +5806,11 @@ static void intel_init_display(struct drm_device *dev) | |||
5550 | dev_priv->display.dpms = i9xx_crtc_dpms; | 5806 | dev_priv->display.dpms = i9xx_crtc_dpms; |
5551 | 5807 | ||
5552 | if (I915_HAS_FBC(dev)) { | 5808 | if (I915_HAS_FBC(dev)) { |
5553 | if (IS_GM45(dev)) { | 5809 | if (IS_IRONLAKE_M(dev)) { |
5810 | dev_priv->display.fbc_enabled = ironlake_fbc_enabled; | ||
5811 | dev_priv->display.enable_fbc = ironlake_enable_fbc; | ||
5812 | dev_priv->display.disable_fbc = ironlake_disable_fbc; | ||
5813 | } else if (IS_GM45(dev)) { | ||
5554 | dev_priv->display.fbc_enabled = g4x_fbc_enabled; | 5814 | dev_priv->display.fbc_enabled = g4x_fbc_enabled; |
5555 | dev_priv->display.enable_fbc = g4x_enable_fbc; | 5815 | dev_priv->display.enable_fbc = g4x_enable_fbc; |
5556 | dev_priv->display.disable_fbc = g4x_disable_fbc; | 5816 | dev_priv->display.disable_fbc = g4x_disable_fbc; |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5dde80f9e652..40be1fa65be1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #define DP_LINK_CONFIGURATION_SIZE 9 | 43 | #define DP_LINK_CONFIGURATION_SIZE 9 |
44 | 44 | ||
45 | #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP) | 45 | #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP) |
46 | #define IS_PCH_eDP(dp_priv) ((dp_priv)->is_pch_edp) | ||
46 | 47 | ||
47 | struct intel_dp_priv { | 48 | struct intel_dp_priv { |
48 | uint32_t output_reg; | 49 | uint32_t output_reg; |
@@ -56,6 +57,7 @@ struct intel_dp_priv { | |||
56 | struct intel_encoder *intel_encoder; | 57 | struct intel_encoder *intel_encoder; |
57 | struct i2c_adapter adapter; | 58 | struct i2c_adapter adapter; |
58 | struct i2c_algo_dp_aux_data algo; | 59 | struct i2c_algo_dp_aux_data algo; |
60 | bool is_pch_edp; | ||
59 | }; | 61 | }; |
60 | 62 | ||
61 | static void | 63 | static void |
@@ -128,8 +130,9 @@ intel_dp_link_required(struct drm_device *dev, | |||
128 | struct intel_encoder *intel_encoder, int pixel_clock) | 130 | struct intel_encoder *intel_encoder, int pixel_clock) |
129 | { | 131 | { |
130 | struct drm_i915_private *dev_priv = dev->dev_private; | 132 | struct drm_i915_private *dev_priv = dev->dev_private; |
133 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
131 | 134 | ||
132 | if (IS_eDP(intel_encoder)) | 135 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) |
133 | return (pixel_clock * dev_priv->edp_bpp) / 8; | 136 | return (pixel_clock * dev_priv->edp_bpp) / 8; |
134 | else | 137 | else |
135 | return pixel_clock * 3; | 138 | return pixel_clock * 3; |
@@ -147,9 +150,21 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
147 | { | 150 | { |
148 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 151 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
149 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 152 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
153 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
154 | struct drm_device *dev = connector->dev; | ||
155 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
150 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); | 156 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); |
151 | int max_lanes = intel_dp_max_lane_count(intel_encoder); | 157 | int max_lanes = intel_dp_max_lane_count(intel_encoder); |
152 | 158 | ||
159 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | ||
160 | dev_priv->panel_fixed_mode) { | ||
161 | if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay) | ||
162 | return MODE_PANEL; | ||
163 | |||
164 | if (mode->vdisplay > dev_priv->panel_fixed_mode->vdisplay) | ||
165 | return MODE_PANEL; | ||
166 | } | ||
167 | |||
153 | /* only refuse the mode on non eDP since we have seen some wierd eDP panels | 168 | /* only refuse the mode on non eDP since we have seen some wierd eDP panels |
154 | which are outside spec tolerances but somehow work by magic */ | 169 | which are outside spec tolerances but somehow work by magic */ |
155 | if (!IS_eDP(intel_encoder) && | 170 | if (!IS_eDP(intel_encoder) && |
@@ -508,11 +523,37 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
508 | { | 523 | { |
509 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 524 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
510 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 525 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
526 | struct drm_device *dev = encoder->dev; | ||
527 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
511 | int lane_count, clock; | 528 | int lane_count, clock; |
512 | int max_lane_count = intel_dp_max_lane_count(intel_encoder); | 529 | int max_lane_count = intel_dp_max_lane_count(intel_encoder); |
513 | int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0; | 530 | int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0; |
514 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | 531 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; |
515 | 532 | ||
533 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | ||
534 | dev_priv->panel_fixed_mode) { | ||
535 | struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode; | ||
536 | |||
537 | adjusted_mode->hdisplay = fixed_mode->hdisplay; | ||
538 | adjusted_mode->hsync_start = fixed_mode->hsync_start; | ||
539 | adjusted_mode->hsync_end = fixed_mode->hsync_end; | ||
540 | adjusted_mode->htotal = fixed_mode->htotal; | ||
541 | |||
542 | adjusted_mode->vdisplay = fixed_mode->vdisplay; | ||
543 | adjusted_mode->vsync_start = fixed_mode->vsync_start; | ||
544 | adjusted_mode->vsync_end = fixed_mode->vsync_end; | ||
545 | adjusted_mode->vtotal = fixed_mode->vtotal; | ||
546 | |||
547 | adjusted_mode->clock = fixed_mode->clock; | ||
548 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
549 | |||
550 | /* | ||
551 | * the mode->clock is used to calculate the Data&Link M/N | ||
552 | * of the pipe. For the eDP the fixed clock should be used. | ||
553 | */ | ||
554 | mode->clock = dev_priv->panel_fixed_mode->clock; | ||
555 | } | ||
556 | |||
516 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | 557 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { |
517 | for (clock = 0; clock <= max_clock; clock++) { | 558 | for (clock = 0; clock <= max_clock; clock++) { |
518 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); | 559 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
@@ -531,7 +572,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
531 | } | 572 | } |
532 | } | 573 | } |
533 | 574 | ||
534 | if (IS_eDP(intel_encoder)) { | 575 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { |
535 | /* okay we failed just pick the highest */ | 576 | /* okay we failed just pick the highest */ |
536 | dp_priv->lane_count = max_lane_count; | 577 | dp_priv->lane_count = max_lane_count; |
537 | dp_priv->link_bw = bws[max_clock]; | 578 | dp_priv->link_bw = bws[max_clock]; |
@@ -563,14 +604,14 @@ intel_reduce_ratio(uint32_t *num, uint32_t *den) | |||
563 | } | 604 | } |
564 | 605 | ||
565 | static void | 606 | static void |
566 | intel_dp_compute_m_n(int bytes_per_pixel, | 607 | intel_dp_compute_m_n(int bpp, |
567 | int nlanes, | 608 | int nlanes, |
568 | int pixel_clock, | 609 | int pixel_clock, |
569 | int link_clock, | 610 | int link_clock, |
570 | struct intel_dp_m_n *m_n) | 611 | struct intel_dp_m_n *m_n) |
571 | { | 612 | { |
572 | m_n->tu = 64; | 613 | m_n->tu = 64; |
573 | m_n->gmch_m = pixel_clock * bytes_per_pixel; | 614 | m_n->gmch_m = (pixel_clock * bpp) >> 3; |
574 | m_n->gmch_n = link_clock * nlanes; | 615 | m_n->gmch_n = link_clock * nlanes; |
575 | intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | 616 | intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
576 | m_n->link_m = pixel_clock; | 617 | m_n->link_m = pixel_clock; |
@@ -578,6 +619,28 @@ intel_dp_compute_m_n(int bytes_per_pixel, | |||
578 | intel_reduce_ratio(&m_n->link_m, &m_n->link_n); | 619 | intel_reduce_ratio(&m_n->link_m, &m_n->link_n); |
579 | } | 620 | } |
580 | 621 | ||
622 | bool intel_pch_has_edp(struct drm_crtc *crtc) | ||
623 | { | ||
624 | struct drm_device *dev = crtc->dev; | ||
625 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
626 | struct drm_encoder *encoder; | ||
627 | |||
628 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | ||
629 | struct intel_encoder *intel_encoder; | ||
630 | struct intel_dp_priv *dp_priv; | ||
631 | |||
632 | if (!encoder || encoder->crtc != crtc) | ||
633 | continue; | ||
634 | |||
635 | intel_encoder = enc_to_intel_encoder(encoder); | ||
636 | dp_priv = intel_encoder->dev_priv; | ||
637 | |||
638 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) | ||
639 | return dp_priv->is_pch_edp; | ||
640 | } | ||
641 | return false; | ||
642 | } | ||
643 | |||
581 | void | 644 | void |
582 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | 645 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, |
583 | struct drm_display_mode *adjusted_mode) | 646 | struct drm_display_mode *adjusted_mode) |
@@ -587,7 +650,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
587 | struct drm_encoder *encoder; | 650 | struct drm_encoder *encoder; |
588 | struct drm_i915_private *dev_priv = dev->dev_private; | 651 | struct drm_i915_private *dev_priv = dev->dev_private; |
589 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 652 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
590 | int lane_count = 4; | 653 | int lane_count = 4, bpp = 24; |
591 | struct intel_dp_m_n m_n; | 654 | struct intel_dp_m_n m_n; |
592 | 655 | ||
593 | /* | 656 | /* |
@@ -605,6 +668,8 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
605 | 668 | ||
606 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { | 669 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { |
607 | lane_count = dp_priv->lane_count; | 670 | lane_count = dp_priv->lane_count; |
671 | if (IS_PCH_eDP(dp_priv)) | ||
672 | bpp = dev_priv->edp_bpp; | ||
608 | break; | 673 | break; |
609 | } | 674 | } |
610 | } | 675 | } |
@@ -614,7 +679,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
614 | * the number of bytes_per_pixel post-LUT, which we always | 679 | * the number of bytes_per_pixel post-LUT, which we always |
615 | * set up for 8-bits of R/G/B, or 3 bytes total. | 680 | * set up for 8-bits of R/G/B, or 3 bytes total. |
616 | */ | 681 | */ |
617 | intel_dp_compute_m_n(3, lane_count, | 682 | intel_dp_compute_m_n(bpp, lane_count, |
618 | mode->clock, adjusted_mode->clock, &m_n); | 683 | mode->clock, adjusted_mode->clock, &m_n); |
619 | 684 | ||
620 | if (HAS_PCH_SPLIT(dev)) { | 685 | if (HAS_PCH_SPLIT(dev)) { |
@@ -796,7 +861,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
796 | if (mode != DRM_MODE_DPMS_ON) { | 861 | if (mode != DRM_MODE_DPMS_ON) { |
797 | if (dp_reg & DP_PORT_EN) { | 862 | if (dp_reg & DP_PORT_EN) { |
798 | intel_dp_link_down(intel_encoder, dp_priv->DP); | 863 | intel_dp_link_down(intel_encoder, dp_priv->DP); |
799 | if (IS_eDP(intel_encoder)) { | 864 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { |
800 | ironlake_edp_backlight_off(dev); | 865 | ironlake_edp_backlight_off(dev); |
801 | ironlake_edp_panel_off(dev); | 866 | ironlake_edp_panel_off(dev); |
802 | } | 867 | } |
@@ -804,7 +869,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
804 | } else { | 869 | } else { |
805 | if (!(dp_reg & DP_PORT_EN)) { | 870 | if (!(dp_reg & DP_PORT_EN)) { |
806 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); | 871 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); |
807 | if (IS_eDP(intel_encoder)) { | 872 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { |
808 | ironlake_edp_panel_on(dev); | 873 | ironlake_edp_panel_on(dev); |
809 | ironlake_edp_backlight_on(dev); | 874 | ironlake_edp_backlight_on(dev); |
810 | } | 875 | } |
@@ -1340,17 +1405,32 @@ static int intel_dp_get_modes(struct drm_connector *connector) | |||
1340 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1405 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
1341 | struct drm_device *dev = intel_encoder->enc.dev; | 1406 | struct drm_device *dev = intel_encoder->enc.dev; |
1342 | struct drm_i915_private *dev_priv = dev->dev_private; | 1407 | struct drm_i915_private *dev_priv = dev->dev_private; |
1408 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1343 | int ret; | 1409 | int ret; |
1344 | 1410 | ||
1345 | /* We should parse the EDID data and find out if it has an audio sink | 1411 | /* We should parse the EDID data and find out if it has an audio sink |
1346 | */ | 1412 | */ |
1347 | 1413 | ||
1348 | ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 1414 | ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); |
1349 | if (ret) | 1415 | if (ret) { |
1416 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | ||
1417 | !dev_priv->panel_fixed_mode) { | ||
1418 | struct drm_display_mode *newmode; | ||
1419 | list_for_each_entry(newmode, &connector->probed_modes, | ||
1420 | head) { | ||
1421 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { | ||
1422 | dev_priv->panel_fixed_mode = | ||
1423 | drm_mode_duplicate(dev, newmode); | ||
1424 | break; | ||
1425 | } | ||
1426 | } | ||
1427 | } | ||
1428 | |||
1350 | return ret; | 1429 | return ret; |
1430 | } | ||
1351 | 1431 | ||
1352 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ | 1432 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ |
1353 | if (IS_eDP(intel_encoder)) { | 1433 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { |
1354 | if (dev_priv->panel_fixed_mode != NULL) { | 1434 | if (dev_priv->panel_fixed_mode != NULL) { |
1355 | struct drm_display_mode *mode; | 1435 | struct drm_display_mode *mode; |
1356 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); | 1436 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); |
@@ -1435,6 +1515,26 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc) | |||
1435 | return -1; | 1515 | return -1; |
1436 | } | 1516 | } |
1437 | 1517 | ||
1518 | /* check the VBT to see whether the eDP is on DP-D port */ | ||
1519 | bool intel_dpd_is_edp(struct drm_device *dev) | ||
1520 | { | ||
1521 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1522 | struct child_device_config *p_child; | ||
1523 | int i; | ||
1524 | |||
1525 | if (!dev_priv->child_dev_num) | ||
1526 | return false; | ||
1527 | |||
1528 | for (i = 0; i < dev_priv->child_dev_num; i++) { | ||
1529 | p_child = dev_priv->child_dev + i; | ||
1530 | |||
1531 | if (p_child->dvo_port == PORT_IDPD && | ||
1532 | p_child->device_type == DEVICE_TYPE_eDP) | ||
1533 | return true; | ||
1534 | } | ||
1535 | return false; | ||
1536 | } | ||
1537 | |||
1438 | void | 1538 | void |
1439 | intel_dp_init(struct drm_device *dev, int output_reg) | 1539 | intel_dp_init(struct drm_device *dev, int output_reg) |
1440 | { | 1540 | { |
@@ -1444,6 +1544,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1444 | struct intel_connector *intel_connector; | 1544 | struct intel_connector *intel_connector; |
1445 | struct intel_dp_priv *dp_priv; | 1545 | struct intel_dp_priv *dp_priv; |
1446 | const char *name = NULL; | 1546 | const char *name = NULL; |
1547 | int type; | ||
1447 | 1548 | ||
1448 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + | 1549 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + |
1449 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); | 1550 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); |
@@ -1458,18 +1559,24 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1458 | 1559 | ||
1459 | dp_priv = (struct intel_dp_priv *)(intel_encoder + 1); | 1560 | dp_priv = (struct intel_dp_priv *)(intel_encoder + 1); |
1460 | 1561 | ||
1562 | if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D)) | ||
1563 | if (intel_dpd_is_edp(dev)) | ||
1564 | dp_priv->is_pch_edp = true; | ||
1565 | |||
1566 | if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) { | ||
1567 | type = DRM_MODE_CONNECTOR_eDP; | ||
1568 | intel_encoder->type = INTEL_OUTPUT_EDP; | ||
1569 | } else { | ||
1570 | type = DRM_MODE_CONNECTOR_DisplayPort; | ||
1571 | intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; | ||
1572 | } | ||
1573 | |||
1461 | connector = &intel_connector->base; | 1574 | connector = &intel_connector->base; |
1462 | drm_connector_init(dev, connector, &intel_dp_connector_funcs, | 1575 | drm_connector_init(dev, connector, &intel_dp_connector_funcs, type); |
1463 | DRM_MODE_CONNECTOR_DisplayPort); | ||
1464 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); | 1576 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); |
1465 | 1577 | ||
1466 | connector->polled = DRM_CONNECTOR_POLL_HPD; | 1578 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
1467 | 1579 | ||
1468 | if (output_reg == DP_A) | ||
1469 | intel_encoder->type = INTEL_OUTPUT_EDP; | ||
1470 | else | ||
1471 | intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; | ||
1472 | |||
1473 | if (output_reg == DP_B || output_reg == PCH_DP_B) | 1580 | if (output_reg == DP_B || output_reg == PCH_DP_B) |
1474 | intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); | 1581 | intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); |
1475 | else if (output_reg == DP_C || output_reg == PCH_DP_C) | 1582 | else if (output_reg == DP_C || output_reg == PCH_DP_C) |
@@ -1528,7 +1635,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1528 | intel_encoder->ddc_bus = &dp_priv->adapter; | 1635 | intel_encoder->ddc_bus = &dp_priv->adapter; |
1529 | intel_encoder->hot_plug = intel_dp_hot_plug; | 1636 | intel_encoder->hot_plug = intel_dp_hot_plug; |
1530 | 1637 | ||
1531 | if (output_reg == DP_A) { | 1638 | if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) { |
1532 | /* initialize panel mode from VBT if available for eDP */ | 1639 | /* initialize panel mode from VBT if available for eDP */ |
1533 | if (dev_priv->lfp_lvds_vbt_mode) { | 1640 | if (dev_priv->lfp_lvds_vbt_mode) { |
1534 | dev_priv->panel_fixed_mode = | 1641 | dev_priv->panel_fixed_mode = |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 2f7970be9051..b2190148703a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -143,8 +143,6 @@ struct intel_crtc { | |||
143 | struct drm_crtc base; | 143 | struct drm_crtc base; |
144 | enum pipe pipe; | 144 | enum pipe pipe; |
145 | enum plane plane; | 145 | enum plane plane; |
146 | struct drm_gem_object *cursor_bo; | ||
147 | uint32_t cursor_addr; | ||
148 | u8 lut_r[256], lut_g[256], lut_b[256]; | 146 | u8 lut_r[256], lut_g[256], lut_b[256]; |
149 | int dpms_mode; | 147 | int dpms_mode; |
150 | bool busy; /* is scanout buffer being updated frequently? */ | 148 | bool busy; /* is scanout buffer being updated frequently? */ |
@@ -153,6 +151,12 @@ struct intel_crtc { | |||
153 | struct intel_overlay *overlay; | 151 | struct intel_overlay *overlay; |
154 | struct intel_unpin_work *unpin_work; | 152 | struct intel_unpin_work *unpin_work; |
155 | int fdi_lanes; | 153 | int fdi_lanes; |
154 | |||
155 | struct drm_gem_object *cursor_bo; | ||
156 | uint32_t cursor_addr; | ||
157 | int16_t cursor_x, cursor_y; | ||
158 | int16_t cursor_width, cursor_height; | ||
159 | bool cursor_visble; | ||
156 | }; | 160 | }; |
157 | 161 | ||
158 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) | 162 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) |
@@ -179,6 +183,8 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg); | |||
179 | void | 183 | void |
180 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | 184 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, |
181 | struct drm_display_mode *adjusted_mode); | 185 | struct drm_display_mode *adjusted_mode); |
186 | extern bool intel_pch_has_edp(struct drm_crtc *crtc); | ||
187 | extern bool intel_dpd_is_edp(struct drm_device *dev); | ||
182 | extern void intel_edp_link_config (struct intel_encoder *, int *, int *); | 188 | extern void intel_edp_link_config (struct intel_encoder *, int *, int *); |
183 | 189 | ||
184 | 190 | ||
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 83bd764b000e..197887ed1823 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -54,10 +54,11 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
54 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | 54 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; |
55 | u32 sdvox; | 55 | u32 sdvox; |
56 | 56 | ||
57 | sdvox = SDVO_ENCODING_HDMI | | 57 | sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; |
58 | SDVO_BORDER_ENABLE | | 58 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
59 | SDVO_VSYNC_ACTIVE_HIGH | | 59 | sdvox |= SDVO_VSYNC_ACTIVE_HIGH; |
60 | SDVO_HSYNC_ACTIVE_HIGH; | 60 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
61 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; | ||
61 | 62 | ||
62 | if (hdmi_priv->has_hdmi_sink) { | 63 | if (hdmi_priv->has_hdmi_sink) { |
63 | sdvox |= SDVO_AUDIO_ENABLE; | 64 | sdvox |= SDVO_AUDIO_ENABLE; |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 0eab8df5bf7e..0a2e60059fb3 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -156,31 +156,73 @@ static int intel_lvds_mode_valid(struct drm_connector *connector, | |||
156 | return MODE_OK; | 156 | return MODE_OK; |
157 | } | 157 | } |
158 | 158 | ||
159 | static void | ||
160 | centre_horizontally(struct drm_display_mode *mode, | ||
161 | int width) | ||
162 | { | ||
163 | u32 border, sync_pos, blank_width, sync_width; | ||
164 | |||
165 | /* keep the hsync and hblank widths constant */ | ||
166 | sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start; | ||
167 | blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start; | ||
168 | sync_pos = (blank_width - sync_width + 1) / 2; | ||
169 | |||
170 | border = (mode->hdisplay - width + 1) / 2; | ||
171 | border += border & 1; /* make the border even */ | ||
172 | |||
173 | mode->crtc_hdisplay = width; | ||
174 | mode->crtc_hblank_start = width + border; | ||
175 | mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width; | ||
176 | |||
177 | mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; | ||
178 | mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; | ||
179 | } | ||
180 | |||
181 | static void | ||
182 | centre_vertically(struct drm_display_mode *mode, | ||
183 | int height) | ||
184 | { | ||
185 | u32 border, sync_pos, blank_width, sync_width; | ||
186 | |||
187 | /* keep the vsync and vblank widths constant */ | ||
188 | sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start; | ||
189 | blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start; | ||
190 | sync_pos = (blank_width - sync_width + 1) / 2; | ||
191 | |||
192 | border = (mode->vdisplay - height + 1) / 2; | ||
193 | |||
194 | mode->crtc_vdisplay = height; | ||
195 | mode->crtc_vblank_start = height + border; | ||
196 | mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width; | ||
197 | |||
198 | mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; | ||
199 | mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; | ||
200 | } | ||
201 | |||
202 | static inline u32 panel_fitter_scaling(u32 source, u32 target) | ||
203 | { | ||
204 | /* | ||
205 | * Floating point operation is not supported. So the FACTOR | ||
206 | * is defined, which can avoid the floating point computation | ||
207 | * when calculating the panel ratio. | ||
208 | */ | ||
209 | #define ACCURACY 12 | ||
210 | #define FACTOR (1 << ACCURACY) | ||
211 | u32 ratio = source * FACTOR / target; | ||
212 | return (FACTOR * ratio + FACTOR/2) / FACTOR; | ||
213 | } | ||
214 | |||
159 | static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | 215 | static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, |
160 | struct drm_display_mode *mode, | 216 | struct drm_display_mode *mode, |
161 | struct drm_display_mode *adjusted_mode) | 217 | struct drm_display_mode *adjusted_mode) |
162 | { | 218 | { |
163 | /* | ||
164 | * float point operation is not supported . So the PANEL_RATIO_FACTOR | ||
165 | * is defined, which can avoid the float point computation when | ||
166 | * calculating the panel ratio. | ||
167 | */ | ||
168 | #define PANEL_RATIO_FACTOR 8192 | ||
169 | struct drm_device *dev = encoder->dev; | 219 | struct drm_device *dev = encoder->dev; |
170 | struct drm_i915_private *dev_priv = dev->dev_private; | 220 | struct drm_i915_private *dev_priv = dev->dev_private; |
171 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 221 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
172 | struct drm_encoder *tmp_encoder; | 222 | struct drm_encoder *tmp_encoder; |
173 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 223 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
174 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | 224 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; |
175 | u32 pfit_control = 0, pfit_pgm_ratios = 0; | 225 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
176 | int left_border = 0, right_border = 0, top_border = 0; | ||
177 | int bottom_border = 0; | ||
178 | bool border = 0; | ||
179 | int panel_ratio, desired_ratio, vert_scale, horiz_scale; | ||
180 | int horiz_ratio, vert_ratio; | ||
181 | u32 hsync_width, vsync_width; | ||
182 | u32 hblank_width, vblank_width; | ||
183 | u32 hsync_pos, vsync_pos; | ||
184 | 226 | ||
185 | /* Should never happen!! */ | 227 | /* Should never happen!! */ |
186 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { | 228 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { |
@@ -200,27 +242,25 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
200 | if (dev_priv->panel_fixed_mode == NULL) | 242 | if (dev_priv->panel_fixed_mode == NULL) |
201 | return true; | 243 | return true; |
202 | /* | 244 | /* |
203 | * If we have timings from the BIOS for the panel, put them in | 245 | * We have timings from the BIOS for the panel, put them in |
204 | * to the adjusted mode. The CRTC will be set up for this mode, | 246 | * to the adjusted mode. The CRTC will be set up for this mode, |
205 | * with the panel scaling set up to source from the H/VDisplay | 247 | * with the panel scaling set up to source from the H/VDisplay |
206 | * of the original mode. | 248 | * of the original mode. |
207 | */ | 249 | */ |
208 | if (dev_priv->panel_fixed_mode != NULL) { | 250 | adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay; |
209 | adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay; | 251 | adjusted_mode->hsync_start = |
210 | adjusted_mode->hsync_start = | 252 | dev_priv->panel_fixed_mode->hsync_start; |
211 | dev_priv->panel_fixed_mode->hsync_start; | 253 | adjusted_mode->hsync_end = |
212 | adjusted_mode->hsync_end = | 254 | dev_priv->panel_fixed_mode->hsync_end; |
213 | dev_priv->panel_fixed_mode->hsync_end; | 255 | adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal; |
214 | adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal; | 256 | adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay; |
215 | adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay; | 257 | adjusted_mode->vsync_start = |
216 | adjusted_mode->vsync_start = | 258 | dev_priv->panel_fixed_mode->vsync_start; |
217 | dev_priv->panel_fixed_mode->vsync_start; | 259 | adjusted_mode->vsync_end = |
218 | adjusted_mode->vsync_end = | 260 | dev_priv->panel_fixed_mode->vsync_end; |
219 | dev_priv->panel_fixed_mode->vsync_end; | 261 | adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal; |
220 | adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal; | 262 | adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; |
221 | adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; | 263 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); |
222 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
223 | } | ||
224 | 264 | ||
225 | /* Make sure pre-965s set dither correctly */ | 265 | /* Make sure pre-965s set dither correctly */ |
226 | if (!IS_I965G(dev)) { | 266 | if (!IS_I965G(dev)) { |
@@ -230,11 +270,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
230 | 270 | ||
231 | /* Native modes don't need fitting */ | 271 | /* Native modes don't need fitting */ |
232 | if (adjusted_mode->hdisplay == mode->hdisplay && | 272 | if (adjusted_mode->hdisplay == mode->hdisplay && |
233 | adjusted_mode->vdisplay == mode->vdisplay) { | 273 | adjusted_mode->vdisplay == mode->vdisplay) |
234 | pfit_pgm_ratios = 0; | ||
235 | border = 0; | ||
236 | goto out; | 274 | goto out; |
237 | } | ||
238 | 275 | ||
239 | /* full screen scale for now */ | 276 | /* full screen scale for now */ |
240 | if (HAS_PCH_SPLIT(dev)) | 277 | if (HAS_PCH_SPLIT(dev)) |
@@ -242,25 +279,9 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
242 | 279 | ||
243 | /* 965+ wants fuzzy fitting */ | 280 | /* 965+ wants fuzzy fitting */ |
244 | if (IS_I965G(dev)) | 281 | if (IS_I965G(dev)) |
245 | pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) | | 282 | pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | |
246 | PFIT_FILTER_FUZZY; | 283 | PFIT_FILTER_FUZZY); |
247 | 284 | ||
248 | hsync_width = adjusted_mode->crtc_hsync_end - | ||
249 | adjusted_mode->crtc_hsync_start; | ||
250 | vsync_width = adjusted_mode->crtc_vsync_end - | ||
251 | adjusted_mode->crtc_vsync_start; | ||
252 | hblank_width = adjusted_mode->crtc_hblank_end - | ||
253 | adjusted_mode->crtc_hblank_start; | ||
254 | vblank_width = adjusted_mode->crtc_vblank_end - | ||
255 | adjusted_mode->crtc_vblank_start; | ||
256 | /* | ||
257 | * Deal with panel fitting options. Figure out how to stretch the | ||
258 | * image based on its aspect ratio & the current panel fitting mode. | ||
259 | */ | ||
260 | panel_ratio = adjusted_mode->hdisplay * PANEL_RATIO_FACTOR / | ||
261 | adjusted_mode->vdisplay; | ||
262 | desired_ratio = mode->hdisplay * PANEL_RATIO_FACTOR / | ||
263 | mode->vdisplay; | ||
264 | /* | 285 | /* |
265 | * Enable automatic panel scaling for non-native modes so that they fill | 286 | * Enable automatic panel scaling for non-native modes so that they fill |
266 | * the screen. Should be enabled before the pipe is enabled, according | 287 | * the screen. Should be enabled before the pipe is enabled, according |
@@ -278,170 +299,63 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
278 | * For centered modes, we have to calculate border widths & | 299 | * For centered modes, we have to calculate border widths & |
279 | * heights and modify the values programmed into the CRTC. | 300 | * heights and modify the values programmed into the CRTC. |
280 | */ | 301 | */ |
281 | left_border = (adjusted_mode->hdisplay - mode->hdisplay) / 2; | 302 | centre_horizontally(adjusted_mode, mode->hdisplay); |
282 | right_border = left_border; | 303 | centre_vertically(adjusted_mode, mode->vdisplay); |
283 | if (mode->hdisplay & 1) | 304 | border = LVDS_BORDER_ENABLE; |
284 | right_border++; | ||
285 | top_border = (adjusted_mode->vdisplay - mode->vdisplay) / 2; | ||
286 | bottom_border = top_border; | ||
287 | if (mode->vdisplay & 1) | ||
288 | bottom_border++; | ||
289 | /* Set active & border values */ | ||
290 | adjusted_mode->crtc_hdisplay = mode->hdisplay; | ||
291 | /* Keep the boder be even */ | ||
292 | if (right_border & 1) | ||
293 | right_border++; | ||
294 | /* use the border directly instead of border minuse one */ | ||
295 | adjusted_mode->crtc_hblank_start = mode->hdisplay + | ||
296 | right_border; | ||
297 | /* keep the blank width constant */ | ||
298 | adjusted_mode->crtc_hblank_end = | ||
299 | adjusted_mode->crtc_hblank_start + hblank_width; | ||
300 | /* get the hsync pos relative to hblank start */ | ||
301 | hsync_pos = (hblank_width - hsync_width) / 2; | ||
302 | /* keep the hsync pos be even */ | ||
303 | if (hsync_pos & 1) | ||
304 | hsync_pos++; | ||
305 | adjusted_mode->crtc_hsync_start = | ||
306 | adjusted_mode->crtc_hblank_start + hsync_pos; | ||
307 | /* keep the hsync width constant */ | ||
308 | adjusted_mode->crtc_hsync_end = | ||
309 | adjusted_mode->crtc_hsync_start + hsync_width; | ||
310 | adjusted_mode->crtc_vdisplay = mode->vdisplay; | ||
311 | /* use the border instead of border minus one */ | ||
312 | adjusted_mode->crtc_vblank_start = mode->vdisplay + | ||
313 | bottom_border; | ||
314 | /* keep the vblank width constant */ | ||
315 | adjusted_mode->crtc_vblank_end = | ||
316 | adjusted_mode->crtc_vblank_start + vblank_width; | ||
317 | /* get the vsync start postion relative to vblank start */ | ||
318 | vsync_pos = (vblank_width - vsync_width) / 2; | ||
319 | adjusted_mode->crtc_vsync_start = | ||
320 | adjusted_mode->crtc_vblank_start + vsync_pos; | ||
321 | /* keep the vsync width constant */ | ||
322 | adjusted_mode->crtc_vsync_end = | ||
323 | adjusted_mode->crtc_vsync_start + vsync_width; | ||
324 | border = 1; | ||
325 | break; | 305 | break; |
306 | |||
326 | case DRM_MODE_SCALE_ASPECT: | 307 | case DRM_MODE_SCALE_ASPECT: |
327 | /* Scale but preserve the spect ratio */ | 308 | /* Scale but preserve the aspect ratio */ |
328 | pfit_control |= PFIT_ENABLE; | ||
329 | if (IS_I965G(dev)) { | 309 | if (IS_I965G(dev)) { |
310 | u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; | ||
311 | u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; | ||
312 | |||
313 | pfit_control |= PFIT_ENABLE; | ||
330 | /* 965+ is easy, it does everything in hw */ | 314 | /* 965+ is easy, it does everything in hw */ |
331 | if (panel_ratio > desired_ratio) | 315 | if (scaled_width > scaled_height) |
332 | pfit_control |= PFIT_SCALING_PILLAR; | 316 | pfit_control |= PFIT_SCALING_PILLAR; |
333 | else if (panel_ratio < desired_ratio) | 317 | else if (scaled_width < scaled_height) |
334 | pfit_control |= PFIT_SCALING_LETTER; | 318 | pfit_control |= PFIT_SCALING_LETTER; |
335 | else | 319 | else |
336 | pfit_control |= PFIT_SCALING_AUTO; | 320 | pfit_control |= PFIT_SCALING_AUTO; |
337 | } else { | 321 | } else { |
322 | u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; | ||
323 | u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; | ||
338 | /* | 324 | /* |
339 | * For earlier chips we have to calculate the scaling | 325 | * For earlier chips we have to calculate the scaling |
340 | * ratio by hand and program it into the | 326 | * ratio by hand and program it into the |
341 | * PFIT_PGM_RATIO register | 327 | * PFIT_PGM_RATIO register |
342 | */ | 328 | */ |
343 | u32 horiz_bits, vert_bits, bits = 12; | 329 | if (scaled_width > scaled_height) { /* pillar */ |
344 | horiz_ratio = mode->hdisplay * PANEL_RATIO_FACTOR/ | 330 | centre_horizontally(adjusted_mode, scaled_height / mode->vdisplay); |
345 | adjusted_mode->hdisplay; | 331 | |
346 | vert_ratio = mode->vdisplay * PANEL_RATIO_FACTOR/ | 332 | border = LVDS_BORDER_ENABLE; |
347 | adjusted_mode->vdisplay; | 333 | if (mode->vdisplay != adjusted_mode->vdisplay) { |
348 | horiz_scale = adjusted_mode->hdisplay * | 334 | u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay); |
349 | PANEL_RATIO_FACTOR / mode->hdisplay; | 335 | pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | |
350 | vert_scale = adjusted_mode->vdisplay * | 336 | bits << PFIT_VERT_SCALE_SHIFT); |
351 | PANEL_RATIO_FACTOR / mode->vdisplay; | 337 | pfit_control |= (PFIT_ENABLE | |
352 | 338 | VERT_INTERP_BILINEAR | | |
353 | /* retain aspect ratio */ | 339 | HORIZ_INTERP_BILINEAR); |
354 | if (panel_ratio > desired_ratio) { /* Pillar */ | 340 | } |
355 | u32 scaled_width; | 341 | } else if (scaled_width < scaled_height) { /* letter */ |
356 | scaled_width = mode->hdisplay * vert_scale / | 342 | centre_vertically(adjusted_mode, scaled_width / mode->hdisplay); |
357 | PANEL_RATIO_FACTOR; | 343 | |
358 | horiz_ratio = vert_ratio; | 344 | border = LVDS_BORDER_ENABLE; |
359 | pfit_control |= (VERT_AUTO_SCALE | | 345 | if (mode->hdisplay != adjusted_mode->hdisplay) { |
360 | VERT_INTERP_BILINEAR | | 346 | u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay); |
361 | HORIZ_INTERP_BILINEAR); | 347 | pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | |
362 | /* Pillar will have left/right borders */ | 348 | bits << PFIT_VERT_SCALE_SHIFT); |
363 | left_border = (adjusted_mode->hdisplay - | 349 | pfit_control |= (PFIT_ENABLE | |
364 | scaled_width) / 2; | 350 | VERT_INTERP_BILINEAR | |
365 | right_border = left_border; | 351 | HORIZ_INTERP_BILINEAR); |
366 | if (mode->hdisplay & 1) /* odd resolutions */ | 352 | } |
367 | right_border++; | 353 | } else |
368 | /* keep the border be even */ | 354 | /* Aspects match, Let hw scale both directions */ |
369 | if (right_border & 1) | 355 | pfit_control |= (PFIT_ENABLE | |
370 | right_border++; | 356 | VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | |
371 | adjusted_mode->crtc_hdisplay = scaled_width; | ||
372 | /* use border instead of border minus one */ | ||
373 | adjusted_mode->crtc_hblank_start = | ||
374 | scaled_width + right_border; | ||
375 | /* keep the hblank width constant */ | ||
376 | adjusted_mode->crtc_hblank_end = | ||
377 | adjusted_mode->crtc_hblank_start + | ||
378 | hblank_width; | ||
379 | /* | ||
380 | * get the hsync start pos relative to | ||
381 | * hblank start | ||
382 | */ | ||
383 | hsync_pos = (hblank_width - hsync_width) / 2; | ||
384 | /* keep the hsync_pos be even */ | ||
385 | if (hsync_pos & 1) | ||
386 | hsync_pos++; | ||
387 | adjusted_mode->crtc_hsync_start = | ||
388 | adjusted_mode->crtc_hblank_start + | ||
389 | hsync_pos; | ||
390 | /* keept hsync width constant */ | ||
391 | adjusted_mode->crtc_hsync_end = | ||
392 | adjusted_mode->crtc_hsync_start + | ||
393 | hsync_width; | ||
394 | border = 1; | ||
395 | } else if (panel_ratio < desired_ratio) { /* letter */ | ||
396 | u32 scaled_height = mode->vdisplay * | ||
397 | horiz_scale / PANEL_RATIO_FACTOR; | ||
398 | vert_ratio = horiz_ratio; | ||
399 | pfit_control |= (HORIZ_AUTO_SCALE | | ||
400 | VERT_INTERP_BILINEAR | | ||
401 | HORIZ_INTERP_BILINEAR); | ||
402 | /* Letterbox will have top/bottom border */ | ||
403 | top_border = (adjusted_mode->vdisplay - | ||
404 | scaled_height) / 2; | ||
405 | bottom_border = top_border; | ||
406 | if (mode->vdisplay & 1) | ||
407 | bottom_border++; | ||
408 | adjusted_mode->crtc_vdisplay = scaled_height; | ||
409 | /* use border instead of border minus one */ | ||
410 | adjusted_mode->crtc_vblank_start = | ||
411 | scaled_height + bottom_border; | ||
412 | /* keep the vblank width constant */ | ||
413 | adjusted_mode->crtc_vblank_end = | ||
414 | adjusted_mode->crtc_vblank_start + | ||
415 | vblank_width; | ||
416 | /* | ||
417 | * get the vsync start pos relative to | ||
418 | * vblank start | ||
419 | */ | ||
420 | vsync_pos = (vblank_width - vsync_width) / 2; | ||
421 | adjusted_mode->crtc_vsync_start = | ||
422 | adjusted_mode->crtc_vblank_start + | ||
423 | vsync_pos; | ||
424 | /* keep the vsync width constant */ | ||
425 | adjusted_mode->crtc_vsync_end = | ||
426 | adjusted_mode->crtc_vsync_start + | ||
427 | vsync_width; | ||
428 | border = 1; | ||
429 | } else { | ||
430 | /* Aspects match, Let hw scale both directions */ | ||
431 | pfit_control |= (VERT_AUTO_SCALE | | ||
432 | HORIZ_AUTO_SCALE | | ||
433 | VERT_INTERP_BILINEAR | | 357 | VERT_INTERP_BILINEAR | |
434 | HORIZ_INTERP_BILINEAR); | 358 | HORIZ_INTERP_BILINEAR); |
435 | } | ||
436 | horiz_bits = (1 << bits) * horiz_ratio / | ||
437 | PANEL_RATIO_FACTOR; | ||
438 | vert_bits = (1 << bits) * vert_ratio / | ||
439 | PANEL_RATIO_FACTOR; | ||
440 | pfit_pgm_ratios = | ||
441 | ((vert_bits << PFIT_VERT_SCALE_SHIFT) & | ||
442 | PFIT_VERT_SCALE_MASK) | | ||
443 | ((horiz_bits << PFIT_HORIZ_SCALE_SHIFT) & | ||
444 | PFIT_HORIZ_SCALE_MASK); | ||
445 | } | 359 | } |
446 | break; | 360 | break; |
447 | 361 | ||
@@ -458,6 +372,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
458 | VERT_INTERP_BILINEAR | | 372 | VERT_INTERP_BILINEAR | |
459 | HORIZ_INTERP_BILINEAR); | 373 | HORIZ_INTERP_BILINEAR); |
460 | break; | 374 | break; |
375 | |||
461 | default: | 376 | default: |
462 | break; | 377 | break; |
463 | } | 378 | } |
@@ -465,14 +380,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
465 | out: | 380 | out: |
466 | lvds_priv->pfit_control = pfit_control; | 381 | lvds_priv->pfit_control = pfit_control; |
467 | lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; | 382 | lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; |
468 | /* | 383 | dev_priv->lvds_border_bits = border; |
469 | * When there exists the border, it means that the LVDS_BORDR | 384 | |
470 | * should be enabled. | ||
471 | */ | ||
472 | if (border) | ||
473 | dev_priv->lvds_border_bits |= LVDS_BORDER_ENABLE; | ||
474 | else | ||
475 | dev_priv->lvds_border_bits &= ~(LVDS_BORDER_ENABLE); | ||
476 | /* | 385 | /* |
477 | * XXX: It would be nice to support lower refresh rates on the | 386 | * XXX: It would be nice to support lower refresh rates on the |
478 | * panels to reduce power consumption, and perhaps match the | 387 | * panels to reduce power consumption, and perhaps match the |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index d7ad5139d17c..d39aea24eabe 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -65,7 +65,7 @@ | |||
65 | #define OCMD_YUV_410_PLANAR (0xe<<10) /* also 411 */ | 65 | #define OCMD_YUV_410_PLANAR (0xe<<10) /* also 411 */ |
66 | #define OCMD_TVSYNCFLIP_PARITY (0x1<<9) | 66 | #define OCMD_TVSYNCFLIP_PARITY (0x1<<9) |
67 | #define OCMD_TVSYNCFLIP_ENABLE (0x1<<7) | 67 | #define OCMD_TVSYNCFLIP_ENABLE (0x1<<7) |
68 | #define OCMD_BUF_TYPE_MASK (Ox1<<5) | 68 | #define OCMD_BUF_TYPE_MASK (0x1<<5) |
69 | #define OCMD_BUF_TYPE_FRAME (0x0<<5) | 69 | #define OCMD_BUF_TYPE_FRAME (0x0<<5) |
70 | #define OCMD_BUF_TYPE_FIELD (0x1<<5) | 70 | #define OCMD_BUF_TYPE_FIELD (0x1<<5) |
71 | #define OCMD_TEST_MODE (0x1<<4) | 71 | #define OCMD_TEST_MODE (0x1<<4) |
@@ -185,7 +185,8 @@ static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_over | |||
185 | 185 | ||
186 | if (OVERLAY_NONPHYSICAL(overlay->dev)) { | 186 | if (OVERLAY_NONPHYSICAL(overlay->dev)) { |
187 | regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, | 187 | regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, |
188 | overlay->reg_bo->gtt_offset); | 188 | overlay->reg_bo->gtt_offset, |
189 | KM_USER0); | ||
189 | 190 | ||
190 | if (!regs) { | 191 | if (!regs) { |
191 | DRM_ERROR("failed to map overlay regs in GTT\n"); | 192 | DRM_ERROR("failed to map overlay regs in GTT\n"); |
@@ -200,7 +201,7 @@ static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_over | |||
200 | static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay) | 201 | static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay) |
201 | { | 202 | { |
202 | if (OVERLAY_NONPHYSICAL(overlay->dev)) | 203 | if (OVERLAY_NONPHYSICAL(overlay->dev)) |
203 | io_mapping_unmap_atomic(overlay->virt_addr); | 204 | io_mapping_unmap_atomic(overlay->virt_addr, KM_USER0); |
204 | 205 | ||
205 | overlay->virt_addr = NULL; | 206 | overlay->virt_addr = NULL; |
206 | 207 | ||
@@ -958,7 +959,7 @@ static int check_overlay_src(struct drm_device *dev, | |||
958 | || rec->src_width < N_HORIZ_Y_TAPS*4) | 959 | || rec->src_width < N_HORIZ_Y_TAPS*4) |
959 | return -EINVAL; | 960 | return -EINVAL; |
960 | 961 | ||
961 | /* check alingment constrains */ | 962 | /* check alignment constraints */ |
962 | switch (rec->flags & I915_OVERLAY_TYPE_MASK) { | 963 | switch (rec->flags & I915_OVERLAY_TYPE_MASK) { |
963 | case I915_OVERLAY_RGB: | 964 | case I915_OVERLAY_RGB: |
964 | /* not implemented */ | 965 | /* not implemented */ |
@@ -990,7 +991,10 @@ static int check_overlay_src(struct drm_device *dev, | |||
990 | return -EINVAL; | 991 | return -EINVAL; |
991 | 992 | ||
992 | /* stride checking */ | 993 | /* stride checking */ |
993 | stride_mask = 63; | 994 | if (IS_I830(dev) || IS_845G(dev)) |
995 | stride_mask = 255; | ||
996 | else | ||
997 | stride_mask = 63; | ||
994 | 998 | ||
995 | if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask) | 999 | if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask) |
996 | return -EINVAL; | 1000 | return -EINVAL; |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 03c231be2273..d9d4d51aa89e 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1237,9 +1237,11 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1237 | 1237 | ||
1238 | /* Set the SDVO control regs. */ | 1238 | /* Set the SDVO control regs. */ |
1239 | if (IS_I965G(dev)) { | 1239 | if (IS_I965G(dev)) { |
1240 | sdvox |= SDVO_BORDER_ENABLE | | 1240 | sdvox |= SDVO_BORDER_ENABLE; |
1241 | SDVO_VSYNC_ACTIVE_HIGH | | 1241 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
1242 | SDVO_HSYNC_ACTIVE_HIGH; | 1242 | sdvox |= SDVO_VSYNC_ACTIVE_HIGH; |
1243 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | ||
1244 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; | ||
1243 | } else { | 1245 | } else { |
1244 | sdvox |= I915_READ(sdvo_priv->sdvo_reg); | 1246 | sdvox |= I915_READ(sdvo_priv->sdvo_reg); |
1245 | switch (sdvo_priv->sdvo_reg) { | 1247 | switch (sdvo_priv->sdvo_reg) { |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index d2d4e4045ca9..cc3726a4a1cb 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -476,7 +476,7 @@ static const struct tv_mode tv_modes[] = { | |||
476 | .vi_end_f1 = 20, .vi_end_f2 = 21, | 476 | .vi_end_f1 = 20, .vi_end_f2 = 21, |
477 | .nbr_end = 240, | 477 | .nbr_end = 240, |
478 | 478 | ||
479 | .burst_ena = 8, | 479 | .burst_ena = true, |
480 | .hburst_start = 72, .hburst_len = 34, | 480 | .hburst_start = 72, .hburst_len = 34, |
481 | .vburst_start_f1 = 9, .vburst_end_f1 = 240, | 481 | .vburst_start_f1 = 9, .vburst_end_f1 = 240, |
482 | .vburst_start_f2 = 10, .vburst_end_f2 = 240, | 482 | .vburst_start_f2 = 10, .vburst_end_f2 = 240, |
@@ -896,8 +896,6 @@ static const struct tv_mode tv_modes[] = { | |||
896 | }, | 896 | }, |
897 | }; | 897 | }; |
898 | 898 | ||
899 | #define NUM_TV_MODES sizeof(tv_modes) / sizeof (tv_modes[0]) | ||
900 | |||
901 | static void | 899 | static void |
902 | intel_tv_dpms(struct drm_encoder *encoder, int mode) | 900 | intel_tv_dpms(struct drm_encoder *encoder, int mode) |
903 | { | 901 | { |
@@ -1512,7 +1510,7 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
1512 | tv_priv->margin[TV_MARGIN_BOTTOM] = val; | 1510 | tv_priv->margin[TV_MARGIN_BOTTOM] = val; |
1513 | changed = true; | 1511 | changed = true; |
1514 | } else if (property == dev->mode_config.tv_mode_property) { | 1512 | } else if (property == dev->mode_config.tv_mode_property) { |
1515 | if (val >= NUM_TV_MODES) { | 1513 | if (val >= ARRAY_SIZE(tv_modes)) { |
1516 | ret = -EINVAL; | 1514 | ret = -EINVAL; |
1517 | goto out; | 1515 | goto out; |
1518 | } | 1516 | } |
@@ -1693,13 +1691,13 @@ intel_tv_init(struct drm_device *dev) | |||
1693 | connector->doublescan_allowed = false; | 1691 | connector->doublescan_allowed = false; |
1694 | 1692 | ||
1695 | /* Create TV properties then attach current values */ | 1693 | /* Create TV properties then attach current values */ |
1696 | tv_format_names = kmalloc(sizeof(char *) * NUM_TV_MODES, | 1694 | tv_format_names = kmalloc(sizeof(char *) * ARRAY_SIZE(tv_modes), |
1697 | GFP_KERNEL); | 1695 | GFP_KERNEL); |
1698 | if (!tv_format_names) | 1696 | if (!tv_format_names) |
1699 | goto out; | 1697 | goto out; |
1700 | for (i = 0; i < NUM_TV_MODES; i++) | 1698 | for (i = 0; i < ARRAY_SIZE(tv_modes); i++) |
1701 | tv_format_names[i] = tv_modes[i].name; | 1699 | tv_format_names[i] = tv_modes[i].name; |
1702 | drm_mode_create_tv_properties(dev, NUM_TV_MODES, tv_format_names); | 1700 | drm_mode_create_tv_properties(dev, ARRAY_SIZE(tv_modes), tv_format_names); |
1703 | 1701 | ||
1704 | drm_connector_attach_property(connector, dev->mode_config.tv_mode_property, | 1702 | drm_connector_attach_property(connector, dev->mode_config.tv_mode_property, |
1705 | initial_mode); | 1703 | initial_mode); |
diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c index 3c917fb3a60b..08868ac3048a 100644 --- a/drivers/gpu/drm/mga/mga_dma.c +++ b/drivers/gpu/drm/mga/mga_dma.c | |||
@@ -52,7 +52,7 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup); | |||
52 | * Engine control | 52 | * Engine control |
53 | */ | 53 | */ |
54 | 54 | ||
55 | int mga_do_wait_for_idle(drm_mga_private_t * dev_priv) | 55 | int mga_do_wait_for_idle(drm_mga_private_t *dev_priv) |
56 | { | 56 | { |
57 | u32 status = 0; | 57 | u32 status = 0; |
58 | int i; | 58 | int i; |
@@ -74,7 +74,7 @@ int mga_do_wait_for_idle(drm_mga_private_t * dev_priv) | |||
74 | return -EBUSY; | 74 | return -EBUSY; |
75 | } | 75 | } |
76 | 76 | ||
77 | static int mga_do_dma_reset(drm_mga_private_t * dev_priv) | 77 | static int mga_do_dma_reset(drm_mga_private_t *dev_priv) |
78 | { | 78 | { |
79 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 79 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
80 | drm_mga_primary_buffer_t *primary = &dev_priv->prim; | 80 | drm_mga_primary_buffer_t *primary = &dev_priv->prim; |
@@ -102,7 +102,7 @@ static int mga_do_dma_reset(drm_mga_private_t * dev_priv) | |||
102 | * Primary DMA stream | 102 | * Primary DMA stream |
103 | */ | 103 | */ |
104 | 104 | ||
105 | void mga_do_dma_flush(drm_mga_private_t * dev_priv) | 105 | void mga_do_dma_flush(drm_mga_private_t *dev_priv) |
106 | { | 106 | { |
107 | drm_mga_primary_buffer_t *primary = &dev_priv->prim; | 107 | drm_mga_primary_buffer_t *primary = &dev_priv->prim; |
108 | u32 head, tail; | 108 | u32 head, tail; |
@@ -142,11 +142,10 @@ void mga_do_dma_flush(drm_mga_private_t * dev_priv) | |||
142 | 142 | ||
143 | head = MGA_READ(MGA_PRIMADDRESS); | 143 | head = MGA_READ(MGA_PRIMADDRESS); |
144 | 144 | ||
145 | if (head <= tail) { | 145 | if (head <= tail) |
146 | primary->space = primary->size - primary->tail; | 146 | primary->space = primary->size - primary->tail; |
147 | } else { | 147 | else |
148 | primary->space = head - tail; | 148 | primary->space = head - tail; |
149 | } | ||
150 | 149 | ||
151 | DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); | 150 | DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); |
152 | DRM_DEBUG(" tail = 0x%06lx\n", (unsigned long)(tail - dev_priv->primary->offset)); | 151 | DRM_DEBUG(" tail = 0x%06lx\n", (unsigned long)(tail - dev_priv->primary->offset)); |
@@ -158,7 +157,7 @@ void mga_do_dma_flush(drm_mga_private_t * dev_priv) | |||
158 | DRM_DEBUG("done.\n"); | 157 | DRM_DEBUG("done.\n"); |
159 | } | 158 | } |
160 | 159 | ||
161 | void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv) | 160 | void mga_do_dma_wrap_start(drm_mga_private_t *dev_priv) |
162 | { | 161 | { |
163 | drm_mga_primary_buffer_t *primary = &dev_priv->prim; | 162 | drm_mga_primary_buffer_t *primary = &dev_priv->prim; |
164 | u32 head, tail; | 163 | u32 head, tail; |
@@ -181,11 +180,10 @@ void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv) | |||
181 | 180 | ||
182 | head = MGA_READ(MGA_PRIMADDRESS); | 181 | head = MGA_READ(MGA_PRIMADDRESS); |
183 | 182 | ||
184 | if (head == dev_priv->primary->offset) { | 183 | if (head == dev_priv->primary->offset) |
185 | primary->space = primary->size; | 184 | primary->space = primary->size; |
186 | } else { | 185 | else |
187 | primary->space = head - dev_priv->primary->offset; | 186 | primary->space = head - dev_priv->primary->offset; |
188 | } | ||
189 | 187 | ||
190 | DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); | 188 | DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); |
191 | DRM_DEBUG(" tail = 0x%06x\n", primary->tail); | 189 | DRM_DEBUG(" tail = 0x%06x\n", primary->tail); |
@@ -199,7 +197,7 @@ void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv) | |||
199 | DRM_DEBUG("done.\n"); | 197 | DRM_DEBUG("done.\n"); |
200 | } | 198 | } |
201 | 199 | ||
202 | void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv) | 200 | void mga_do_dma_wrap_end(drm_mga_private_t *dev_priv) |
203 | { | 201 | { |
204 | drm_mga_primary_buffer_t *primary = &dev_priv->prim; | 202 | drm_mga_primary_buffer_t *primary = &dev_priv->prim; |
205 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 203 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
@@ -220,11 +218,11 @@ void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv) | |||
220 | * Freelist management | 218 | * Freelist management |
221 | */ | 219 | */ |
222 | 220 | ||
223 | #define MGA_BUFFER_USED ~0 | 221 | #define MGA_BUFFER_USED (~0) |
224 | #define MGA_BUFFER_FREE 0 | 222 | #define MGA_BUFFER_FREE 0 |
225 | 223 | ||
226 | #if MGA_FREELIST_DEBUG | 224 | #if MGA_FREELIST_DEBUG |
227 | static void mga_freelist_print(struct drm_device * dev) | 225 | static void mga_freelist_print(struct drm_device *dev) |
228 | { | 226 | { |
229 | drm_mga_private_t *dev_priv = dev->dev_private; | 227 | drm_mga_private_t *dev_priv = dev->dev_private; |
230 | drm_mga_freelist_t *entry; | 228 | drm_mga_freelist_t *entry; |
@@ -245,7 +243,7 @@ static void mga_freelist_print(struct drm_device * dev) | |||
245 | } | 243 | } |
246 | #endif | 244 | #endif |
247 | 245 | ||
248 | static int mga_freelist_init(struct drm_device * dev, drm_mga_private_t * dev_priv) | 246 | static int mga_freelist_init(struct drm_device *dev, drm_mga_private_t *dev_priv) |
249 | { | 247 | { |
250 | struct drm_device_dma *dma = dev->dma; | 248 | struct drm_device_dma *dma = dev->dma; |
251 | struct drm_buf *buf; | 249 | struct drm_buf *buf; |
@@ -288,7 +286,7 @@ static int mga_freelist_init(struct drm_device * dev, drm_mga_private_t * dev_pr | |||
288 | return 0; | 286 | return 0; |
289 | } | 287 | } |
290 | 288 | ||
291 | static void mga_freelist_cleanup(struct drm_device * dev) | 289 | static void mga_freelist_cleanup(struct drm_device *dev) |
292 | { | 290 | { |
293 | drm_mga_private_t *dev_priv = dev->dev_private; | 291 | drm_mga_private_t *dev_priv = dev->dev_private; |
294 | drm_mga_freelist_t *entry; | 292 | drm_mga_freelist_t *entry; |
@@ -308,7 +306,7 @@ static void mga_freelist_cleanup(struct drm_device * dev) | |||
308 | #if 0 | 306 | #if 0 |
309 | /* FIXME: Still needed? | 307 | /* FIXME: Still needed? |
310 | */ | 308 | */ |
311 | static void mga_freelist_reset(struct drm_device * dev) | 309 | static void mga_freelist_reset(struct drm_device *dev) |
312 | { | 310 | { |
313 | struct drm_device_dma *dma = dev->dma; | 311 | struct drm_device_dma *dma = dev->dma; |
314 | struct drm_buf *buf; | 312 | struct drm_buf *buf; |
@@ -356,7 +354,7 @@ static struct drm_buf *mga_freelist_get(struct drm_device * dev) | |||
356 | return NULL; | 354 | return NULL; |
357 | } | 355 | } |
358 | 356 | ||
359 | int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf) | 357 | int mga_freelist_put(struct drm_device *dev, struct drm_buf *buf) |
360 | { | 358 | { |
361 | drm_mga_private_t *dev_priv = dev->dev_private; | 359 | drm_mga_private_t *dev_priv = dev->dev_private; |
362 | drm_mga_buf_priv_t *buf_priv = buf->dev_private; | 360 | drm_mga_buf_priv_t *buf_priv = buf->dev_private; |
@@ -391,7 +389,7 @@ int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf) | |||
391 | * DMA initialization, cleanup | 389 | * DMA initialization, cleanup |
392 | */ | 390 | */ |
393 | 391 | ||
394 | int mga_driver_load(struct drm_device * dev, unsigned long flags) | 392 | int mga_driver_load(struct drm_device *dev, unsigned long flags) |
395 | { | 393 | { |
396 | drm_mga_private_t *dev_priv; | 394 | drm_mga_private_t *dev_priv; |
397 | int ret; | 395 | int ret; |
@@ -405,8 +403,8 @@ int mga_driver_load(struct drm_device * dev, unsigned long flags) | |||
405 | dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; | 403 | dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; |
406 | dev_priv->chipset = flags; | 404 | dev_priv->chipset = flags; |
407 | 405 | ||
408 | dev_priv->mmio_base = drm_get_resource_start(dev, 1); | 406 | dev_priv->mmio_base = pci_resource_start(dev->pdev, 1); |
409 | dev_priv->mmio_size = drm_get_resource_len(dev, 1); | 407 | dev_priv->mmio_size = pci_resource_len(dev->pdev, 1); |
410 | 408 | ||
411 | dev->counters += 3; | 409 | dev->counters += 3; |
412 | dev->types[6] = _DRM_STAT_IRQ; | 410 | dev->types[6] = _DRM_STAT_IRQ; |
@@ -439,8 +437,8 @@ int mga_driver_load(struct drm_device * dev, unsigned long flags) | |||
439 | * | 437 | * |
440 | * \sa mga_do_dma_bootstrap, mga_do_pci_dma_bootstrap | 438 | * \sa mga_do_dma_bootstrap, mga_do_pci_dma_bootstrap |
441 | */ | 439 | */ |
442 | static int mga_do_agp_dma_bootstrap(struct drm_device * dev, | 440 | static int mga_do_agp_dma_bootstrap(struct drm_device *dev, |
443 | drm_mga_dma_bootstrap_t * dma_bs) | 441 | drm_mga_dma_bootstrap_t *dma_bs) |
444 | { | 442 | { |
445 | drm_mga_private_t *const dev_priv = | 443 | drm_mga_private_t *const dev_priv = |
446 | (drm_mga_private_t *) dev->dev_private; | 444 | (drm_mga_private_t *) dev->dev_private; |
@@ -481,11 +479,10 @@ static int mga_do_agp_dma_bootstrap(struct drm_device * dev, | |||
481 | */ | 479 | */ |
482 | 480 | ||
483 | if (dev_priv->chipset == MGA_CARD_TYPE_G200) { | 481 | if (dev_priv->chipset == MGA_CARD_TYPE_G200) { |
484 | if (mode.mode & 0x02) { | 482 | if (mode.mode & 0x02) |
485 | MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE); | 483 | MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE); |
486 | } else { | 484 | else |
487 | MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE); | 485 | MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE); |
488 | } | ||
489 | } | 486 | } |
490 | 487 | ||
491 | /* Allocate and bind AGP memory. */ | 488 | /* Allocate and bind AGP memory. */ |
@@ -593,8 +590,8 @@ static int mga_do_agp_dma_bootstrap(struct drm_device * dev, | |||
593 | return 0; | 590 | return 0; |
594 | } | 591 | } |
595 | #else | 592 | #else |
596 | static int mga_do_agp_dma_bootstrap(struct drm_device * dev, | 593 | static int mga_do_agp_dma_bootstrap(struct drm_device *dev, |
597 | drm_mga_dma_bootstrap_t * dma_bs) | 594 | drm_mga_dma_bootstrap_t *dma_bs) |
598 | { | 595 | { |
599 | return -EINVAL; | 596 | return -EINVAL; |
600 | } | 597 | } |
@@ -614,8 +611,8 @@ static int mga_do_agp_dma_bootstrap(struct drm_device * dev, | |||
614 | * | 611 | * |
615 | * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap | 612 | * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap |
616 | */ | 613 | */ |
617 | static int mga_do_pci_dma_bootstrap(struct drm_device * dev, | 614 | static int mga_do_pci_dma_bootstrap(struct drm_device *dev, |
618 | drm_mga_dma_bootstrap_t * dma_bs) | 615 | drm_mga_dma_bootstrap_t *dma_bs) |
619 | { | 616 | { |
620 | drm_mga_private_t *const dev_priv = | 617 | drm_mga_private_t *const dev_priv = |
621 | (drm_mga_private_t *) dev->dev_private; | 618 | (drm_mga_private_t *) dev->dev_private; |
@@ -678,9 +675,8 @@ static int mga_do_pci_dma_bootstrap(struct drm_device * dev, | |||
678 | req.size = dma_bs->secondary_bin_size; | 675 | req.size = dma_bs->secondary_bin_size; |
679 | 676 | ||
680 | err = drm_addbufs_pci(dev, &req); | 677 | err = drm_addbufs_pci(dev, &req); |
681 | if (!err) { | 678 | if (!err) |
682 | break; | 679 | break; |
683 | } | ||
684 | } | 680 | } |
685 | 681 | ||
686 | if (bin_count == 0) { | 682 | if (bin_count == 0) { |
@@ -704,8 +700,8 @@ static int mga_do_pci_dma_bootstrap(struct drm_device * dev, | |||
704 | return 0; | 700 | return 0; |
705 | } | 701 | } |
706 | 702 | ||
707 | static int mga_do_dma_bootstrap(struct drm_device * dev, | 703 | static int mga_do_dma_bootstrap(struct drm_device *dev, |
708 | drm_mga_dma_bootstrap_t * dma_bs) | 704 | drm_mga_dma_bootstrap_t *dma_bs) |
709 | { | 705 | { |
710 | const int is_agp = (dma_bs->agp_mode != 0) && drm_device_is_agp(dev); | 706 | const int is_agp = (dma_bs->agp_mode != 0) && drm_device_is_agp(dev); |
711 | int err; | 707 | int err; |
@@ -737,17 +733,15 @@ static int mga_do_dma_bootstrap(struct drm_device * dev, | |||
737 | * carve off portions of it for internal uses. The remaining memory | 733 | * carve off portions of it for internal uses. The remaining memory |
738 | * is returned to user-mode to be used for AGP textures. | 734 | * is returned to user-mode to be used for AGP textures. |
739 | */ | 735 | */ |
740 | if (is_agp) { | 736 | if (is_agp) |
741 | err = mga_do_agp_dma_bootstrap(dev, dma_bs); | 737 | err = mga_do_agp_dma_bootstrap(dev, dma_bs); |
742 | } | ||
743 | 738 | ||
744 | /* If we attempted to initialize the card for AGP DMA but failed, | 739 | /* If we attempted to initialize the card for AGP DMA but failed, |
745 | * clean-up any mess that may have been created. | 740 | * clean-up any mess that may have been created. |
746 | */ | 741 | */ |
747 | 742 | ||
748 | if (err) { | 743 | if (err) |
749 | mga_do_cleanup_dma(dev, MINIMAL_CLEANUP); | 744 | mga_do_cleanup_dma(dev, MINIMAL_CLEANUP); |
750 | } | ||
751 | 745 | ||
752 | /* Not only do we want to try and initialized PCI cards for PCI DMA, | 746 | /* Not only do we want to try and initialized PCI cards for PCI DMA, |
753 | * but we also try to initialized AGP cards that could not be | 747 | * but we also try to initialized AGP cards that could not be |
@@ -757,9 +751,8 @@ static int mga_do_dma_bootstrap(struct drm_device * dev, | |||
757 | * AGP memory, etc. | 751 | * AGP memory, etc. |
758 | */ | 752 | */ |
759 | 753 | ||
760 | if (!is_agp || err) { | 754 | if (!is_agp || err) |
761 | err = mga_do_pci_dma_bootstrap(dev, dma_bs); | 755 | err = mga_do_pci_dma_bootstrap(dev, dma_bs); |
762 | } | ||
763 | 756 | ||
764 | return err; | 757 | return err; |
765 | } | 758 | } |
@@ -792,7 +785,7 @@ int mga_dma_bootstrap(struct drm_device *dev, void *data, | |||
792 | return err; | 785 | return err; |
793 | } | 786 | } |
794 | 787 | ||
795 | static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init) | 788 | static int mga_do_init_dma(struct drm_device *dev, drm_mga_init_t *init) |
796 | { | 789 | { |
797 | drm_mga_private_t *dev_priv; | 790 | drm_mga_private_t *dev_priv; |
798 | int ret; | 791 | int ret; |
@@ -800,11 +793,10 @@ static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init) | |||
800 | 793 | ||
801 | dev_priv = dev->dev_private; | 794 | dev_priv = dev->dev_private; |
802 | 795 | ||
803 | if (init->sgram) { | 796 | if (init->sgram) |
804 | dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK; | 797 | dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK; |
805 | } else { | 798 | else |
806 | dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR; | 799 | dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR; |
807 | } | ||
808 | dev_priv->maccess = init->maccess; | 800 | dev_priv->maccess = init->maccess; |
809 | 801 | ||
810 | dev_priv->fb_cpp = init->fb_cpp; | 802 | dev_priv->fb_cpp = init->fb_cpp; |
@@ -975,9 +967,8 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup) | |||
975 | dev_priv->agp_handle = 0; | 967 | dev_priv->agp_handle = 0; |
976 | } | 968 | } |
977 | 969 | ||
978 | if ((dev->agp != NULL) && dev->agp->acquired) { | 970 | if ((dev->agp != NULL) && dev->agp->acquired) |
979 | err = drm_agp_release(dev); | 971 | err = drm_agp_release(dev); |
980 | } | ||
981 | #endif | 972 | #endif |
982 | } | 973 | } |
983 | 974 | ||
@@ -998,9 +989,8 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup) | |||
998 | memset(dev_priv->warp_pipe_phys, 0, | 989 | memset(dev_priv->warp_pipe_phys, 0, |
999 | sizeof(dev_priv->warp_pipe_phys)); | 990 | sizeof(dev_priv->warp_pipe_phys)); |
1000 | 991 | ||
1001 | if (dev_priv->head != NULL) { | 992 | if (dev_priv->head != NULL) |
1002 | mga_freelist_cleanup(dev); | 993 | mga_freelist_cleanup(dev); |
1003 | } | ||
1004 | } | 994 | } |
1005 | 995 | ||
1006 | return err; | 996 | return err; |
@@ -1017,9 +1007,8 @@ int mga_dma_init(struct drm_device *dev, void *data, | |||
1017 | switch (init->func) { | 1007 | switch (init->func) { |
1018 | case MGA_INIT_DMA: | 1008 | case MGA_INIT_DMA: |
1019 | err = mga_do_init_dma(dev, init); | 1009 | err = mga_do_init_dma(dev, init); |
1020 | if (err) { | 1010 | if (err) |
1021 | (void)mga_do_cleanup_dma(dev, FULL_CLEANUP); | 1011 | (void)mga_do_cleanup_dma(dev, FULL_CLEANUP); |
1022 | } | ||
1023 | return err; | 1012 | return err; |
1024 | case MGA_CLEANUP_DMA: | 1013 | case MGA_CLEANUP_DMA: |
1025 | return mga_do_cleanup_dma(dev, FULL_CLEANUP); | 1014 | return mga_do_cleanup_dma(dev, FULL_CLEANUP); |
@@ -1047,9 +1036,8 @@ int mga_dma_flush(struct drm_device *dev, void *data, | |||
1047 | 1036 | ||
1048 | WRAP_WAIT_WITH_RETURN(dev_priv); | 1037 | WRAP_WAIT_WITH_RETURN(dev_priv); |
1049 | 1038 | ||
1050 | if (lock->flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) { | 1039 | if (lock->flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) |
1051 | mga_do_dma_flush(dev_priv); | 1040 | mga_do_dma_flush(dev_priv); |
1052 | } | ||
1053 | 1041 | ||
1054 | if (lock->flags & _DRM_LOCK_QUIESCENT) { | 1042 | if (lock->flags & _DRM_LOCK_QUIESCENT) { |
1055 | #if MGA_DMA_DEBUG | 1043 | #if MGA_DMA_DEBUG |
@@ -1079,8 +1067,8 @@ int mga_dma_reset(struct drm_device *dev, void *data, | |||
1079 | * DMA buffer management | 1067 | * DMA buffer management |
1080 | */ | 1068 | */ |
1081 | 1069 | ||
1082 | static int mga_dma_get_buffers(struct drm_device * dev, | 1070 | static int mga_dma_get_buffers(struct drm_device *dev, |
1083 | struct drm_file *file_priv, struct drm_dma * d) | 1071 | struct drm_file *file_priv, struct drm_dma *d) |
1084 | { | 1072 | { |
1085 | struct drm_buf *buf; | 1073 | struct drm_buf *buf; |
1086 | int i; | 1074 | int i; |
@@ -1134,9 +1122,8 @@ int mga_dma_buffers(struct drm_device *dev, void *data, | |||
1134 | 1122 | ||
1135 | d->granted_count = 0; | 1123 | d->granted_count = 0; |
1136 | 1124 | ||
1137 | if (d->request_count) { | 1125 | if (d->request_count) |
1138 | ret = mga_dma_get_buffers(dev, file_priv, d); | 1126 | ret = mga_dma_get_buffers(dev, file_priv, d); |
1139 | } | ||
1140 | 1127 | ||
1141 | return ret; | 1128 | return ret; |
1142 | } | 1129 | } |
@@ -1144,7 +1131,7 @@ int mga_dma_buffers(struct drm_device *dev, void *data, | |||
1144 | /** | 1131 | /** |
1145 | * Called just before the module is unloaded. | 1132 | * Called just before the module is unloaded. |
1146 | */ | 1133 | */ |
1147 | int mga_driver_unload(struct drm_device * dev) | 1134 | int mga_driver_unload(struct drm_device *dev) |
1148 | { | 1135 | { |
1149 | kfree(dev->dev_private); | 1136 | kfree(dev->dev_private); |
1150 | dev->dev_private = NULL; | 1137 | dev->dev_private = NULL; |
@@ -1155,12 +1142,12 @@ int mga_driver_unload(struct drm_device * dev) | |||
1155 | /** | 1142 | /** |
1156 | * Called when the last opener of the device is closed. | 1143 | * Called when the last opener of the device is closed. |
1157 | */ | 1144 | */ |
1158 | void mga_driver_lastclose(struct drm_device * dev) | 1145 | void mga_driver_lastclose(struct drm_device *dev) |
1159 | { | 1146 | { |
1160 | mga_do_cleanup_dma(dev, FULL_CLEANUP); | 1147 | mga_do_cleanup_dma(dev, FULL_CLEANUP); |
1161 | } | 1148 | } |
1162 | 1149 | ||
1163 | int mga_driver_dma_quiescent(struct drm_device * dev) | 1150 | int mga_driver_dma_quiescent(struct drm_device *dev) |
1164 | { | 1151 | { |
1165 | drm_mga_private_t *dev_priv = dev->dev_private; | 1152 | drm_mga_private_t *dev_priv = dev->dev_private; |
1166 | return mga_do_wait_for_idle(dev_priv); | 1153 | return mga_do_wait_for_idle(dev_priv); |
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c index ddfe16197b59..26d0d8ced80d 100644 --- a/drivers/gpu/drm/mga/mga_drv.c +++ b/drivers/gpu/drm/mga/mga_drv.c | |||
@@ -36,7 +36,7 @@ | |||
36 | 36 | ||
37 | #include "drm_pciids.h" | 37 | #include "drm_pciids.h" |
38 | 38 | ||
39 | static int mga_driver_device_is_agp(struct drm_device * dev); | 39 | static int mga_driver_device_is_agp(struct drm_device *dev); |
40 | 40 | ||
41 | static struct pci_device_id pciidlist[] = { | 41 | static struct pci_device_id pciidlist[] = { |
42 | mga_PCI_IDS | 42 | mga_PCI_IDS |
@@ -119,7 +119,7 @@ MODULE_LICENSE("GPL and additional rights"); | |||
119 | * \returns | 119 | * \returns |
120 | * If the device is a PCI G450, zero is returned. Otherwise 2 is returned. | 120 | * If the device is a PCI G450, zero is returned. Otherwise 2 is returned. |
121 | */ | 121 | */ |
122 | static int mga_driver_device_is_agp(struct drm_device * dev) | 122 | static int mga_driver_device_is_agp(struct drm_device *dev) |
123 | { | 123 | { |
124 | const struct pci_dev *const pdev = dev->pdev; | 124 | const struct pci_dev *const pdev = dev->pdev; |
125 | 125 | ||
diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h index be6c6b9b0e89..1084fa4d261b 100644 --- a/drivers/gpu/drm/mga/mga_drv.h +++ b/drivers/gpu/drm/mga/mga_drv.h | |||
@@ -164,59 +164,59 @@ extern int mga_dma_reset(struct drm_device *dev, void *data, | |||
164 | extern int mga_dma_buffers(struct drm_device *dev, void *data, | 164 | extern int mga_dma_buffers(struct drm_device *dev, void *data, |
165 | struct drm_file *file_priv); | 165 | struct drm_file *file_priv); |
166 | extern int mga_driver_load(struct drm_device *dev, unsigned long flags); | 166 | extern int mga_driver_load(struct drm_device *dev, unsigned long flags); |
167 | extern int mga_driver_unload(struct drm_device * dev); | 167 | extern int mga_driver_unload(struct drm_device *dev); |
168 | extern void mga_driver_lastclose(struct drm_device * dev); | 168 | extern void mga_driver_lastclose(struct drm_device *dev); |
169 | extern int mga_driver_dma_quiescent(struct drm_device * dev); | 169 | extern int mga_driver_dma_quiescent(struct drm_device *dev); |
170 | 170 | ||
171 | extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv); | 171 | extern int mga_do_wait_for_idle(drm_mga_private_t *dev_priv); |
172 | 172 | ||
173 | extern void mga_do_dma_flush(drm_mga_private_t * dev_priv); | 173 | extern void mga_do_dma_flush(drm_mga_private_t *dev_priv); |
174 | extern void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv); | 174 | extern void mga_do_dma_wrap_start(drm_mga_private_t *dev_priv); |
175 | extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv); | 175 | extern void mga_do_dma_wrap_end(drm_mga_private_t *dev_priv); |
176 | 176 | ||
177 | extern int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf); | 177 | extern int mga_freelist_put(struct drm_device *dev, struct drm_buf *buf); |
178 | 178 | ||
179 | /* mga_warp.c */ | 179 | /* mga_warp.c */ |
180 | extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv); | 180 | extern int mga_warp_install_microcode(drm_mga_private_t *dev_priv); |
181 | extern int mga_warp_init(drm_mga_private_t * dev_priv); | 181 | extern int mga_warp_init(drm_mga_private_t *dev_priv); |
182 | 182 | ||
183 | /* mga_irq.c */ | 183 | /* mga_irq.c */ |
184 | extern int mga_enable_vblank(struct drm_device *dev, int crtc); | 184 | extern int mga_enable_vblank(struct drm_device *dev, int crtc); |
185 | extern void mga_disable_vblank(struct drm_device *dev, int crtc); | 185 | extern void mga_disable_vblank(struct drm_device *dev, int crtc); |
186 | extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc); | 186 | extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc); |
187 | extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); | 187 | extern int mga_driver_fence_wait(struct drm_device *dev, unsigned int *sequence); |
188 | extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); | 188 | extern int mga_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence); |
189 | extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); | 189 | extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); |
190 | extern void mga_driver_irq_preinstall(struct drm_device * dev); | 190 | extern void mga_driver_irq_preinstall(struct drm_device *dev); |
191 | extern int mga_driver_irq_postinstall(struct drm_device *dev); | 191 | extern int mga_driver_irq_postinstall(struct drm_device *dev); |
192 | extern void mga_driver_irq_uninstall(struct drm_device * dev); | 192 | extern void mga_driver_irq_uninstall(struct drm_device *dev); |
193 | extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, | 193 | extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, |
194 | unsigned long arg); | 194 | unsigned long arg); |
195 | 195 | ||
196 | #define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER() | 196 | #define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER() |
197 | 197 | ||
198 | #if defined(__linux__) && defined(__alpha__) | 198 | #if defined(__linux__) && defined(__alpha__) |
199 | #define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle)) | 199 | #define MGA_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) |
200 | #define MGA_ADDR( reg ) (MGA_BASE(reg) + reg) | 200 | #define MGA_ADDR(reg) (MGA_BASE(reg) + reg) |
201 | 201 | ||
202 | #define MGA_DEREF( reg ) *(volatile u32 *)MGA_ADDR( reg ) | 202 | #define MGA_DEREF(reg) (*(volatile u32 *)MGA_ADDR(reg)) |
203 | #define MGA_DEREF8( reg ) *(volatile u8 *)MGA_ADDR( reg ) | 203 | #define MGA_DEREF8(reg) (*(volatile u8 *)MGA_ADDR(reg)) |
204 | 204 | ||
205 | #define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg))) | 205 | #define MGA_READ(reg) (_MGA_READ((u32 *)MGA_ADDR(reg))) |
206 | #define MGA_READ8( reg ) (_MGA_READ((u8 *)MGA_ADDR(reg))) | 206 | #define MGA_READ8(reg) (_MGA_READ((u8 *)MGA_ADDR(reg))) |
207 | #define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0) | 207 | #define MGA_WRITE(reg, val) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF(reg) = val; } while (0) |
208 | #define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0) | 208 | #define MGA_WRITE8(reg, val) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8(reg) = val; } while (0) |
209 | 209 | ||
210 | static inline u32 _MGA_READ(u32 * addr) | 210 | static inline u32 _MGA_READ(u32 *addr) |
211 | { | 211 | { |
212 | DRM_MEMORYBARRIER(); | 212 | DRM_MEMORYBARRIER(); |
213 | return *(volatile u32 *)addr; | 213 | return *(volatile u32 *)addr; |
214 | } | 214 | } |
215 | #else | 215 | #else |
216 | #define MGA_READ8( reg ) DRM_READ8(dev_priv->mmio, (reg)) | 216 | #define MGA_READ8(reg) DRM_READ8(dev_priv->mmio, (reg)) |
217 | #define MGA_READ( reg ) DRM_READ32(dev_priv->mmio, (reg)) | 217 | #define MGA_READ(reg) DRM_READ32(dev_priv->mmio, (reg)) |
218 | #define MGA_WRITE8( reg, val ) DRM_WRITE8(dev_priv->mmio, (reg), (val)) | 218 | #define MGA_WRITE8(reg, val) DRM_WRITE8(dev_priv->mmio, (reg), (val)) |
219 | #define MGA_WRITE( reg, val ) DRM_WRITE32(dev_priv->mmio, (reg), (val)) | 219 | #define MGA_WRITE(reg, val) DRM_WRITE32(dev_priv->mmio, (reg), (val)) |
220 | #endif | 220 | #endif |
221 | 221 | ||
222 | #define DWGREG0 0x1c00 | 222 | #define DWGREG0 0x1c00 |
@@ -233,40 +233,39 @@ static inline u32 _MGA_READ(u32 * addr) | |||
233 | * Helper macross... | 233 | * Helper macross... |
234 | */ | 234 | */ |
235 | 235 | ||
236 | #define MGA_EMIT_STATE( dev_priv, dirty ) \ | 236 | #define MGA_EMIT_STATE(dev_priv, dirty) \ |
237 | do { \ | 237 | do { \ |
238 | if ( (dirty) & ~MGA_UPLOAD_CLIPRECTS ) { \ | 238 | if ((dirty) & ~MGA_UPLOAD_CLIPRECTS) { \ |
239 | if ( dev_priv->chipset >= MGA_CARD_TYPE_G400 ) { \ | 239 | if (dev_priv->chipset >= MGA_CARD_TYPE_G400) \ |
240 | mga_g400_emit_state( dev_priv ); \ | 240 | mga_g400_emit_state(dev_priv); \ |
241 | } else { \ | 241 | else \ |
242 | mga_g200_emit_state( dev_priv ); \ | 242 | mga_g200_emit_state(dev_priv); \ |
243 | } \ | ||
244 | } \ | 243 | } \ |
245 | } while (0) | 244 | } while (0) |
246 | 245 | ||
247 | #define WRAP_TEST_WITH_RETURN( dev_priv ) \ | 246 | #define WRAP_TEST_WITH_RETURN(dev_priv) \ |
248 | do { \ | 247 | do { \ |
249 | if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \ | 248 | if (test_bit(0, &dev_priv->prim.wrapped)) { \ |
250 | if ( mga_is_idle( dev_priv ) ) { \ | 249 | if (mga_is_idle(dev_priv)) { \ |
251 | mga_do_dma_wrap_end( dev_priv ); \ | 250 | mga_do_dma_wrap_end(dev_priv); \ |
252 | } else if ( dev_priv->prim.space < \ | 251 | } else if (dev_priv->prim.space < \ |
253 | dev_priv->prim.high_mark ) { \ | 252 | dev_priv->prim.high_mark) { \ |
254 | if ( MGA_DMA_DEBUG ) \ | 253 | if (MGA_DMA_DEBUG) \ |
255 | DRM_INFO( "wrap...\n"); \ | 254 | DRM_INFO("wrap...\n"); \ |
256 | return -EBUSY; \ | 255 | return -EBUSY; \ |
257 | } \ | 256 | } \ |
258 | } \ | 257 | } \ |
259 | } while (0) | 258 | } while (0) |
260 | 259 | ||
261 | #define WRAP_WAIT_WITH_RETURN( dev_priv ) \ | 260 | #define WRAP_WAIT_WITH_RETURN(dev_priv) \ |
262 | do { \ | 261 | do { \ |
263 | if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \ | 262 | if (test_bit(0, &dev_priv->prim.wrapped)) { \ |
264 | if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { \ | 263 | if (mga_do_wait_for_idle(dev_priv) < 0) { \ |
265 | if ( MGA_DMA_DEBUG ) \ | 264 | if (MGA_DMA_DEBUG) \ |
266 | DRM_INFO( "wrap...\n"); \ | 265 | DRM_INFO("wrap...\n"); \ |
267 | return -EBUSY; \ | 266 | return -EBUSY; \ |
268 | } \ | 267 | } \ |
269 | mga_do_dma_wrap_end( dev_priv ); \ | 268 | mga_do_dma_wrap_end(dev_priv); \ |
270 | } \ | 269 | } \ |
271 | } while (0) | 270 | } while (0) |
272 | 271 | ||
@@ -280,12 +279,12 @@ do { \ | |||
280 | 279 | ||
281 | #define DMA_BLOCK_SIZE (5 * sizeof(u32)) | 280 | #define DMA_BLOCK_SIZE (5 * sizeof(u32)) |
282 | 281 | ||
283 | #define BEGIN_DMA( n ) \ | 282 | #define BEGIN_DMA(n) \ |
284 | do { \ | 283 | do { \ |
285 | if ( MGA_VERBOSE ) { \ | 284 | if (MGA_VERBOSE) { \ |
286 | DRM_INFO( "BEGIN_DMA( %d )\n", (n) ); \ | 285 | DRM_INFO("BEGIN_DMA(%d)\n", (n)); \ |
287 | DRM_INFO( " space=0x%x req=0x%Zx\n", \ | 286 | DRM_INFO(" space=0x%x req=0x%Zx\n", \ |
288 | dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \ | 287 | dev_priv->prim.space, (n) * DMA_BLOCK_SIZE); \ |
289 | } \ | 288 | } \ |
290 | prim = dev_priv->prim.start; \ | 289 | prim = dev_priv->prim.start; \ |
291 | write = dev_priv->prim.tail; \ | 290 | write = dev_priv->prim.tail; \ |
@@ -293,9 +292,9 @@ do { \ | |||
293 | 292 | ||
294 | #define BEGIN_DMA_WRAP() \ | 293 | #define BEGIN_DMA_WRAP() \ |
295 | do { \ | 294 | do { \ |
296 | if ( MGA_VERBOSE ) { \ | 295 | if (MGA_VERBOSE) { \ |
297 | DRM_INFO( "BEGIN_DMA()\n" ); \ | 296 | DRM_INFO("BEGIN_DMA()\n"); \ |
298 | DRM_INFO( " space=0x%x\n", dev_priv->prim.space ); \ | 297 | DRM_INFO(" space=0x%x\n", dev_priv->prim.space); \ |
299 | } \ | 298 | } \ |
300 | prim = dev_priv->prim.start; \ | 299 | prim = dev_priv->prim.start; \ |
301 | write = dev_priv->prim.tail; \ | 300 | write = dev_priv->prim.tail; \ |
@@ -304,72 +303,68 @@ do { \ | |||
304 | #define ADVANCE_DMA() \ | 303 | #define ADVANCE_DMA() \ |
305 | do { \ | 304 | do { \ |
306 | dev_priv->prim.tail = write; \ | 305 | dev_priv->prim.tail = write; \ |
307 | if ( MGA_VERBOSE ) { \ | 306 | if (MGA_VERBOSE) \ |
308 | DRM_INFO( "ADVANCE_DMA() tail=0x%05x sp=0x%x\n", \ | 307 | DRM_INFO("ADVANCE_DMA() tail=0x%05x sp=0x%x\n", \ |
309 | write, dev_priv->prim.space ); \ | 308 | write, dev_priv->prim.space); \ |
310 | } \ | ||
311 | } while (0) | 309 | } while (0) |
312 | 310 | ||
313 | #define FLUSH_DMA() \ | 311 | #define FLUSH_DMA() \ |
314 | do { \ | 312 | do { \ |
315 | if ( 0 ) { \ | 313 | if (0) { \ |
316 | DRM_INFO( "\n" ); \ | 314 | DRM_INFO("\n"); \ |
317 | DRM_INFO( " tail=0x%06x head=0x%06lx\n", \ | 315 | DRM_INFO(" tail=0x%06x head=0x%06lx\n", \ |
318 | dev_priv->prim.tail, \ | 316 | dev_priv->prim.tail, \ |
319 | (unsigned long)(MGA_READ(MGA_PRIMADDRESS) - \ | 317 | (unsigned long)(MGA_READ(MGA_PRIMADDRESS) - \ |
320 | dev_priv->primary->offset)); \ | 318 | dev_priv->primary->offset)); \ |
321 | } \ | 319 | } \ |
322 | if ( !test_bit( 0, &dev_priv->prim.wrapped ) ) { \ | 320 | if (!test_bit(0, &dev_priv->prim.wrapped)) { \ |
323 | if ( dev_priv->prim.space < \ | 321 | if (dev_priv->prim.space < dev_priv->prim.high_mark) \ |
324 | dev_priv->prim.high_mark ) { \ | 322 | mga_do_dma_wrap_start(dev_priv); \ |
325 | mga_do_dma_wrap_start( dev_priv ); \ | 323 | else \ |
326 | } else { \ | 324 | mga_do_dma_flush(dev_priv); \ |
327 | mga_do_dma_flush( dev_priv ); \ | ||
328 | } \ | ||
329 | } \ | 325 | } \ |
330 | } while (0) | 326 | } while (0) |
331 | 327 | ||
332 | /* Never use this, always use DMA_BLOCK(...) for primary DMA output. | 328 | /* Never use this, always use DMA_BLOCK(...) for primary DMA output. |
333 | */ | 329 | */ |
334 | #define DMA_WRITE( offset, val ) \ | 330 | #define DMA_WRITE(offset, val) \ |
335 | do { \ | 331 | do { \ |
336 | if ( MGA_VERBOSE ) { \ | 332 | if (MGA_VERBOSE) \ |
337 | DRM_INFO( " DMA_WRITE( 0x%08x ) at 0x%04Zx\n", \ | 333 | DRM_INFO(" DMA_WRITE( 0x%08x ) at 0x%04Zx\n", \ |
338 | (u32)(val), write + (offset) * sizeof(u32) ); \ | 334 | (u32)(val), write + (offset) * sizeof(u32)); \ |
339 | } \ | ||
340 | *(volatile u32 *)(prim + write + (offset) * sizeof(u32)) = val; \ | 335 | *(volatile u32 *)(prim + write + (offset) * sizeof(u32)) = val; \ |
341 | } while (0) | 336 | } while (0) |
342 | 337 | ||
343 | #define DMA_BLOCK( reg0, val0, reg1, val1, reg2, val2, reg3, val3 ) \ | 338 | #define DMA_BLOCK(reg0, val0, reg1, val1, reg2, val2, reg3, val3) \ |
344 | do { \ | 339 | do { \ |
345 | DMA_WRITE( 0, ((DMAREG( reg0 ) << 0) | \ | 340 | DMA_WRITE(0, ((DMAREG(reg0) << 0) | \ |
346 | (DMAREG( reg1 ) << 8) | \ | 341 | (DMAREG(reg1) << 8) | \ |
347 | (DMAREG( reg2 ) << 16) | \ | 342 | (DMAREG(reg2) << 16) | \ |
348 | (DMAREG( reg3 ) << 24)) ); \ | 343 | (DMAREG(reg3) << 24))); \ |
349 | DMA_WRITE( 1, val0 ); \ | 344 | DMA_WRITE(1, val0); \ |
350 | DMA_WRITE( 2, val1 ); \ | 345 | DMA_WRITE(2, val1); \ |
351 | DMA_WRITE( 3, val2 ); \ | 346 | DMA_WRITE(3, val2); \ |
352 | DMA_WRITE( 4, val3 ); \ | 347 | DMA_WRITE(4, val3); \ |
353 | write += DMA_BLOCK_SIZE; \ | 348 | write += DMA_BLOCK_SIZE; \ |
354 | } while (0) | 349 | } while (0) |
355 | 350 | ||
356 | /* Buffer aging via primary DMA stream head pointer. | 351 | /* Buffer aging via primary DMA stream head pointer. |
357 | */ | 352 | */ |
358 | 353 | ||
359 | #define SET_AGE( age, h, w ) \ | 354 | #define SET_AGE(age, h, w) \ |
360 | do { \ | 355 | do { \ |
361 | (age)->head = h; \ | 356 | (age)->head = h; \ |
362 | (age)->wrap = w; \ | 357 | (age)->wrap = w; \ |
363 | } while (0) | 358 | } while (0) |
364 | 359 | ||
365 | #define TEST_AGE( age, h, w ) ( (age)->wrap < w || \ | 360 | #define TEST_AGE(age, h, w) ((age)->wrap < w || \ |
366 | ( (age)->wrap == w && \ | 361 | ((age)->wrap == w && \ |
367 | (age)->head < h ) ) | 362 | (age)->head < h)) |
368 | 363 | ||
369 | #define AGE_BUFFER( buf_priv ) \ | 364 | #define AGE_BUFFER(buf_priv) \ |
370 | do { \ | 365 | do { \ |
371 | drm_mga_freelist_t *entry = (buf_priv)->list_entry; \ | 366 | drm_mga_freelist_t *entry = (buf_priv)->list_entry; \ |
372 | if ( (buf_priv)->dispatched ) { \ | 367 | if ((buf_priv)->dispatched) { \ |
373 | entry->age.head = (dev_priv->prim.tail + \ | 368 | entry->age.head = (dev_priv->prim.tail + \ |
374 | dev_priv->primary->offset); \ | 369 | dev_priv->primary->offset); \ |
375 | entry->age.wrap = dev_priv->sarea_priv->last_wrap; \ | 370 | entry->age.wrap = dev_priv->sarea_priv->last_wrap; \ |
@@ -681,7 +676,7 @@ do { \ | |||
681 | 676 | ||
682 | /* Simple idle test. | 677 | /* Simple idle test. |
683 | */ | 678 | */ |
684 | static __inline__ int mga_is_idle(drm_mga_private_t * dev_priv) | 679 | static __inline__ int mga_is_idle(drm_mga_private_t *dev_priv) |
685 | { | 680 | { |
686 | u32 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; | 681 | u32 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; |
687 | return (status == MGA_ENDPRDMASTS); | 682 | return (status == MGA_ENDPRDMASTS); |
diff --git a/drivers/gpu/drm/mga/mga_irq.c b/drivers/gpu/drm/mga/mga_irq.c index daa6041a483a..2581202297e4 100644 --- a/drivers/gpu/drm/mga/mga_irq.c +++ b/drivers/gpu/drm/mga/mga_irq.c | |||
@@ -76,9 +76,8 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) | |||
76 | /* In addition to clearing the interrupt-pending bit, we | 76 | /* In addition to clearing the interrupt-pending bit, we |
77 | * have to write to MGA_PRIMEND to re-start the DMA operation. | 77 | * have to write to MGA_PRIMEND to re-start the DMA operation. |
78 | */ | 78 | */ |
79 | if ((prim_start & ~0x03) != (prim_end & ~0x03)) { | 79 | if ((prim_start & ~0x03) != (prim_end & ~0x03)) |
80 | MGA_WRITE(MGA_PRIMEND, prim_end); | 80 | MGA_WRITE(MGA_PRIMEND, prim_end); |
81 | } | ||
82 | 81 | ||
83 | atomic_inc(&dev_priv->last_fence_retired); | 82 | atomic_inc(&dev_priv->last_fence_retired); |
84 | DRM_WAKEUP(&dev_priv->fence_queue); | 83 | DRM_WAKEUP(&dev_priv->fence_queue); |
@@ -120,7 +119,7 @@ void mga_disable_vblank(struct drm_device *dev, int crtc) | |||
120 | /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ | 119 | /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ |
121 | } | 120 | } |
122 | 121 | ||
123 | int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) | 122 | int mga_driver_fence_wait(struct drm_device *dev, unsigned int *sequence) |
124 | { | 123 | { |
125 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | 124 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; |
126 | unsigned int cur_fence; | 125 | unsigned int cur_fence; |
@@ -139,7 +138,7 @@ int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) | |||
139 | return ret; | 138 | return ret; |
140 | } | 139 | } |
141 | 140 | ||
142 | void mga_driver_irq_preinstall(struct drm_device * dev) | 141 | void mga_driver_irq_preinstall(struct drm_device *dev) |
143 | { | 142 | { |
144 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | 143 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; |
145 | 144 | ||
@@ -162,7 +161,7 @@ int mga_driver_irq_postinstall(struct drm_device *dev) | |||
162 | return 0; | 161 | return 0; |
163 | } | 162 | } |
164 | 163 | ||
165 | void mga_driver_irq_uninstall(struct drm_device * dev) | 164 | void mga_driver_irq_uninstall(struct drm_device *dev) |
166 | { | 165 | { |
167 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | 166 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; |
168 | if (!dev_priv) | 167 | if (!dev_priv) |
diff --git a/drivers/gpu/drm/mga/mga_state.c b/drivers/gpu/drm/mga/mga_state.c index a53b848e0f17..fff82045c427 100644 --- a/drivers/gpu/drm/mga/mga_state.c +++ b/drivers/gpu/drm/mga/mga_state.c | |||
@@ -41,8 +41,8 @@ | |||
41 | * DMA hardware state programming functions | 41 | * DMA hardware state programming functions |
42 | */ | 42 | */ |
43 | 43 | ||
44 | static void mga_emit_clip_rect(drm_mga_private_t * dev_priv, | 44 | static void mga_emit_clip_rect(drm_mga_private_t *dev_priv, |
45 | struct drm_clip_rect * box) | 45 | struct drm_clip_rect *box) |
46 | { | 46 | { |
47 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 47 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
48 | drm_mga_context_regs_t *ctx = &sarea_priv->context_state; | 48 | drm_mga_context_regs_t *ctx = &sarea_priv->context_state; |
@@ -66,7 +66,7 @@ static void mga_emit_clip_rect(drm_mga_private_t * dev_priv, | |||
66 | ADVANCE_DMA(); | 66 | ADVANCE_DMA(); |
67 | } | 67 | } |
68 | 68 | ||
69 | static __inline__ void mga_g200_emit_context(drm_mga_private_t * dev_priv) | 69 | static __inline__ void mga_g200_emit_context(drm_mga_private_t *dev_priv) |
70 | { | 70 | { |
71 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 71 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
72 | drm_mga_context_regs_t *ctx = &sarea_priv->context_state; | 72 | drm_mga_context_regs_t *ctx = &sarea_priv->context_state; |
@@ -89,7 +89,7 @@ static __inline__ void mga_g200_emit_context(drm_mga_private_t * dev_priv) | |||
89 | ADVANCE_DMA(); | 89 | ADVANCE_DMA(); |
90 | } | 90 | } |
91 | 91 | ||
92 | static __inline__ void mga_g400_emit_context(drm_mga_private_t * dev_priv) | 92 | static __inline__ void mga_g400_emit_context(drm_mga_private_t *dev_priv) |
93 | { | 93 | { |
94 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 94 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
95 | drm_mga_context_regs_t *ctx = &sarea_priv->context_state; | 95 | drm_mga_context_regs_t *ctx = &sarea_priv->context_state; |
@@ -116,7 +116,7 @@ static __inline__ void mga_g400_emit_context(drm_mga_private_t * dev_priv) | |||
116 | ADVANCE_DMA(); | 116 | ADVANCE_DMA(); |
117 | } | 117 | } |
118 | 118 | ||
119 | static __inline__ void mga_g200_emit_tex0(drm_mga_private_t * dev_priv) | 119 | static __inline__ void mga_g200_emit_tex0(drm_mga_private_t *dev_priv) |
120 | { | 120 | { |
121 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 121 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
122 | drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; | 122 | drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; |
@@ -144,7 +144,7 @@ static __inline__ void mga_g200_emit_tex0(drm_mga_private_t * dev_priv) | |||
144 | ADVANCE_DMA(); | 144 | ADVANCE_DMA(); |
145 | } | 145 | } |
146 | 146 | ||
147 | static __inline__ void mga_g400_emit_tex0(drm_mga_private_t * dev_priv) | 147 | static __inline__ void mga_g400_emit_tex0(drm_mga_private_t *dev_priv) |
148 | { | 148 | { |
149 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 149 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
150 | drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; | 150 | drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; |
@@ -184,7 +184,7 @@ static __inline__ void mga_g400_emit_tex0(drm_mga_private_t * dev_priv) | |||
184 | ADVANCE_DMA(); | 184 | ADVANCE_DMA(); |
185 | } | 185 | } |
186 | 186 | ||
187 | static __inline__ void mga_g400_emit_tex1(drm_mga_private_t * dev_priv) | 187 | static __inline__ void mga_g400_emit_tex1(drm_mga_private_t *dev_priv) |
188 | { | 188 | { |
189 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 189 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
190 | drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1]; | 190 | drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1]; |
@@ -223,7 +223,7 @@ static __inline__ void mga_g400_emit_tex1(drm_mga_private_t * dev_priv) | |||
223 | ADVANCE_DMA(); | 223 | ADVANCE_DMA(); |
224 | } | 224 | } |
225 | 225 | ||
226 | static __inline__ void mga_g200_emit_pipe(drm_mga_private_t * dev_priv) | 226 | static __inline__ void mga_g200_emit_pipe(drm_mga_private_t *dev_priv) |
227 | { | 227 | { |
228 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 228 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
229 | unsigned int pipe = sarea_priv->warp_pipe; | 229 | unsigned int pipe = sarea_priv->warp_pipe; |
@@ -250,7 +250,7 @@ static __inline__ void mga_g200_emit_pipe(drm_mga_private_t * dev_priv) | |||
250 | ADVANCE_DMA(); | 250 | ADVANCE_DMA(); |
251 | } | 251 | } |
252 | 252 | ||
253 | static __inline__ void mga_g400_emit_pipe(drm_mga_private_t * dev_priv) | 253 | static __inline__ void mga_g400_emit_pipe(drm_mga_private_t *dev_priv) |
254 | { | 254 | { |
255 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 255 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
256 | unsigned int pipe = sarea_priv->warp_pipe; | 256 | unsigned int pipe = sarea_priv->warp_pipe; |
@@ -327,7 +327,7 @@ static __inline__ void mga_g400_emit_pipe(drm_mga_private_t * dev_priv) | |||
327 | ADVANCE_DMA(); | 327 | ADVANCE_DMA(); |
328 | } | 328 | } |
329 | 329 | ||
330 | static void mga_g200_emit_state(drm_mga_private_t * dev_priv) | 330 | static void mga_g200_emit_state(drm_mga_private_t *dev_priv) |
331 | { | 331 | { |
332 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 332 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
333 | unsigned int dirty = sarea_priv->dirty; | 333 | unsigned int dirty = sarea_priv->dirty; |
@@ -348,7 +348,7 @@ static void mga_g200_emit_state(drm_mga_private_t * dev_priv) | |||
348 | } | 348 | } |
349 | } | 349 | } |
350 | 350 | ||
351 | static void mga_g400_emit_state(drm_mga_private_t * dev_priv) | 351 | static void mga_g400_emit_state(drm_mga_private_t *dev_priv) |
352 | { | 352 | { |
353 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 353 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
354 | unsigned int dirty = sarea_priv->dirty; | 354 | unsigned int dirty = sarea_priv->dirty; |
@@ -381,7 +381,7 @@ static void mga_g400_emit_state(drm_mga_private_t * dev_priv) | |||
381 | 381 | ||
382 | /* Disallow all write destinations except the front and backbuffer. | 382 | /* Disallow all write destinations except the front and backbuffer. |
383 | */ | 383 | */ |
384 | static int mga_verify_context(drm_mga_private_t * dev_priv) | 384 | static int mga_verify_context(drm_mga_private_t *dev_priv) |
385 | { | 385 | { |
386 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 386 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
387 | drm_mga_context_regs_t *ctx = &sarea_priv->context_state; | 387 | drm_mga_context_regs_t *ctx = &sarea_priv->context_state; |
@@ -400,7 +400,7 @@ static int mga_verify_context(drm_mga_private_t * dev_priv) | |||
400 | 400 | ||
401 | /* Disallow texture reads from PCI space. | 401 | /* Disallow texture reads from PCI space. |
402 | */ | 402 | */ |
403 | static int mga_verify_tex(drm_mga_private_t * dev_priv, int unit) | 403 | static int mga_verify_tex(drm_mga_private_t *dev_priv, int unit) |
404 | { | 404 | { |
405 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 405 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
406 | drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit]; | 406 | drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit]; |
@@ -417,7 +417,7 @@ static int mga_verify_tex(drm_mga_private_t * dev_priv, int unit) | |||
417 | return 0; | 417 | return 0; |
418 | } | 418 | } |
419 | 419 | ||
420 | static int mga_verify_state(drm_mga_private_t * dev_priv) | 420 | static int mga_verify_state(drm_mga_private_t *dev_priv) |
421 | { | 421 | { |
422 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 422 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
423 | unsigned int dirty = sarea_priv->dirty; | 423 | unsigned int dirty = sarea_priv->dirty; |
@@ -446,7 +446,7 @@ static int mga_verify_state(drm_mga_private_t * dev_priv) | |||
446 | return (ret == 0); | 446 | return (ret == 0); |
447 | } | 447 | } |
448 | 448 | ||
449 | static int mga_verify_iload(drm_mga_private_t * dev_priv, | 449 | static int mga_verify_iload(drm_mga_private_t *dev_priv, |
450 | unsigned int dstorg, unsigned int length) | 450 | unsigned int dstorg, unsigned int length) |
451 | { | 451 | { |
452 | if (dstorg < dev_priv->texture_offset || | 452 | if (dstorg < dev_priv->texture_offset || |
@@ -465,7 +465,7 @@ static int mga_verify_iload(drm_mga_private_t * dev_priv, | |||
465 | return 0; | 465 | return 0; |
466 | } | 466 | } |
467 | 467 | ||
468 | static int mga_verify_blit(drm_mga_private_t * dev_priv, | 468 | static int mga_verify_blit(drm_mga_private_t *dev_priv, |
469 | unsigned int srcorg, unsigned int dstorg) | 469 | unsigned int srcorg, unsigned int dstorg) |
470 | { | 470 | { |
471 | if ((srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) || | 471 | if ((srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) || |
@@ -480,7 +480,7 @@ static int mga_verify_blit(drm_mga_private_t * dev_priv, | |||
480 | * | 480 | * |
481 | */ | 481 | */ |
482 | 482 | ||
483 | static void mga_dma_dispatch_clear(struct drm_device * dev, drm_mga_clear_t * clear) | 483 | static void mga_dma_dispatch_clear(struct drm_device *dev, drm_mga_clear_t *clear) |
484 | { | 484 | { |
485 | drm_mga_private_t *dev_priv = dev->dev_private; | 485 | drm_mga_private_t *dev_priv = dev->dev_private; |
486 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 486 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
@@ -568,7 +568,7 @@ static void mga_dma_dispatch_clear(struct drm_device * dev, drm_mga_clear_t * cl | |||
568 | FLUSH_DMA(); | 568 | FLUSH_DMA(); |
569 | } | 569 | } |
570 | 570 | ||
571 | static void mga_dma_dispatch_swap(struct drm_device * dev) | 571 | static void mga_dma_dispatch_swap(struct drm_device *dev) |
572 | { | 572 | { |
573 | drm_mga_private_t *dev_priv = dev->dev_private; | 573 | drm_mga_private_t *dev_priv = dev->dev_private; |
574 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 574 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
@@ -622,7 +622,7 @@ static void mga_dma_dispatch_swap(struct drm_device * dev) | |||
622 | DRM_DEBUG("... done.\n"); | 622 | DRM_DEBUG("... done.\n"); |
623 | } | 623 | } |
624 | 624 | ||
625 | static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf) | 625 | static void mga_dma_dispatch_vertex(struct drm_device *dev, struct drm_buf *buf) |
626 | { | 626 | { |
627 | drm_mga_private_t *dev_priv = dev->dev_private; | 627 | drm_mga_private_t *dev_priv = dev->dev_private; |
628 | drm_mga_buf_priv_t *buf_priv = buf->dev_private; | 628 | drm_mga_buf_priv_t *buf_priv = buf->dev_private; |
@@ -669,7 +669,7 @@ static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * bu | |||
669 | FLUSH_DMA(); | 669 | FLUSH_DMA(); |
670 | } | 670 | } |
671 | 671 | ||
672 | static void mga_dma_dispatch_indices(struct drm_device * dev, struct drm_buf * buf, | 672 | static void mga_dma_dispatch_indices(struct drm_device *dev, struct drm_buf *buf, |
673 | unsigned int start, unsigned int end) | 673 | unsigned int start, unsigned int end) |
674 | { | 674 | { |
675 | drm_mga_private_t *dev_priv = dev->dev_private; | 675 | drm_mga_private_t *dev_priv = dev->dev_private; |
@@ -718,7 +718,7 @@ static void mga_dma_dispatch_indices(struct drm_device * dev, struct drm_buf * b | |||
718 | /* This copies a 64 byte aligned agp region to the frambuffer with a | 718 | /* This copies a 64 byte aligned agp region to the frambuffer with a |
719 | * standard blit, the ioctl needs to do checking. | 719 | * standard blit, the ioctl needs to do checking. |
720 | */ | 720 | */ |
721 | static void mga_dma_dispatch_iload(struct drm_device * dev, struct drm_buf * buf, | 721 | static void mga_dma_dispatch_iload(struct drm_device *dev, struct drm_buf *buf, |
722 | unsigned int dstorg, unsigned int length) | 722 | unsigned int dstorg, unsigned int length) |
723 | { | 723 | { |
724 | drm_mga_private_t *dev_priv = dev->dev_private; | 724 | drm_mga_private_t *dev_priv = dev->dev_private; |
@@ -766,7 +766,7 @@ static void mga_dma_dispatch_iload(struct drm_device * dev, struct drm_buf * buf | |||
766 | FLUSH_DMA(); | 766 | FLUSH_DMA(); |
767 | } | 767 | } |
768 | 768 | ||
769 | static void mga_dma_dispatch_blit(struct drm_device * dev, drm_mga_blit_t * blit) | 769 | static void mga_dma_dispatch_blit(struct drm_device *dev, drm_mga_blit_t *blit) |
770 | { | 770 | { |
771 | drm_mga_private_t *dev_priv = dev->dev_private; | 771 | drm_mga_private_t *dev_priv = dev->dev_private; |
772 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; | 772 | drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; |
@@ -801,9 +801,8 @@ static void mga_dma_dispatch_blit(struct drm_device * dev, drm_mga_blit_t * blit | |||
801 | int w = pbox[i].x2 - pbox[i].x1 - 1; | 801 | int w = pbox[i].x2 - pbox[i].x1 - 1; |
802 | int start; | 802 | int start; |
803 | 803 | ||
804 | if (blit->ydir == -1) { | 804 | if (blit->ydir == -1) |
805 | srcy = blit->height - srcy - 1; | 805 | srcy = blit->height - srcy - 1; |
806 | } | ||
807 | 806 | ||
808 | start = srcy * blit->src_pitch + srcx; | 807 | start = srcy * blit->src_pitch + srcx; |
809 | 808 | ||
diff --git a/drivers/gpu/drm/mga/mga_warp.c b/drivers/gpu/drm/mga/mga_warp.c index 9aad4847afdf..f172bd5c257f 100644 --- a/drivers/gpu/drm/mga/mga_warp.c +++ b/drivers/gpu/drm/mga/mga_warp.c | |||
@@ -46,7 +46,7 @@ MODULE_FIRMWARE(FIRMWARE_G400); | |||
46 | 46 | ||
47 | #define WARP_UCODE_SIZE(size) ALIGN(size, MGA_WARP_CODE_ALIGN) | 47 | #define WARP_UCODE_SIZE(size) ALIGN(size, MGA_WARP_CODE_ALIGN) |
48 | 48 | ||
49 | int mga_warp_install_microcode(drm_mga_private_t * dev_priv) | 49 | int mga_warp_install_microcode(drm_mga_private_t *dev_priv) |
50 | { | 50 | { |
51 | unsigned char *vcbase = dev_priv->warp->handle; | 51 | unsigned char *vcbase = dev_priv->warp->handle; |
52 | unsigned long pcbase = dev_priv->warp->offset; | 52 | unsigned long pcbase = dev_priv->warp->offset; |
@@ -133,7 +133,7 @@ out: | |||
133 | 133 | ||
134 | #define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE) | 134 | #define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE) |
135 | 135 | ||
136 | int mga_warp_init(drm_mga_private_t * dev_priv) | 136 | int mga_warp_init(drm_mga_private_t *dev_priv) |
137 | { | 137 | { |
138 | u32 wmisc; | 138 | u32 wmisc; |
139 | 139 | ||
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 1175429da102..d2d28048efb2 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config DRM_NOUVEAU | 1 | config DRM_NOUVEAU |
2 | tristate "Nouveau (nVidia) cards" | 2 | tristate "Nouveau (nVidia) cards" |
3 | depends on DRM | 3 | depends on DRM && PCI |
4 | select FW_LOADER | 4 | select FW_LOADER |
5 | select DRM_KMS_HELPER | 5 | select DRM_KMS_HELPER |
6 | select DRM_TTM | 6 | select DRM_TTM |
@@ -41,4 +41,13 @@ config DRM_I2C_CH7006 | |||
41 | 41 | ||
42 | This driver is currently only useful if you're also using | 42 | This driver is currently only useful if you're also using |
43 | the nouveau driver. | 43 | the nouveau driver. |
44 | |||
45 | config DRM_I2C_SIL164 | ||
46 | tristate "Silicon Image sil164 TMDS transmitter" | ||
47 | default m if DRM_NOUVEAU | ||
48 | help | ||
49 | Support for sil164 and similar single-link (or dual-link | ||
50 | when used in pairs) TMDS transmitters, used in some nVidia | ||
51 | video cards. | ||
52 | |||
44 | endmenu | 53 | endmenu |
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index acd31ed861ef..2405d5ef0ca7 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
@@ -9,10 +9,10 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ | |||
9 | nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ | 9 | nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ |
10 | nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ | 10 | nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ |
11 | nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ | 11 | nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ |
12 | nouveau_dp.o nouveau_grctx.o \ | 12 | nouveau_dp.o \ |
13 | nv04_timer.o \ | 13 | nv04_timer.o \ |
14 | nv04_mc.o nv40_mc.o nv50_mc.o \ | 14 | nv04_mc.o nv40_mc.o nv50_mc.o \ |
15 | nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \ | 15 | nv04_fb.o nv10_fb.o nv30_fb.o nv40_fb.o nv50_fb.o \ |
16 | nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ | 16 | nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ |
17 | nv04_graph.o nv10_graph.o nv20_graph.o \ | 17 | nv04_graph.o nv10_graph.o nv20_graph.o \ |
18 | nv40_graph.o nv50_graph.o \ | 18 | nv40_graph.o nv50_graph.o \ |
@@ -22,7 +22,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ | |||
22 | nv50_cursor.o nv50_display.o nv50_fbcon.o \ | 22 | nv50_cursor.o nv50_display.o nv50_fbcon.o \ |
23 | nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ | 23 | nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ |
24 | nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \ | 24 | nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \ |
25 | nv17_gpio.o nv50_gpio.o \ | 25 | nv10_gpio.o nv50_gpio.o \ |
26 | nv50_calc.o | 26 | nv50_calc.o |
27 | 27 | ||
28 | nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o | 28 | nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o |
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index d4bcca8a5133..c17a055ee3e5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/slab.h> | 3 | #include <linux/slab.h> |
4 | #include <acpi/acpi_drivers.h> | 4 | #include <acpi/acpi_drivers.h> |
5 | #include <acpi/acpi_bus.h> | 5 | #include <acpi/acpi_bus.h> |
6 | #include <acpi/video.h> | ||
6 | 7 | ||
7 | #include "drmP.h" | 8 | #include "drmP.h" |
8 | #include "drm.h" | 9 | #include "drm.h" |
@@ -11,6 +12,7 @@ | |||
11 | #include "nouveau_drv.h" | 12 | #include "nouveau_drv.h" |
12 | #include "nouveau_drm.h" | 13 | #include "nouveau_drm.h" |
13 | #include "nv50_display.h" | 14 | #include "nv50_display.h" |
15 | #include "nouveau_connector.h" | ||
14 | 16 | ||
15 | #include <linux/vga_switcheroo.h> | 17 | #include <linux/vga_switcheroo.h> |
16 | 18 | ||
@@ -42,7 +44,7 @@ static const char nouveau_dsm_muid[] = { | |||
42 | 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4, | 44 | 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4, |
43 | }; | 45 | }; |
44 | 46 | ||
45 | static int nouveau_dsm(acpi_handle handle, int func, int arg, int *result) | 47 | static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result) |
46 | { | 48 | { |
47 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 49 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; |
48 | struct acpi_object_list input; | 50 | struct acpi_object_list input; |
@@ -259,3 +261,37 @@ int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) | |||
259 | { | 261 | { |
260 | return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len); | 262 | return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len); |
261 | } | 263 | } |
264 | |||
265 | int | ||
266 | nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) | ||
267 | { | ||
268 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | ||
269 | struct acpi_device *acpidev; | ||
270 | acpi_handle handle; | ||
271 | int type, ret; | ||
272 | void *edid; | ||
273 | |||
274 | switch (connector->connector_type) { | ||
275 | case DRM_MODE_CONNECTOR_LVDS: | ||
276 | case DRM_MODE_CONNECTOR_eDP: | ||
277 | type = ACPI_VIDEO_DISPLAY_LCD; | ||
278 | break; | ||
279 | default: | ||
280 | return -EINVAL; | ||
281 | } | ||
282 | |||
283 | handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); | ||
284 | if (!handle) | ||
285 | return -ENODEV; | ||
286 | |||
287 | ret = acpi_bus_get_device(handle, &acpidev); | ||
288 | if (ret) | ||
289 | return -ENODEV; | ||
290 | |||
291 | ret = acpi_video_get_edid(acpidev, type, -1, &edid); | ||
292 | if (ret < 0) | ||
293 | return ret; | ||
294 | |||
295 | nv_connector->edid = edid; | ||
296 | return 0; | ||
297 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index e492919faf44..7369b5e73649 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include "nouveau_hw.h" | 28 | #include "nouveau_hw.h" |
29 | #include "nouveau_encoder.h" | 29 | #include "nouveau_encoder.h" |
30 | 30 | ||
31 | #include <linux/io-mapping.h> | ||
32 | |||
31 | /* these defines are made up */ | 33 | /* these defines are made up */ |
32 | #define NV_CIO_CRE_44_HEADA 0x0 | 34 | #define NV_CIO_CRE_44_HEADA 0x0 |
33 | #define NV_CIO_CRE_44_HEADB 0x3 | 35 | #define NV_CIO_CRE_44_HEADB 0x3 |
@@ -209,20 +211,20 @@ static struct methods shadow_methods[] = { | |||
209 | { "PCIROM", load_vbios_pci, true }, | 211 | { "PCIROM", load_vbios_pci, true }, |
210 | { "ACPI", load_vbios_acpi, true }, | 212 | { "ACPI", load_vbios_acpi, true }, |
211 | }; | 213 | }; |
214 | #define NUM_SHADOW_METHODS ARRAY_SIZE(shadow_methods) | ||
212 | 215 | ||
213 | static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) | 216 | static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) |
214 | { | 217 | { |
215 | const int nr_methods = ARRAY_SIZE(shadow_methods); | ||
216 | struct methods *methods = shadow_methods; | 218 | struct methods *methods = shadow_methods; |
217 | int testscore = 3; | 219 | int testscore = 3; |
218 | int scores[nr_methods], i; | 220 | int scores[NUM_SHADOW_METHODS], i; |
219 | 221 | ||
220 | if (nouveau_vbios) { | 222 | if (nouveau_vbios) { |
221 | for (i = 0; i < nr_methods; i++) | 223 | for (i = 0; i < NUM_SHADOW_METHODS; i++) |
222 | if (!strcasecmp(nouveau_vbios, methods[i].desc)) | 224 | if (!strcasecmp(nouveau_vbios, methods[i].desc)) |
223 | break; | 225 | break; |
224 | 226 | ||
225 | if (i < nr_methods) { | 227 | if (i < NUM_SHADOW_METHODS) { |
226 | NV_INFO(dev, "Attempting to use BIOS image from %s\n", | 228 | NV_INFO(dev, "Attempting to use BIOS image from %s\n", |
227 | methods[i].desc); | 229 | methods[i].desc); |
228 | 230 | ||
@@ -234,7 +236,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) | |||
234 | NV_ERROR(dev, "VBIOS source \'%s\' invalid\n", nouveau_vbios); | 236 | NV_ERROR(dev, "VBIOS source \'%s\' invalid\n", nouveau_vbios); |
235 | } | 237 | } |
236 | 238 | ||
237 | for (i = 0; i < nr_methods; i++) { | 239 | for (i = 0; i < NUM_SHADOW_METHODS; i++) { |
238 | NV_TRACE(dev, "Attempting to load BIOS image from %s\n", | 240 | NV_TRACE(dev, "Attempting to load BIOS image from %s\n", |
239 | methods[i].desc); | 241 | methods[i].desc); |
240 | data[0] = data[1] = 0; /* avoid reuse of previous image */ | 242 | data[0] = data[1] = 0; /* avoid reuse of previous image */ |
@@ -245,7 +247,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) | |||
245 | } | 247 | } |
246 | 248 | ||
247 | while (--testscore > 0) { | 249 | while (--testscore > 0) { |
248 | for (i = 0; i < nr_methods; i++) { | 250 | for (i = 0; i < NUM_SHADOW_METHODS; i++) { |
249 | if (scores[i] == testscore) { | 251 | if (scores[i] == testscore) { |
250 | NV_TRACE(dev, "Using BIOS image from %s\n", | 252 | NV_TRACE(dev, "Using BIOS image from %s\n", |
251 | methods[i].desc); | 253 | methods[i].desc); |
@@ -920,7 +922,7 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset, | |||
920 | NV_ERROR(bios->dev, | 922 | NV_ERROR(bios->dev, |
921 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", | 923 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", |
922 | offset, config, count); | 924 | offset, config, count); |
923 | return -EINVAL; | 925 | return len; |
924 | } | 926 | } |
925 | 927 | ||
926 | configval = ROM32(bios->data[offset + 11 + config * 4]); | 928 | configval = ROM32(bios->data[offset + 11 + config * 4]); |
@@ -1022,7 +1024,7 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset, | |||
1022 | NV_ERROR(bios->dev, | 1024 | NV_ERROR(bios->dev, |
1023 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", | 1025 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", |
1024 | offset, config, count); | 1026 | offset, config, count); |
1025 | return -EINVAL; | 1027 | return len; |
1026 | } | 1028 | } |
1027 | 1029 | ||
1028 | freq = ROM16(bios->data[offset + 12 + config * 2]); | 1030 | freq = ROM16(bios->data[offset + 12 + config * 2]); |
@@ -1194,7 +1196,7 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1194 | dpe = nouveau_bios_dp_table(dev, dcb, &dummy); | 1196 | dpe = nouveau_bios_dp_table(dev, dcb, &dummy); |
1195 | if (!dpe) { | 1197 | if (!dpe) { |
1196 | NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset); | 1198 | NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset); |
1197 | return -EINVAL; | 1199 | return 3; |
1198 | } | 1200 | } |
1199 | 1201 | ||
1200 | switch (cond) { | 1202 | switch (cond) { |
@@ -1218,12 +1220,16 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1218 | int ret; | 1220 | int ret; |
1219 | 1221 | ||
1220 | auxch = nouveau_i2c_find(dev, bios->display.output->i2c_index); | 1222 | auxch = nouveau_i2c_find(dev, bios->display.output->i2c_index); |
1221 | if (!auxch) | 1223 | if (!auxch) { |
1222 | return -ENODEV; | 1224 | NV_ERROR(dev, "0x%04X: couldn't get auxch\n", offset); |
1225 | return 3; | ||
1226 | } | ||
1223 | 1227 | ||
1224 | ret = nouveau_dp_auxch(auxch, 9, 0xd, &cond, 1); | 1228 | ret = nouveau_dp_auxch(auxch, 9, 0xd, &cond, 1); |
1225 | if (ret) | 1229 | if (ret) { |
1226 | return ret; | 1230 | NV_ERROR(dev, "0x%04X: auxch rd fail: %d\n", offset, ret); |
1231 | return 3; | ||
1232 | } | ||
1227 | 1233 | ||
1228 | if (cond & 1) | 1234 | if (cond & 1) |
1229 | iexec->execute = false; | 1235 | iexec->execute = false; |
@@ -1392,7 +1398,7 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset, | |||
1392 | NV_ERROR(bios->dev, | 1398 | NV_ERROR(bios->dev, |
1393 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", | 1399 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", |
1394 | offset, config, count); | 1400 | offset, config, count); |
1395 | return -EINVAL; | 1401 | return len; |
1396 | } | 1402 | } |
1397 | 1403 | ||
1398 | freq = ROM32(bios->data[offset + 11 + config * 4]); | 1404 | freq = ROM32(bios->data[offset + 11 + config * 4]); |
@@ -1452,6 +1458,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1452 | * "mask n" and OR it with "data n" before writing it back to the device | 1458 | * "mask n" and OR it with "data n" before writing it back to the device |
1453 | */ | 1459 | */ |
1454 | 1460 | ||
1461 | struct drm_device *dev = bios->dev; | ||
1455 | uint8_t i2c_index = bios->data[offset + 1]; | 1462 | uint8_t i2c_index = bios->data[offset + 1]; |
1456 | uint8_t i2c_address = bios->data[offset + 2] >> 1; | 1463 | uint8_t i2c_address = bios->data[offset + 2] >> 1; |
1457 | uint8_t count = bios->data[offset + 3]; | 1464 | uint8_t count = bios->data[offset + 3]; |
@@ -1466,9 +1473,11 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1466 | "Count: 0x%02X\n", | 1473 | "Count: 0x%02X\n", |
1467 | offset, i2c_index, i2c_address, count); | 1474 | offset, i2c_index, i2c_address, count); |
1468 | 1475 | ||
1469 | chan = init_i2c_device_find(bios->dev, i2c_index); | 1476 | chan = init_i2c_device_find(dev, i2c_index); |
1470 | if (!chan) | 1477 | if (!chan) { |
1471 | return -ENODEV; | 1478 | NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset); |
1479 | return len; | ||
1480 | } | ||
1472 | 1481 | ||
1473 | for (i = 0; i < count; i++) { | 1482 | for (i = 0; i < count; i++) { |
1474 | uint8_t reg = bios->data[offset + 4 + i * 3]; | 1483 | uint8_t reg = bios->data[offset + 4 + i * 3]; |
@@ -1479,8 +1488,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1479 | ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, | 1488 | ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, |
1480 | I2C_SMBUS_READ, reg, | 1489 | I2C_SMBUS_READ, reg, |
1481 | I2C_SMBUS_BYTE_DATA, &val); | 1490 | I2C_SMBUS_BYTE_DATA, &val); |
1482 | if (ret < 0) | 1491 | if (ret < 0) { |
1483 | return ret; | 1492 | NV_ERROR(dev, "0x%04X: i2c rd fail: %d\n", offset, ret); |
1493 | return len; | ||
1494 | } | ||
1484 | 1495 | ||
1485 | BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " | 1496 | BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " |
1486 | "Mask: 0x%02X, Data: 0x%02X\n", | 1497 | "Mask: 0x%02X, Data: 0x%02X\n", |
@@ -1494,8 +1505,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1494 | ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, | 1505 | ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, |
1495 | I2C_SMBUS_WRITE, reg, | 1506 | I2C_SMBUS_WRITE, reg, |
1496 | I2C_SMBUS_BYTE_DATA, &val); | 1507 | I2C_SMBUS_BYTE_DATA, &val); |
1497 | if (ret < 0) | 1508 | if (ret < 0) { |
1498 | return ret; | 1509 | NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret); |
1510 | return len; | ||
1511 | } | ||
1499 | } | 1512 | } |
1500 | 1513 | ||
1501 | return len; | 1514 | return len; |
@@ -1520,6 +1533,7 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1520 | * "DCB I2C table entry index", set the register to "data n" | 1533 | * "DCB I2C table entry index", set the register to "data n" |
1521 | */ | 1534 | */ |
1522 | 1535 | ||
1536 | struct drm_device *dev = bios->dev; | ||
1523 | uint8_t i2c_index = bios->data[offset + 1]; | 1537 | uint8_t i2c_index = bios->data[offset + 1]; |
1524 | uint8_t i2c_address = bios->data[offset + 2] >> 1; | 1538 | uint8_t i2c_address = bios->data[offset + 2] >> 1; |
1525 | uint8_t count = bios->data[offset + 3]; | 1539 | uint8_t count = bios->data[offset + 3]; |
@@ -1534,9 +1548,11 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1534 | "Count: 0x%02X\n", | 1548 | "Count: 0x%02X\n", |
1535 | offset, i2c_index, i2c_address, count); | 1549 | offset, i2c_index, i2c_address, count); |
1536 | 1550 | ||
1537 | chan = init_i2c_device_find(bios->dev, i2c_index); | 1551 | chan = init_i2c_device_find(dev, i2c_index); |
1538 | if (!chan) | 1552 | if (!chan) { |
1539 | return -ENODEV; | 1553 | NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset); |
1554 | return len; | ||
1555 | } | ||
1540 | 1556 | ||
1541 | for (i = 0; i < count; i++) { | 1557 | for (i = 0; i < count; i++) { |
1542 | uint8_t reg = bios->data[offset + 4 + i * 2]; | 1558 | uint8_t reg = bios->data[offset + 4 + i * 2]; |
@@ -1553,8 +1569,10 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1553 | ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, | 1569 | ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, |
1554 | I2C_SMBUS_WRITE, reg, | 1570 | I2C_SMBUS_WRITE, reg, |
1555 | I2C_SMBUS_BYTE_DATA, &val); | 1571 | I2C_SMBUS_BYTE_DATA, &val); |
1556 | if (ret < 0) | 1572 | if (ret < 0) { |
1557 | return ret; | 1573 | NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret); |
1574 | return len; | ||
1575 | } | ||
1558 | } | 1576 | } |
1559 | 1577 | ||
1560 | return len; | 1578 | return len; |
@@ -1577,6 +1595,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1577 | * address" on the I2C bus given by "DCB I2C table entry index" | 1595 | * address" on the I2C bus given by "DCB I2C table entry index" |
1578 | */ | 1596 | */ |
1579 | 1597 | ||
1598 | struct drm_device *dev = bios->dev; | ||
1580 | uint8_t i2c_index = bios->data[offset + 1]; | 1599 | uint8_t i2c_index = bios->data[offset + 1]; |
1581 | uint8_t i2c_address = bios->data[offset + 2] >> 1; | 1600 | uint8_t i2c_address = bios->data[offset + 2] >> 1; |
1582 | uint8_t count = bios->data[offset + 3]; | 1601 | uint8_t count = bios->data[offset + 3]; |
@@ -1584,7 +1603,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1584 | struct nouveau_i2c_chan *chan; | 1603 | struct nouveau_i2c_chan *chan; |
1585 | struct i2c_msg msg; | 1604 | struct i2c_msg msg; |
1586 | uint8_t data[256]; | 1605 | uint8_t data[256]; |
1587 | int i; | 1606 | int ret, i; |
1588 | 1607 | ||
1589 | if (!iexec->execute) | 1608 | if (!iexec->execute) |
1590 | return len; | 1609 | return len; |
@@ -1593,9 +1612,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1593 | "Count: 0x%02X\n", | 1612 | "Count: 0x%02X\n", |
1594 | offset, i2c_index, i2c_address, count); | 1613 | offset, i2c_index, i2c_address, count); |
1595 | 1614 | ||
1596 | chan = init_i2c_device_find(bios->dev, i2c_index); | 1615 | chan = init_i2c_device_find(dev, i2c_index); |
1597 | if (!chan) | 1616 | if (!chan) { |
1598 | return -ENODEV; | 1617 | NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset); |
1618 | return len; | ||
1619 | } | ||
1599 | 1620 | ||
1600 | for (i = 0; i < count; i++) { | 1621 | for (i = 0; i < count; i++) { |
1601 | data[i] = bios->data[offset + 4 + i]; | 1622 | data[i] = bios->data[offset + 4 + i]; |
@@ -1608,8 +1629,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1608 | msg.flags = 0; | 1629 | msg.flags = 0; |
1609 | msg.len = count; | 1630 | msg.len = count; |
1610 | msg.buf = data; | 1631 | msg.buf = data; |
1611 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) | 1632 | ret = i2c_transfer(&chan->adapter, &msg, 1); |
1612 | return -EIO; | 1633 | if (ret != 1) { |
1634 | NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret); | ||
1635 | return len; | ||
1636 | } | ||
1613 | } | 1637 | } |
1614 | 1638 | ||
1615 | return len; | 1639 | return len; |
@@ -1633,6 +1657,7 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1633 | * used -- see get_tmds_index_reg() | 1657 | * used -- see get_tmds_index_reg() |
1634 | */ | 1658 | */ |
1635 | 1659 | ||
1660 | struct drm_device *dev = bios->dev; | ||
1636 | uint8_t mlv = bios->data[offset + 1]; | 1661 | uint8_t mlv = bios->data[offset + 1]; |
1637 | uint32_t tmdsaddr = bios->data[offset + 2]; | 1662 | uint32_t tmdsaddr = bios->data[offset + 2]; |
1638 | uint8_t mask = bios->data[offset + 3]; | 1663 | uint8_t mask = bios->data[offset + 3]; |
@@ -1647,8 +1672,10 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1647 | offset, mlv, tmdsaddr, mask, data); | 1672 | offset, mlv, tmdsaddr, mask, data); |
1648 | 1673 | ||
1649 | reg = get_tmds_index_reg(bios->dev, mlv); | 1674 | reg = get_tmds_index_reg(bios->dev, mlv); |
1650 | if (!reg) | 1675 | if (!reg) { |
1651 | return -EINVAL; | 1676 | NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset); |
1677 | return 5; | ||
1678 | } | ||
1652 | 1679 | ||
1653 | bios_wr32(bios, reg, | 1680 | bios_wr32(bios, reg, |
1654 | tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); | 1681 | tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); |
@@ -1678,6 +1705,7 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset, | |||
1678 | * register is used -- see get_tmds_index_reg() | 1705 | * register is used -- see get_tmds_index_reg() |
1679 | */ | 1706 | */ |
1680 | 1707 | ||
1708 | struct drm_device *dev = bios->dev; | ||
1681 | uint8_t mlv = bios->data[offset + 1]; | 1709 | uint8_t mlv = bios->data[offset + 1]; |
1682 | uint8_t count = bios->data[offset + 2]; | 1710 | uint8_t count = bios->data[offset + 2]; |
1683 | int len = 3 + count * 2; | 1711 | int len = 3 + count * 2; |
@@ -1691,8 +1719,10 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset, | |||
1691 | offset, mlv, count); | 1719 | offset, mlv, count); |
1692 | 1720 | ||
1693 | reg = get_tmds_index_reg(bios->dev, mlv); | 1721 | reg = get_tmds_index_reg(bios->dev, mlv); |
1694 | if (!reg) | 1722 | if (!reg) { |
1695 | return -EINVAL; | 1723 | NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset); |
1724 | return len; | ||
1725 | } | ||
1696 | 1726 | ||
1697 | for (i = 0; i < count; i++) { | 1727 | for (i = 0; i < count; i++) { |
1698 | uint8_t tmdsaddr = bios->data[offset + 3 + i * 2]; | 1728 | uint8_t tmdsaddr = bios->data[offset + 3 + i * 2]; |
@@ -2039,6 +2069,323 @@ init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2039 | return 5; | 2069 | return 5; |
2040 | } | 2070 | } |
2041 | 2071 | ||
2072 | static inline void | ||
2073 | bios_md32(struct nvbios *bios, uint32_t reg, | ||
2074 | uint32_t mask, uint32_t val) | ||
2075 | { | ||
2076 | bios_wr32(bios, reg, (bios_rd32(bios, reg) & ~mask) | val); | ||
2077 | } | ||
2078 | |||
2079 | static uint32_t | ||
2080 | peek_fb(struct drm_device *dev, struct io_mapping *fb, | ||
2081 | uint32_t off) | ||
2082 | { | ||
2083 | uint32_t val = 0; | ||
2084 | |||
2085 | if (off < pci_resource_len(dev->pdev, 1)) { | ||
2086 | uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off, KM_USER0); | ||
2087 | |||
2088 | val = ioread32(p); | ||
2089 | |||
2090 | io_mapping_unmap_atomic(p, KM_USER0); | ||
2091 | } | ||
2092 | |||
2093 | return val; | ||
2094 | } | ||
2095 | |||
2096 | static void | ||
2097 | poke_fb(struct drm_device *dev, struct io_mapping *fb, | ||
2098 | uint32_t off, uint32_t val) | ||
2099 | { | ||
2100 | if (off < pci_resource_len(dev->pdev, 1)) { | ||
2101 | uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off, KM_USER0); | ||
2102 | |||
2103 | iowrite32(val, p); | ||
2104 | wmb(); | ||
2105 | |||
2106 | io_mapping_unmap_atomic(p, KM_USER0); | ||
2107 | } | ||
2108 | } | ||
2109 | |||
2110 | static inline bool | ||
2111 | read_back_fb(struct drm_device *dev, struct io_mapping *fb, | ||
2112 | uint32_t off, uint32_t val) | ||
2113 | { | ||
2114 | poke_fb(dev, fb, off, val); | ||
2115 | return val == peek_fb(dev, fb, off); | ||
2116 | } | ||
2117 | |||
2118 | static int | ||
2119 | nv04_init_compute_mem(struct nvbios *bios) | ||
2120 | { | ||
2121 | struct drm_device *dev = bios->dev; | ||
2122 | uint32_t patt = 0xdeadbeef; | ||
2123 | struct io_mapping *fb; | ||
2124 | int i; | ||
2125 | |||
2126 | /* Map the framebuffer aperture */ | ||
2127 | fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), | ||
2128 | pci_resource_len(dev->pdev, 1)); | ||
2129 | if (!fb) | ||
2130 | return -ENOMEM; | ||
2131 | |||
2132 | /* Sequencer and refresh off */ | ||
2133 | NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20); | ||
2134 | bios_md32(bios, NV04_PFB_DEBUG_0, 0, NV04_PFB_DEBUG_0_REFRESH_OFF); | ||
2135 | |||
2136 | bios_md32(bios, NV04_PFB_BOOT_0, ~0, | ||
2137 | NV04_PFB_BOOT_0_RAM_AMOUNT_16MB | | ||
2138 | NV04_PFB_BOOT_0_RAM_WIDTH_128 | | ||
2139 | NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT); | ||
2140 | |||
2141 | for (i = 0; i < 4; i++) | ||
2142 | poke_fb(dev, fb, 4 * i, patt); | ||
2143 | |||
2144 | poke_fb(dev, fb, 0x400000, patt + 1); | ||
2145 | |||
2146 | if (peek_fb(dev, fb, 0) == patt + 1) { | ||
2147 | bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE, | ||
2148 | NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT); | ||
2149 | bios_md32(bios, NV04_PFB_DEBUG_0, | ||
2150 | NV04_PFB_DEBUG_0_REFRESH_OFF, 0); | ||
2151 | |||
2152 | for (i = 0; i < 4; i++) | ||
2153 | poke_fb(dev, fb, 4 * i, patt); | ||
2154 | |||
2155 | if ((peek_fb(dev, fb, 0xc) & 0xffff) != (patt & 0xffff)) | ||
2156 | bios_md32(bios, NV04_PFB_BOOT_0, | ||
2157 | NV04_PFB_BOOT_0_RAM_WIDTH_128 | | ||
2158 | NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2159 | NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); | ||
2160 | |||
2161 | } else if ((peek_fb(dev, fb, 0xc) & 0xffff0000) != | ||
2162 | (patt & 0xffff0000)) { | ||
2163 | bios_md32(bios, NV04_PFB_BOOT_0, | ||
2164 | NV04_PFB_BOOT_0_RAM_WIDTH_128 | | ||
2165 | NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2166 | NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); | ||
2167 | |||
2168 | } else if (peek_fb(dev, fb, 0) == patt) { | ||
2169 | if (read_back_fb(dev, fb, 0x800000, patt)) | ||
2170 | bios_md32(bios, NV04_PFB_BOOT_0, | ||
2171 | NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2172 | NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); | ||
2173 | else | ||
2174 | bios_md32(bios, NV04_PFB_BOOT_0, | ||
2175 | NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2176 | NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); | ||
2177 | |||
2178 | bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE, | ||
2179 | NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT); | ||
2180 | |||
2181 | } else if (!read_back_fb(dev, fb, 0x800000, patt)) { | ||
2182 | bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2183 | NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); | ||
2184 | |||
2185 | } | ||
2186 | |||
2187 | /* Refresh on, sequencer on */ | ||
2188 | bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0); | ||
2189 | NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20); | ||
2190 | |||
2191 | io_mapping_free(fb); | ||
2192 | return 0; | ||
2193 | } | ||
2194 | |||
2195 | static const uint8_t * | ||
2196 | nv05_memory_config(struct nvbios *bios) | ||
2197 | { | ||
2198 | /* Defaults for BIOSes lacking a memory config table */ | ||
2199 | static const uint8_t default_config_tab[][2] = { | ||
2200 | { 0x24, 0x00 }, | ||
2201 | { 0x28, 0x00 }, | ||
2202 | { 0x24, 0x01 }, | ||
2203 | { 0x1f, 0x00 }, | ||
2204 | { 0x0f, 0x00 }, | ||
2205 | { 0x17, 0x00 }, | ||
2206 | { 0x06, 0x00 }, | ||
2207 | { 0x00, 0x00 } | ||
2208 | }; | ||
2209 | int i = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) & | ||
2210 | NV_PEXTDEV_BOOT_0_RAMCFG) >> 2; | ||
2211 | |||
2212 | if (bios->legacy.mem_init_tbl_ptr) | ||
2213 | return &bios->data[bios->legacy.mem_init_tbl_ptr + 2 * i]; | ||
2214 | else | ||
2215 | return default_config_tab[i]; | ||
2216 | } | ||
2217 | |||
2218 | static int | ||
2219 | nv05_init_compute_mem(struct nvbios *bios) | ||
2220 | { | ||
2221 | struct drm_device *dev = bios->dev; | ||
2222 | const uint8_t *ramcfg = nv05_memory_config(bios); | ||
2223 | uint32_t patt = 0xdeadbeef; | ||
2224 | struct io_mapping *fb; | ||
2225 | int i, v; | ||
2226 | |||
2227 | /* Map the framebuffer aperture */ | ||
2228 | fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), | ||
2229 | pci_resource_len(dev->pdev, 1)); | ||
2230 | if (!fb) | ||
2231 | return -ENOMEM; | ||
2232 | |||
2233 | /* Sequencer off */ | ||
2234 | NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20); | ||
2235 | |||
2236 | if (bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_UMA_ENABLE) | ||
2237 | goto out; | ||
2238 | |||
2239 | bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0); | ||
2240 | |||
2241 | /* If present load the hardcoded scrambling table */ | ||
2242 | if (bios->legacy.mem_init_tbl_ptr) { | ||
2243 | uint32_t *scramble_tab = (uint32_t *)&bios->data[ | ||
2244 | bios->legacy.mem_init_tbl_ptr + 0x10]; | ||
2245 | |||
2246 | for (i = 0; i < 8; i++) | ||
2247 | bios_wr32(bios, NV04_PFB_SCRAMBLE(i), | ||
2248 | ROM32(scramble_tab[i])); | ||
2249 | } | ||
2250 | |||
2251 | /* Set memory type/width/length defaults depending on the straps */ | ||
2252 | bios_md32(bios, NV04_PFB_BOOT_0, 0x3f, ramcfg[0]); | ||
2253 | |||
2254 | if (ramcfg[1] & 0x80) | ||
2255 | bios_md32(bios, NV04_PFB_CFG0, 0, NV04_PFB_CFG0_SCRAMBLE); | ||
2256 | |||
2257 | bios_md32(bios, NV04_PFB_CFG1, 0x700001, (ramcfg[1] & 1) << 20); | ||
2258 | bios_md32(bios, NV04_PFB_CFG1, 0, 1); | ||
2259 | |||
2260 | /* Probe memory bus width */ | ||
2261 | for (i = 0; i < 4; i++) | ||
2262 | poke_fb(dev, fb, 4 * i, patt); | ||
2263 | |||
2264 | if (peek_fb(dev, fb, 0xc) != patt) | ||
2265 | bios_md32(bios, NV04_PFB_BOOT_0, | ||
2266 | NV04_PFB_BOOT_0_RAM_WIDTH_128, 0); | ||
2267 | |||
2268 | /* Probe memory length */ | ||
2269 | v = bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_RAM_AMOUNT; | ||
2270 | |||
2271 | if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_32MB && | ||
2272 | (!read_back_fb(dev, fb, 0x1000000, ++patt) || | ||
2273 | !read_back_fb(dev, fb, 0, ++patt))) | ||
2274 | bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2275 | NV04_PFB_BOOT_0_RAM_AMOUNT_16MB); | ||
2276 | |||
2277 | if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_16MB && | ||
2278 | !read_back_fb(dev, fb, 0x800000, ++patt)) | ||
2279 | bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2280 | NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); | ||
2281 | |||
2282 | if (!read_back_fb(dev, fb, 0x400000, ++patt)) | ||
2283 | bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2284 | NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); | ||
2285 | |||
2286 | out: | ||
2287 | /* Sequencer on */ | ||
2288 | NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20); | ||
2289 | |||
2290 | io_mapping_free(fb); | ||
2291 | return 0; | ||
2292 | } | ||
2293 | |||
2294 | static int | ||
2295 | nv10_init_compute_mem(struct nvbios *bios) | ||
2296 | { | ||
2297 | struct drm_device *dev = bios->dev; | ||
2298 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; | ||
2299 | const int mem_width[] = { 0x10, 0x00, 0x20 }; | ||
2300 | const int mem_width_count = (dev_priv->chipset >= 0x17 ? 3 : 2); | ||
2301 | uint32_t patt = 0xdeadbeef; | ||
2302 | struct io_mapping *fb; | ||
2303 | int i, j, k; | ||
2304 | |||
2305 | /* Map the framebuffer aperture */ | ||
2306 | fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), | ||
2307 | pci_resource_len(dev->pdev, 1)); | ||
2308 | if (!fb) | ||
2309 | return -ENOMEM; | ||
2310 | |||
2311 | bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1); | ||
2312 | |||
2313 | /* Probe memory bus width */ | ||
2314 | for (i = 0; i < mem_width_count; i++) { | ||
2315 | bios_md32(bios, NV04_PFB_CFG0, 0x30, mem_width[i]); | ||
2316 | |||
2317 | for (j = 0; j < 4; j++) { | ||
2318 | for (k = 0; k < 4; k++) | ||
2319 | poke_fb(dev, fb, 0x1c, 0); | ||
2320 | |||
2321 | poke_fb(dev, fb, 0x1c, patt); | ||
2322 | poke_fb(dev, fb, 0x3c, 0); | ||
2323 | |||
2324 | if (peek_fb(dev, fb, 0x1c) == patt) | ||
2325 | goto mem_width_found; | ||
2326 | } | ||
2327 | } | ||
2328 | |||
2329 | mem_width_found: | ||
2330 | patt <<= 1; | ||
2331 | |||
2332 | /* Probe amount of installed memory */ | ||
2333 | for (i = 0; i < 4; i++) { | ||
2334 | int off = bios_rd32(bios, NV04_PFB_FIFO_DATA) - 0x100000; | ||
2335 | |||
2336 | poke_fb(dev, fb, off, patt); | ||
2337 | poke_fb(dev, fb, 0, 0); | ||
2338 | |||
2339 | peek_fb(dev, fb, 0); | ||
2340 | peek_fb(dev, fb, 0); | ||
2341 | peek_fb(dev, fb, 0); | ||
2342 | peek_fb(dev, fb, 0); | ||
2343 | |||
2344 | if (peek_fb(dev, fb, off) == patt) | ||
2345 | goto amount_found; | ||
2346 | } | ||
2347 | |||
2348 | /* IC missing - disable the upper half memory space. */ | ||
2349 | bios_md32(bios, NV04_PFB_CFG0, 0x1000, 0); | ||
2350 | |||
2351 | amount_found: | ||
2352 | io_mapping_free(fb); | ||
2353 | return 0; | ||
2354 | } | ||
2355 | |||
2356 | static int | ||
2357 | nv20_init_compute_mem(struct nvbios *bios) | ||
2358 | { | ||
2359 | struct drm_device *dev = bios->dev; | ||
2360 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; | ||
2361 | uint32_t mask = (dev_priv->chipset >= 0x25 ? 0x300 : 0x900); | ||
2362 | uint32_t amount, off; | ||
2363 | struct io_mapping *fb; | ||
2364 | |||
2365 | /* Map the framebuffer aperture */ | ||
2366 | fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), | ||
2367 | pci_resource_len(dev->pdev, 1)); | ||
2368 | if (!fb) | ||
2369 | return -ENOMEM; | ||
2370 | |||
2371 | bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1); | ||
2372 | |||
2373 | /* Allow full addressing */ | ||
2374 | bios_md32(bios, NV04_PFB_CFG0, 0, mask); | ||
2375 | |||
2376 | amount = bios_rd32(bios, NV04_PFB_FIFO_DATA); | ||
2377 | for (off = amount; off > 0x2000000; off -= 0x2000000) | ||
2378 | poke_fb(dev, fb, off - 4, off); | ||
2379 | |||
2380 | amount = bios_rd32(bios, NV04_PFB_FIFO_DATA); | ||
2381 | if (amount != peek_fb(dev, fb, amount - 4)) | ||
2382 | /* IC missing - disable the upper half memory space. */ | ||
2383 | bios_md32(bios, NV04_PFB_CFG0, mask, 0); | ||
2384 | |||
2385 | io_mapping_free(fb); | ||
2386 | return 0; | ||
2387 | } | ||
2388 | |||
2042 | static int | 2389 | static int |
2043 | init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2390 | init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2044 | { | 2391 | { |
@@ -2047,64 +2394,57 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2047 | * | 2394 | * |
2048 | * offset (8 bit): opcode | 2395 | * offset (8 bit): opcode |
2049 | * | 2396 | * |
2050 | * This opcode is meant to set NV_PFB_CFG0 (0x100200) appropriately so | 2397 | * This opcode is meant to set the PFB memory config registers |
2051 | * that the hardware can correctly calculate how much VRAM it has | 2398 | * appropriately so that we can correctly calculate how much VRAM it |
2052 | * (and subsequently report that value in NV_PFB_CSTATUS (0x10020C)) | 2399 | * has (on nv10 and better chipsets the amount of installed VRAM is |
2400 | * subsequently reported in NV_PFB_CSTATUS (0x10020C)). | ||
2053 | * | 2401 | * |
2054 | * The implementation of this opcode in general consists of two parts: | 2402 | * The implementation of this opcode in general consists of several |
2055 | * 1) determination of the memory bus width | 2403 | * parts: |
2056 | * 2) determination of how many of the card's RAM pads have ICs attached | ||
2057 | * | 2404 | * |
2058 | * 1) is done by a cunning combination of writes to offsets 0x1c and | 2405 | * 1) Determination of memory type and density. Only necessary for |
2059 | * 0x3c in the framebuffer, and seeing whether the written values are | 2406 | * really old chipsets, the memory type reported by the strap bits |
2060 | * read back correctly. This then affects bits 4-7 of NV_PFB_CFG0 | 2407 | * (0x101000) is assumed to be accurate on nv05 and newer. |
2061 | * | 2408 | * |
2062 | * 2) is done by a cunning combination of writes to an offset slightly | 2409 | * 2) Determination of the memory bus width. Usually done by a cunning |
2063 | * less than the maximum memory reported by NV_PFB_CSTATUS, then seeing | 2410 | * combination of writes to offsets 0x1c and 0x3c in the fb, and |
2064 | * if the test pattern can be read back. This then affects bits 12-15 of | 2411 | * seeing whether the written values are read back correctly. |
2065 | * NV_PFB_CFG0 | ||
2066 | * | 2412 | * |
2067 | * In this context a "cunning combination" may include multiple reads | 2413 | * Only necessary on nv0x-nv1x and nv34, on the other cards we can |
2068 | * and writes to varying locations, often alternating the test pattern | 2414 | * trust the straps. |
2069 | * and 0, doubtless to make sure buffers are filled, residual charges | ||
2070 | * on tracks are removed etc. | ||
2071 | * | 2415 | * |
2072 | * Unfortunately, the "cunning combination"s mentioned above, and the | 2416 | * 3) Determination of how many of the card's RAM pads have ICs |
2073 | * changes to the bits in NV_PFB_CFG0 differ with nearly every bios | 2417 | * attached, usually done by a cunning combination of writes to an |
2074 | * trace I have. | 2418 | * offset slightly less than the maximum memory reported by |
2419 | * NV_PFB_CSTATUS, then seeing if the test pattern can be read back. | ||
2075 | * | 2420 | * |
2076 | * Therefore, we cheat and assume the value of NV_PFB_CFG0 with which | 2421 | * This appears to be a NOP on IGPs and NV4x or newer chipsets, both io |
2077 | * we started was correct, and use that instead | 2422 | * logs of the VBIOS and kmmio traces of the binary driver POSTing the |
2423 | * card show nothing being done for this opcode. Why is it still listed | ||
2424 | * in the table?! | ||
2078 | */ | 2425 | */ |
2079 | 2426 | ||
2080 | /* no iexec->execute check by design */ | 2427 | /* no iexec->execute check by design */ |
2081 | 2428 | ||
2082 | /* | ||
2083 | * This appears to be a NOP on G8x chipsets, both io logs of the VBIOS | ||
2084 | * and kmmio traces of the binary driver POSTing the card show nothing | ||
2085 | * being done for this opcode. why is it still listed in the table?! | ||
2086 | */ | ||
2087 | |||
2088 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; | 2429 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; |
2430 | int ret; | ||
2089 | 2431 | ||
2090 | if (dev_priv->card_type >= NV_40) | 2432 | if (dev_priv->chipset >= 0x40 || |
2091 | return 1; | 2433 | dev_priv->chipset == 0x1a || |
2092 | 2434 | dev_priv->chipset == 0x1f) | |
2093 | /* | 2435 | ret = 0; |
2094 | * On every card I've seen, this step gets done for us earlier in | 2436 | else if (dev_priv->chipset >= 0x20 && |
2095 | * the init scripts | 2437 | dev_priv->chipset != 0x34) |
2096 | uint8_t crdata = bios_idxprt_rd(dev, NV_VIO_SRX, 0x01); | 2438 | ret = nv20_init_compute_mem(bios); |
2097 | bios_idxprt_wr(dev, NV_VIO_SRX, 0x01, crdata | 0x20); | 2439 | else if (dev_priv->chipset >= 0x10) |
2098 | */ | 2440 | ret = nv10_init_compute_mem(bios); |
2099 | 2441 | else if (dev_priv->chipset >= 0x5) | |
2100 | /* | 2442 | ret = nv05_init_compute_mem(bios); |
2101 | * This also has probably been done in the scripts, but an mmio trace of | 2443 | else |
2102 | * s3 resume shows nvidia doing it anyway (unlike the NV_VIO_SRX write) | 2444 | ret = nv04_init_compute_mem(bios); |
2103 | */ | ||
2104 | bios_wr32(bios, NV_PFB_REFCTRL, NV_PFB_REFCTRL_VALID_1); | ||
2105 | 2445 | ||
2106 | /* write back the saved configuration value */ | 2446 | if (ret) |
2107 | bios_wr32(bios, NV_PFB_CFG0, bios->state.saved_nv_pfb_cfg0); | 2447 | return ret; |
2108 | 2448 | ||
2109 | return 1; | 2449 | return 1; |
2110 | } | 2450 | } |
@@ -2131,7 +2471,8 @@ init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2131 | /* no iexec->execute check by design */ | 2471 | /* no iexec->execute check by design */ |
2132 | 2472 | ||
2133 | pci_nv_19 = bios_rd32(bios, NV_PBUS_PCI_NV_19); | 2473 | pci_nv_19 = bios_rd32(bios, NV_PBUS_PCI_NV_19); |
2134 | bios_wr32(bios, NV_PBUS_PCI_NV_19, 0); | 2474 | bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19 & ~0xf00); |
2475 | |||
2135 | bios_wr32(bios, reg, value1); | 2476 | bios_wr32(bios, reg, value1); |
2136 | 2477 | ||
2137 | udelay(10); | 2478 | udelay(10); |
@@ -2167,7 +2508,7 @@ init_configure_mem(struct nvbios *bios, uint16_t offset, | |||
2167 | uint32_t reg, data; | 2508 | uint32_t reg, data; |
2168 | 2509 | ||
2169 | if (bios->major_version > 2) | 2510 | if (bios->major_version > 2) |
2170 | return -ENODEV; | 2511 | return 0; |
2171 | 2512 | ||
2172 | bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd( | 2513 | bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd( |
2173 | bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20); | 2514 | bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20); |
@@ -2180,14 +2521,14 @@ init_configure_mem(struct nvbios *bios, uint16_t offset, | |||
2180 | reg = ROM32(bios->data[seqtbloffs += 4])) { | 2521 | reg = ROM32(bios->data[seqtbloffs += 4])) { |
2181 | 2522 | ||
2182 | switch (reg) { | 2523 | switch (reg) { |
2183 | case NV_PFB_PRE: | 2524 | case NV04_PFB_PRE: |
2184 | data = NV_PFB_PRE_CMD_PRECHARGE; | 2525 | data = NV04_PFB_PRE_CMD_PRECHARGE; |
2185 | break; | 2526 | break; |
2186 | case NV_PFB_PAD: | 2527 | case NV04_PFB_PAD: |
2187 | data = NV_PFB_PAD_CKE_NORMAL; | 2528 | data = NV04_PFB_PAD_CKE_NORMAL; |
2188 | break; | 2529 | break; |
2189 | case NV_PFB_REF: | 2530 | case NV04_PFB_REF: |
2190 | data = NV_PFB_REF_CMD_REFRESH; | 2531 | data = NV04_PFB_REF_CMD_REFRESH; |
2191 | break; | 2532 | break; |
2192 | default: | 2533 | default: |
2193 | data = ROM32(bios->data[meminitdata]); | 2534 | data = ROM32(bios->data[meminitdata]); |
@@ -2222,7 +2563,7 @@ init_configure_clk(struct nvbios *bios, uint16_t offset, | |||
2222 | int clock; | 2563 | int clock; |
2223 | 2564 | ||
2224 | if (bios->major_version > 2) | 2565 | if (bios->major_version > 2) |
2225 | return -ENODEV; | 2566 | return 0; |
2226 | 2567 | ||
2227 | clock = ROM16(bios->data[meminitoffs + 4]) * 10; | 2568 | clock = ROM16(bios->data[meminitoffs + 4]) * 10; |
2228 | setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock); | 2569 | setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock); |
@@ -2255,7 +2596,7 @@ init_configure_preinit(struct nvbios *bios, uint16_t offset, | |||
2255 | uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6)); | 2596 | uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6)); |
2256 | 2597 | ||
2257 | if (bios->major_version > 2) | 2598 | if (bios->major_version > 2) |
2258 | return -ENODEV; | 2599 | return 0; |
2259 | 2600 | ||
2260 | bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, | 2601 | bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, |
2261 | NV_CIO_CRE_SCRATCH4__INDEX, cr3c); | 2602 | NV_CIO_CRE_SCRATCH4__INDEX, cr3c); |
@@ -2389,7 +2730,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset, | |||
2389 | * offset + 1 (8 bit): mask | 2730 | * offset + 1 (8 bit): mask |
2390 | * offset + 2 (8 bit): cmpval | 2731 | * offset + 2 (8 bit): cmpval |
2391 | * | 2732 | * |
2392 | * Test if (NV_PFB_BOOT_0 & "mask") equals "cmpval". | 2733 | * Test if (NV04_PFB_BOOT_0 & "mask") equals "cmpval". |
2393 | * If condition not met skip subsequent opcodes until condition is | 2734 | * If condition not met skip subsequent opcodes until condition is |
2394 | * inverted (INIT_NOT), or we hit INIT_RESUME | 2735 | * inverted (INIT_NOT), or we hit INIT_RESUME |
2395 | */ | 2736 | */ |
@@ -2401,7 +2742,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset, | |||
2401 | if (!iexec->execute) | 2742 | if (!iexec->execute) |
2402 | return 3; | 2743 | return 3; |
2403 | 2744 | ||
2404 | data = bios_rd32(bios, NV_PFB_BOOT_0) & mask; | 2745 | data = bios_rd32(bios, NV04_PFB_BOOT_0) & mask; |
2405 | 2746 | ||
2406 | BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n", | 2747 | BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n", |
2407 | offset, data, cmpval); | 2748 | offset, data, cmpval); |
@@ -2795,12 +3136,13 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2795 | */ | 3136 | */ |
2796 | 3137 | ||
2797 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; | 3138 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; |
3139 | struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; | ||
2798 | const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; | 3140 | const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; |
2799 | int i; | 3141 | int i; |
2800 | 3142 | ||
2801 | if (dev_priv->card_type != NV_50) { | 3143 | if (dev_priv->card_type != NV_50) { |
2802 | NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n"); | 3144 | NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n"); |
2803 | return -ENODEV; | 3145 | return 1; |
2804 | } | 3146 | } |
2805 | 3147 | ||
2806 | if (!iexec->execute) | 3148 | if (!iexec->execute) |
@@ -2815,7 +3157,7 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2815 | BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n", | 3157 | BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n", |
2816 | offset, gpio->tag, gpio->state_default); | 3158 | offset, gpio->tag, gpio->state_default); |
2817 | if (bios->execute) | 3159 | if (bios->execute) |
2818 | nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default); | 3160 | pgpio->set(bios->dev, gpio->tag, gpio->state_default); |
2819 | 3161 | ||
2820 | /* The NVIDIA binary driver doesn't appear to actually do | 3162 | /* The NVIDIA binary driver doesn't appear to actually do |
2821 | * any of this, my VBIOS does however. | 3163 | * any of this, my VBIOS does however. |
@@ -2872,10 +3214,7 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, | |||
2872 | uint8_t index; | 3214 | uint8_t index; |
2873 | int i; | 3215 | int i; |
2874 | 3216 | ||
2875 | 3217 | /* critical! to know the length of the opcode */; | |
2876 | if (!iexec->execute) | ||
2877 | return len; | ||
2878 | |||
2879 | if (!blocklen) { | 3218 | if (!blocklen) { |
2880 | NV_ERROR(bios->dev, | 3219 | NV_ERROR(bios->dev, |
2881 | "0x%04X: Zero block length - has the M table " | 3220 | "0x%04X: Zero block length - has the M table " |
@@ -2883,6 +3222,9 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, | |||
2883 | return -EINVAL; | 3222 | return -EINVAL; |
2884 | } | 3223 | } |
2885 | 3224 | ||
3225 | if (!iexec->execute) | ||
3226 | return len; | ||
3227 | |||
2886 | strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; | 3228 | strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; |
2887 | index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg]; | 3229 | index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg]; |
2888 | 3230 | ||
@@ -3064,14 +3406,14 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
3064 | 3406 | ||
3065 | if (!bios->display.output) { | 3407 | if (!bios->display.output) { |
3066 | NV_ERROR(dev, "INIT_AUXCH: no active output\n"); | 3408 | NV_ERROR(dev, "INIT_AUXCH: no active output\n"); |
3067 | return -EINVAL; | 3409 | return len; |
3068 | } | 3410 | } |
3069 | 3411 | ||
3070 | auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); | 3412 | auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); |
3071 | if (!auxch) { | 3413 | if (!auxch) { |
3072 | NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n", | 3414 | NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n", |
3073 | bios->display.output->i2c_index); | 3415 | bios->display.output->i2c_index); |
3074 | return -ENODEV; | 3416 | return len; |
3075 | } | 3417 | } |
3076 | 3418 | ||
3077 | if (!iexec->execute) | 3419 | if (!iexec->execute) |
@@ -3084,7 +3426,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
3084 | ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1); | 3426 | ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1); |
3085 | if (ret) { | 3427 | if (ret) { |
3086 | NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret); | 3428 | NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret); |
3087 | return ret; | 3429 | return len; |
3088 | } | 3430 | } |
3089 | 3431 | ||
3090 | data &= bios->data[offset + 0]; | 3432 | data &= bios->data[offset + 0]; |
@@ -3093,7 +3435,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
3093 | ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1); | 3435 | ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1); |
3094 | if (ret) { | 3436 | if (ret) { |
3095 | NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret); | 3437 | NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret); |
3096 | return ret; | 3438 | return len; |
3097 | } | 3439 | } |
3098 | } | 3440 | } |
3099 | 3441 | ||
@@ -3123,14 +3465,14 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
3123 | 3465 | ||
3124 | if (!bios->display.output) { | 3466 | if (!bios->display.output) { |
3125 | NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n"); | 3467 | NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n"); |
3126 | return -EINVAL; | 3468 | return len; |
3127 | } | 3469 | } |
3128 | 3470 | ||
3129 | auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); | 3471 | auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); |
3130 | if (!auxch) { | 3472 | if (!auxch) { |
3131 | NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n", | 3473 | NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n", |
3132 | bios->display.output->i2c_index); | 3474 | bios->display.output->i2c_index); |
3133 | return -ENODEV; | 3475 | return len; |
3134 | } | 3476 | } |
3135 | 3477 | ||
3136 | if (!iexec->execute) | 3478 | if (!iexec->execute) |
@@ -3141,7 +3483,7 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
3141 | ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1); | 3483 | ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1); |
3142 | if (ret) { | 3484 | if (ret) { |
3143 | NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret); | 3485 | NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret); |
3144 | return ret; | 3486 | return len; |
3145 | } | 3487 | } |
3146 | } | 3488 | } |
3147 | 3489 | ||
@@ -5151,10 +5493,14 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi | |||
5151 | bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset]; | 5493 | bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset]; |
5152 | bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1]; | 5494 | bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1]; |
5153 | bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2]; | 5495 | bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2]; |
5154 | bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4]; | 5496 | if (bios->data[legacy_i2c_offset + 4]) |
5155 | bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5]; | 5497 | bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4]; |
5156 | bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6]; | 5498 | if (bios->data[legacy_i2c_offset + 5]) |
5157 | bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7]; | 5499 | bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5]; |
5500 | if (bios->data[legacy_i2c_offset + 6]) | ||
5501 | bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6]; | ||
5502 | if (bios->data[legacy_i2c_offset + 7]) | ||
5503 | bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7]; | ||
5158 | 5504 | ||
5159 | if (bmplength > 74) { | 5505 | if (bmplength > 74) { |
5160 | bios->fmaxvco = ROM32(bmp[67]); | 5506 | bios->fmaxvco = ROM32(bmp[67]); |
@@ -5589,9 +5935,12 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, | |||
5589 | if (conf & 0x4 || conf & 0x8) | 5935 | if (conf & 0x4 || conf & 0x8) |
5590 | entry->lvdsconf.use_power_scripts = true; | 5936 | entry->lvdsconf.use_power_scripts = true; |
5591 | } else { | 5937 | } else { |
5592 | mask = ~0x5; | 5938 | mask = ~0x7; |
5939 | if (conf & 0x2) | ||
5940 | entry->lvdsconf.use_acpi_for_edid = true; | ||
5593 | if (conf & 0x4) | 5941 | if (conf & 0x4) |
5594 | entry->lvdsconf.use_power_scripts = true; | 5942 | entry->lvdsconf.use_power_scripts = true; |
5943 | entry->lvdsconf.sor.link = (conf & 0x00000030) >> 4; | ||
5595 | } | 5944 | } |
5596 | if (conf & mask) { | 5945 | if (conf & mask) { |
5597 | /* | 5946 | /* |
@@ -5706,13 +6055,6 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, | |||
5706 | case OUTPUT_TV: | 6055 | case OUTPUT_TV: |
5707 | entry->tvconf.has_component_output = false; | 6056 | entry->tvconf.has_component_output = false; |
5708 | break; | 6057 | break; |
5709 | case OUTPUT_TMDS: | ||
5710 | /* | ||
5711 | * Invent a DVI-A output, by copying the fields of the DVI-D | ||
5712 | * output; reported to work by math_b on an NV20(!). | ||
5713 | */ | ||
5714 | fabricate_vga_output(dcb, entry->i2c_index, entry->heads); | ||
5715 | break; | ||
5716 | case OUTPUT_LVDS: | 6058 | case OUTPUT_LVDS: |
5717 | if ((conn & 0x00003f00) != 0x10) | 6059 | if ((conn & 0x00003f00) != 0x10) |
5718 | entry->lvdsconf.use_straps_for_mode = true; | 6060 | entry->lvdsconf.use_straps_for_mode = true; |
@@ -5793,6 +6135,31 @@ void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb) | |||
5793 | dcb->entries = newentries; | 6135 | dcb->entries = newentries; |
5794 | } | 6136 | } |
5795 | 6137 | ||
6138 | static bool | ||
6139 | apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) | ||
6140 | { | ||
6141 | /* Dell Precision M6300 | ||
6142 | * DCB entry 2: 02025312 00000010 | ||
6143 | * DCB entry 3: 02026312 00000020 | ||
6144 | * | ||
6145 | * Identical, except apparently a different connector on a | ||
6146 | * different SOR link. Not a clue how we're supposed to know | ||
6147 | * which one is in use if it even shares an i2c line... | ||
6148 | * | ||
6149 | * Ignore the connector on the second SOR link to prevent | ||
6150 | * nasty problems until this is sorted (assuming it's not a | ||
6151 | * VBIOS bug). | ||
6152 | */ | ||
6153 | if ((dev->pdev->device == 0x040d) && | ||
6154 | (dev->pdev->subsystem_vendor == 0x1028) && | ||
6155 | (dev->pdev->subsystem_device == 0x019b)) { | ||
6156 | if (*conn == 0x02026312 && *conf == 0x00000020) | ||
6157 | return false; | ||
6158 | } | ||
6159 | |||
6160 | return true; | ||
6161 | } | ||
6162 | |||
5796 | static int | 6163 | static int |
5797 | parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) | 6164 | parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) |
5798 | { | 6165 | { |
@@ -5926,6 +6293,9 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) | |||
5926 | if ((connection & 0x0000000f) == 0x0000000f) | 6293 | if ((connection & 0x0000000f) == 0x0000000f) |
5927 | continue; | 6294 | continue; |
5928 | 6295 | ||
6296 | if (!apply_dcb_encoder_quirks(dev, i, &connection, &config)) | ||
6297 | continue; | ||
6298 | |||
5929 | NV_TRACEWARN(dev, "Raw DCB entry %d: %08x %08x\n", | 6299 | NV_TRACEWARN(dev, "Raw DCB entry %d: %08x %08x\n", |
5930 | dcb->entries, connection, config); | 6300 | dcb->entries, connection, config); |
5931 | 6301 | ||
@@ -6181,9 +6551,8 @@ nouveau_run_vbios_init(struct drm_device *dev) | |||
6181 | struct nvbios *bios = &dev_priv->vbios; | 6551 | struct nvbios *bios = &dev_priv->vbios; |
6182 | int i, ret = 0; | 6552 | int i, ret = 0; |
6183 | 6553 | ||
6184 | NVLockVgaCrtcs(dev, false); | 6554 | /* Reset the BIOS head to 0. */ |
6185 | if (nv_two_heads(dev)) | 6555 | bios->state.crtchead = 0; |
6186 | NVSetOwner(dev, bios->state.crtchead); | ||
6187 | 6556 | ||
6188 | if (bios->major_version < 5) /* BMP only */ | 6557 | if (bios->major_version < 5) /* BMP only */ |
6189 | load_nv17_hw_sequencer_ucode(dev, bios); | 6558 | load_nv17_hw_sequencer_ucode(dev, bios); |
@@ -6216,8 +6585,6 @@ nouveau_run_vbios_init(struct drm_device *dev) | |||
6216 | } | 6585 | } |
6217 | } | 6586 | } |
6218 | 6587 | ||
6219 | NVLockVgaCrtcs(dev, true); | ||
6220 | |||
6221 | return ret; | 6588 | return ret; |
6222 | } | 6589 | } |
6223 | 6590 | ||
@@ -6238,7 +6605,6 @@ static bool | |||
6238 | nouveau_bios_posted(struct drm_device *dev) | 6605 | nouveau_bios_posted(struct drm_device *dev) |
6239 | { | 6606 | { |
6240 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 6607 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
6241 | bool was_locked; | ||
6242 | unsigned htotal; | 6608 | unsigned htotal; |
6243 | 6609 | ||
6244 | if (dev_priv->chipset >= NV_50) { | 6610 | if (dev_priv->chipset >= NV_50) { |
@@ -6248,13 +6614,12 @@ nouveau_bios_posted(struct drm_device *dev) | |||
6248 | return true; | 6614 | return true; |
6249 | } | 6615 | } |
6250 | 6616 | ||
6251 | was_locked = NVLockVgaCrtcs(dev, false); | ||
6252 | htotal = NVReadVgaCrtc(dev, 0, 0x06); | 6617 | htotal = NVReadVgaCrtc(dev, 0, 0x06); |
6253 | htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8; | 6618 | htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8; |
6254 | htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4; | 6619 | htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4; |
6255 | htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10; | 6620 | htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10; |
6256 | htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11; | 6621 | htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11; |
6257 | NVLockVgaCrtcs(dev, was_locked); | 6622 | |
6258 | return (htotal != 0); | 6623 | return (htotal != 0); |
6259 | } | 6624 | } |
6260 | 6625 | ||
@@ -6263,8 +6628,6 @@ nouveau_bios_init(struct drm_device *dev) | |||
6263 | { | 6628 | { |
6264 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 6629 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
6265 | struct nvbios *bios = &dev_priv->vbios; | 6630 | struct nvbios *bios = &dev_priv->vbios; |
6266 | uint32_t saved_nv_pextdev_boot_0; | ||
6267 | bool was_locked; | ||
6268 | int ret; | 6631 | int ret; |
6269 | 6632 | ||
6270 | if (!NVInitVBIOS(dev)) | 6633 | if (!NVInitVBIOS(dev)) |
@@ -6284,40 +6647,27 @@ nouveau_bios_init(struct drm_device *dev) | |||
6284 | if (!bios->major_version) /* we don't run version 0 bios */ | 6647 | if (!bios->major_version) /* we don't run version 0 bios */ |
6285 | return 0; | 6648 | return 0; |
6286 | 6649 | ||
6287 | /* these will need remembering across a suspend */ | ||
6288 | saved_nv_pextdev_boot_0 = bios_rd32(bios, NV_PEXTDEV_BOOT_0); | ||
6289 | bios->state.saved_nv_pfb_cfg0 = bios_rd32(bios, NV_PFB_CFG0); | ||
6290 | |||
6291 | /* init script execution disabled */ | 6650 | /* init script execution disabled */ |
6292 | bios->execute = false; | 6651 | bios->execute = false; |
6293 | 6652 | ||
6294 | /* ... unless card isn't POSTed already */ | 6653 | /* ... unless card isn't POSTed already */ |
6295 | if (!nouveau_bios_posted(dev)) { | 6654 | if (!nouveau_bios_posted(dev)) { |
6296 | NV_INFO(dev, "Adaptor not initialised\n"); | 6655 | NV_INFO(dev, "Adaptor not initialised, " |
6297 | if (dev_priv->card_type < NV_40) { | 6656 | "running VBIOS init tables.\n"); |
6298 | NV_ERROR(dev, "Unable to POST this chipset\n"); | ||
6299 | return -ENODEV; | ||
6300 | } | ||
6301 | |||
6302 | NV_INFO(dev, "Running VBIOS init tables\n"); | ||
6303 | bios->execute = true; | 6657 | bios->execute = true; |
6304 | } | 6658 | } |
6305 | 6659 | ||
6306 | bios_wr32(bios, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0); | ||
6307 | |||
6308 | ret = nouveau_run_vbios_init(dev); | 6660 | ret = nouveau_run_vbios_init(dev); |
6309 | if (ret) | 6661 | if (ret) |
6310 | return ret; | 6662 | return ret; |
6311 | 6663 | ||
6312 | /* feature_byte on BMP is poor, but init always sets CR4B */ | 6664 | /* feature_byte on BMP is poor, but init always sets CR4B */ |
6313 | was_locked = NVLockVgaCrtcs(dev, false); | ||
6314 | if (bios->major_version < 5) | 6665 | if (bios->major_version < 5) |
6315 | bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40; | 6666 | bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40; |
6316 | 6667 | ||
6317 | /* all BIT systems need p_f_m_t for digital_min_front_porch */ | 6668 | /* all BIT systems need p_f_m_t for digital_min_front_porch */ |
6318 | if (bios->is_mobile || bios->major_version >= 5) | 6669 | if (bios->is_mobile || bios->major_version >= 5) |
6319 | ret = parse_fp_mode_table(dev, bios); | 6670 | ret = parse_fp_mode_table(dev, bios); |
6320 | NVLockVgaCrtcs(dev, was_locked); | ||
6321 | 6671 | ||
6322 | /* allow subsequent scripts to execute */ | 6672 | /* allow subsequent scripts to execute */ |
6323 | bios->execute = true; | 6673 | bios->execute = true; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index adf4ec2d06c0..024458a8d060 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h | |||
@@ -81,6 +81,7 @@ struct dcb_connector_table_entry { | |||
81 | enum dcb_connector_type type; | 81 | enum dcb_connector_type type; |
82 | uint8_t index2; | 82 | uint8_t index2; |
83 | uint8_t gpio_tag; | 83 | uint8_t gpio_tag; |
84 | void *drm; | ||
84 | }; | 85 | }; |
85 | 86 | ||
86 | struct dcb_connector_table { | 87 | struct dcb_connector_table { |
@@ -117,6 +118,7 @@ struct dcb_entry { | |||
117 | struct { | 118 | struct { |
118 | struct sor_conf sor; | 119 | struct sor_conf sor; |
119 | bool use_straps_for_mode; | 120 | bool use_straps_for_mode; |
121 | bool use_acpi_for_edid; | ||
120 | bool use_power_scripts; | 122 | bool use_power_scripts; |
121 | } lvdsconf; | 123 | } lvdsconf; |
122 | struct { | 124 | struct { |
@@ -249,8 +251,6 @@ struct nvbios { | |||
249 | 251 | ||
250 | struct { | 252 | struct { |
251 | int crtchead; | 253 | int crtchead; |
252 | /* these need remembering across suspend */ | ||
253 | uint32_t saved_nv_pfb_cfg0; | ||
254 | } state; | 254 | } state; |
255 | 255 | ||
256 | struct { | 256 | struct { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 6f3c19522377..3ca8343c15df 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -461,9 +461,9 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, | |||
461 | return ret; | 461 | return ret; |
462 | 462 | ||
463 | ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL, | 463 | ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL, |
464 | evict, no_wait_reserve, no_wait_gpu, new_mem); | 464 | evict || (nvbo->channel && |
465 | if (nvbo->channel && nvbo->channel != chan) | 465 | nvbo->channel != chan), |
466 | ret = nouveau_fence_wait(fence, NULL, false, false); | 466 | no_wait_reserve, no_wait_gpu, new_mem); |
467 | nouveau_fence_unref((void *)&fence); | 467 | nouveau_fence_unref((void *)&fence); |
468 | return ret; | 468 | return ret; |
469 | } | 469 | } |
@@ -711,8 +711,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, | |||
711 | return ret; | 711 | return ret; |
712 | 712 | ||
713 | /* Software copy if the card isn't up and running yet. */ | 713 | /* Software copy if the card isn't up and running yet. */ |
714 | if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE || | 714 | if (!dev_priv->channel) { |
715 | !dev_priv->channel) { | ||
716 | ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); | 715 | ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); |
717 | goto out; | 716 | goto out; |
718 | } | 717 | } |
@@ -783,7 +782,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) | |||
783 | break; | 782 | break; |
784 | case TTM_PL_VRAM: | 783 | case TTM_PL_VRAM: |
785 | mem->bus.offset = mem->mm_node->start << PAGE_SHIFT; | 784 | mem->bus.offset = mem->mm_node->start << PAGE_SHIFT; |
786 | mem->bus.base = drm_get_resource_start(dev, 1); | 785 | mem->bus.base = pci_resource_start(dev->pdev, 1); |
787 | mem->bus.is_iomem = true; | 786 | mem->bus.is_iomem = true; |
788 | break; | 787 | break; |
789 | default: | 788 | default: |
diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/nouveau_calc.c index 88f9bc0941eb..ca85da784846 100644 --- a/drivers/gpu/drm/nouveau/nouveau_calc.c +++ b/drivers/gpu/drm/nouveau/nouveau_calc.c | |||
@@ -200,7 +200,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp, | |||
200 | struct nv_sim_state sim_data; | 200 | struct nv_sim_state sim_data; |
201 | int MClk = nouveau_hw_get_clock(dev, MPLL); | 201 | int MClk = nouveau_hw_get_clock(dev, MPLL); |
202 | int NVClk = nouveau_hw_get_clock(dev, NVPLL); | 202 | int NVClk = nouveau_hw_get_clock(dev, NVPLL); |
203 | uint32_t cfg1 = nvReadFB(dev, NV_PFB_CFG1); | 203 | uint32_t cfg1 = nvReadFB(dev, NV04_PFB_CFG1); |
204 | 204 | ||
205 | sim_data.pclk_khz = VClk; | 205 | sim_data.pclk_khz = VClk; |
206 | sim_data.mclk_khz = MClk; | 206 | sim_data.mclk_khz = MClk; |
@@ -218,7 +218,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp, | |||
218 | sim_data.mem_latency = 3; | 218 | sim_data.mem_latency = 3; |
219 | sim_data.mem_page_miss = 10; | 219 | sim_data.mem_page_miss = 10; |
220 | } else { | 220 | } else { |
221 | sim_data.memory_type = nvReadFB(dev, NV_PFB_CFG0) & 0x1; | 221 | sim_data.memory_type = nvReadFB(dev, NV04_PFB_CFG0) & 0x1; |
222 | sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64; | 222 | sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64; |
223 | sim_data.mem_latency = cfg1 & 0xf; | 223 | sim_data.mem_latency = cfg1 & 0xf; |
224 | sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1); | 224 | sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 1fc57ef58295..90fdcda332be 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -62,7 +62,8 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) | |||
62 | * VRAM. | 62 | * VRAM. |
63 | */ | 63 | */ |
64 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, | 64 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, |
65 | drm_get_resource_start(dev, 1), | 65 | pci_resource_start(dev->pdev, |
66 | 1), | ||
66 | dev_priv->fb_available_size, | 67 | dev_priv->fb_available_size, |
67 | NV_DMA_ACCESS_RO, | 68 | NV_DMA_ACCESS_RO, |
68 | NV_DMA_TARGET_PCI, &pushbuf); | 69 | NV_DMA_TARGET_PCI, &pushbuf); |
@@ -257,9 +258,7 @@ nouveau_channel_free(struct nouveau_channel *chan) | |||
257 | nouveau_debugfs_channel_fini(chan); | 258 | nouveau_debugfs_channel_fini(chan); |
258 | 259 | ||
259 | /* Give outstanding push buffers a chance to complete */ | 260 | /* Give outstanding push buffers a chance to complete */ |
260 | spin_lock_irqsave(&chan->fence.lock, flags); | ||
261 | nouveau_fence_update(chan); | 261 | nouveau_fence_update(chan); |
262 | spin_unlock_irqrestore(&chan->fence.lock, flags); | ||
263 | if (chan->fence.sequence != chan->fence.sequence_ack) { | 262 | if (chan->fence.sequence != chan->fence.sequence_ack) { |
264 | struct nouveau_fence *fence = NULL; | 263 | struct nouveau_fence *fence = NULL; |
265 | 264 | ||
@@ -368,8 +367,6 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, | |||
368 | struct nouveau_channel *chan; | 367 | struct nouveau_channel *chan; |
369 | int ret; | 368 | int ret; |
370 | 369 | ||
371 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
372 | |||
373 | if (dev_priv->engine.graph.accel_blocked) | 370 | if (dev_priv->engine.graph.accel_blocked) |
374 | return -ENODEV; | 371 | return -ENODEV; |
375 | 372 | ||
@@ -418,7 +415,6 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, | |||
418 | struct drm_nouveau_channel_free *cfree = data; | 415 | struct drm_nouveau_channel_free *cfree = data; |
419 | struct nouveau_channel *chan; | 416 | struct nouveau_channel *chan; |
420 | 417 | ||
421 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
422 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan); | 418 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan); |
423 | 419 | ||
424 | nouveau_channel_free(chan); | 420 | nouveau_channel_free(chan); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 149ed224c3cb..734e92635e83 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -102,63 +102,15 @@ nouveau_connector_destroy(struct drm_connector *drm_connector) | |||
102 | kfree(drm_connector); | 102 | kfree(drm_connector); |
103 | } | 103 | } |
104 | 104 | ||
105 | static void | ||
106 | nouveau_connector_ddc_prepare(struct drm_connector *connector, int *flags) | ||
107 | { | ||
108 | struct drm_nouveau_private *dev_priv = connector->dev->dev_private; | ||
109 | |||
110 | if (dev_priv->card_type >= NV_50) | ||
111 | return; | ||
112 | |||
113 | *flags = 0; | ||
114 | if (NVLockVgaCrtcs(dev_priv->dev, false)) | ||
115 | *flags |= 1; | ||
116 | if (nv_heads_tied(dev_priv->dev)) | ||
117 | *flags |= 2; | ||
118 | |||
119 | if (*flags & 2) | ||
120 | NVSetOwner(dev_priv->dev, 0); /* necessary? */ | ||
121 | } | ||
122 | |||
123 | static void | ||
124 | nouveau_connector_ddc_finish(struct drm_connector *connector, int flags) | ||
125 | { | ||
126 | struct drm_nouveau_private *dev_priv = connector->dev->dev_private; | ||
127 | |||
128 | if (dev_priv->card_type >= NV_50) | ||
129 | return; | ||
130 | |||
131 | if (flags & 2) | ||
132 | NVSetOwner(dev_priv->dev, 4); | ||
133 | if (flags & 1) | ||
134 | NVLockVgaCrtcs(dev_priv->dev, true); | ||
135 | } | ||
136 | |||
137 | static struct nouveau_i2c_chan * | 105 | static struct nouveau_i2c_chan * |
138 | nouveau_connector_ddc_detect(struct drm_connector *connector, | 106 | nouveau_connector_ddc_detect(struct drm_connector *connector, |
139 | struct nouveau_encoder **pnv_encoder) | 107 | struct nouveau_encoder **pnv_encoder) |
140 | { | 108 | { |
141 | struct drm_device *dev = connector->dev; | 109 | struct drm_device *dev = connector->dev; |
142 | uint8_t out_buf[] = { 0x0, 0x0}, buf[2]; | 110 | int i; |
143 | int ret, flags, i; | ||
144 | |||
145 | struct i2c_msg msgs[] = { | ||
146 | { | ||
147 | .addr = 0x50, | ||
148 | .flags = 0, | ||
149 | .len = 1, | ||
150 | .buf = out_buf, | ||
151 | }, | ||
152 | { | ||
153 | .addr = 0x50, | ||
154 | .flags = I2C_M_RD, | ||
155 | .len = 1, | ||
156 | .buf = buf, | ||
157 | } | ||
158 | }; | ||
159 | 111 | ||
160 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | 112 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
161 | struct nouveau_i2c_chan *i2c = NULL; | 113 | struct nouveau_i2c_chan *i2c; |
162 | struct nouveau_encoder *nv_encoder; | 114 | struct nouveau_encoder *nv_encoder; |
163 | struct drm_mode_object *obj; | 115 | struct drm_mode_object *obj; |
164 | int id; | 116 | int id; |
@@ -171,17 +123,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, | |||
171 | if (!obj) | 123 | if (!obj) |
172 | continue; | 124 | continue; |
173 | nv_encoder = nouveau_encoder(obj_to_encoder(obj)); | 125 | nv_encoder = nouveau_encoder(obj_to_encoder(obj)); |
126 | i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | ||
174 | 127 | ||
175 | if (nv_encoder->dcb->i2c_index < 0xf) | 128 | if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) { |
176 | i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | ||
177 | if (!i2c) | ||
178 | continue; | ||
179 | |||
180 | nouveau_connector_ddc_prepare(connector, &flags); | ||
181 | ret = i2c_transfer(&i2c->adapter, msgs, 2); | ||
182 | nouveau_connector_ddc_finish(connector, flags); | ||
183 | |||
184 | if (ret == 2) { | ||
185 | *pnv_encoder = nv_encoder; | 129 | *pnv_encoder = nv_encoder; |
186 | return i2c; | 130 | return i2c; |
187 | } | 131 | } |
@@ -234,21 +178,7 @@ nouveau_connector_detect(struct drm_connector *connector) | |||
234 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | 178 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
235 | struct nouveau_encoder *nv_encoder = NULL; | 179 | struct nouveau_encoder *nv_encoder = NULL; |
236 | struct nouveau_i2c_chan *i2c; | 180 | struct nouveau_i2c_chan *i2c; |
237 | int type, flags; | 181 | int type; |
238 | |||
239 | if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS) | ||
240 | nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); | ||
241 | if (nv_encoder && nv_connector->native_mode) { | ||
242 | unsigned status = connector_status_connected; | ||
243 | |||
244 | #if defined(CONFIG_ACPI_BUTTON) || \ | ||
245 | (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE)) | ||
246 | if (!nouveau_ignorelid && !acpi_lid_open()) | ||
247 | status = connector_status_unknown; | ||
248 | #endif | ||
249 | nouveau_connector_set_encoder(connector, nv_encoder); | ||
250 | return status; | ||
251 | } | ||
252 | 182 | ||
253 | /* Cleanup the previous EDID block. */ | 183 | /* Cleanup the previous EDID block. */ |
254 | if (nv_connector->edid) { | 184 | if (nv_connector->edid) { |
@@ -259,9 +189,7 @@ nouveau_connector_detect(struct drm_connector *connector) | |||
259 | 189 | ||
260 | i2c = nouveau_connector_ddc_detect(connector, &nv_encoder); | 190 | i2c = nouveau_connector_ddc_detect(connector, &nv_encoder); |
261 | if (i2c) { | 191 | if (i2c) { |
262 | nouveau_connector_ddc_prepare(connector, &flags); | ||
263 | nv_connector->edid = drm_get_edid(connector, &i2c->adapter); | 192 | nv_connector->edid = drm_get_edid(connector, &i2c->adapter); |
264 | nouveau_connector_ddc_finish(connector, flags); | ||
265 | drm_mode_connector_update_edid_property(connector, | 193 | drm_mode_connector_update_edid_property(connector, |
266 | nv_connector->edid); | 194 | nv_connector->edid); |
267 | if (!nv_connector->edid) { | 195 | if (!nv_connector->edid) { |
@@ -321,6 +249,85 @@ detect_analog: | |||
321 | return connector_status_disconnected; | 249 | return connector_status_disconnected; |
322 | } | 250 | } |
323 | 251 | ||
252 | static enum drm_connector_status | ||
253 | nouveau_connector_detect_lvds(struct drm_connector *connector) | ||
254 | { | ||
255 | struct drm_device *dev = connector->dev; | ||
256 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
257 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | ||
258 | struct nouveau_encoder *nv_encoder = NULL; | ||
259 | enum drm_connector_status status = connector_status_disconnected; | ||
260 | |||
261 | /* Cleanup the previous EDID block. */ | ||
262 | if (nv_connector->edid) { | ||
263 | drm_mode_connector_update_edid_property(connector, NULL); | ||
264 | kfree(nv_connector->edid); | ||
265 | nv_connector->edid = NULL; | ||
266 | } | ||
267 | |||
268 | nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); | ||
269 | if (!nv_encoder) | ||
270 | return connector_status_disconnected; | ||
271 | |||
272 | /* Try retrieving EDID via DDC */ | ||
273 | if (!dev_priv->vbios.fp_no_ddc) { | ||
274 | status = nouveau_connector_detect(connector); | ||
275 | if (status == connector_status_connected) | ||
276 | goto out; | ||
277 | } | ||
278 | |||
279 | /* On some laptops (Sony, i'm looking at you) there appears to | ||
280 | * be no direct way of accessing the panel's EDID. The only | ||
281 | * option available to us appears to be to ask ACPI for help.. | ||
282 | * | ||
283 | * It's important this check's before trying straps, one of the | ||
284 | * said manufacturer's laptops are configured in such a way | ||
285 | * the nouveau decides an entry in the VBIOS FP mode table is | ||
286 | * valid - it's not (rh#613284) | ||
287 | */ | ||
288 | if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { | ||
289 | if (!nouveau_acpi_edid(dev, connector)) { | ||
290 | status = connector_status_connected; | ||
291 | goto out; | ||
292 | } | ||
293 | } | ||
294 | |||
295 | /* If no EDID found above, and the VBIOS indicates a hardcoded | ||
296 | * modeline is avalilable for the panel, set it as the panel's | ||
297 | * native mode and exit. | ||
298 | */ | ||
299 | if (nouveau_bios_fp_mode(dev, NULL) && (dev_priv->vbios.fp_no_ddc || | ||
300 | nv_encoder->dcb->lvdsconf.use_straps_for_mode)) { | ||
301 | status = connector_status_connected; | ||
302 | goto out; | ||
303 | } | ||
304 | |||
305 | /* Still nothing, some VBIOS images have a hardcoded EDID block | ||
306 | * stored for the panel stored in them. | ||
307 | */ | ||
308 | if (!dev_priv->vbios.fp_no_ddc) { | ||
309 | struct edid *edid = | ||
310 | (struct edid *)nouveau_bios_embedded_edid(dev); | ||
311 | if (edid) { | ||
312 | nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL); | ||
313 | *(nv_connector->edid) = *edid; | ||
314 | status = connector_status_connected; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | out: | ||
319 | #if defined(CONFIG_ACPI_BUTTON) || \ | ||
320 | (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE)) | ||
321 | if (status == connector_status_connected && | ||
322 | !nouveau_ignorelid && !acpi_lid_open()) | ||
323 | status = connector_status_unknown; | ||
324 | #endif | ||
325 | |||
326 | drm_mode_connector_update_edid_property(connector, nv_connector->edid); | ||
327 | nouveau_connector_set_encoder(connector, nv_encoder); | ||
328 | return status; | ||
329 | } | ||
330 | |||
324 | static void | 331 | static void |
325 | nouveau_connector_force(struct drm_connector *connector) | 332 | nouveau_connector_force(struct drm_connector *connector) |
326 | { | 333 | { |
@@ -441,7 +448,8 @@ nouveau_connector_native_mode(struct drm_connector *connector) | |||
441 | int high_w = 0, high_h = 0, high_v = 0; | 448 | int high_w = 0, high_h = 0, high_v = 0; |
442 | 449 | ||
443 | list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { | 450 | list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { |
444 | if (helper->mode_valid(connector, mode) != MODE_OK) | 451 | if (helper->mode_valid(connector, mode) != MODE_OK || |
452 | (mode->flags & DRM_MODE_FLAG_INTERLACE)) | ||
445 | continue; | 453 | continue; |
446 | 454 | ||
447 | /* Use preferred mode if there is one.. */ | 455 | /* Use preferred mode if there is one.. */ |
@@ -534,21 +542,27 @@ static int | |||
534 | nouveau_connector_get_modes(struct drm_connector *connector) | 542 | nouveau_connector_get_modes(struct drm_connector *connector) |
535 | { | 543 | { |
536 | struct drm_device *dev = connector->dev; | 544 | struct drm_device *dev = connector->dev; |
545 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
537 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | 546 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
538 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; | 547 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; |
539 | int ret = 0; | 548 | int ret = 0; |
540 | 549 | ||
541 | /* If we're not LVDS, destroy the previous native mode, the attached | 550 | /* destroy the native mode, the attached monitor could have changed. |
542 | * monitor could have changed. | ||
543 | */ | 551 | */ |
544 | if (nv_connector->dcb->type != DCB_CONNECTOR_LVDS && | 552 | if (nv_connector->native_mode) { |
545 | nv_connector->native_mode) { | ||
546 | drm_mode_destroy(dev, nv_connector->native_mode); | 553 | drm_mode_destroy(dev, nv_connector->native_mode); |
547 | nv_connector->native_mode = NULL; | 554 | nv_connector->native_mode = NULL; |
548 | } | 555 | } |
549 | 556 | ||
550 | if (nv_connector->edid) | 557 | if (nv_connector->edid) |
551 | ret = drm_add_edid_modes(connector, nv_connector->edid); | 558 | ret = drm_add_edid_modes(connector, nv_connector->edid); |
559 | else | ||
560 | if (nv_encoder->dcb->type == OUTPUT_LVDS && | ||
561 | (nv_encoder->dcb->lvdsconf.use_straps_for_mode || | ||
562 | dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { | ||
563 | nv_connector->native_mode = drm_mode_create(dev); | ||
564 | nouveau_bios_fp_mode(dev, nv_connector->native_mode); | ||
565 | } | ||
552 | 566 | ||
553 | /* Find the native mode if this is a digital panel, if we didn't | 567 | /* Find the native mode if this is a digital panel, if we didn't |
554 | * find any modes through DDC previously add the native mode to | 568 | * find any modes through DDC previously add the native mode to |
@@ -569,7 +583,8 @@ nouveau_connector_get_modes(struct drm_connector *connector) | |||
569 | ret = get_slave_funcs(nv_encoder)-> | 583 | ret = get_slave_funcs(nv_encoder)-> |
570 | get_modes(to_drm_encoder(nv_encoder), connector); | 584 | get_modes(to_drm_encoder(nv_encoder), connector); |
571 | 585 | ||
572 | if (nv_encoder->dcb->type == OUTPUT_LVDS) | 586 | if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS || |
587 | nv_connector->dcb->type == DCB_CONNECTOR_eDP) | ||
573 | ret += nouveau_connector_scaler_modes_add(connector); | 588 | ret += nouveau_connector_scaler_modes_add(connector); |
574 | 589 | ||
575 | return ret; | 590 | return ret; |
@@ -643,6 +658,44 @@ nouveau_connector_best_encoder(struct drm_connector *connector) | |||
643 | return NULL; | 658 | return NULL; |
644 | } | 659 | } |
645 | 660 | ||
661 | void | ||
662 | nouveau_connector_set_polling(struct drm_connector *connector) | ||
663 | { | ||
664 | struct drm_device *dev = connector->dev; | ||
665 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
666 | struct drm_crtc *crtc; | ||
667 | bool spare_crtc = false; | ||
668 | |||
669 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | ||
670 | spare_crtc |= !crtc->enabled; | ||
671 | |||
672 | connector->polled = 0; | ||
673 | |||
674 | switch (connector->connector_type) { | ||
675 | case DRM_MODE_CONNECTOR_VGA: | ||
676 | case DRM_MODE_CONNECTOR_TV: | ||
677 | if (dev_priv->card_type >= NV_50 || | ||
678 | (nv_gf4_disp_arch(dev) && spare_crtc)) | ||
679 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
680 | break; | ||
681 | |||
682 | case DRM_MODE_CONNECTOR_DVII: | ||
683 | case DRM_MODE_CONNECTOR_DVID: | ||
684 | case DRM_MODE_CONNECTOR_HDMIA: | ||
685 | case DRM_MODE_CONNECTOR_DisplayPort: | ||
686 | case DRM_MODE_CONNECTOR_eDP: | ||
687 | if (dev_priv->card_type >= NV_50) | ||
688 | connector->polled = DRM_CONNECTOR_POLL_HPD; | ||
689 | else if (connector->connector_type == DRM_MODE_CONNECTOR_DVID || | ||
690 | spare_crtc) | ||
691 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
692 | break; | ||
693 | |||
694 | default: | ||
695 | break; | ||
696 | } | ||
697 | } | ||
698 | |||
646 | static const struct drm_connector_helper_funcs | 699 | static const struct drm_connector_helper_funcs |
647 | nouveau_connector_helper_funcs = { | 700 | nouveau_connector_helper_funcs = { |
648 | .get_modes = nouveau_connector_get_modes, | 701 | .get_modes = nouveau_connector_get_modes, |
@@ -662,148 +715,74 @@ nouveau_connector_funcs = { | |||
662 | .force = nouveau_connector_force | 715 | .force = nouveau_connector_force |
663 | }; | 716 | }; |
664 | 717 | ||
665 | static int | 718 | static const struct drm_connector_funcs |
666 | nouveau_connector_create_lvds(struct drm_device *dev, | 719 | nouveau_connector_funcs_lvds = { |
667 | struct drm_connector *connector) | 720 | .dpms = drm_helper_connector_dpms, |
668 | { | 721 | .save = NULL, |
669 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | 722 | .restore = NULL, |
670 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 723 | .detect = nouveau_connector_detect_lvds, |
671 | struct nouveau_i2c_chan *i2c = NULL; | 724 | .destroy = nouveau_connector_destroy, |
672 | struct nouveau_encoder *nv_encoder; | 725 | .fill_modes = drm_helper_probe_single_connector_modes, |
673 | struct drm_display_mode native, *mode, *temp; | 726 | .set_property = nouveau_connector_set_property, |
674 | bool dummy, if_is_24bit = false; | 727 | .force = nouveau_connector_force |
675 | int ret, flags; | 728 | }; |
676 | |||
677 | nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); | ||
678 | if (!nv_encoder) | ||
679 | return -ENODEV; | ||
680 | |||
681 | ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &if_is_24bit); | ||
682 | if (ret) { | ||
683 | NV_ERROR(dev, "Error parsing LVDS table, disabling LVDS\n"); | ||
684 | return ret; | ||
685 | } | ||
686 | nv_connector->use_dithering = !if_is_24bit; | ||
687 | |||
688 | /* Firstly try getting EDID over DDC, if allowed and I2C channel | ||
689 | * is available. | ||
690 | */ | ||
691 | if (!dev_priv->vbios.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf) | ||
692 | i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | ||
693 | |||
694 | if (i2c) { | ||
695 | nouveau_connector_ddc_prepare(connector, &flags); | ||
696 | nv_connector->edid = drm_get_edid(connector, &i2c->adapter); | ||
697 | nouveau_connector_ddc_finish(connector, flags); | ||
698 | } | ||
699 | |||
700 | /* If no EDID found above, and the VBIOS indicates a hardcoded | ||
701 | * modeline is avalilable for the panel, set it as the panel's | ||
702 | * native mode and exit. | ||
703 | */ | ||
704 | if (!nv_connector->edid && nouveau_bios_fp_mode(dev, &native) && | ||
705 | (nv_encoder->dcb->lvdsconf.use_straps_for_mode || | ||
706 | dev_priv->vbios.fp_no_ddc)) { | ||
707 | nv_connector->native_mode = drm_mode_duplicate(dev, &native); | ||
708 | goto out; | ||
709 | } | ||
710 | |||
711 | /* Still nothing, some VBIOS images have a hardcoded EDID block | ||
712 | * stored for the panel stored in them. | ||
713 | */ | ||
714 | if (!nv_connector->edid && !nv_connector->native_mode && | ||
715 | !dev_priv->vbios.fp_no_ddc) { | ||
716 | struct edid *edid = | ||
717 | (struct edid *)nouveau_bios_embedded_edid(dev); | ||
718 | if (edid) { | ||
719 | nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL); | ||
720 | *(nv_connector->edid) = *edid; | ||
721 | } | ||
722 | } | ||
723 | |||
724 | if (!nv_connector->edid) | ||
725 | goto out; | ||
726 | |||
727 | /* We didn't find/use a panel mode from the VBIOS, so parse the EDID | ||
728 | * block and look for the preferred mode there. | ||
729 | */ | ||
730 | ret = drm_add_edid_modes(connector, nv_connector->edid); | ||
731 | if (ret == 0) | ||
732 | goto out; | ||
733 | nv_connector->detected_encoder = nv_encoder; | ||
734 | nv_connector->native_mode = nouveau_connector_native_mode(connector); | ||
735 | list_for_each_entry_safe(mode, temp, &connector->probed_modes, head) | ||
736 | drm_mode_remove(connector, mode); | ||
737 | |||
738 | out: | ||
739 | if (!nv_connector->native_mode) { | ||
740 | NV_ERROR(dev, "LVDS present in DCB table, but couldn't " | ||
741 | "determine its native mode. Disabling.\n"); | ||
742 | return -ENODEV; | ||
743 | } | ||
744 | |||
745 | drm_mode_connector_update_edid_property(connector, nv_connector->edid); | ||
746 | return 0; | ||
747 | } | ||
748 | 729 | ||
749 | int | 730 | struct drm_connector * |
750 | nouveau_connector_create(struct drm_device *dev, | 731 | nouveau_connector_create(struct drm_device *dev, int index) |
751 | struct dcb_connector_table_entry *dcb) | ||
752 | { | 732 | { |
733 | const struct drm_connector_funcs *funcs = &nouveau_connector_funcs; | ||
753 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 734 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
754 | struct nouveau_connector *nv_connector = NULL; | 735 | struct nouveau_connector *nv_connector = NULL; |
736 | struct dcb_connector_table_entry *dcb = NULL; | ||
755 | struct drm_connector *connector; | 737 | struct drm_connector *connector; |
756 | struct drm_encoder *encoder; | 738 | int type, ret = 0; |
757 | int ret, type; | ||
758 | 739 | ||
759 | NV_DEBUG_KMS(dev, "\n"); | 740 | NV_DEBUG_KMS(dev, "\n"); |
760 | 741 | ||
742 | if (index >= dev_priv->vbios.dcb.connector.entries) | ||
743 | return ERR_PTR(-EINVAL); | ||
744 | |||
745 | dcb = &dev_priv->vbios.dcb.connector.entry[index]; | ||
746 | if (dcb->drm) | ||
747 | return dcb->drm; | ||
748 | |||
761 | switch (dcb->type) { | 749 | switch (dcb->type) { |
762 | case DCB_CONNECTOR_NONE: | ||
763 | return 0; | ||
764 | case DCB_CONNECTOR_VGA: | 750 | case DCB_CONNECTOR_VGA: |
765 | NV_INFO(dev, "Detected a VGA connector\n"); | ||
766 | type = DRM_MODE_CONNECTOR_VGA; | 751 | type = DRM_MODE_CONNECTOR_VGA; |
767 | break; | 752 | break; |
768 | case DCB_CONNECTOR_TV_0: | 753 | case DCB_CONNECTOR_TV_0: |
769 | case DCB_CONNECTOR_TV_1: | 754 | case DCB_CONNECTOR_TV_1: |
770 | case DCB_CONNECTOR_TV_3: | 755 | case DCB_CONNECTOR_TV_3: |
771 | NV_INFO(dev, "Detected a TV connector\n"); | ||
772 | type = DRM_MODE_CONNECTOR_TV; | 756 | type = DRM_MODE_CONNECTOR_TV; |
773 | break; | 757 | break; |
774 | case DCB_CONNECTOR_DVI_I: | 758 | case DCB_CONNECTOR_DVI_I: |
775 | NV_INFO(dev, "Detected a DVI-I connector\n"); | ||
776 | type = DRM_MODE_CONNECTOR_DVII; | 759 | type = DRM_MODE_CONNECTOR_DVII; |
777 | break; | 760 | break; |
778 | case DCB_CONNECTOR_DVI_D: | 761 | case DCB_CONNECTOR_DVI_D: |
779 | NV_INFO(dev, "Detected a DVI-D connector\n"); | ||
780 | type = DRM_MODE_CONNECTOR_DVID; | 762 | type = DRM_MODE_CONNECTOR_DVID; |
781 | break; | 763 | break; |
782 | case DCB_CONNECTOR_HDMI_0: | 764 | case DCB_CONNECTOR_HDMI_0: |
783 | case DCB_CONNECTOR_HDMI_1: | 765 | case DCB_CONNECTOR_HDMI_1: |
784 | NV_INFO(dev, "Detected a HDMI connector\n"); | ||
785 | type = DRM_MODE_CONNECTOR_HDMIA; | 766 | type = DRM_MODE_CONNECTOR_HDMIA; |
786 | break; | 767 | break; |
787 | case DCB_CONNECTOR_LVDS: | 768 | case DCB_CONNECTOR_LVDS: |
788 | NV_INFO(dev, "Detected a LVDS connector\n"); | ||
789 | type = DRM_MODE_CONNECTOR_LVDS; | 769 | type = DRM_MODE_CONNECTOR_LVDS; |
770 | funcs = &nouveau_connector_funcs_lvds; | ||
790 | break; | 771 | break; |
791 | case DCB_CONNECTOR_DP: | 772 | case DCB_CONNECTOR_DP: |
792 | NV_INFO(dev, "Detected a DisplayPort connector\n"); | ||
793 | type = DRM_MODE_CONNECTOR_DisplayPort; | 773 | type = DRM_MODE_CONNECTOR_DisplayPort; |
794 | break; | 774 | break; |
795 | case DCB_CONNECTOR_eDP: | 775 | case DCB_CONNECTOR_eDP: |
796 | NV_INFO(dev, "Detected an eDP connector\n"); | ||
797 | type = DRM_MODE_CONNECTOR_eDP; | 776 | type = DRM_MODE_CONNECTOR_eDP; |
798 | break; | 777 | break; |
799 | default: | 778 | default: |
800 | NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type); | 779 | NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type); |
801 | return -EINVAL; | 780 | return ERR_PTR(-EINVAL); |
802 | } | 781 | } |
803 | 782 | ||
804 | nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); | 783 | nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); |
805 | if (!nv_connector) | 784 | if (!nv_connector) |
806 | return -ENOMEM; | 785 | return ERR_PTR(-ENOMEM); |
807 | nv_connector->dcb = dcb; | 786 | nv_connector->dcb = dcb; |
808 | connector = &nv_connector->base; | 787 | connector = &nv_connector->base; |
809 | 788 | ||
@@ -811,27 +790,21 @@ nouveau_connector_create(struct drm_device *dev, | |||
811 | connector->interlace_allowed = false; | 790 | connector->interlace_allowed = false; |
812 | connector->doublescan_allowed = false; | 791 | connector->doublescan_allowed = false; |
813 | 792 | ||
814 | drm_connector_init(dev, connector, &nouveau_connector_funcs, type); | 793 | drm_connector_init(dev, connector, funcs, type); |
815 | drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); | 794 | drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); |
816 | 795 | ||
817 | /* attach encoders */ | 796 | /* Check if we need dithering enabled */ |
818 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 797 | if (dcb->type == DCB_CONNECTOR_LVDS) { |
819 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 798 | bool dummy, is_24bit = false; |
820 | |||
821 | if (nv_encoder->dcb->connector != dcb->index) | ||
822 | continue; | ||
823 | |||
824 | if (get_slave_funcs(nv_encoder)) | ||
825 | get_slave_funcs(nv_encoder)->create_resources(encoder, connector); | ||
826 | 799 | ||
827 | drm_mode_connector_attach_encoder(connector, encoder); | 800 | ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &is_24bit); |
828 | } | 801 | if (ret) { |
802 | NV_ERROR(dev, "Error parsing LVDS table, disabling " | ||
803 | "LVDS\n"); | ||
804 | goto fail; | ||
805 | } | ||
829 | 806 | ||
830 | if (!connector->encoder_ids[0]) { | 807 | nv_connector->use_dithering = !is_24bit; |
831 | NV_WARN(dev, " no encoders, ignoring\n"); | ||
832 | drm_connector_cleanup(connector); | ||
833 | kfree(connector); | ||
834 | return 0; | ||
835 | } | 808 | } |
836 | 809 | ||
837 | /* Init DVI-I specific properties */ | 810 | /* Init DVI-I specific properties */ |
@@ -841,12 +814,8 @@ nouveau_connector_create(struct drm_device *dev, | |||
841 | drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0); | 814 | drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0); |
842 | } | 815 | } |
843 | 816 | ||
844 | if (dcb->type != DCB_CONNECTOR_LVDS) | ||
845 | nv_connector->use_dithering = false; | ||
846 | |||
847 | switch (dcb->type) { | 817 | switch (dcb->type) { |
848 | case DCB_CONNECTOR_VGA: | 818 | case DCB_CONNECTOR_VGA: |
849 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
850 | if (dev_priv->card_type >= NV_50) { | 819 | if (dev_priv->card_type >= NV_50) { |
851 | drm_connector_attach_property(connector, | 820 | drm_connector_attach_property(connector, |
852 | dev->mode_config.scaling_mode_property, | 821 | dev->mode_config.scaling_mode_property, |
@@ -858,17 +827,6 @@ nouveau_connector_create(struct drm_device *dev, | |||
858 | case DCB_CONNECTOR_TV_3: | 827 | case DCB_CONNECTOR_TV_3: |
859 | nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; | 828 | nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; |
860 | break; | 829 | break; |
861 | case DCB_CONNECTOR_DP: | ||
862 | case DCB_CONNECTOR_eDP: | ||
863 | case DCB_CONNECTOR_HDMI_0: | ||
864 | case DCB_CONNECTOR_HDMI_1: | ||
865 | case DCB_CONNECTOR_DVI_I: | ||
866 | case DCB_CONNECTOR_DVI_D: | ||
867 | if (dev_priv->card_type >= NV_50) | ||
868 | connector->polled = DRM_CONNECTOR_POLL_HPD; | ||
869 | else | ||
870 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
871 | /* fall-through */ | ||
872 | default: | 830 | default: |
873 | nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; | 831 | nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; |
874 | 832 | ||
@@ -882,15 +840,15 @@ nouveau_connector_create(struct drm_device *dev, | |||
882 | break; | 840 | break; |
883 | } | 841 | } |
884 | 842 | ||
843 | nouveau_connector_set_polling(connector); | ||
844 | |||
885 | drm_sysfs_connector_add(connector); | 845 | drm_sysfs_connector_add(connector); |
846 | dcb->drm = connector; | ||
847 | return dcb->drm; | ||
886 | 848 | ||
887 | if (dcb->type == DCB_CONNECTOR_LVDS) { | 849 | fail: |
888 | ret = nouveau_connector_create_lvds(dev, connector); | 850 | drm_connector_cleanup(connector); |
889 | if (ret) { | 851 | kfree(connector); |
890 | connector->funcs->destroy(connector); | 852 | return ERR_PTR(ret); |
891 | return ret; | ||
892 | } | ||
893 | } | ||
894 | 853 | ||
895 | return 0; | ||
896 | } | 854 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h index 4ef38abc2d9c..0d2e668ccfe5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.h +++ b/drivers/gpu/drm/nouveau/nouveau_connector.h | |||
@@ -49,7 +49,10 @@ static inline struct nouveau_connector *nouveau_connector( | |||
49 | return container_of(con, struct nouveau_connector, base); | 49 | return container_of(con, struct nouveau_connector, base); |
50 | } | 50 | } |
51 | 51 | ||
52 | int nouveau_connector_create(struct drm_device *, | 52 | struct drm_connector * |
53 | struct dcb_connector_table_entry *); | 53 | nouveau_connector_create(struct drm_device *, int index); |
54 | |||
55 | void | ||
56 | nouveau_connector_set_polling(struct drm_connector *); | ||
54 | 57 | ||
55 | #endif /* __NOUVEAU_CONNECTOR_H__ */ | 58 | #endif /* __NOUVEAU_CONNECTOR_H__ */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 65c441a1999f..2e3c6caa97ee 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c | |||
@@ -92,11 +92,9 @@ nouveau_dma_init(struct nouveau_channel *chan) | |||
92 | return ret; | 92 | return ret; |
93 | 93 | ||
94 | /* Map M2MF notifier object - fbcon. */ | 94 | /* Map M2MF notifier object - fbcon. */ |
95 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 95 | ret = nouveau_bo_map(chan->notifier_bo); |
96 | ret = nouveau_bo_map(chan->notifier_bo); | 96 | if (ret) |
97 | if (ret) | 97 | return ret; |
98 | return ret; | ||
99 | } | ||
100 | 98 | ||
101 | /* Insert NOPS for NOUVEAU_DMA_SKIPS */ | 99 | /* Insert NOPS for NOUVEAU_DMA_SKIPS */ |
102 | ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); | 100 | ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index deeb21c6865c..33742b11188b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c | |||
@@ -23,8 +23,10 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "drmP.h" | 25 | #include "drmP.h" |
26 | |||
26 | #include "nouveau_drv.h" | 27 | #include "nouveau_drv.h" |
27 | #include "nouveau_i2c.h" | 28 | #include "nouveau_i2c.h" |
29 | #include "nouveau_connector.h" | ||
28 | #include "nouveau_encoder.h" | 30 | #include "nouveau_encoder.h" |
29 | 31 | ||
30 | static int | 32 | static int |
@@ -270,13 +272,39 @@ bool | |||
270 | nouveau_dp_link_train(struct drm_encoder *encoder) | 272 | nouveau_dp_link_train(struct drm_encoder *encoder) |
271 | { | 273 | { |
272 | struct drm_device *dev = encoder->dev; | 274 | struct drm_device *dev = encoder->dev; |
275 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
276 | struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; | ||
273 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 277 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
274 | uint8_t config[4]; | 278 | struct nouveau_connector *nv_connector; |
275 | uint8_t status[3]; | 279 | struct bit_displayport_encoder_table *dpe; |
280 | int dpe_headerlen; | ||
281 | uint8_t config[4], status[3]; | ||
276 | bool cr_done, cr_max_vs, eq_done; | 282 | bool cr_done, cr_max_vs, eq_done; |
277 | int ret = 0, i, tries, voltage; | 283 | int ret = 0, i, tries, voltage; |
278 | 284 | ||
279 | NV_DEBUG_KMS(dev, "link training!!\n"); | 285 | NV_DEBUG_KMS(dev, "link training!!\n"); |
286 | |||
287 | nv_connector = nouveau_encoder_connector_get(nv_encoder); | ||
288 | if (!nv_connector) | ||
289 | return false; | ||
290 | |||
291 | dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen); | ||
292 | if (!dpe) { | ||
293 | NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or); | ||
294 | return false; | ||
295 | } | ||
296 | |||
297 | /* disable hotplug detect, this flips around on some panels during | ||
298 | * link training. | ||
299 | */ | ||
300 | pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, false); | ||
301 | |||
302 | if (dpe->script0) { | ||
303 | NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); | ||
304 | nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0), | ||
305 | nv_encoder->dcb); | ||
306 | } | ||
307 | |||
280 | train: | 308 | train: |
281 | cr_done = eq_done = false; | 309 | cr_done = eq_done = false; |
282 | 310 | ||
@@ -403,6 +431,15 @@ stop: | |||
403 | } | 431 | } |
404 | } | 432 | } |
405 | 433 | ||
434 | if (dpe->script1) { | ||
435 | NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or); | ||
436 | nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1), | ||
437 | nv_encoder->dcb); | ||
438 | } | ||
439 | |||
440 | /* re-enable hotplug detect */ | ||
441 | pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, true); | ||
442 | |||
406 | return eq_done; | 443 | return eq_done; |
407 | } | 444 | } |
408 | 445 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 273770432298..1de5eb53e016 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c | |||
@@ -35,10 +35,6 @@ | |||
35 | 35 | ||
36 | #include "drm_pciids.h" | 36 | #include "drm_pciids.h" |
37 | 37 | ||
38 | MODULE_PARM_DESC(ctxfw, "Use external firmware blob for grctx init (NV40)"); | ||
39 | int nouveau_ctxfw = 0; | ||
40 | module_param_named(ctxfw, nouveau_ctxfw, int, 0400); | ||
41 | |||
42 | MODULE_PARM_DESC(noagp, "Disable AGP"); | 38 | MODULE_PARM_DESC(noagp, "Disable AGP"); |
43 | int nouveau_noagp; | 39 | int nouveau_noagp; |
44 | module_param_named(noagp, nouveau_noagp, int, 0400); | 40 | module_param_named(noagp, nouveau_noagp, int, 0400); |
@@ -56,7 +52,7 @@ int nouveau_vram_pushbuf; | |||
56 | module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400); | 52 | module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400); |
57 | 53 | ||
58 | MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM"); | 54 | MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM"); |
59 | int nouveau_vram_notify = 1; | 55 | int nouveau_vram_notify = 0; |
60 | module_param_named(vram_notify, nouveau_vram_notify, int, 0400); | 56 | module_param_named(vram_notify, nouveau_vram_notify, int, 0400); |
61 | 57 | ||
62 | MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)"); | 58 | MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)"); |
@@ -132,7 +128,7 @@ static struct drm_driver driver; | |||
132 | static int __devinit | 128 | static int __devinit |
133 | nouveau_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 129 | nouveau_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
134 | { | 130 | { |
135 | return drm_get_dev(pdev, ent, &driver); | 131 | return drm_get_pci_dev(pdev, ent, &driver); |
136 | } | 132 | } |
137 | 133 | ||
138 | static void | 134 | static void |
@@ -155,9 +151,6 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) | |||
155 | struct drm_crtc *crtc; | 151 | struct drm_crtc *crtc; |
156 | int ret, i; | 152 | int ret, i; |
157 | 153 | ||
158 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||
159 | return -ENODEV; | ||
160 | |||
161 | if (pm_state.event == PM_EVENT_PRETHAW) | 154 | if (pm_state.event == PM_EVENT_PRETHAW) |
162 | return 0; | 155 | return 0; |
163 | 156 | ||
@@ -257,9 +250,6 @@ nouveau_pci_resume(struct pci_dev *pdev) | |||
257 | struct drm_crtc *crtc; | 250 | struct drm_crtc *crtc; |
258 | int ret, i; | 251 | int ret, i; |
259 | 252 | ||
260 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||
261 | return -ENODEV; | ||
262 | |||
263 | nouveau_fbcon_save_disable_accel(dev); | 253 | nouveau_fbcon_save_disable_accel(dev); |
264 | 254 | ||
265 | NV_INFO(dev, "We're back, enabling device...\n"); | 255 | NV_INFO(dev, "We're back, enabling device...\n"); |
@@ -269,6 +259,13 @@ nouveau_pci_resume(struct pci_dev *pdev) | |||
269 | return -1; | 259 | return -1; |
270 | pci_set_master(dev->pdev); | 260 | pci_set_master(dev->pdev); |
271 | 261 | ||
262 | /* Make sure the AGP controller is in a consistent state */ | ||
263 | if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) | ||
264 | nouveau_mem_reset_agp(dev); | ||
265 | |||
266 | /* Make the CRTCs accessible */ | ||
267 | engine->display.early_init(dev); | ||
268 | |||
272 | NV_INFO(dev, "POSTing device...\n"); | 269 | NV_INFO(dev, "POSTing device...\n"); |
273 | ret = nouveau_run_vbios_init(dev); | 270 | ret = nouveau_run_vbios_init(dev); |
274 | if (ret) | 271 | if (ret) |
@@ -323,7 +320,6 @@ nouveau_pci_resume(struct pci_dev *pdev) | |||
323 | 320 | ||
324 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 321 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
325 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 322 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
326 | int ret; | ||
327 | 323 | ||
328 | ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); | 324 | ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); |
329 | if (!ret) | 325 | if (!ret) |
@@ -332,11 +328,7 @@ nouveau_pci_resume(struct pci_dev *pdev) | |||
332 | NV_ERROR(dev, "Could not pin/map cursor.\n"); | 328 | NV_ERROR(dev, "Could not pin/map cursor.\n"); |
333 | } | 329 | } |
334 | 330 | ||
335 | if (dev_priv->card_type < NV_50) { | 331 | engine->display.init(dev); |
336 | nv04_display_restore(dev); | ||
337 | NVLockVgaCrtcs(dev, false); | ||
338 | } else | ||
339 | nv50_display_init(dev); | ||
340 | 332 | ||
341 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 333 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
342 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 334 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
@@ -371,7 +363,8 @@ nouveau_pci_resume(struct pci_dev *pdev) | |||
371 | static struct drm_driver driver = { | 363 | static struct drm_driver driver = { |
372 | .driver_features = | 364 | .driver_features = |
373 | DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | | 365 | DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | |
374 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM, | 366 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | |
367 | DRIVER_MODESET, | ||
375 | .load = nouveau_load, | 368 | .load = nouveau_load, |
376 | .firstopen = nouveau_firstopen, | 369 | .firstopen = nouveau_firstopen, |
377 | .lastclose = nouveau_lastclose, | 370 | .lastclose = nouveau_lastclose, |
@@ -438,16 +431,18 @@ static int __init nouveau_init(void) | |||
438 | nouveau_modeset = 1; | 431 | nouveau_modeset = 1; |
439 | } | 432 | } |
440 | 433 | ||
441 | if (nouveau_modeset == 1) { | 434 | if (!nouveau_modeset) |
442 | driver.driver_features |= DRIVER_MODESET; | 435 | return 0; |
443 | nouveau_register_dsm_handler(); | ||
444 | } | ||
445 | 436 | ||
437 | nouveau_register_dsm_handler(); | ||
446 | return drm_init(&driver); | 438 | return drm_init(&driver); |
447 | } | 439 | } |
448 | 440 | ||
449 | static void __exit nouveau_exit(void) | 441 | static void __exit nouveau_exit(void) |
450 | { | 442 | { |
443 | if (!nouveau_modeset) | ||
444 | return; | ||
445 | |||
451 | drm_exit(&driver); | 446 | drm_exit(&driver); |
452 | nouveau_unregister_dsm_handler(); | 447 | nouveau_unregister_dsm_handler(); |
453 | } | 448 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index c69719106489..e15db15dca77 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -123,14 +123,6 @@ nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo) | |||
123 | return ioptr; | 123 | return ioptr; |
124 | } | 124 | } |
125 | 125 | ||
126 | struct mem_block { | ||
127 | struct mem_block *next; | ||
128 | struct mem_block *prev; | ||
129 | uint64_t start; | ||
130 | uint64_t size; | ||
131 | struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ | ||
132 | }; | ||
133 | |||
134 | enum nouveau_flags { | 126 | enum nouveau_flags { |
135 | NV_NFORCE = 0x10000000, | 127 | NV_NFORCE = 0x10000000, |
136 | NV_NFORCE2 = 0x20000000 | 128 | NV_NFORCE2 = 0x20000000 |
@@ -149,7 +141,7 @@ struct nouveau_gpuobj { | |||
149 | struct list_head list; | 141 | struct list_head list; |
150 | 142 | ||
151 | struct nouveau_channel *im_channel; | 143 | struct nouveau_channel *im_channel; |
152 | struct mem_block *im_pramin; | 144 | struct drm_mm_node *im_pramin; |
153 | struct nouveau_bo *im_backing; | 145 | struct nouveau_bo *im_backing; |
154 | uint32_t im_backing_start; | 146 | uint32_t im_backing_start; |
155 | uint32_t *im_backing_suspend; | 147 | uint32_t *im_backing_suspend; |
@@ -196,7 +188,7 @@ struct nouveau_channel { | |||
196 | struct list_head pending; | 188 | struct list_head pending; |
197 | uint32_t sequence; | 189 | uint32_t sequence; |
198 | uint32_t sequence_ack; | 190 | uint32_t sequence_ack; |
199 | uint32_t last_sequence_irq; | 191 | atomic_t last_sequence_irq; |
200 | } fence; | 192 | } fence; |
201 | 193 | ||
202 | /* DMA push buffer */ | 194 | /* DMA push buffer */ |
@@ -206,7 +198,7 @@ struct nouveau_channel { | |||
206 | 198 | ||
207 | /* Notifier memory */ | 199 | /* Notifier memory */ |
208 | struct nouveau_bo *notifier_bo; | 200 | struct nouveau_bo *notifier_bo; |
209 | struct mem_block *notifier_heap; | 201 | struct drm_mm notifier_heap; |
210 | 202 | ||
211 | /* PFIFO context */ | 203 | /* PFIFO context */ |
212 | struct nouveau_gpuobj_ref *ramfc; | 204 | struct nouveau_gpuobj_ref *ramfc; |
@@ -224,7 +216,7 @@ struct nouveau_channel { | |||
224 | 216 | ||
225 | /* Objects */ | 217 | /* Objects */ |
226 | struct nouveau_gpuobj_ref *ramin; /* Private instmem */ | 218 | struct nouveau_gpuobj_ref *ramin; /* Private instmem */ |
227 | struct mem_block *ramin_heap; /* Private PRAMIN heap */ | 219 | struct drm_mm ramin_heap; /* Private PRAMIN heap */ |
228 | struct nouveau_gpuobj_ref *ramht; /* Hash table */ | 220 | struct nouveau_gpuobj_ref *ramht; /* Hash table */ |
229 | struct list_head ramht_refs; /* Objects referenced by RAMHT */ | 221 | struct list_head ramht_refs; /* Objects referenced by RAMHT */ |
230 | 222 | ||
@@ -277,8 +269,7 @@ struct nouveau_instmem_engine { | |||
277 | void (*clear)(struct drm_device *, struct nouveau_gpuobj *); | 269 | void (*clear)(struct drm_device *, struct nouveau_gpuobj *); |
278 | int (*bind)(struct drm_device *, struct nouveau_gpuobj *); | 270 | int (*bind)(struct drm_device *, struct nouveau_gpuobj *); |
279 | int (*unbind)(struct drm_device *, struct nouveau_gpuobj *); | 271 | int (*unbind)(struct drm_device *, struct nouveau_gpuobj *); |
280 | void (*prepare_access)(struct drm_device *, bool write); | 272 | void (*flush)(struct drm_device *); |
281 | void (*finish_access)(struct drm_device *); | ||
282 | }; | 273 | }; |
283 | 274 | ||
284 | struct nouveau_mc_engine { | 275 | struct nouveau_mc_engine { |
@@ -303,10 +294,11 @@ struct nouveau_fb_engine { | |||
303 | }; | 294 | }; |
304 | 295 | ||
305 | struct nouveau_fifo_engine { | 296 | struct nouveau_fifo_engine { |
306 | void *priv; | ||
307 | |||
308 | int channels; | 297 | int channels; |
309 | 298 | ||
299 | struct nouveau_gpuobj_ref *playlist[2]; | ||
300 | int cur_playlist; | ||
301 | |||
310 | int (*init)(struct drm_device *); | 302 | int (*init)(struct drm_device *); |
311 | void (*takedown)(struct drm_device *); | 303 | void (*takedown)(struct drm_device *); |
312 | 304 | ||
@@ -339,10 +331,11 @@ struct nouveau_pgraph_object_class { | |||
339 | struct nouveau_pgraph_engine { | 331 | struct nouveau_pgraph_engine { |
340 | struct nouveau_pgraph_object_class *grclass; | 332 | struct nouveau_pgraph_object_class *grclass; |
341 | bool accel_blocked; | 333 | bool accel_blocked; |
342 | void *ctxprog; | ||
343 | void *ctxvals; | ||
344 | int grctx_size; | 334 | int grctx_size; |
345 | 335 | ||
336 | /* NV2x/NV3x context table (0x400780) */ | ||
337 | struct nouveau_gpuobj_ref *ctx_table; | ||
338 | |||
346 | int (*init)(struct drm_device *); | 339 | int (*init)(struct drm_device *); |
347 | void (*takedown)(struct drm_device *); | 340 | void (*takedown)(struct drm_device *); |
348 | 341 | ||
@@ -358,6 +351,24 @@ struct nouveau_pgraph_engine { | |||
358 | uint32_t size, uint32_t pitch); | 351 | uint32_t size, uint32_t pitch); |
359 | }; | 352 | }; |
360 | 353 | ||
354 | struct nouveau_display_engine { | ||
355 | int (*early_init)(struct drm_device *); | ||
356 | void (*late_takedown)(struct drm_device *); | ||
357 | int (*create)(struct drm_device *); | ||
358 | int (*init)(struct drm_device *); | ||
359 | void (*destroy)(struct drm_device *); | ||
360 | }; | ||
361 | |||
362 | struct nouveau_gpio_engine { | ||
363 | int (*init)(struct drm_device *); | ||
364 | void (*takedown)(struct drm_device *); | ||
365 | |||
366 | int (*get)(struct drm_device *, enum dcb_gpio_tag); | ||
367 | int (*set)(struct drm_device *, enum dcb_gpio_tag, int state); | ||
368 | |||
369 | void (*irq_enable)(struct drm_device *, enum dcb_gpio_tag, bool on); | ||
370 | }; | ||
371 | |||
361 | struct nouveau_engine { | 372 | struct nouveau_engine { |
362 | struct nouveau_instmem_engine instmem; | 373 | struct nouveau_instmem_engine instmem; |
363 | struct nouveau_mc_engine mc; | 374 | struct nouveau_mc_engine mc; |
@@ -365,6 +376,8 @@ struct nouveau_engine { | |||
365 | struct nouveau_fb_engine fb; | 376 | struct nouveau_fb_engine fb; |
366 | struct nouveau_pgraph_engine graph; | 377 | struct nouveau_pgraph_engine graph; |
367 | struct nouveau_fifo_engine fifo; | 378 | struct nouveau_fifo_engine fifo; |
379 | struct nouveau_display_engine display; | ||
380 | struct nouveau_gpio_engine gpio; | ||
368 | }; | 381 | }; |
369 | 382 | ||
370 | struct nouveau_pll_vals { | 383 | struct nouveau_pll_vals { |
@@ -500,11 +513,6 @@ enum nouveau_card_type { | |||
500 | 513 | ||
501 | struct drm_nouveau_private { | 514 | struct drm_nouveau_private { |
502 | struct drm_device *dev; | 515 | struct drm_device *dev; |
503 | enum { | ||
504 | NOUVEAU_CARD_INIT_DOWN, | ||
505 | NOUVEAU_CARD_INIT_DONE, | ||
506 | NOUVEAU_CARD_INIT_FAILED | ||
507 | } init_state; | ||
508 | 516 | ||
509 | /* the card type, takes NV_* as values */ | 517 | /* the card type, takes NV_* as values */ |
510 | enum nouveau_card_type card_type; | 518 | enum nouveau_card_type card_type; |
@@ -525,7 +533,7 @@ struct drm_nouveau_private { | |||
525 | struct list_head vbl_waiting; | 533 | struct list_head vbl_waiting; |
526 | 534 | ||
527 | struct { | 535 | struct { |
528 | struct ttm_global_reference mem_global_ref; | 536 | struct drm_global_reference mem_global_ref; |
529 | struct ttm_bo_global_ref bo_global_ref; | 537 | struct ttm_bo_global_ref bo_global_ref; |
530 | struct ttm_bo_device bdev; | 538 | struct ttm_bo_device bdev; |
531 | spinlock_t bo_list_lock; | 539 | spinlock_t bo_list_lock; |
@@ -533,8 +541,6 @@ struct drm_nouveau_private { | |||
533 | atomic_t validate_sequence; | 541 | atomic_t validate_sequence; |
534 | } ttm; | 542 | } ttm; |
535 | 543 | ||
536 | struct fb_info *fbdev_info; | ||
537 | |||
538 | int fifo_alloc_count; | 544 | int fifo_alloc_count; |
539 | struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR]; | 545 | struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR]; |
540 | 546 | ||
@@ -595,11 +601,7 @@ struct drm_nouveau_private { | |||
595 | struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; | 601 | struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; |
596 | int vm_vram_pt_nr; | 602 | int vm_vram_pt_nr; |
597 | 603 | ||
598 | struct mem_block *ramin_heap; | 604 | struct drm_mm ramin_heap; |
599 | |||
600 | /* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */ | ||
601 | uint32_t ctx_table_size; | ||
602 | struct nouveau_gpuobj_ref *ctx_table; | ||
603 | 605 | ||
604 | struct list_head gpuobj_list; | 606 | struct list_head gpuobj_list; |
605 | 607 | ||
@@ -618,6 +620,11 @@ struct drm_nouveau_private { | |||
618 | struct backlight_device *backlight; | 620 | struct backlight_device *backlight; |
619 | 621 | ||
620 | struct nouveau_channel *evo; | 622 | struct nouveau_channel *evo; |
623 | struct { | ||
624 | struct dcb_entry *dcb; | ||
625 | u16 script; | ||
626 | u32 pclk; | ||
627 | } evo_irq; | ||
621 | 628 | ||
622 | struct { | 629 | struct { |
623 | struct dentry *channel_root; | 630 | struct dentry *channel_root; |
@@ -652,14 +659,6 @@ nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo) | |||
652 | return 0; | 659 | return 0; |
653 | } | 660 | } |
654 | 661 | ||
655 | #define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do { \ | ||
656 | struct drm_nouveau_private *nv = dev->dev_private; \ | ||
657 | if (nv->init_state != NOUVEAU_CARD_INIT_DONE) { \ | ||
658 | NV_ERROR(dev, "called without init\n"); \ | ||
659 | return -EINVAL; \ | ||
660 | } \ | ||
661 | } while (0) | ||
662 | |||
663 | #define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id, cl, ch) do { \ | 662 | #define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id, cl, ch) do { \ |
664 | struct drm_nouveau_private *nv = dev->dev_private; \ | 663 | struct drm_nouveau_private *nv = dev->dev_private; \ |
665 | if (!nouveau_channel_owner(dev, (cl), (id))) { \ | 664 | if (!nouveau_channel_owner(dev, (cl), (id))) { \ |
@@ -682,7 +681,6 @@ extern int nouveau_tv_disable; | |||
682 | extern char *nouveau_tv_norm; | 681 | extern char *nouveau_tv_norm; |
683 | extern int nouveau_reg_debug; | 682 | extern int nouveau_reg_debug; |
684 | extern char *nouveau_vbios; | 683 | extern char *nouveau_vbios; |
685 | extern int nouveau_ctxfw; | ||
686 | extern int nouveau_ignorelid; | 684 | extern int nouveau_ignorelid; |
687 | extern int nouveau_nofbaccel; | 685 | extern int nouveau_nofbaccel; |
688 | extern int nouveau_noaccel; | 686 | extern int nouveau_noaccel; |
@@ -707,17 +705,10 @@ extern bool nouveau_wait_for_idle(struct drm_device *); | |||
707 | extern int nouveau_card_init(struct drm_device *); | 705 | extern int nouveau_card_init(struct drm_device *); |
708 | 706 | ||
709 | /* nouveau_mem.c */ | 707 | /* nouveau_mem.c */ |
710 | extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start, | ||
711 | uint64_t size); | ||
712 | extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *, | ||
713 | uint64_t size, int align2, | ||
714 | struct drm_file *, int tail); | ||
715 | extern void nouveau_mem_takedown(struct mem_block **heap); | ||
716 | extern void nouveau_mem_free_block(struct mem_block *); | ||
717 | extern int nouveau_mem_detect(struct drm_device *dev); | 708 | extern int nouveau_mem_detect(struct drm_device *dev); |
718 | extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap); | ||
719 | extern int nouveau_mem_init(struct drm_device *); | 709 | extern int nouveau_mem_init(struct drm_device *); |
720 | extern int nouveau_mem_init_agp(struct drm_device *); | 710 | extern int nouveau_mem_init_agp(struct drm_device *); |
711 | extern int nouveau_mem_reset_agp(struct drm_device *); | ||
721 | extern void nouveau_mem_close(struct drm_device *); | 712 | extern void nouveau_mem_close(struct drm_device *); |
722 | extern struct nouveau_tile_reg *nv10_mem_set_tiling(struct drm_device *dev, | 713 | extern struct nouveau_tile_reg *nv10_mem_set_tiling(struct drm_device *dev, |
723 | uint32_t addr, | 714 | uint32_t addr, |
@@ -857,11 +848,13 @@ void nouveau_register_dsm_handler(void); | |||
857 | void nouveau_unregister_dsm_handler(void); | 848 | void nouveau_unregister_dsm_handler(void); |
858 | int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); | 849 | int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); |
859 | bool nouveau_acpi_rom_supported(struct pci_dev *pdev); | 850 | bool nouveau_acpi_rom_supported(struct pci_dev *pdev); |
851 | int nouveau_acpi_edid(struct drm_device *, struct drm_connector *); | ||
860 | #else | 852 | #else |
861 | static inline void nouveau_register_dsm_handler(void) {} | 853 | static inline void nouveau_register_dsm_handler(void) {} |
862 | static inline void nouveau_unregister_dsm_handler(void) {} | 854 | static inline void nouveau_unregister_dsm_handler(void) {} |
863 | static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; } | 855 | static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; } |
864 | static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; } | 856 | static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; } |
857 | static inline int nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return -EINVAL; } | ||
865 | #endif | 858 | #endif |
866 | 859 | ||
867 | /* nouveau_backlight.c */ | 860 | /* nouveau_backlight.c */ |
@@ -924,6 +917,10 @@ extern void nv10_fb_takedown(struct drm_device *); | |||
924 | extern void nv10_fb_set_region_tiling(struct drm_device *, int, uint32_t, | 917 | extern void nv10_fb_set_region_tiling(struct drm_device *, int, uint32_t, |
925 | uint32_t, uint32_t); | 918 | uint32_t, uint32_t); |
926 | 919 | ||
920 | /* nv30_fb.c */ | ||
921 | extern int nv30_fb_init(struct drm_device *); | ||
922 | extern void nv30_fb_takedown(struct drm_device *); | ||
923 | |||
927 | /* nv40_fb.c */ | 924 | /* nv40_fb.c */ |
928 | extern int nv40_fb_init(struct drm_device *); | 925 | extern int nv40_fb_init(struct drm_device *); |
929 | extern void nv40_fb_takedown(struct drm_device *); | 926 | extern void nv40_fb_takedown(struct drm_device *); |
@@ -1035,12 +1032,6 @@ extern int nv50_graph_unload_context(struct drm_device *); | |||
1035 | extern void nv50_graph_context_switch(struct drm_device *); | 1032 | extern void nv50_graph_context_switch(struct drm_device *); |
1036 | extern int nv50_grctx_init(struct nouveau_grctx *); | 1033 | extern int nv50_grctx_init(struct nouveau_grctx *); |
1037 | 1034 | ||
1038 | /* nouveau_grctx.c */ | ||
1039 | extern int nouveau_grctx_prog_load(struct drm_device *); | ||
1040 | extern void nouveau_grctx_vals_load(struct drm_device *, | ||
1041 | struct nouveau_gpuobj *); | ||
1042 | extern void nouveau_grctx_fini(struct drm_device *); | ||
1043 | |||
1044 | /* nv04_instmem.c */ | 1035 | /* nv04_instmem.c */ |
1045 | extern int nv04_instmem_init(struct drm_device *); | 1036 | extern int nv04_instmem_init(struct drm_device *); |
1046 | extern void nv04_instmem_takedown(struct drm_device *); | 1037 | extern void nv04_instmem_takedown(struct drm_device *); |
@@ -1051,8 +1042,7 @@ extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, | |||
1051 | extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); | 1042 | extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); |
1052 | extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); | 1043 | extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); |
1053 | extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); | 1044 | extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); |
1054 | extern void nv04_instmem_prepare_access(struct drm_device *, bool write); | 1045 | extern void nv04_instmem_flush(struct drm_device *); |
1055 | extern void nv04_instmem_finish_access(struct drm_device *); | ||
1056 | 1046 | ||
1057 | /* nv50_instmem.c */ | 1047 | /* nv50_instmem.c */ |
1058 | extern int nv50_instmem_init(struct drm_device *); | 1048 | extern int nv50_instmem_init(struct drm_device *); |
@@ -1064,8 +1054,9 @@ extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, | |||
1064 | extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); | 1054 | extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); |
1065 | extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); | 1055 | extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); |
1066 | extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); | 1056 | extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); |
1067 | extern void nv50_instmem_prepare_access(struct drm_device *, bool write); | 1057 | extern void nv50_instmem_flush(struct drm_device *); |
1068 | extern void nv50_instmem_finish_access(struct drm_device *); | 1058 | extern void nv84_instmem_flush(struct drm_device *); |
1059 | extern void nv50_vm_flush(struct drm_device *, int engine); | ||
1069 | 1060 | ||
1070 | /* nv04_mc.c */ | 1061 | /* nv04_mc.c */ |
1071 | extern int nv04_mc_init(struct drm_device *); | 1062 | extern int nv04_mc_init(struct drm_device *); |
@@ -1088,13 +1079,14 @@ extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd, | |||
1088 | unsigned long arg); | 1079 | unsigned long arg); |
1089 | 1080 | ||
1090 | /* nv04_dac.c */ | 1081 | /* nv04_dac.c */ |
1091 | extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry); | 1082 | extern int nv04_dac_create(struct drm_connector *, struct dcb_entry *); |
1092 | extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder); | 1083 | extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder); |
1093 | extern int nv04_dac_output_offset(struct drm_encoder *encoder); | 1084 | extern int nv04_dac_output_offset(struct drm_encoder *encoder); |
1094 | extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable); | 1085 | extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable); |
1086 | extern bool nv04_dac_in_use(struct drm_encoder *encoder); | ||
1095 | 1087 | ||
1096 | /* nv04_dfp.c */ | 1088 | /* nv04_dfp.c */ |
1097 | extern int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry); | 1089 | extern int nv04_dfp_create(struct drm_connector *, struct dcb_entry *); |
1098 | extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent); | 1090 | extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent); |
1099 | extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent, | 1091 | extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent, |
1100 | int head, bool dl); | 1092 | int head, bool dl); |
@@ -1103,15 +1095,17 @@ extern void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode); | |||
1103 | 1095 | ||
1104 | /* nv04_tv.c */ | 1096 | /* nv04_tv.c */ |
1105 | extern int nv04_tv_identify(struct drm_device *dev, int i2c_index); | 1097 | extern int nv04_tv_identify(struct drm_device *dev, int i2c_index); |
1106 | extern int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry); | 1098 | extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *); |
1107 | 1099 | ||
1108 | /* nv17_tv.c */ | 1100 | /* nv17_tv.c */ |
1109 | extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry); | 1101 | extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *); |
1110 | 1102 | ||
1111 | /* nv04_display.c */ | 1103 | /* nv04_display.c */ |
1104 | extern int nv04_display_early_init(struct drm_device *); | ||
1105 | extern void nv04_display_late_takedown(struct drm_device *); | ||
1112 | extern int nv04_display_create(struct drm_device *); | 1106 | extern int nv04_display_create(struct drm_device *); |
1107 | extern int nv04_display_init(struct drm_device *); | ||
1113 | extern void nv04_display_destroy(struct drm_device *); | 1108 | extern void nv04_display_destroy(struct drm_device *); |
1114 | extern void nv04_display_restore(struct drm_device *); | ||
1115 | 1109 | ||
1116 | /* nv04_crtc.c */ | 1110 | /* nv04_crtc.c */ |
1117 | extern int nv04_crtc_create(struct drm_device *, int index); | 1111 | extern int nv04_crtc_create(struct drm_device *, int index); |
@@ -1147,7 +1141,6 @@ extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr); | |||
1147 | extern int nouveau_fence_flush(void *obj, void *arg); | 1141 | extern int nouveau_fence_flush(void *obj, void *arg); |
1148 | extern void nouveau_fence_unref(void **obj); | 1142 | extern void nouveau_fence_unref(void **obj); |
1149 | extern void *nouveau_fence_ref(void *obj); | 1143 | extern void *nouveau_fence_ref(void *obj); |
1150 | extern void nouveau_fence_handler(struct drm_device *dev, int channel); | ||
1151 | 1144 | ||
1152 | /* nouveau_gem.c */ | 1145 | /* nouveau_gem.c */ |
1153 | extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *, | 1146 | extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *, |
@@ -1167,13 +1160,15 @@ extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *, | |||
1167 | extern int nouveau_gem_ioctl_info(struct drm_device *, void *, | 1160 | extern int nouveau_gem_ioctl_info(struct drm_device *, void *, |
1168 | struct drm_file *); | 1161 | struct drm_file *); |
1169 | 1162 | ||
1170 | /* nv17_gpio.c */ | 1163 | /* nv10_gpio.c */ |
1171 | int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); | 1164 | int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); |
1172 | int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); | 1165 | int nv10_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); |
1173 | 1166 | ||
1174 | /* nv50_gpio.c */ | 1167 | /* nv50_gpio.c */ |
1168 | int nv50_gpio_init(struct drm_device *dev); | ||
1175 | int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); | 1169 | int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); |
1176 | int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); | 1170 | int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); |
1171 | void nv50_gpio_irq_enable(struct drm_device *, enum dcb_gpio_tag, bool on); | ||
1177 | 1172 | ||
1178 | /* nv50_calc. */ | 1173 | /* nv50_calc. */ |
1179 | int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk, | 1174 | int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk, |
@@ -1220,6 +1215,14 @@ static inline void nv_wr32(struct drm_device *dev, unsigned reg, u32 val) | |||
1220 | iowrite32_native(val, dev_priv->mmio + reg); | 1215 | iowrite32_native(val, dev_priv->mmio + reg); |
1221 | } | 1216 | } |
1222 | 1217 | ||
1218 | static inline void nv_mask(struct drm_device *dev, u32 reg, u32 mask, u32 val) | ||
1219 | { | ||
1220 | u32 tmp = nv_rd32(dev, reg); | ||
1221 | tmp &= ~mask; | ||
1222 | tmp |= val; | ||
1223 | nv_wr32(dev, reg, tmp); | ||
1224 | } | ||
1225 | |||
1223 | static inline u8 nv_rd08(struct drm_device *dev, unsigned reg) | 1226 | static inline u8 nv_rd08(struct drm_device *dev, unsigned reg) |
1224 | { | 1227 | { |
1225 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 1228 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index e1df8209cd0f..a1a0d48ae70c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h | |||
@@ -38,13 +38,15 @@ struct nouveau_encoder { | |||
38 | struct dcb_entry *dcb; | 38 | struct dcb_entry *dcb; |
39 | int or; | 39 | int or; |
40 | 40 | ||
41 | /* different to drm_encoder.crtc, this reflects what's | ||
42 | * actually programmed on the hw, not the proposed crtc */ | ||
43 | struct drm_crtc *crtc; | ||
44 | |||
41 | struct drm_display_mode mode; | 45 | struct drm_display_mode mode; |
42 | int last_dpms; | 46 | int last_dpms; |
43 | 47 | ||
44 | struct nv04_output_reg restore; | 48 | struct nv04_output_reg restore; |
45 | 49 | ||
46 | void (*disconnect)(struct nouveau_encoder *encoder); | ||
47 | |||
48 | union { | 50 | union { |
49 | struct { | 51 | struct { |
50 | int mc_unknown; | 52 | int mc_unknown; |
@@ -71,8 +73,8 @@ static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc) | |||
71 | 73 | ||
72 | struct nouveau_connector * | 74 | struct nouveau_connector * |
73 | nouveau_encoder_connector_get(struct nouveau_encoder *encoder); | 75 | nouveau_encoder_connector_get(struct nouveau_encoder *encoder); |
74 | int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry); | 76 | int nv50_sor_create(struct drm_connector *, struct dcb_entry *); |
75 | int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry); | 77 | int nv50_dac_create(struct drm_connector *, struct dcb_entry *); |
76 | 78 | ||
77 | struct bit_displayport_encoder_table { | 79 | struct bit_displayport_encoder_table { |
78 | uint32_t match; | 80 | uint32_t match; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 257ea130ae13..2fb2444d2322 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -333,7 +333,7 @@ nouveau_fbcon_output_poll_changed(struct drm_device *dev) | |||
333 | drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper); | 333 | drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper); |
334 | } | 334 | } |
335 | 335 | ||
336 | int | 336 | static int |
337 | nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev) | 337 | nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev) |
338 | { | 338 | { |
339 | struct nouveau_framebuffer *nouveau_fb = &nfbdev->nouveau_fb; | 339 | struct nouveau_framebuffer *nouveau_fb = &nfbdev->nouveau_fb; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index faddf53ff9ed..6b208ffafa8d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
@@ -67,12 +67,13 @@ nouveau_fence_update(struct nouveau_channel *chan) | |||
67 | if (USE_REFCNT) | 67 | if (USE_REFCNT) |
68 | sequence = nvchan_rd32(chan, 0x48); | 68 | sequence = nvchan_rd32(chan, 0x48); |
69 | else | 69 | else |
70 | sequence = chan->fence.last_sequence_irq; | 70 | sequence = atomic_read(&chan->fence.last_sequence_irq); |
71 | 71 | ||
72 | if (chan->fence.sequence_ack == sequence) | 72 | if (chan->fence.sequence_ack == sequence) |
73 | return; | 73 | return; |
74 | chan->fence.sequence_ack = sequence; | 74 | chan->fence.sequence_ack = sequence; |
75 | 75 | ||
76 | spin_lock(&chan->fence.lock); | ||
76 | list_for_each_safe(entry, tmp, &chan->fence.pending) { | 77 | list_for_each_safe(entry, tmp, &chan->fence.pending) { |
77 | fence = list_entry(entry, struct nouveau_fence, entry); | 78 | fence = list_entry(entry, struct nouveau_fence, entry); |
78 | 79 | ||
@@ -84,6 +85,7 @@ nouveau_fence_update(struct nouveau_channel *chan) | |||
84 | if (sequence == chan->fence.sequence_ack) | 85 | if (sequence == chan->fence.sequence_ack) |
85 | break; | 86 | break; |
86 | } | 87 | } |
88 | spin_unlock(&chan->fence.lock); | ||
87 | } | 89 | } |
88 | 90 | ||
89 | int | 91 | int |
@@ -119,7 +121,6 @@ nouveau_fence_emit(struct nouveau_fence *fence) | |||
119 | { | 121 | { |
120 | struct drm_nouveau_private *dev_priv = fence->channel->dev->dev_private; | 122 | struct drm_nouveau_private *dev_priv = fence->channel->dev->dev_private; |
121 | struct nouveau_channel *chan = fence->channel; | 123 | struct nouveau_channel *chan = fence->channel; |
122 | unsigned long flags; | ||
123 | int ret; | 124 | int ret; |
124 | 125 | ||
125 | ret = RING_SPACE(chan, 2); | 126 | ret = RING_SPACE(chan, 2); |
@@ -127,9 +128,7 @@ nouveau_fence_emit(struct nouveau_fence *fence) | |||
127 | return ret; | 128 | return ret; |
128 | 129 | ||
129 | if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) { | 130 | if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) { |
130 | spin_lock_irqsave(&chan->fence.lock, flags); | ||
131 | nouveau_fence_update(chan); | 131 | nouveau_fence_update(chan); |
132 | spin_unlock_irqrestore(&chan->fence.lock, flags); | ||
133 | 132 | ||
134 | BUG_ON(chan->fence.sequence == | 133 | BUG_ON(chan->fence.sequence == |
135 | chan->fence.sequence_ack - 1); | 134 | chan->fence.sequence_ack - 1); |
@@ -138,9 +137,9 @@ nouveau_fence_emit(struct nouveau_fence *fence) | |||
138 | fence->sequence = ++chan->fence.sequence; | 137 | fence->sequence = ++chan->fence.sequence; |
139 | 138 | ||
140 | kref_get(&fence->refcount); | 139 | kref_get(&fence->refcount); |
141 | spin_lock_irqsave(&chan->fence.lock, flags); | 140 | spin_lock(&chan->fence.lock); |
142 | list_add_tail(&fence->entry, &chan->fence.pending); | 141 | list_add_tail(&fence->entry, &chan->fence.pending); |
143 | spin_unlock_irqrestore(&chan->fence.lock, flags); | 142 | spin_unlock(&chan->fence.lock); |
144 | 143 | ||
145 | BEGIN_RING(chan, NvSubSw, USE_REFCNT ? 0x0050 : 0x0150, 1); | 144 | BEGIN_RING(chan, NvSubSw, USE_REFCNT ? 0x0050 : 0x0150, 1); |
146 | OUT_RING(chan, fence->sequence); | 145 | OUT_RING(chan, fence->sequence); |
@@ -173,14 +172,11 @@ nouveau_fence_signalled(void *sync_obj, void *sync_arg) | |||
173 | { | 172 | { |
174 | struct nouveau_fence *fence = nouveau_fence(sync_obj); | 173 | struct nouveau_fence *fence = nouveau_fence(sync_obj); |
175 | struct nouveau_channel *chan = fence->channel; | 174 | struct nouveau_channel *chan = fence->channel; |
176 | unsigned long flags; | ||
177 | 175 | ||
178 | if (fence->signalled) | 176 | if (fence->signalled) |
179 | return true; | 177 | return true; |
180 | 178 | ||
181 | spin_lock_irqsave(&chan->fence.lock, flags); | ||
182 | nouveau_fence_update(chan); | 179 | nouveau_fence_update(chan); |
183 | spin_unlock_irqrestore(&chan->fence.lock, flags); | ||
184 | return fence->signalled; | 180 | return fence->signalled; |
185 | } | 181 | } |
186 | 182 | ||
@@ -190,8 +186,6 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) | |||
190 | unsigned long timeout = jiffies + (3 * DRM_HZ); | 186 | unsigned long timeout = jiffies + (3 * DRM_HZ); |
191 | int ret = 0; | 187 | int ret = 0; |
192 | 188 | ||
193 | __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); | ||
194 | |||
195 | while (1) { | 189 | while (1) { |
196 | if (nouveau_fence_signalled(sync_obj, sync_arg)) | 190 | if (nouveau_fence_signalled(sync_obj, sync_arg)) |
197 | break; | 191 | break; |
@@ -201,6 +195,8 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) | |||
201 | break; | 195 | break; |
202 | } | 196 | } |
203 | 197 | ||
198 | __set_current_state(intr ? TASK_INTERRUPTIBLE | ||
199 | : TASK_UNINTERRUPTIBLE); | ||
204 | if (lazy) | 200 | if (lazy) |
205 | schedule_timeout(1); | 201 | schedule_timeout(1); |
206 | 202 | ||
@@ -221,27 +217,12 @@ nouveau_fence_flush(void *sync_obj, void *sync_arg) | |||
221 | return 0; | 217 | return 0; |
222 | } | 218 | } |
223 | 219 | ||
224 | void | ||
225 | nouveau_fence_handler(struct drm_device *dev, int channel) | ||
226 | { | ||
227 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
228 | struct nouveau_channel *chan = NULL; | ||
229 | |||
230 | if (channel >= 0 && channel < dev_priv->engine.fifo.channels) | ||
231 | chan = dev_priv->fifos[channel]; | ||
232 | |||
233 | if (chan) { | ||
234 | spin_lock_irq(&chan->fence.lock); | ||
235 | nouveau_fence_update(chan); | ||
236 | spin_unlock_irq(&chan->fence.lock); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | int | 220 | int |
241 | nouveau_fence_init(struct nouveau_channel *chan) | 221 | nouveau_fence_init(struct nouveau_channel *chan) |
242 | { | 222 | { |
243 | INIT_LIST_HEAD(&chan->fence.pending); | 223 | INIT_LIST_HEAD(&chan->fence.pending); |
244 | spin_lock_init(&chan->fence.lock); | 224 | spin_lock_init(&chan->fence.lock); |
225 | atomic_set(&chan->fence.last_sequence_irq, 0); | ||
245 | return 0; | 226 | return 0; |
246 | } | 227 | } |
247 | 228 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 69c76cf93407..547f2c24c1e7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -137,8 +137,6 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, | |||
137 | uint32_t flags = 0; | 137 | uint32_t flags = 0; |
138 | int ret = 0; | 138 | int ret = 0; |
139 | 139 | ||
140 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
141 | |||
142 | if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL)) | 140 | if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL)) |
143 | dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping; | 141 | dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping; |
144 | 142 | ||
@@ -577,10 +575,9 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
577 | struct drm_nouveau_gem_pushbuf_bo *bo; | 575 | struct drm_nouveau_gem_pushbuf_bo *bo; |
578 | struct nouveau_channel *chan; | 576 | struct nouveau_channel *chan; |
579 | struct validate_op op; | 577 | struct validate_op op; |
580 | struct nouveau_fence *fence = 0; | 578 | struct nouveau_fence *fence = NULL; |
581 | int i, j, ret = 0, do_reloc = 0; | 579 | int i, j, ret = 0, do_reloc = 0; |
582 | 580 | ||
583 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
584 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan); | 581 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan); |
585 | 582 | ||
586 | req->vram_available = dev_priv->fb_aper_free; | 583 | req->vram_available = dev_priv->fb_aper_free; |
@@ -760,8 +757,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, | |||
760 | bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT); | 757 | bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT); |
761 | int ret = -EINVAL; | 758 | int ret = -EINVAL; |
762 | 759 | ||
763 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
764 | |||
765 | gem = drm_gem_object_lookup(dev, file_priv, req->handle); | 760 | gem = drm_gem_object_lookup(dev, file_priv, req->handle); |
766 | if (!gem) | 761 | if (!gem) |
767 | return ret; | 762 | return ret; |
@@ -800,8 +795,6 @@ nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data, | |||
800 | struct nouveau_bo *nvbo; | 795 | struct nouveau_bo *nvbo; |
801 | int ret = -EINVAL; | 796 | int ret = -EINVAL; |
802 | 797 | ||
803 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
804 | |||
805 | gem = drm_gem_object_lookup(dev, file_priv, req->handle); | 798 | gem = drm_gem_object_lookup(dev, file_priv, req->handle); |
806 | if (!gem) | 799 | if (!gem) |
807 | return ret; | 800 | return ret; |
@@ -827,8 +820,6 @@ nouveau_gem_ioctl_info(struct drm_device *dev, void *data, | |||
827 | struct drm_gem_object *gem; | 820 | struct drm_gem_object *gem; |
828 | int ret; | 821 | int ret; |
829 | 822 | ||
830 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
831 | |||
832 | gem = drm_gem_object_lookup(dev, file_priv, req->handle); | 823 | gem = drm_gem_object_lookup(dev, file_priv, req->handle); |
833 | if (!gem) | 824 | if (!gem) |
834 | return -EINVAL; | 825 | return -EINVAL; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.c b/drivers/gpu/drm/nouveau/nouveau_grctx.c deleted file mode 100644 index f731c5f60536..000000000000 --- a/drivers/gpu/drm/nouveau/nouveau_grctx.c +++ /dev/null | |||
@@ -1,160 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | #include <linux/firmware.h> | ||
26 | #include <linux/slab.h> | ||
27 | |||
28 | #include "drmP.h" | ||
29 | #include "nouveau_drv.h" | ||
30 | |||
31 | struct nouveau_ctxprog { | ||
32 | uint32_t signature; | ||
33 | uint8_t version; | ||
34 | uint16_t length; | ||
35 | uint32_t data[]; | ||
36 | } __attribute__ ((packed)); | ||
37 | |||
38 | struct nouveau_ctxvals { | ||
39 | uint32_t signature; | ||
40 | uint8_t version; | ||
41 | uint32_t length; | ||
42 | struct { | ||
43 | uint32_t offset; | ||
44 | uint32_t value; | ||
45 | } data[]; | ||
46 | } __attribute__ ((packed)); | ||
47 | |||
48 | int | ||
49 | nouveau_grctx_prog_load(struct drm_device *dev) | ||
50 | { | ||
51 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
52 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
53 | const int chipset = dev_priv->chipset; | ||
54 | const struct firmware *fw; | ||
55 | const struct nouveau_ctxprog *cp; | ||
56 | const struct nouveau_ctxvals *cv; | ||
57 | char name[32]; | ||
58 | int ret, i; | ||
59 | |||
60 | if (pgraph->accel_blocked) | ||
61 | return -ENODEV; | ||
62 | |||
63 | if (!pgraph->ctxprog) { | ||
64 | sprintf(name, "nouveau/nv%02x.ctxprog", chipset); | ||
65 | ret = request_firmware(&fw, name, &dev->pdev->dev); | ||
66 | if (ret) { | ||
67 | NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset); | ||
68 | return ret; | ||
69 | } | ||
70 | |||
71 | pgraph->ctxprog = kmemdup(fw->data, fw->size, GFP_KERNEL); | ||
72 | if (!pgraph->ctxprog) { | ||
73 | NV_ERROR(dev, "OOM copying ctxprog\n"); | ||
74 | release_firmware(fw); | ||
75 | return -ENOMEM; | ||
76 | } | ||
77 | |||
78 | cp = pgraph->ctxprog; | ||
79 | if (le32_to_cpu(cp->signature) != 0x5043564e || | ||
80 | cp->version != 0 || | ||
81 | le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) { | ||
82 | NV_ERROR(dev, "ctxprog invalid\n"); | ||
83 | release_firmware(fw); | ||
84 | nouveau_grctx_fini(dev); | ||
85 | return -EINVAL; | ||
86 | } | ||
87 | release_firmware(fw); | ||
88 | } | ||
89 | |||
90 | if (!pgraph->ctxvals) { | ||
91 | sprintf(name, "nouveau/nv%02x.ctxvals", chipset); | ||
92 | ret = request_firmware(&fw, name, &dev->pdev->dev); | ||
93 | if (ret) { | ||
94 | NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset); | ||
95 | nouveau_grctx_fini(dev); | ||
96 | return ret; | ||
97 | } | ||
98 | |||
99 | pgraph->ctxvals = kmemdup(fw->data, fw->size, GFP_KERNEL); | ||
100 | if (!pgraph->ctxvals) { | ||
101 | NV_ERROR(dev, "OOM copying ctxvals\n"); | ||
102 | release_firmware(fw); | ||
103 | nouveau_grctx_fini(dev); | ||
104 | return -ENOMEM; | ||
105 | } | ||
106 | |||
107 | cv = (void *)pgraph->ctxvals; | ||
108 | if (le32_to_cpu(cv->signature) != 0x5643564e || | ||
109 | cv->version != 0 || | ||
110 | le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) { | ||
111 | NV_ERROR(dev, "ctxvals invalid\n"); | ||
112 | release_firmware(fw); | ||
113 | nouveau_grctx_fini(dev); | ||
114 | return -EINVAL; | ||
115 | } | ||
116 | release_firmware(fw); | ||
117 | } | ||
118 | |||
119 | cp = pgraph->ctxprog; | ||
120 | |||
121 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); | ||
122 | for (i = 0; i < le16_to_cpu(cp->length); i++) | ||
123 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, | ||
124 | le32_to_cpu(cp->data[i])); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | void | ||
130 | nouveau_grctx_fini(struct drm_device *dev) | ||
131 | { | ||
132 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
133 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
134 | |||
135 | if (pgraph->ctxprog) { | ||
136 | kfree(pgraph->ctxprog); | ||
137 | pgraph->ctxprog = NULL; | ||
138 | } | ||
139 | |||
140 | if (pgraph->ctxvals) { | ||
141 | kfree(pgraph->ctxprog); | ||
142 | pgraph->ctxvals = NULL; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | void | ||
147 | nouveau_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx) | ||
148 | { | ||
149 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
150 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
151 | struct nouveau_ctxvals *cv = pgraph->ctxvals; | ||
152 | int i; | ||
153 | |||
154 | if (!cv) | ||
155 | return; | ||
156 | |||
157 | for (i = 0; i < le32_to_cpu(cv->length); i++) | ||
158 | nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset), | ||
159 | le32_to_cpu(cv->data[i].value)); | ||
160 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 316a3c7e6eb4..cb0cb34440c6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
@@ -278,3 +278,45 @@ nouveau_i2c_find(struct drm_device *dev, int index) | |||
278 | return i2c->chan; | 278 | return i2c->chan; |
279 | } | 279 | } |
280 | 280 | ||
281 | bool | ||
282 | nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr) | ||
283 | { | ||
284 | uint8_t buf[] = { 0 }; | ||
285 | struct i2c_msg msgs[] = { | ||
286 | { | ||
287 | .addr = addr, | ||
288 | .flags = 0, | ||
289 | .len = 1, | ||
290 | .buf = buf, | ||
291 | }, | ||
292 | { | ||
293 | .addr = addr, | ||
294 | .flags = I2C_M_RD, | ||
295 | .len = 1, | ||
296 | .buf = buf, | ||
297 | } | ||
298 | }; | ||
299 | |||
300 | return i2c_transfer(&i2c->adapter, msgs, 2) == 2; | ||
301 | } | ||
302 | |||
303 | int | ||
304 | nouveau_i2c_identify(struct drm_device *dev, const char *what, | ||
305 | struct i2c_board_info *info, int index) | ||
306 | { | ||
307 | struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index); | ||
308 | int i; | ||
309 | |||
310 | NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index); | ||
311 | |||
312 | for (i = 0; info[i].addr; i++) { | ||
313 | if (nouveau_probe_i2c_addr(i2c, info[i].addr)) { | ||
314 | NV_INFO(dev, "Detected %s: %s\n", what, info[i].type); | ||
315 | return i; | ||
316 | } | ||
317 | } | ||
318 | |||
319 | NV_DEBUG(dev, "No devices found.\n"); | ||
320 | |||
321 | return -ENODEV; | ||
322 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/nouveau_i2c.h index c8eaf7a9fcbb..6dd2f8713cd1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.h +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.h | |||
@@ -45,6 +45,9 @@ struct nouveau_i2c_chan { | |||
45 | int nouveau_i2c_init(struct drm_device *, struct dcb_i2c_entry *, int index); | 45 | int nouveau_i2c_init(struct drm_device *, struct dcb_i2c_entry *, int index); |
46 | void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *); | 46 | void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *); |
47 | struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index); | 47 | struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index); |
48 | bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr); | ||
49 | int nouveau_i2c_identify(struct drm_device *dev, const char *what, | ||
50 | struct i2c_board_info *info, int index); | ||
48 | 51 | ||
49 | int nouveau_dp_i2c_aux_ch(struct i2c_adapter *, int mode, uint8_t write_byte, | 52 | int nouveau_dp_i2c_aux_ch(struct i2c_adapter *, int mode, uint8_t write_byte, |
50 | uint8_t *read_byte); | 53 | uint8_t *read_byte); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index c1fd42b0dad1..a9f36ab256b7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c | |||
@@ -35,162 +35,6 @@ | |||
35 | #include "drm_sarea.h" | 35 | #include "drm_sarea.h" |
36 | #include "nouveau_drv.h" | 36 | #include "nouveau_drv.h" |
37 | 37 | ||
38 | static struct mem_block * | ||
39 | split_block(struct mem_block *p, uint64_t start, uint64_t size, | ||
40 | struct drm_file *file_priv) | ||
41 | { | ||
42 | /* Maybe cut off the start of an existing block */ | ||
43 | if (start > p->start) { | ||
44 | struct mem_block *newblock = | ||
45 | kmalloc(sizeof(*newblock), GFP_KERNEL); | ||
46 | if (!newblock) | ||
47 | goto out; | ||
48 | newblock->start = start; | ||
49 | newblock->size = p->size - (start - p->start); | ||
50 | newblock->file_priv = NULL; | ||
51 | newblock->next = p->next; | ||
52 | newblock->prev = p; | ||
53 | p->next->prev = newblock; | ||
54 | p->next = newblock; | ||
55 | p->size -= newblock->size; | ||
56 | p = newblock; | ||
57 | } | ||
58 | |||
59 | /* Maybe cut off the end of an existing block */ | ||
60 | if (size < p->size) { | ||
61 | struct mem_block *newblock = | ||
62 | kmalloc(sizeof(*newblock), GFP_KERNEL); | ||
63 | if (!newblock) | ||
64 | goto out; | ||
65 | newblock->start = start + size; | ||
66 | newblock->size = p->size - size; | ||
67 | newblock->file_priv = NULL; | ||
68 | newblock->next = p->next; | ||
69 | newblock->prev = p; | ||
70 | p->next->prev = newblock; | ||
71 | p->next = newblock; | ||
72 | p->size = size; | ||
73 | } | ||
74 | |||
75 | out: | ||
76 | /* Our block is in the middle */ | ||
77 | p->file_priv = file_priv; | ||
78 | return p; | ||
79 | } | ||
80 | |||
81 | struct mem_block * | ||
82 | nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size, | ||
83 | int align2, struct drm_file *file_priv, int tail) | ||
84 | { | ||
85 | struct mem_block *p; | ||
86 | uint64_t mask = (1 << align2) - 1; | ||
87 | |||
88 | if (!heap) | ||
89 | return NULL; | ||
90 | |||
91 | if (tail) { | ||
92 | list_for_each_prev(p, heap) { | ||
93 | uint64_t start = ((p->start + p->size) - size) & ~mask; | ||
94 | |||
95 | if (p->file_priv == NULL && start >= p->start && | ||
96 | start + size <= p->start + p->size) | ||
97 | return split_block(p, start, size, file_priv); | ||
98 | } | ||
99 | } else { | ||
100 | list_for_each(p, heap) { | ||
101 | uint64_t start = (p->start + mask) & ~mask; | ||
102 | |||
103 | if (p->file_priv == NULL && | ||
104 | start + size <= p->start + p->size) | ||
105 | return split_block(p, start, size, file_priv); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | return NULL; | ||
110 | } | ||
111 | |||
112 | void nouveau_mem_free_block(struct mem_block *p) | ||
113 | { | ||
114 | p->file_priv = NULL; | ||
115 | |||
116 | /* Assumes a single contiguous range. Needs a special file_priv in | ||
117 | * 'heap' to stop it being subsumed. | ||
118 | */ | ||
119 | if (p->next->file_priv == NULL) { | ||
120 | struct mem_block *q = p->next; | ||
121 | p->size += q->size; | ||
122 | p->next = q->next; | ||
123 | p->next->prev = p; | ||
124 | kfree(q); | ||
125 | } | ||
126 | |||
127 | if (p->prev->file_priv == NULL) { | ||
128 | struct mem_block *q = p->prev; | ||
129 | q->size += p->size; | ||
130 | q->next = p->next; | ||
131 | q->next->prev = q; | ||
132 | kfree(p); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | /* Initialize. How to check for an uninitialized heap? | ||
137 | */ | ||
138 | int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start, | ||
139 | uint64_t size) | ||
140 | { | ||
141 | struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL); | ||
142 | |||
143 | if (!blocks) | ||
144 | return -ENOMEM; | ||
145 | |||
146 | *heap = kmalloc(sizeof(**heap), GFP_KERNEL); | ||
147 | if (!*heap) { | ||
148 | kfree(blocks); | ||
149 | return -ENOMEM; | ||
150 | } | ||
151 | |||
152 | blocks->start = start; | ||
153 | blocks->size = size; | ||
154 | blocks->file_priv = NULL; | ||
155 | blocks->next = blocks->prev = *heap; | ||
156 | |||
157 | memset(*heap, 0, sizeof(**heap)); | ||
158 | (*heap)->file_priv = (struct drm_file *) -1; | ||
159 | (*heap)->next = (*heap)->prev = blocks; | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * Free all blocks associated with the releasing file_priv | ||
165 | */ | ||
166 | void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap) | ||
167 | { | ||
168 | struct mem_block *p; | ||
169 | |||
170 | if (!heap || !heap->next) | ||
171 | return; | ||
172 | |||
173 | list_for_each(p, heap) { | ||
174 | if (p->file_priv == file_priv) | ||
175 | p->file_priv = NULL; | ||
176 | } | ||
177 | |||
178 | /* Assumes a single contiguous range. Needs a special file_priv in | ||
179 | * 'heap' to stop it being subsumed. | ||
180 | */ | ||
181 | list_for_each(p, heap) { | ||
182 | while ((p->file_priv == NULL) && | ||
183 | (p->next->file_priv == NULL) && | ||
184 | (p->next != heap)) { | ||
185 | struct mem_block *q = p->next; | ||
186 | p->size += q->size; | ||
187 | p->next = q->next; | ||
188 | p->next->prev = p; | ||
189 | kfree(q); | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | |||
194 | /* | 38 | /* |
195 | * NV10-NV40 tiling helpers | 39 | * NV10-NV40 tiling helpers |
196 | */ | 40 | */ |
@@ -299,7 +143,6 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, | |||
299 | phys |= 0x30; | 143 | phys |= 0x30; |
300 | } | 144 | } |
301 | 145 | ||
302 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
303 | while (size) { | 146 | while (size) { |
304 | unsigned offset_h = upper_32_bits(phys); | 147 | unsigned offset_h = upper_32_bits(phys); |
305 | unsigned offset_l = lower_32_bits(phys); | 148 | unsigned offset_l = lower_32_bits(phys); |
@@ -331,36 +174,12 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, | |||
331 | } | 174 | } |
332 | } | 175 | } |
333 | } | 176 | } |
334 | dev_priv->engine.instmem.finish_access(dev); | 177 | dev_priv->engine.instmem.flush(dev); |
335 | |||
336 | nv_wr32(dev, 0x100c80, 0x00050001); | ||
337 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
338 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
339 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
340 | return -EBUSY; | ||
341 | } | ||
342 | |||
343 | nv_wr32(dev, 0x100c80, 0x00000001); | ||
344 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
345 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
346 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
347 | return -EBUSY; | ||
348 | } | ||
349 | |||
350 | nv_wr32(dev, 0x100c80, 0x00040001); | ||
351 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
352 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
353 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
354 | return -EBUSY; | ||
355 | } | ||
356 | |||
357 | nv_wr32(dev, 0x100c80, 0x00060001); | ||
358 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
359 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
360 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
361 | return -EBUSY; | ||
362 | } | ||
363 | 178 | ||
179 | nv50_vm_flush(dev, 5); | ||
180 | nv50_vm_flush(dev, 0); | ||
181 | nv50_vm_flush(dev, 4); | ||
182 | nv50_vm_flush(dev, 6); | ||
364 | return 0; | 183 | return 0; |
365 | } | 184 | } |
366 | 185 | ||
@@ -374,7 +193,6 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) | |||
374 | virt -= dev_priv->vm_vram_base; | 193 | virt -= dev_priv->vm_vram_base; |
375 | pages = (size >> 16) << 1; | 194 | pages = (size >> 16) << 1; |
376 | 195 | ||
377 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
378 | while (pages) { | 196 | while (pages) { |
379 | pgt = dev_priv->vm_vram_pt[virt >> 29]; | 197 | pgt = dev_priv->vm_vram_pt[virt >> 29]; |
380 | pte = (virt & 0x1ffe0000ULL) >> 15; | 198 | pte = (virt & 0x1ffe0000ULL) >> 15; |
@@ -388,57 +206,19 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) | |||
388 | while (pte < end) | 206 | while (pte < end) |
389 | nv_wo32(dev, pgt, pte++, 0); | 207 | nv_wo32(dev, pgt, pte++, 0); |
390 | } | 208 | } |
391 | dev_priv->engine.instmem.finish_access(dev); | 209 | dev_priv->engine.instmem.flush(dev); |
392 | |||
393 | nv_wr32(dev, 0x100c80, 0x00050001); | ||
394 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
395 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
396 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
397 | return; | ||
398 | } | ||
399 | |||
400 | nv_wr32(dev, 0x100c80, 0x00000001); | ||
401 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
402 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
403 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
404 | return; | ||
405 | } | ||
406 | |||
407 | nv_wr32(dev, 0x100c80, 0x00040001); | ||
408 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
409 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
410 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
411 | return; | ||
412 | } | ||
413 | 210 | ||
414 | nv_wr32(dev, 0x100c80, 0x00060001); | 211 | nv50_vm_flush(dev, 5); |
415 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | 212 | nv50_vm_flush(dev, 0); |
416 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | 213 | nv50_vm_flush(dev, 4); |
417 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | 214 | nv50_vm_flush(dev, 6); |
418 | } | ||
419 | } | 215 | } |
420 | 216 | ||
421 | /* | 217 | /* |
422 | * Cleanup everything | 218 | * Cleanup everything |
423 | */ | 219 | */ |
424 | void nouveau_mem_takedown(struct mem_block **heap) | 220 | void |
425 | { | 221 | nouveau_mem_close(struct drm_device *dev) |
426 | struct mem_block *p; | ||
427 | |||
428 | if (!*heap) | ||
429 | return; | ||
430 | |||
431 | for (p = (*heap)->next; p != *heap;) { | ||
432 | struct mem_block *q = p; | ||
433 | p = p->next; | ||
434 | kfree(q); | ||
435 | } | ||
436 | |||
437 | kfree(*heap); | ||
438 | *heap = NULL; | ||
439 | } | ||
440 | |||
441 | void nouveau_mem_close(struct drm_device *dev) | ||
442 | { | 222 | { |
443 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 223 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
444 | 224 | ||
@@ -449,8 +229,7 @@ void nouveau_mem_close(struct drm_device *dev) | |||
449 | 229 | ||
450 | nouveau_ttm_global_release(dev_priv); | 230 | nouveau_ttm_global_release(dev_priv); |
451 | 231 | ||
452 | if (drm_core_has_AGP(dev) && dev->agp && | 232 | if (drm_core_has_AGP(dev) && dev->agp) { |
453 | drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
454 | struct drm_agp_mem *entry, *tempe; | 233 | struct drm_agp_mem *entry, *tempe; |
455 | 234 | ||
456 | /* Remove AGP resources, but leave dev->agp | 235 | /* Remove AGP resources, but leave dev->agp |
@@ -471,28 +250,29 @@ void nouveau_mem_close(struct drm_device *dev) | |||
471 | } | 250 | } |
472 | 251 | ||
473 | if (dev_priv->fb_mtrr) { | 252 | if (dev_priv->fb_mtrr) { |
474 | drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1), | 253 | drm_mtrr_del(dev_priv->fb_mtrr, |
475 | drm_get_resource_len(dev, 1), DRM_MTRR_WC); | 254 | pci_resource_start(dev->pdev, 1), |
476 | dev_priv->fb_mtrr = 0; | 255 | pci_resource_len(dev->pdev, 1), DRM_MTRR_WC); |
256 | dev_priv->fb_mtrr = -1; | ||
477 | } | 257 | } |
478 | } | 258 | } |
479 | 259 | ||
480 | static uint32_t | 260 | static uint32_t |
481 | nouveau_mem_detect_nv04(struct drm_device *dev) | 261 | nouveau_mem_detect_nv04(struct drm_device *dev) |
482 | { | 262 | { |
483 | uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0); | 263 | uint32_t boot0 = nv_rd32(dev, NV04_PFB_BOOT_0); |
484 | 264 | ||
485 | if (boot0 & 0x00000100) | 265 | if (boot0 & 0x00000100) |
486 | return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024; | 266 | return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024; |
487 | 267 | ||
488 | switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) { | 268 | switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) { |
489 | case NV04_BOOT_0_RAM_AMOUNT_32MB: | 269 | case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB: |
490 | return 32 * 1024 * 1024; | 270 | return 32 * 1024 * 1024; |
491 | case NV04_BOOT_0_RAM_AMOUNT_16MB: | 271 | case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB: |
492 | return 16 * 1024 * 1024; | 272 | return 16 * 1024 * 1024; |
493 | case NV04_BOOT_0_RAM_AMOUNT_8MB: | 273 | case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB: |
494 | return 8 * 1024 * 1024; | 274 | return 8 * 1024 * 1024; |
495 | case NV04_BOOT_0_RAM_AMOUNT_4MB: | 275 | case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB: |
496 | return 4 * 1024 * 1024; | 276 | return 4 * 1024 * 1024; |
497 | } | 277 | } |
498 | 278 | ||
@@ -536,12 +316,18 @@ nouveau_mem_detect(struct drm_device *dev) | |||
536 | } else | 316 | } else |
537 | if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) { | 317 | if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) { |
538 | dev_priv->vram_size = nouveau_mem_detect_nforce(dev); | 318 | dev_priv->vram_size = nouveau_mem_detect_nforce(dev); |
319 | } else | ||
320 | if (dev_priv->card_type < NV_50) { | ||
321 | dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA); | ||
322 | dev_priv->vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK; | ||
539 | } else { | 323 | } else { |
540 | dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA); | 324 | dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA); |
541 | dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK; | 325 | dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32; |
542 | if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) | 326 | dev_priv->vram_size &= 0xffffffff00ll; |
327 | if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) { | ||
543 | dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10); | 328 | dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10); |
544 | dev_priv->vram_sys_base <<= 12; | 329 | dev_priv->vram_sys_base <<= 12; |
330 | } | ||
545 | } | 331 | } |
546 | 332 | ||
547 | NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20)); | 333 | NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20)); |
@@ -555,18 +341,36 @@ nouveau_mem_detect(struct drm_device *dev) | |||
555 | return -ENOMEM; | 341 | return -ENOMEM; |
556 | } | 342 | } |
557 | 343 | ||
558 | #if __OS_HAS_AGP | 344 | int |
559 | static void nouveau_mem_reset_agp(struct drm_device *dev) | 345 | nouveau_mem_reset_agp(struct drm_device *dev) |
560 | { | 346 | { |
561 | uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable; | 347 | #if __OS_HAS_AGP |
348 | uint32_t saved_pci_nv_1, pmc_enable; | ||
349 | int ret; | ||
350 | |||
351 | /* First of all, disable fast writes, otherwise if it's | ||
352 | * already enabled in the AGP bridge and we disable the card's | ||
353 | * AGP controller we might be locking ourselves out of it. */ | ||
354 | if (dev->agp->acquired) { | ||
355 | struct drm_agp_info info; | ||
356 | struct drm_agp_mode mode; | ||
357 | |||
358 | ret = drm_agp_info(dev, &info); | ||
359 | if (ret) | ||
360 | return ret; | ||
361 | |||
362 | mode.mode = info.mode & ~0x10; | ||
363 | ret = drm_agp_enable(dev, mode); | ||
364 | if (ret) | ||
365 | return ret; | ||
366 | } | ||
562 | 367 | ||
563 | saved_pci_nv_1 = nv_rd32(dev, NV04_PBUS_PCI_NV_1); | 368 | saved_pci_nv_1 = nv_rd32(dev, NV04_PBUS_PCI_NV_1); |
564 | saved_pci_nv_19 = nv_rd32(dev, NV04_PBUS_PCI_NV_19); | ||
565 | 369 | ||
566 | /* clear busmaster bit */ | 370 | /* clear busmaster bit */ |
567 | nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4); | 371 | nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4); |
568 | /* clear SBA and AGP bits */ | 372 | /* disable AGP */ |
569 | nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff); | 373 | nv_wr32(dev, NV04_PBUS_PCI_NV_19, 0); |
570 | 374 | ||
571 | /* power cycle pgraph, if enabled */ | 375 | /* power cycle pgraph, if enabled */ |
572 | pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE); | 376 | pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE); |
@@ -578,11 +382,12 @@ static void nouveau_mem_reset_agp(struct drm_device *dev) | |||
578 | } | 382 | } |
579 | 383 | ||
580 | /* and restore (gives effect of resetting AGP) */ | 384 | /* and restore (gives effect of resetting AGP) */ |
581 | nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19); | ||
582 | nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1); | 385 | nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1); |
583 | } | ||
584 | #endif | 386 | #endif |
585 | 387 | ||
388 | return 0; | ||
389 | } | ||
390 | |||
586 | int | 391 | int |
587 | nouveau_mem_init_agp(struct drm_device *dev) | 392 | nouveau_mem_init_agp(struct drm_device *dev) |
588 | { | 393 | { |
@@ -592,11 +397,6 @@ nouveau_mem_init_agp(struct drm_device *dev) | |||
592 | struct drm_agp_mode mode; | 397 | struct drm_agp_mode mode; |
593 | int ret; | 398 | int ret; |
594 | 399 | ||
595 | if (nouveau_noagp) | ||
596 | return 0; | ||
597 | |||
598 | nouveau_mem_reset_agp(dev); | ||
599 | |||
600 | if (!dev->agp->acquired) { | 400 | if (!dev->agp->acquired) { |
601 | ret = drm_agp_acquire(dev); | 401 | ret = drm_agp_acquire(dev); |
602 | if (ret) { | 402 | if (ret) { |
@@ -633,7 +433,7 @@ nouveau_mem_init(struct drm_device *dev) | |||
633 | struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; | 433 | struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; |
634 | int ret, dma_bits = 32; | 434 | int ret, dma_bits = 32; |
635 | 435 | ||
636 | dev_priv->fb_phys = drm_get_resource_start(dev, 1); | 436 | dev_priv->fb_phys = pci_resource_start(dev->pdev, 1); |
637 | dev_priv->gart_info.type = NOUVEAU_GART_NONE; | 437 | dev_priv->gart_info.type = NOUVEAU_GART_NONE; |
638 | 438 | ||
639 | if (dev_priv->card_type >= NV_50 && | 439 | if (dev_priv->card_type >= NV_50 && |
@@ -665,8 +465,9 @@ nouveau_mem_init(struct drm_device *dev) | |||
665 | 465 | ||
666 | dev_priv->fb_available_size = dev_priv->vram_size; | 466 | dev_priv->fb_available_size = dev_priv->vram_size; |
667 | dev_priv->fb_mappable_pages = dev_priv->fb_available_size; | 467 | dev_priv->fb_mappable_pages = dev_priv->fb_available_size; |
668 | if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1)) | 468 | if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1)) |
669 | dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1); | 469 | dev_priv->fb_mappable_pages = |
470 | pci_resource_len(dev->pdev, 1); | ||
670 | dev_priv->fb_mappable_pages >>= PAGE_SHIFT; | 471 | dev_priv->fb_mappable_pages >>= PAGE_SHIFT; |
671 | 472 | ||
672 | /* remove reserved space at end of vram from available amount */ | 473 | /* remove reserved space at end of vram from available amount */ |
@@ -692,7 +493,8 @@ nouveau_mem_init(struct drm_device *dev) | |||
692 | 493 | ||
693 | /* GART */ | 494 | /* GART */ |
694 | #if !defined(__powerpc__) && !defined(__ia64__) | 495 | #if !defined(__powerpc__) && !defined(__ia64__) |
695 | if (drm_device_is_agp(dev) && dev->agp) { | 496 | if (drm_device_is_agp(dev) && dev->agp && !nouveau_noagp) { |
497 | nouveau_mem_reset_agp(dev); | ||
696 | ret = nouveau_mem_init_agp(dev); | 498 | ret = nouveau_mem_init_agp(dev); |
697 | if (ret) | 499 | if (ret) |
698 | NV_ERROR(dev, "Error initialising AGP: %d\n", ret); | 500 | NV_ERROR(dev, "Error initialising AGP: %d\n", ret); |
@@ -718,8 +520,8 @@ nouveau_mem_init(struct drm_device *dev) | |||
718 | return ret; | 520 | return ret; |
719 | } | 521 | } |
720 | 522 | ||
721 | dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1), | 523 | dev_priv->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1), |
722 | drm_get_resource_len(dev, 1), | 524 | pci_resource_len(dev->pdev, 1), |
723 | DRM_MTRR_WC); | 525 | DRM_MTRR_WC); |
724 | 526 | ||
725 | return 0; | 527 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 9537f3e30115..3ec181ff50ce 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c | |||
@@ -55,7 +55,7 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan) | |||
55 | if (ret) | 55 | if (ret) |
56 | goto out_err; | 56 | goto out_err; |
57 | 57 | ||
58 | ret = nouveau_mem_init_heap(&chan->notifier_heap, 0, ntfy->bo.mem.size); | 58 | ret = drm_mm_init(&chan->notifier_heap, 0, ntfy->bo.mem.size); |
59 | if (ret) | 59 | if (ret) |
60 | goto out_err; | 60 | goto out_err; |
61 | 61 | ||
@@ -80,7 +80,7 @@ nouveau_notifier_takedown_channel(struct nouveau_channel *chan) | |||
80 | nouveau_bo_unpin(chan->notifier_bo); | 80 | nouveau_bo_unpin(chan->notifier_bo); |
81 | mutex_unlock(&dev->struct_mutex); | 81 | mutex_unlock(&dev->struct_mutex); |
82 | drm_gem_object_unreference_unlocked(chan->notifier_bo->gem); | 82 | drm_gem_object_unreference_unlocked(chan->notifier_bo->gem); |
83 | nouveau_mem_takedown(&chan->notifier_heap); | 83 | drm_mm_takedown(&chan->notifier_heap); |
84 | } | 84 | } |
85 | 85 | ||
86 | static void | 86 | static void |
@@ -90,7 +90,7 @@ nouveau_notifier_gpuobj_dtor(struct drm_device *dev, | |||
90 | NV_DEBUG(dev, "\n"); | 90 | NV_DEBUG(dev, "\n"); |
91 | 91 | ||
92 | if (gpuobj->priv) | 92 | if (gpuobj->priv) |
93 | nouveau_mem_free_block(gpuobj->priv); | 93 | drm_mm_put_block(gpuobj->priv); |
94 | } | 94 | } |
95 | 95 | ||
96 | int | 96 | int |
@@ -100,18 +100,13 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, | |||
100 | struct drm_device *dev = chan->dev; | 100 | struct drm_device *dev = chan->dev; |
101 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 101 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
102 | struct nouveau_gpuobj *nobj = NULL; | 102 | struct nouveau_gpuobj *nobj = NULL; |
103 | struct mem_block *mem; | 103 | struct drm_mm_node *mem; |
104 | uint32_t offset; | 104 | uint32_t offset; |
105 | int target, ret; | 105 | int target, ret; |
106 | 106 | ||
107 | if (!chan->notifier_heap) { | 107 | mem = drm_mm_search_free(&chan->notifier_heap, size, 0, 0); |
108 | NV_ERROR(dev, "Channel %d doesn't have a notifier heap!\n", | 108 | if (mem) |
109 | chan->id); | 109 | mem = drm_mm_get_block(mem, size, 0); |
110 | return -EINVAL; | ||
111 | } | ||
112 | |||
113 | mem = nouveau_mem_alloc_block(chan->notifier_heap, size, 0, | ||
114 | (struct drm_file *)-2, 0); | ||
115 | if (!mem) { | 110 | if (!mem) { |
116 | NV_ERROR(dev, "Channel %d notifier block full\n", chan->id); | 111 | NV_ERROR(dev, "Channel %d notifier block full\n", chan->id); |
117 | return -ENOMEM; | 112 | return -ENOMEM; |
@@ -144,17 +139,17 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, | |||
144 | mem->size, NV_DMA_ACCESS_RW, target, | 139 | mem->size, NV_DMA_ACCESS_RW, target, |
145 | &nobj); | 140 | &nobj); |
146 | if (ret) { | 141 | if (ret) { |
147 | nouveau_mem_free_block(mem); | 142 | drm_mm_put_block(mem); |
148 | NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret); | 143 | NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret); |
149 | return ret; | 144 | return ret; |
150 | } | 145 | } |
151 | nobj->dtor = nouveau_notifier_gpuobj_dtor; | 146 | nobj->dtor = nouveau_notifier_gpuobj_dtor; |
152 | nobj->priv = mem; | 147 | nobj->priv = mem; |
153 | 148 | ||
154 | ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL); | 149 | ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL); |
155 | if (ret) { | 150 | if (ret) { |
156 | nouveau_gpuobj_del(dev, &nobj); | 151 | nouveau_gpuobj_del(dev, &nobj); |
157 | nouveau_mem_free_block(mem); | 152 | drm_mm_put_block(mem); |
158 | NV_ERROR(dev, "Error referencing notifier ctxdma: %d\n", ret); | 153 | NV_ERROR(dev, "Error referencing notifier ctxdma: %d\n", ret); |
159 | return ret; | 154 | return ret; |
160 | } | 155 | } |
@@ -170,7 +165,7 @@ nouveau_notifier_offset(struct nouveau_gpuobj *nobj, uint32_t *poffset) | |||
170 | return -EINVAL; | 165 | return -EINVAL; |
171 | 166 | ||
172 | if (poffset) { | 167 | if (poffset) { |
173 | struct mem_block *mem = nobj->priv; | 168 | struct drm_mm_node *mem = nobj->priv; |
174 | 169 | ||
175 | if (*poffset >= mem->size) | 170 | if (*poffset >= mem->size) |
176 | return false; | 171 | return false; |
@@ -189,7 +184,6 @@ nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, | |||
189 | struct nouveau_channel *chan; | 184 | struct nouveau_channel *chan; |
190 | int ret; | 185 | int ret; |
191 | 186 | ||
192 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
193 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan); | 187 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan); |
194 | 188 | ||
195 | ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset); | 189 | ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index e7c100ba63a1..b6bcb254f4ab 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c | |||
@@ -132,7 +132,6 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) | |||
132 | } | 132 | } |
133 | } | 133 | } |
134 | 134 | ||
135 | instmem->prepare_access(dev, true); | ||
136 | co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle); | 135 | co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle); |
137 | do { | 136 | do { |
138 | if (!nouveau_ramht_entry_valid(dev, ramht, co)) { | 137 | if (!nouveau_ramht_entry_valid(dev, ramht, co)) { |
@@ -143,7 +142,7 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) | |||
143 | nv_wo32(dev, ramht, (co + 4)/4, ctx); | 142 | nv_wo32(dev, ramht, (co + 4)/4, ctx); |
144 | 143 | ||
145 | list_add_tail(&ref->list, &chan->ramht_refs); | 144 | list_add_tail(&ref->list, &chan->ramht_refs); |
146 | instmem->finish_access(dev); | 145 | instmem->flush(dev); |
147 | return 0; | 146 | return 0; |
148 | } | 147 | } |
149 | NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n", | 148 | NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n", |
@@ -153,7 +152,6 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) | |||
153 | if (co >= dev_priv->ramht_size) | 152 | if (co >= dev_priv->ramht_size) |
154 | co = 0; | 153 | co = 0; |
155 | } while (co != ho); | 154 | } while (co != ho); |
156 | instmem->finish_access(dev); | ||
157 | 155 | ||
158 | NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id); | 156 | NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id); |
159 | return -ENOMEM; | 157 | return -ENOMEM; |
@@ -173,7 +171,6 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) | |||
173 | return; | 171 | return; |
174 | } | 172 | } |
175 | 173 | ||
176 | instmem->prepare_access(dev, true); | ||
177 | co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle); | 174 | co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle); |
178 | do { | 175 | do { |
179 | if (nouveau_ramht_entry_valid(dev, ramht, co) && | 176 | if (nouveau_ramht_entry_valid(dev, ramht, co) && |
@@ -186,7 +183,7 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) | |||
186 | nv_wo32(dev, ramht, (co + 4)/4, 0x00000000); | 183 | nv_wo32(dev, ramht, (co + 4)/4, 0x00000000); |
187 | 184 | ||
188 | list_del(&ref->list); | 185 | list_del(&ref->list); |
189 | instmem->finish_access(dev); | 186 | instmem->flush(dev); |
190 | return; | 187 | return; |
191 | } | 188 | } |
192 | 189 | ||
@@ -195,7 +192,6 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) | |||
195 | co = 0; | 192 | co = 0; |
196 | } while (co != ho); | 193 | } while (co != ho); |
197 | list_del(&ref->list); | 194 | list_del(&ref->list); |
198 | instmem->finish_access(dev); | ||
199 | 195 | ||
200 | NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n", | 196 | NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n", |
201 | chan->id, ref->handle); | 197 | chan->id, ref->handle); |
@@ -209,7 +205,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, | |||
209 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 205 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
210 | struct nouveau_engine *engine = &dev_priv->engine; | 206 | struct nouveau_engine *engine = &dev_priv->engine; |
211 | struct nouveau_gpuobj *gpuobj; | 207 | struct nouveau_gpuobj *gpuobj; |
212 | struct mem_block *pramin = NULL; | 208 | struct drm_mm *pramin = NULL; |
213 | int ret; | 209 | int ret; |
214 | 210 | ||
215 | NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n", | 211 | NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n", |
@@ -233,25 +229,12 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, | |||
233 | * available. | 229 | * available. |
234 | */ | 230 | */ |
235 | if (chan) { | 231 | if (chan) { |
236 | if (chan->ramin_heap) { | 232 | NV_DEBUG(dev, "channel heap\n"); |
237 | NV_DEBUG(dev, "private heap\n"); | 233 | pramin = &chan->ramin_heap; |
238 | pramin = chan->ramin_heap; | ||
239 | } else | ||
240 | if (dev_priv->card_type < NV_50) { | ||
241 | NV_DEBUG(dev, "global heap fallback\n"); | ||
242 | pramin = dev_priv->ramin_heap; | ||
243 | } | ||
244 | } else { | 234 | } else { |
245 | NV_DEBUG(dev, "global heap\n"); | 235 | NV_DEBUG(dev, "global heap\n"); |
246 | pramin = dev_priv->ramin_heap; | 236 | pramin = &dev_priv->ramin_heap; |
247 | } | ||
248 | |||
249 | if (!pramin) { | ||
250 | NV_ERROR(dev, "No PRAMIN heap!\n"); | ||
251 | return -EINVAL; | ||
252 | } | ||
253 | 237 | ||
254 | if (!chan) { | ||
255 | ret = engine->instmem.populate(dev, gpuobj, &size); | 238 | ret = engine->instmem.populate(dev, gpuobj, &size); |
256 | if (ret) { | 239 | if (ret) { |
257 | nouveau_gpuobj_del(dev, &gpuobj); | 240 | nouveau_gpuobj_del(dev, &gpuobj); |
@@ -260,9 +243,10 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, | |||
260 | } | 243 | } |
261 | 244 | ||
262 | /* Allocate a chunk of the PRAMIN aperture */ | 245 | /* Allocate a chunk of the PRAMIN aperture */ |
263 | gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size, | 246 | gpuobj->im_pramin = drm_mm_search_free(pramin, size, align, 0); |
264 | drm_order(align), | 247 | if (gpuobj->im_pramin) |
265 | (struct drm_file *)-2, 0); | 248 | gpuobj->im_pramin = drm_mm_get_block(gpuobj->im_pramin, size, align); |
249 | |||
266 | if (!gpuobj->im_pramin) { | 250 | if (!gpuobj->im_pramin) { |
267 | nouveau_gpuobj_del(dev, &gpuobj); | 251 | nouveau_gpuobj_del(dev, &gpuobj); |
268 | return -ENOMEM; | 252 | return -ENOMEM; |
@@ -279,10 +263,9 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, | |||
279 | if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { | 263 | if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { |
280 | int i; | 264 | int i; |
281 | 265 | ||
282 | engine->instmem.prepare_access(dev, true); | ||
283 | for (i = 0; i < gpuobj->im_pramin->size; i += 4) | 266 | for (i = 0; i < gpuobj->im_pramin->size; i += 4) |
284 | nv_wo32(dev, gpuobj, i/4, 0); | 267 | nv_wo32(dev, gpuobj, i/4, 0); |
285 | engine->instmem.finish_access(dev); | 268 | engine->instmem.flush(dev); |
286 | } | 269 | } |
287 | 270 | ||
288 | *gpuobj_ret = gpuobj; | 271 | *gpuobj_ret = gpuobj; |
@@ -370,10 +353,9 @@ nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj) | |||
370 | } | 353 | } |
371 | 354 | ||
372 | if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) { | 355 | if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) { |
373 | engine->instmem.prepare_access(dev, true); | ||
374 | for (i = 0; i < gpuobj->im_pramin->size; i += 4) | 356 | for (i = 0; i < gpuobj->im_pramin->size; i += 4) |
375 | nv_wo32(dev, gpuobj, i/4, 0); | 357 | nv_wo32(dev, gpuobj, i/4, 0); |
376 | engine->instmem.finish_access(dev); | 358 | engine->instmem.flush(dev); |
377 | } | 359 | } |
378 | 360 | ||
379 | if (gpuobj->dtor) | 361 | if (gpuobj->dtor) |
@@ -386,7 +368,7 @@ nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj) | |||
386 | if (gpuobj->flags & NVOBJ_FLAG_FAKE) | 368 | if (gpuobj->flags & NVOBJ_FLAG_FAKE) |
387 | kfree(gpuobj->im_pramin); | 369 | kfree(gpuobj->im_pramin); |
388 | else | 370 | else |
389 | nouveau_mem_free_block(gpuobj->im_pramin); | 371 | drm_mm_put_block(gpuobj->im_pramin); |
390 | } | 372 | } |
391 | 373 | ||
392 | list_del(&gpuobj->list); | 374 | list_del(&gpuobj->list); |
@@ -589,7 +571,7 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset, | |||
589 | list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); | 571 | list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); |
590 | 572 | ||
591 | if (p_offset != ~0) { | 573 | if (p_offset != ~0) { |
592 | gpuobj->im_pramin = kzalloc(sizeof(struct mem_block), | 574 | gpuobj->im_pramin = kzalloc(sizeof(struct drm_mm_node), |
593 | GFP_KERNEL); | 575 | GFP_KERNEL); |
594 | if (!gpuobj->im_pramin) { | 576 | if (!gpuobj->im_pramin) { |
595 | nouveau_gpuobj_del(dev, &gpuobj); | 577 | nouveau_gpuobj_del(dev, &gpuobj); |
@@ -605,10 +587,9 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset, | |||
605 | } | 587 | } |
606 | 588 | ||
607 | if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { | 589 | if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { |
608 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
609 | for (i = 0; i < gpuobj->im_pramin->size; i += 4) | 590 | for (i = 0; i < gpuobj->im_pramin->size; i += 4) |
610 | nv_wo32(dev, gpuobj, i/4, 0); | 591 | nv_wo32(dev, gpuobj, i/4, 0); |
611 | dev_priv->engine.instmem.finish_access(dev); | 592 | dev_priv->engine.instmem.flush(dev); |
612 | } | 593 | } |
613 | 594 | ||
614 | if (pref) { | 595 | if (pref) { |
@@ -696,8 +677,6 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, | |||
696 | return ret; | 677 | return ret; |
697 | } | 678 | } |
698 | 679 | ||
699 | instmem->prepare_access(dev, true); | ||
700 | |||
701 | if (dev_priv->card_type < NV_50) { | 680 | if (dev_priv->card_type < NV_50) { |
702 | uint32_t frame, adjust, pte_flags = 0; | 681 | uint32_t frame, adjust, pte_flags = 0; |
703 | 682 | ||
@@ -734,7 +713,7 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, | |||
734 | nv_wo32(dev, *gpuobj, 5, flags5); | 713 | nv_wo32(dev, *gpuobj, 5, flags5); |
735 | } | 714 | } |
736 | 715 | ||
737 | instmem->finish_access(dev); | 716 | instmem->flush(dev); |
738 | 717 | ||
739 | (*gpuobj)->engine = NVOBJ_ENGINE_SW; | 718 | (*gpuobj)->engine = NVOBJ_ENGINE_SW; |
740 | (*gpuobj)->class = class; | 719 | (*gpuobj)->class = class; |
@@ -849,7 +828,6 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, | |||
849 | return ret; | 828 | return ret; |
850 | } | 829 | } |
851 | 830 | ||
852 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
853 | if (dev_priv->card_type >= NV_50) { | 831 | if (dev_priv->card_type >= NV_50) { |
854 | nv_wo32(dev, *gpuobj, 0, class); | 832 | nv_wo32(dev, *gpuobj, 0, class); |
855 | nv_wo32(dev, *gpuobj, 5, 0x00010000); | 833 | nv_wo32(dev, *gpuobj, 5, 0x00010000); |
@@ -874,7 +852,7 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, | |||
874 | } | 852 | } |
875 | } | 853 | } |
876 | } | 854 | } |
877 | dev_priv->engine.instmem.finish_access(dev); | 855 | dev_priv->engine.instmem.flush(dev); |
878 | 856 | ||
879 | (*gpuobj)->engine = NVOBJ_ENGINE_GR; | 857 | (*gpuobj)->engine = NVOBJ_ENGINE_GR; |
880 | (*gpuobj)->class = class; | 858 | (*gpuobj)->class = class; |
@@ -920,6 +898,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) | |||
920 | base = 0; | 898 | base = 0; |
921 | 899 | ||
922 | /* PGRAPH context */ | 900 | /* PGRAPH context */ |
901 | size += dev_priv->engine.graph.grctx_size; | ||
923 | 902 | ||
924 | if (dev_priv->card_type == NV_50) { | 903 | if (dev_priv->card_type == NV_50) { |
925 | /* Various fixed table thingos */ | 904 | /* Various fixed table thingos */ |
@@ -930,12 +909,8 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) | |||
930 | size += 0x8000; | 909 | size += 0x8000; |
931 | /* RAMFC */ | 910 | /* RAMFC */ |
932 | size += 0x1000; | 911 | size += 0x1000; |
933 | /* PGRAPH context */ | ||
934 | size += 0x70000; | ||
935 | } | 912 | } |
936 | 913 | ||
937 | NV_DEBUG(dev, "ch%d PRAMIN size: 0x%08x bytes, base alloc=0x%08x\n", | ||
938 | chan->id, size, base); | ||
939 | ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0, | 914 | ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0, |
940 | &chan->ramin); | 915 | &chan->ramin); |
941 | if (ret) { | 916 | if (ret) { |
@@ -944,8 +919,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) | |||
944 | } | 919 | } |
945 | pramin = chan->ramin->gpuobj; | 920 | pramin = chan->ramin->gpuobj; |
946 | 921 | ||
947 | ret = nouveau_mem_init_heap(&chan->ramin_heap, | 922 | ret = drm_mm_init(&chan->ramin_heap, pramin->im_pramin->start + base, size); |
948 | pramin->im_pramin->start + base, size); | ||
949 | if (ret) { | 923 | if (ret) { |
950 | NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret); | 924 | NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret); |
951 | nouveau_gpuobj_ref_del(dev, &chan->ramin); | 925 | nouveau_gpuobj_ref_del(dev, &chan->ramin); |
@@ -969,15 +943,11 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, | |||
969 | 943 | ||
970 | NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); | 944 | NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); |
971 | 945 | ||
972 | /* Reserve a block of PRAMIN for the channel | 946 | /* Allocate a chunk of memory for per-channel object storage */ |
973 | *XXX: maybe on <NV50 too at some point | 947 | ret = nouveau_gpuobj_channel_init_pramin(chan); |
974 | */ | 948 | if (ret) { |
975 | if (0 || dev_priv->card_type == NV_50) { | 949 | NV_ERROR(dev, "init pramin\n"); |
976 | ret = nouveau_gpuobj_channel_init_pramin(chan); | 950 | return ret; |
977 | if (ret) { | ||
978 | NV_ERROR(dev, "init pramin\n"); | ||
979 | return ret; | ||
980 | } | ||
981 | } | 951 | } |
982 | 952 | ||
983 | /* NV50 VM | 953 | /* NV50 VM |
@@ -988,17 +958,13 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, | |||
988 | if (dev_priv->card_type >= NV_50) { | 958 | if (dev_priv->card_type >= NV_50) { |
989 | uint32_t vm_offset, pde; | 959 | uint32_t vm_offset, pde; |
990 | 960 | ||
991 | instmem->prepare_access(dev, true); | ||
992 | |||
993 | vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200; | 961 | vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200; |
994 | vm_offset += chan->ramin->gpuobj->im_pramin->start; | 962 | vm_offset += chan->ramin->gpuobj->im_pramin->start; |
995 | 963 | ||
996 | ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000, | 964 | ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000, |
997 | 0, &chan->vm_pd, NULL); | 965 | 0, &chan->vm_pd, NULL); |
998 | if (ret) { | 966 | if (ret) |
999 | instmem->finish_access(dev); | ||
1000 | return ret; | 967 | return ret; |
1001 | } | ||
1002 | for (i = 0; i < 0x4000; i += 8) { | 968 | for (i = 0; i < 0x4000; i += 8) { |
1003 | nv_wo32(dev, chan->vm_pd, (i+0)/4, 0x00000000); | 969 | nv_wo32(dev, chan->vm_pd, (i+0)/4, 0x00000000); |
1004 | nv_wo32(dev, chan->vm_pd, (i+4)/4, 0xdeadcafe); | 970 | nv_wo32(dev, chan->vm_pd, (i+4)/4, 0xdeadcafe); |
@@ -1008,10 +974,8 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, | |||
1008 | ret = nouveau_gpuobj_ref_add(dev, NULL, 0, | 974 | ret = nouveau_gpuobj_ref_add(dev, NULL, 0, |
1009 | dev_priv->gart_info.sg_ctxdma, | 975 | dev_priv->gart_info.sg_ctxdma, |
1010 | &chan->vm_gart_pt); | 976 | &chan->vm_gart_pt); |
1011 | if (ret) { | 977 | if (ret) |
1012 | instmem->finish_access(dev); | ||
1013 | return ret; | 978 | return ret; |
1014 | } | ||
1015 | nv_wo32(dev, chan->vm_pd, pde++, | 979 | nv_wo32(dev, chan->vm_pd, pde++, |
1016 | chan->vm_gart_pt->instance | 0x03); | 980 | chan->vm_gart_pt->instance | 0x03); |
1017 | nv_wo32(dev, chan->vm_pd, pde++, 0x00000000); | 981 | nv_wo32(dev, chan->vm_pd, pde++, 0x00000000); |
@@ -1021,17 +985,15 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, | |||
1021 | ret = nouveau_gpuobj_ref_add(dev, NULL, 0, | 985 | ret = nouveau_gpuobj_ref_add(dev, NULL, 0, |
1022 | dev_priv->vm_vram_pt[i], | 986 | dev_priv->vm_vram_pt[i], |
1023 | &chan->vm_vram_pt[i]); | 987 | &chan->vm_vram_pt[i]); |
1024 | if (ret) { | 988 | if (ret) |
1025 | instmem->finish_access(dev); | ||
1026 | return ret; | 989 | return ret; |
1027 | } | ||
1028 | 990 | ||
1029 | nv_wo32(dev, chan->vm_pd, pde++, | 991 | nv_wo32(dev, chan->vm_pd, pde++, |
1030 | chan->vm_vram_pt[i]->instance | 0x61); | 992 | chan->vm_vram_pt[i]->instance | 0x61); |
1031 | nv_wo32(dev, chan->vm_pd, pde++, 0x00000000); | 993 | nv_wo32(dev, chan->vm_pd, pde++, 0x00000000); |
1032 | } | 994 | } |
1033 | 995 | ||
1034 | instmem->finish_access(dev); | 996 | instmem->flush(dev); |
1035 | } | 997 | } |
1036 | 998 | ||
1037 | /* RAMHT */ | 999 | /* RAMHT */ |
@@ -1130,8 +1092,8 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) | |||
1130 | for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) | 1092 | for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) |
1131 | nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]); | 1093 | nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]); |
1132 | 1094 | ||
1133 | if (chan->ramin_heap) | 1095 | if (chan->ramin_heap.free_stack.next) |
1134 | nouveau_mem_takedown(&chan->ramin_heap); | 1096 | drm_mm_takedown(&chan->ramin_heap); |
1135 | if (chan->ramin) | 1097 | if (chan->ramin) |
1136 | nouveau_gpuobj_ref_del(dev, &chan->ramin); | 1098 | nouveau_gpuobj_ref_del(dev, &chan->ramin); |
1137 | 1099 | ||
@@ -1164,10 +1126,8 @@ nouveau_gpuobj_suspend(struct drm_device *dev) | |||
1164 | return -ENOMEM; | 1126 | return -ENOMEM; |
1165 | } | 1127 | } |
1166 | 1128 | ||
1167 | dev_priv->engine.instmem.prepare_access(dev, false); | ||
1168 | for (i = 0; i < gpuobj->im_pramin->size / 4; i++) | 1129 | for (i = 0; i < gpuobj->im_pramin->size / 4; i++) |
1169 | gpuobj->im_backing_suspend[i] = nv_ro32(dev, gpuobj, i); | 1130 | gpuobj->im_backing_suspend[i] = nv_ro32(dev, gpuobj, i); |
1170 | dev_priv->engine.instmem.finish_access(dev); | ||
1171 | } | 1131 | } |
1172 | 1132 | ||
1173 | return 0; | 1133 | return 0; |
@@ -1212,10 +1172,9 @@ nouveau_gpuobj_resume(struct drm_device *dev) | |||
1212 | if (!gpuobj->im_backing_suspend) | 1172 | if (!gpuobj->im_backing_suspend) |
1213 | continue; | 1173 | continue; |
1214 | 1174 | ||
1215 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
1216 | for (i = 0; i < gpuobj->im_pramin->size / 4; i++) | 1175 | for (i = 0; i < gpuobj->im_pramin->size / 4; i++) |
1217 | nv_wo32(dev, gpuobj, i, gpuobj->im_backing_suspend[i]); | 1176 | nv_wo32(dev, gpuobj, i, gpuobj->im_backing_suspend[i]); |
1218 | dev_priv->engine.instmem.finish_access(dev); | 1177 | dev_priv->engine.instmem.flush(dev); |
1219 | } | 1178 | } |
1220 | 1179 | ||
1221 | nouveau_gpuobj_suspend_cleanup(dev); | 1180 | nouveau_gpuobj_suspend_cleanup(dev); |
@@ -1232,7 +1191,6 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, | |||
1232 | struct nouveau_channel *chan; | 1191 | struct nouveau_channel *chan; |
1233 | int ret; | 1192 | int ret; |
1234 | 1193 | ||
1235 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
1236 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan); | 1194 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan); |
1237 | 1195 | ||
1238 | if (init->handle == ~0) | 1196 | if (init->handle == ~0) |
@@ -1283,7 +1241,6 @@ int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, | |||
1283 | struct nouveau_channel *chan; | 1241 | struct nouveau_channel *chan; |
1284 | int ret; | 1242 | int ret; |
1285 | 1243 | ||
1286 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
1287 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan); | 1244 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan); |
1288 | 1245 | ||
1289 | ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref); | 1246 | ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index 6ca80a3fe70d..9c1056cb8a90 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h | |||
@@ -1,19 +1,64 @@ | |||
1 | 1 | ||
2 | #define NV04_PFB_BOOT_0 0x00100000 | ||
3 | # define NV04_PFB_BOOT_0_RAM_AMOUNT 0x00000003 | ||
4 | # define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000 | ||
5 | # define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001 | ||
6 | # define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002 | ||
7 | # define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003 | ||
8 | # define NV04_PFB_BOOT_0_RAM_WIDTH_128 0x00000004 | ||
9 | # define NV04_PFB_BOOT_0_RAM_TYPE 0x00000028 | ||
10 | # define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT 0x00000000 | ||
11 | # define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT 0x00000008 | ||
12 | # define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK 0x00000010 | ||
13 | # define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT 0x00000018 | ||
14 | # define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT 0x00000020 | ||
15 | # define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16 0x00000028 | ||
16 | # define NV04_PFB_BOOT_0_UMA_ENABLE 0x00000100 | ||
17 | # define NV04_PFB_BOOT_0_UMA_SIZE 0x0000f000 | ||
18 | #define NV04_PFB_DEBUG_0 0x00100080 | ||
19 | # define NV04_PFB_DEBUG_0_PAGE_MODE 0x00000001 | ||
20 | # define NV04_PFB_DEBUG_0_REFRESH_OFF 0x00000010 | ||
21 | # define NV04_PFB_DEBUG_0_REFRESH_COUNTX64 0x00003f00 | ||
22 | # define NV04_PFB_DEBUG_0_REFRESH_SLOW_CLK 0x00004000 | ||
23 | # define NV04_PFB_DEBUG_0_SAFE_MODE 0x00008000 | ||
24 | # define NV04_PFB_DEBUG_0_ALOM_ENABLE 0x00010000 | ||
25 | # define NV04_PFB_DEBUG_0_CASOE 0x00100000 | ||
26 | # define NV04_PFB_DEBUG_0_CKE_INVERT 0x10000000 | ||
27 | # define NV04_PFB_DEBUG_0_REFINC 0x20000000 | ||
28 | # define NV04_PFB_DEBUG_0_SAVE_POWER_OFF 0x40000000 | ||
29 | #define NV04_PFB_CFG0 0x00100200 | ||
30 | # define NV04_PFB_CFG0_SCRAMBLE 0x20000000 | ||
31 | #define NV04_PFB_CFG1 0x00100204 | ||
32 | #define NV04_PFB_FIFO_DATA 0x0010020c | ||
33 | # define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000 | ||
34 | # define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20 | ||
35 | #define NV10_PFB_REFCTRL 0x00100210 | ||
36 | # define NV10_PFB_REFCTRL_VALID_1 (1 << 31) | ||
37 | #define NV04_PFB_PAD 0x0010021c | ||
38 | # define NV04_PFB_PAD_CKE_NORMAL (1 << 0) | ||
39 | #define NV10_PFB_TILE(i) (0x00100240 + (i*16)) | ||
40 | #define NV10_PFB_TILE__SIZE 8 | ||
41 | #define NV10_PFB_TLIMIT(i) (0x00100244 + (i*16)) | ||
42 | #define NV10_PFB_TSIZE(i) (0x00100248 + (i*16)) | ||
43 | #define NV10_PFB_TSTATUS(i) (0x0010024c + (i*16)) | ||
44 | #define NV04_PFB_REF 0x001002d0 | ||
45 | # define NV04_PFB_REF_CMD_REFRESH (1 << 0) | ||
46 | #define NV04_PFB_PRE 0x001002d4 | ||
47 | # define NV04_PFB_PRE_CMD_PRECHARGE (1 << 0) | ||
48 | #define NV10_PFB_CLOSE_PAGE2 0x0010033c | ||
49 | #define NV04_PFB_SCRAMBLE(i) (0x00100400 + 4 * (i)) | ||
50 | #define NV40_PFB_TILE(i) (0x00100600 + (i*16)) | ||
51 | #define NV40_PFB_TILE__SIZE_0 12 | ||
52 | #define NV40_PFB_TILE__SIZE_1 15 | ||
53 | #define NV40_PFB_TLIMIT(i) (0x00100604 + (i*16)) | ||
54 | #define NV40_PFB_TSIZE(i) (0x00100608 + (i*16)) | ||
55 | #define NV40_PFB_TSTATUS(i) (0x0010060c + (i*16)) | ||
56 | #define NV40_PFB_UNK_800 0x00100800 | ||
2 | 57 | ||
3 | #define NV03_BOOT_0 0x00100000 | 58 | #define NV_PEXTDEV_BOOT_0 0x00101000 |
4 | # define NV03_BOOT_0_RAM_AMOUNT 0x00000003 | 59 | #define NV_PEXTDEV_BOOT_0_RAMCFG 0x0000003c |
5 | # define NV03_BOOT_0_RAM_AMOUNT_8MB 0x00000000 | 60 | # define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT (8 << 12) |
6 | # define NV03_BOOT_0_RAM_AMOUNT_2MB 0x00000001 | 61 | #define NV_PEXTDEV_BOOT_3 0x0010100c |
7 | # define NV03_BOOT_0_RAM_AMOUNT_4MB 0x00000002 | ||
8 | # define NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM 0x00000003 | ||
9 | # define NV04_BOOT_0_RAM_AMOUNT_32MB 0x00000000 | ||
10 | # define NV04_BOOT_0_RAM_AMOUNT_4MB 0x00000001 | ||
11 | # define NV04_BOOT_0_RAM_AMOUNT_8MB 0x00000002 | ||
12 | # define NV04_BOOT_0_RAM_AMOUNT_16MB 0x00000003 | ||
13 | |||
14 | #define NV04_FIFO_DATA 0x0010020c | ||
15 | # define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000 | ||
16 | # define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20 | ||
17 | 62 | ||
18 | #define NV_RAMIN 0x00700000 | 63 | #define NV_RAMIN 0x00700000 |
19 | 64 | ||
@@ -131,23 +176,6 @@ | |||
131 | #define NV04_PTIMER_TIME_1 0x00009410 | 176 | #define NV04_PTIMER_TIME_1 0x00009410 |
132 | #define NV04_PTIMER_ALARM_0 0x00009420 | 177 | #define NV04_PTIMER_ALARM_0 0x00009420 |
133 | 178 | ||
134 | #define NV04_PFB_CFG0 0x00100200 | ||
135 | #define NV04_PFB_CFG1 0x00100204 | ||
136 | #define NV40_PFB_020C 0x0010020C | ||
137 | #define NV10_PFB_TILE(i) (0x00100240 + (i*16)) | ||
138 | #define NV10_PFB_TILE__SIZE 8 | ||
139 | #define NV10_PFB_TLIMIT(i) (0x00100244 + (i*16)) | ||
140 | #define NV10_PFB_TSIZE(i) (0x00100248 + (i*16)) | ||
141 | #define NV10_PFB_TSTATUS(i) (0x0010024C + (i*16)) | ||
142 | #define NV10_PFB_CLOSE_PAGE2 0x0010033C | ||
143 | #define NV40_PFB_TILE(i) (0x00100600 + (i*16)) | ||
144 | #define NV40_PFB_TILE__SIZE_0 12 | ||
145 | #define NV40_PFB_TILE__SIZE_1 15 | ||
146 | #define NV40_PFB_TLIMIT(i) (0x00100604 + (i*16)) | ||
147 | #define NV40_PFB_TSIZE(i) (0x00100608 + (i*16)) | ||
148 | #define NV40_PFB_TSTATUS(i) (0x0010060C + (i*16)) | ||
149 | #define NV40_PFB_UNK_800 0x00100800 | ||
150 | |||
151 | #define NV04_PGRAPH_DEBUG_0 0x00400080 | 179 | #define NV04_PGRAPH_DEBUG_0 0x00400080 |
152 | #define NV04_PGRAPH_DEBUG_1 0x00400084 | 180 | #define NV04_PGRAPH_DEBUG_1 0x00400084 |
153 | #define NV04_PGRAPH_DEBUG_2 0x00400088 | 181 | #define NV04_PGRAPH_DEBUG_2 0x00400088 |
@@ -814,6 +842,7 @@ | |||
814 | #define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000 | 842 | #define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000 |
815 | #define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff | 843 | #define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff |
816 | #define NV50_SOR_DP_CTRL(i,l) (0x0061c10c + (i) * 0x800 + (l) * 0x80) | 844 | #define NV50_SOR_DP_CTRL(i,l) (0x0061c10c + (i) * 0x800 + (l) * 0x80) |
845 | #define NV50_SOR_DP_CTRL_ENABLED 0x00000001 | ||
817 | #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000 | 846 | #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000 |
818 | #define NV50_SOR_DP_CTRL_LANE_MASK 0x001f0000 | 847 | #define NV50_SOR_DP_CTRL_LANE_MASK 0x001f0000 |
819 | #define NV50_SOR_DP_CTRL_LANE_0_ENABLED 0x00010000 | 848 | #define NV50_SOR_DP_CTRL_LANE_0_ENABLED 0x00010000 |
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 1d6ee8b55154..491767fe4fcf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
@@ -97,7 +97,6 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) | |||
97 | 97 | ||
98 | NV_DEBUG(dev, "pg=0x%lx\n", mem->mm_node->start); | 98 | NV_DEBUG(dev, "pg=0x%lx\n", mem->mm_node->start); |
99 | 99 | ||
100 | dev_priv->engine.instmem.prepare_access(nvbe->dev, true); | ||
101 | pte = nouveau_sgdma_pte(nvbe->dev, mem->mm_node->start << PAGE_SHIFT); | 100 | pte = nouveau_sgdma_pte(nvbe->dev, mem->mm_node->start << PAGE_SHIFT); |
102 | nvbe->pte_start = pte; | 101 | nvbe->pte_start = pte; |
103 | for (i = 0; i < nvbe->nr_pages; i++) { | 102 | for (i = 0; i < nvbe->nr_pages; i++) { |
@@ -116,24 +115,11 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) | |||
116 | dma_offset += NV_CTXDMA_PAGE_SIZE; | 115 | dma_offset += NV_CTXDMA_PAGE_SIZE; |
117 | } | 116 | } |
118 | } | 117 | } |
119 | dev_priv->engine.instmem.finish_access(nvbe->dev); | 118 | dev_priv->engine.instmem.flush(nvbe->dev); |
120 | 119 | ||
121 | if (dev_priv->card_type == NV_50) { | 120 | if (dev_priv->card_type == NV_50) { |
122 | nv_wr32(dev, 0x100c80, 0x00050001); | 121 | nv50_vm_flush(dev, 5); /* PGRAPH */ |
123 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | 122 | nv50_vm_flush(dev, 0); /* PFIFO */ |
124 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
125 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", | ||
126 | nv_rd32(dev, 0x100c80)); | ||
127 | return -EBUSY; | ||
128 | } | ||
129 | |||
130 | nv_wr32(dev, 0x100c80, 0x00000001); | ||
131 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
132 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
133 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", | ||
134 | nv_rd32(dev, 0x100c80)); | ||
135 | return -EBUSY; | ||
136 | } | ||
137 | } | 123 | } |
138 | 124 | ||
139 | nvbe->bound = true; | 125 | nvbe->bound = true; |
@@ -154,7 +140,6 @@ nouveau_sgdma_unbind(struct ttm_backend *be) | |||
154 | if (!nvbe->bound) | 140 | if (!nvbe->bound) |
155 | return 0; | 141 | return 0; |
156 | 142 | ||
157 | dev_priv->engine.instmem.prepare_access(nvbe->dev, true); | ||
158 | pte = nvbe->pte_start; | 143 | pte = nvbe->pte_start; |
159 | for (i = 0; i < nvbe->nr_pages; i++) { | 144 | for (i = 0; i < nvbe->nr_pages; i++) { |
160 | dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus; | 145 | dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus; |
@@ -170,24 +155,11 @@ nouveau_sgdma_unbind(struct ttm_backend *be) | |||
170 | dma_offset += NV_CTXDMA_PAGE_SIZE; | 155 | dma_offset += NV_CTXDMA_PAGE_SIZE; |
171 | } | 156 | } |
172 | } | 157 | } |
173 | dev_priv->engine.instmem.finish_access(nvbe->dev); | 158 | dev_priv->engine.instmem.flush(nvbe->dev); |
174 | 159 | ||
175 | if (dev_priv->card_type == NV_50) { | 160 | if (dev_priv->card_type == NV_50) { |
176 | nv_wr32(dev, 0x100c80, 0x00050001); | 161 | nv50_vm_flush(dev, 5); |
177 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | 162 | nv50_vm_flush(dev, 0); |
178 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
179 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", | ||
180 | nv_rd32(dev, 0x100c80)); | ||
181 | return -EBUSY; | ||
182 | } | ||
183 | |||
184 | nv_wr32(dev, 0x100c80, 0x00000001); | ||
185 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
186 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
187 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", | ||
188 | nv_rd32(dev, 0x100c80)); | ||
189 | return -EBUSY; | ||
190 | } | ||
191 | } | 163 | } |
192 | 164 | ||
193 | nvbe->bound = false; | 165 | nvbe->bound = false; |
@@ -272,7 +244,6 @@ nouveau_sgdma_init(struct drm_device *dev) | |||
272 | pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0, | 244 | pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0, |
273 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 245 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
274 | 246 | ||
275 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
276 | if (dev_priv->card_type < NV_50) { | 247 | if (dev_priv->card_type < NV_50) { |
277 | /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and | 248 | /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and |
278 | * confirmed to work on c51. Perhaps means NV_DMA_TARGET_PCIE | 249 | * confirmed to work on c51. Perhaps means NV_DMA_TARGET_PCIE |
@@ -294,7 +265,7 @@ nouveau_sgdma_init(struct drm_device *dev) | |||
294 | nv_wo32(dev, gpuobj, (i+4)/4, 0); | 265 | nv_wo32(dev, gpuobj, (i+4)/4, 0); |
295 | } | 266 | } |
296 | } | 267 | } |
297 | dev_priv->engine.instmem.finish_access(dev); | 268 | dev_priv->engine.instmem.flush(dev); |
298 | 269 | ||
299 | dev_priv->gart_info.type = NOUVEAU_GART_SGDMA; | 270 | dev_priv->gart_info.type = NOUVEAU_GART_SGDMA; |
300 | dev_priv->gart_info.aper_base = 0; | 271 | dev_priv->gart_info.aper_base = 0; |
@@ -325,14 +296,11 @@ nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page) | |||
325 | { | 296 | { |
326 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 297 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
327 | struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; | 298 | struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; |
328 | struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; | ||
329 | int pte; | 299 | int pte; |
330 | 300 | ||
331 | pte = (offset >> NV_CTXDMA_PAGE_SHIFT); | 301 | pte = (offset >> NV_CTXDMA_PAGE_SHIFT); |
332 | if (dev_priv->card_type < NV_50) { | 302 | if (dev_priv->card_type < NV_50) { |
333 | instmem->prepare_access(dev, false); | ||
334 | *page = nv_ro32(dev, gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK; | 303 | *page = nv_ro32(dev, gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK; |
335 | instmem->finish_access(dev); | ||
336 | return 0; | 304 | return 0; |
337 | } | 305 | } |
338 | 306 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index b02a231d6937..ee3729e7823b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "nv50_display.h" | 38 | #include "nv50_display.h" |
39 | 39 | ||
40 | static void nouveau_stub_takedown(struct drm_device *dev) {} | 40 | static void nouveau_stub_takedown(struct drm_device *dev) {} |
41 | static int nouveau_stub_init(struct drm_device *dev) { return 0; } | ||
41 | 42 | ||
42 | static int nouveau_init_engine_ptrs(struct drm_device *dev) | 43 | static int nouveau_init_engine_ptrs(struct drm_device *dev) |
43 | { | 44 | { |
@@ -54,8 +55,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
54 | engine->instmem.clear = nv04_instmem_clear; | 55 | engine->instmem.clear = nv04_instmem_clear; |
55 | engine->instmem.bind = nv04_instmem_bind; | 56 | engine->instmem.bind = nv04_instmem_bind; |
56 | engine->instmem.unbind = nv04_instmem_unbind; | 57 | engine->instmem.unbind = nv04_instmem_unbind; |
57 | engine->instmem.prepare_access = nv04_instmem_prepare_access; | 58 | engine->instmem.flush = nv04_instmem_flush; |
58 | engine->instmem.finish_access = nv04_instmem_finish_access; | ||
59 | engine->mc.init = nv04_mc_init; | 59 | engine->mc.init = nv04_mc_init; |
60 | engine->mc.takedown = nv04_mc_takedown; | 60 | engine->mc.takedown = nv04_mc_takedown; |
61 | engine->timer.init = nv04_timer_init; | 61 | engine->timer.init = nv04_timer_init; |
@@ -85,6 +85,16 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
85 | engine->fifo.destroy_context = nv04_fifo_destroy_context; | 85 | engine->fifo.destroy_context = nv04_fifo_destroy_context; |
86 | engine->fifo.load_context = nv04_fifo_load_context; | 86 | engine->fifo.load_context = nv04_fifo_load_context; |
87 | engine->fifo.unload_context = nv04_fifo_unload_context; | 87 | engine->fifo.unload_context = nv04_fifo_unload_context; |
88 | engine->display.early_init = nv04_display_early_init; | ||
89 | engine->display.late_takedown = nv04_display_late_takedown; | ||
90 | engine->display.create = nv04_display_create; | ||
91 | engine->display.init = nv04_display_init; | ||
92 | engine->display.destroy = nv04_display_destroy; | ||
93 | engine->gpio.init = nouveau_stub_init; | ||
94 | engine->gpio.takedown = nouveau_stub_takedown; | ||
95 | engine->gpio.get = NULL; | ||
96 | engine->gpio.set = NULL; | ||
97 | engine->gpio.irq_enable = NULL; | ||
88 | break; | 98 | break; |
89 | case 0x10: | 99 | case 0x10: |
90 | engine->instmem.init = nv04_instmem_init; | 100 | engine->instmem.init = nv04_instmem_init; |
@@ -95,8 +105,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
95 | engine->instmem.clear = nv04_instmem_clear; | 105 | engine->instmem.clear = nv04_instmem_clear; |
96 | engine->instmem.bind = nv04_instmem_bind; | 106 | engine->instmem.bind = nv04_instmem_bind; |
97 | engine->instmem.unbind = nv04_instmem_unbind; | 107 | engine->instmem.unbind = nv04_instmem_unbind; |
98 | engine->instmem.prepare_access = nv04_instmem_prepare_access; | 108 | engine->instmem.flush = nv04_instmem_flush; |
99 | engine->instmem.finish_access = nv04_instmem_finish_access; | ||
100 | engine->mc.init = nv04_mc_init; | 109 | engine->mc.init = nv04_mc_init; |
101 | engine->mc.takedown = nv04_mc_takedown; | 110 | engine->mc.takedown = nv04_mc_takedown; |
102 | engine->timer.init = nv04_timer_init; | 111 | engine->timer.init = nv04_timer_init; |
@@ -128,6 +137,16 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
128 | engine->fifo.destroy_context = nv10_fifo_destroy_context; | 137 | engine->fifo.destroy_context = nv10_fifo_destroy_context; |
129 | engine->fifo.load_context = nv10_fifo_load_context; | 138 | engine->fifo.load_context = nv10_fifo_load_context; |
130 | engine->fifo.unload_context = nv10_fifo_unload_context; | 139 | engine->fifo.unload_context = nv10_fifo_unload_context; |
140 | engine->display.early_init = nv04_display_early_init; | ||
141 | engine->display.late_takedown = nv04_display_late_takedown; | ||
142 | engine->display.create = nv04_display_create; | ||
143 | engine->display.init = nv04_display_init; | ||
144 | engine->display.destroy = nv04_display_destroy; | ||
145 | engine->gpio.init = nouveau_stub_init; | ||
146 | engine->gpio.takedown = nouveau_stub_takedown; | ||
147 | engine->gpio.get = nv10_gpio_get; | ||
148 | engine->gpio.set = nv10_gpio_set; | ||
149 | engine->gpio.irq_enable = NULL; | ||
131 | break; | 150 | break; |
132 | case 0x20: | 151 | case 0x20: |
133 | engine->instmem.init = nv04_instmem_init; | 152 | engine->instmem.init = nv04_instmem_init; |
@@ -138,8 +157,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
138 | engine->instmem.clear = nv04_instmem_clear; | 157 | engine->instmem.clear = nv04_instmem_clear; |
139 | engine->instmem.bind = nv04_instmem_bind; | 158 | engine->instmem.bind = nv04_instmem_bind; |
140 | engine->instmem.unbind = nv04_instmem_unbind; | 159 | engine->instmem.unbind = nv04_instmem_unbind; |
141 | engine->instmem.prepare_access = nv04_instmem_prepare_access; | 160 | engine->instmem.flush = nv04_instmem_flush; |
142 | engine->instmem.finish_access = nv04_instmem_finish_access; | ||
143 | engine->mc.init = nv04_mc_init; | 161 | engine->mc.init = nv04_mc_init; |
144 | engine->mc.takedown = nv04_mc_takedown; | 162 | engine->mc.takedown = nv04_mc_takedown; |
145 | engine->timer.init = nv04_timer_init; | 163 | engine->timer.init = nv04_timer_init; |
@@ -171,6 +189,16 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
171 | engine->fifo.destroy_context = nv10_fifo_destroy_context; | 189 | engine->fifo.destroy_context = nv10_fifo_destroy_context; |
172 | engine->fifo.load_context = nv10_fifo_load_context; | 190 | engine->fifo.load_context = nv10_fifo_load_context; |
173 | engine->fifo.unload_context = nv10_fifo_unload_context; | 191 | engine->fifo.unload_context = nv10_fifo_unload_context; |
192 | engine->display.early_init = nv04_display_early_init; | ||
193 | engine->display.late_takedown = nv04_display_late_takedown; | ||
194 | engine->display.create = nv04_display_create; | ||
195 | engine->display.init = nv04_display_init; | ||
196 | engine->display.destroy = nv04_display_destroy; | ||
197 | engine->gpio.init = nouveau_stub_init; | ||
198 | engine->gpio.takedown = nouveau_stub_takedown; | ||
199 | engine->gpio.get = nv10_gpio_get; | ||
200 | engine->gpio.set = nv10_gpio_set; | ||
201 | engine->gpio.irq_enable = NULL; | ||
174 | break; | 202 | break; |
175 | case 0x30: | 203 | case 0x30: |
176 | engine->instmem.init = nv04_instmem_init; | 204 | engine->instmem.init = nv04_instmem_init; |
@@ -181,15 +209,14 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
181 | engine->instmem.clear = nv04_instmem_clear; | 209 | engine->instmem.clear = nv04_instmem_clear; |
182 | engine->instmem.bind = nv04_instmem_bind; | 210 | engine->instmem.bind = nv04_instmem_bind; |
183 | engine->instmem.unbind = nv04_instmem_unbind; | 211 | engine->instmem.unbind = nv04_instmem_unbind; |
184 | engine->instmem.prepare_access = nv04_instmem_prepare_access; | 212 | engine->instmem.flush = nv04_instmem_flush; |
185 | engine->instmem.finish_access = nv04_instmem_finish_access; | ||
186 | engine->mc.init = nv04_mc_init; | 213 | engine->mc.init = nv04_mc_init; |
187 | engine->mc.takedown = nv04_mc_takedown; | 214 | engine->mc.takedown = nv04_mc_takedown; |
188 | engine->timer.init = nv04_timer_init; | 215 | engine->timer.init = nv04_timer_init; |
189 | engine->timer.read = nv04_timer_read; | 216 | engine->timer.read = nv04_timer_read; |
190 | engine->timer.takedown = nv04_timer_takedown; | 217 | engine->timer.takedown = nv04_timer_takedown; |
191 | engine->fb.init = nv10_fb_init; | 218 | engine->fb.init = nv30_fb_init; |
192 | engine->fb.takedown = nv10_fb_takedown; | 219 | engine->fb.takedown = nv30_fb_takedown; |
193 | engine->fb.set_region_tiling = nv10_fb_set_region_tiling; | 220 | engine->fb.set_region_tiling = nv10_fb_set_region_tiling; |
194 | engine->graph.grclass = nv30_graph_grclass; | 221 | engine->graph.grclass = nv30_graph_grclass; |
195 | engine->graph.init = nv30_graph_init; | 222 | engine->graph.init = nv30_graph_init; |
@@ -214,6 +241,16 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
214 | engine->fifo.destroy_context = nv10_fifo_destroy_context; | 241 | engine->fifo.destroy_context = nv10_fifo_destroy_context; |
215 | engine->fifo.load_context = nv10_fifo_load_context; | 242 | engine->fifo.load_context = nv10_fifo_load_context; |
216 | engine->fifo.unload_context = nv10_fifo_unload_context; | 243 | engine->fifo.unload_context = nv10_fifo_unload_context; |
244 | engine->display.early_init = nv04_display_early_init; | ||
245 | engine->display.late_takedown = nv04_display_late_takedown; | ||
246 | engine->display.create = nv04_display_create; | ||
247 | engine->display.init = nv04_display_init; | ||
248 | engine->display.destroy = nv04_display_destroy; | ||
249 | engine->gpio.init = nouveau_stub_init; | ||
250 | engine->gpio.takedown = nouveau_stub_takedown; | ||
251 | engine->gpio.get = nv10_gpio_get; | ||
252 | engine->gpio.set = nv10_gpio_set; | ||
253 | engine->gpio.irq_enable = NULL; | ||
217 | break; | 254 | break; |
218 | case 0x40: | 255 | case 0x40: |
219 | case 0x60: | 256 | case 0x60: |
@@ -225,8 +262,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
225 | engine->instmem.clear = nv04_instmem_clear; | 262 | engine->instmem.clear = nv04_instmem_clear; |
226 | engine->instmem.bind = nv04_instmem_bind; | 263 | engine->instmem.bind = nv04_instmem_bind; |
227 | engine->instmem.unbind = nv04_instmem_unbind; | 264 | engine->instmem.unbind = nv04_instmem_unbind; |
228 | engine->instmem.prepare_access = nv04_instmem_prepare_access; | 265 | engine->instmem.flush = nv04_instmem_flush; |
229 | engine->instmem.finish_access = nv04_instmem_finish_access; | ||
230 | engine->mc.init = nv40_mc_init; | 266 | engine->mc.init = nv40_mc_init; |
231 | engine->mc.takedown = nv40_mc_takedown; | 267 | engine->mc.takedown = nv40_mc_takedown; |
232 | engine->timer.init = nv04_timer_init; | 268 | engine->timer.init = nv04_timer_init; |
@@ -258,6 +294,16 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
258 | engine->fifo.destroy_context = nv40_fifo_destroy_context; | 294 | engine->fifo.destroy_context = nv40_fifo_destroy_context; |
259 | engine->fifo.load_context = nv40_fifo_load_context; | 295 | engine->fifo.load_context = nv40_fifo_load_context; |
260 | engine->fifo.unload_context = nv40_fifo_unload_context; | 296 | engine->fifo.unload_context = nv40_fifo_unload_context; |
297 | engine->display.early_init = nv04_display_early_init; | ||
298 | engine->display.late_takedown = nv04_display_late_takedown; | ||
299 | engine->display.create = nv04_display_create; | ||
300 | engine->display.init = nv04_display_init; | ||
301 | engine->display.destroy = nv04_display_destroy; | ||
302 | engine->gpio.init = nouveau_stub_init; | ||
303 | engine->gpio.takedown = nouveau_stub_takedown; | ||
304 | engine->gpio.get = nv10_gpio_get; | ||
305 | engine->gpio.set = nv10_gpio_set; | ||
306 | engine->gpio.irq_enable = NULL; | ||
261 | break; | 307 | break; |
262 | case 0x50: | 308 | case 0x50: |
263 | case 0x80: /* gotta love NVIDIA's consistency.. */ | 309 | case 0x80: /* gotta love NVIDIA's consistency.. */ |
@@ -271,8 +317,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
271 | engine->instmem.clear = nv50_instmem_clear; | 317 | engine->instmem.clear = nv50_instmem_clear; |
272 | engine->instmem.bind = nv50_instmem_bind; | 318 | engine->instmem.bind = nv50_instmem_bind; |
273 | engine->instmem.unbind = nv50_instmem_unbind; | 319 | engine->instmem.unbind = nv50_instmem_unbind; |
274 | engine->instmem.prepare_access = nv50_instmem_prepare_access; | 320 | if (dev_priv->chipset == 0x50) |
275 | engine->instmem.finish_access = nv50_instmem_finish_access; | 321 | engine->instmem.flush = nv50_instmem_flush; |
322 | else | ||
323 | engine->instmem.flush = nv84_instmem_flush; | ||
276 | engine->mc.init = nv50_mc_init; | 324 | engine->mc.init = nv50_mc_init; |
277 | engine->mc.takedown = nv50_mc_takedown; | 325 | engine->mc.takedown = nv50_mc_takedown; |
278 | engine->timer.init = nv04_timer_init; | 326 | engine->timer.init = nv04_timer_init; |
@@ -300,6 +348,16 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
300 | engine->fifo.destroy_context = nv50_fifo_destroy_context; | 348 | engine->fifo.destroy_context = nv50_fifo_destroy_context; |
301 | engine->fifo.load_context = nv50_fifo_load_context; | 349 | engine->fifo.load_context = nv50_fifo_load_context; |
302 | engine->fifo.unload_context = nv50_fifo_unload_context; | 350 | engine->fifo.unload_context = nv50_fifo_unload_context; |
351 | engine->display.early_init = nv50_display_early_init; | ||
352 | engine->display.late_takedown = nv50_display_late_takedown; | ||
353 | engine->display.create = nv50_display_create; | ||
354 | engine->display.init = nv50_display_init; | ||
355 | engine->display.destroy = nv50_display_destroy; | ||
356 | engine->gpio.init = nv50_gpio_init; | ||
357 | engine->gpio.takedown = nouveau_stub_takedown; | ||
358 | engine->gpio.get = nv50_gpio_get; | ||
359 | engine->gpio.set = nv50_gpio_set; | ||
360 | engine->gpio.irq_enable = nv50_gpio_irq_enable; | ||
303 | break; | 361 | break; |
304 | default: | 362 | default: |
305 | NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); | 363 | NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); |
@@ -407,11 +465,6 @@ nouveau_card_init(struct drm_device *dev) | |||
407 | struct nouveau_engine *engine; | 465 | struct nouveau_engine *engine; |
408 | int ret; | 466 | int ret; |
409 | 467 | ||
410 | NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); | ||
411 | |||
412 | if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE) | ||
413 | return 0; | ||
414 | |||
415 | vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); | 468 | vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); |
416 | vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, | 469 | vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, |
417 | nouveau_switcheroo_can_switch); | 470 | nouveau_switcheroo_can_switch); |
@@ -421,15 +474,17 @@ nouveau_card_init(struct drm_device *dev) | |||
421 | if (ret) | 474 | if (ret) |
422 | goto out; | 475 | goto out; |
423 | engine = &dev_priv->engine; | 476 | engine = &dev_priv->engine; |
424 | dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; | ||
425 | spin_lock_init(&dev_priv->context_switch_lock); | 477 | spin_lock_init(&dev_priv->context_switch_lock); |
426 | 478 | ||
479 | /* Make the CRTCs and I2C buses accessible */ | ||
480 | ret = engine->display.early_init(dev); | ||
481 | if (ret) | ||
482 | goto out; | ||
483 | |||
427 | /* Parse BIOS tables / Run init tables if card not POSTed */ | 484 | /* Parse BIOS tables / Run init tables if card not POSTed */ |
428 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 485 | ret = nouveau_bios_init(dev); |
429 | ret = nouveau_bios_init(dev); | 486 | if (ret) |
430 | if (ret) | 487 | goto out_display_early; |
431 | goto out; | ||
432 | } | ||
433 | 488 | ||
434 | ret = nouveau_mem_detect(dev); | 489 | ret = nouveau_mem_detect(dev); |
435 | if (ret) | 490 | if (ret) |
@@ -461,10 +516,15 @@ nouveau_card_init(struct drm_device *dev) | |||
461 | if (ret) | 516 | if (ret) |
462 | goto out_gpuobj; | 517 | goto out_gpuobj; |
463 | 518 | ||
519 | /* PGPIO */ | ||
520 | ret = engine->gpio.init(dev); | ||
521 | if (ret) | ||
522 | goto out_mc; | ||
523 | |||
464 | /* PTIMER */ | 524 | /* PTIMER */ |
465 | ret = engine->timer.init(dev); | 525 | ret = engine->timer.init(dev); |
466 | if (ret) | 526 | if (ret) |
467 | goto out_mc; | 527 | goto out_gpio; |
468 | 528 | ||
469 | /* PFB */ | 529 | /* PFB */ |
470 | ret = engine->fb.init(dev); | 530 | ret = engine->fb.init(dev); |
@@ -485,12 +545,16 @@ nouveau_card_init(struct drm_device *dev) | |||
485 | goto out_graph; | 545 | goto out_graph; |
486 | } | 546 | } |
487 | 547 | ||
548 | ret = engine->display.create(dev); | ||
549 | if (ret) | ||
550 | goto out_fifo; | ||
551 | |||
488 | /* this call irq_preinstall, register irq handler and | 552 | /* this call irq_preinstall, register irq handler and |
489 | * call irq_postinstall | 553 | * call irq_postinstall |
490 | */ | 554 | */ |
491 | ret = drm_irq_install(dev); | 555 | ret = drm_irq_install(dev); |
492 | if (ret) | 556 | if (ret) |
493 | goto out_fifo; | 557 | goto out_display; |
494 | 558 | ||
495 | ret = drm_vblank_init(dev, 0); | 559 | ret = drm_vblank_init(dev, 0); |
496 | if (ret) | 560 | if (ret) |
@@ -504,35 +568,18 @@ nouveau_card_init(struct drm_device *dev) | |||
504 | goto out_irq; | 568 | goto out_irq; |
505 | } | 569 | } |
506 | 570 | ||
507 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
508 | if (dev_priv->card_type >= NV_50) | ||
509 | ret = nv50_display_create(dev); | ||
510 | else | ||
511 | ret = nv04_display_create(dev); | ||
512 | if (ret) | ||
513 | goto out_channel; | ||
514 | } | ||
515 | |||
516 | ret = nouveau_backlight_init(dev); | 571 | ret = nouveau_backlight_init(dev); |
517 | if (ret) | 572 | if (ret) |
518 | NV_ERROR(dev, "Error %d registering backlight\n", ret); | 573 | NV_ERROR(dev, "Error %d registering backlight\n", ret); |
519 | 574 | ||
520 | dev_priv->init_state = NOUVEAU_CARD_INIT_DONE; | 575 | nouveau_fbcon_init(dev); |
521 | 576 | drm_kms_helper_poll_init(dev); | |
522 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
523 | nouveau_fbcon_init(dev); | ||
524 | drm_kms_helper_poll_init(dev); | ||
525 | } | ||
526 | |||
527 | return 0; | 577 | return 0; |
528 | 578 | ||
529 | out_channel: | ||
530 | if (dev_priv->channel) { | ||
531 | nouveau_channel_free(dev_priv->channel); | ||
532 | dev_priv->channel = NULL; | ||
533 | } | ||
534 | out_irq: | 579 | out_irq: |
535 | drm_irq_uninstall(dev); | 580 | drm_irq_uninstall(dev); |
581 | out_display: | ||
582 | engine->display.destroy(dev); | ||
536 | out_fifo: | 583 | out_fifo: |
537 | if (!nouveau_noaccel) | 584 | if (!nouveau_noaccel) |
538 | engine->fifo.takedown(dev); | 585 | engine->fifo.takedown(dev); |
@@ -543,6 +590,8 @@ out_fb: | |||
543 | engine->fb.takedown(dev); | 590 | engine->fb.takedown(dev); |
544 | out_timer: | 591 | out_timer: |
545 | engine->timer.takedown(dev); | 592 | engine->timer.takedown(dev); |
593 | out_gpio: | ||
594 | engine->gpio.takedown(dev); | ||
546 | out_mc: | 595 | out_mc: |
547 | engine->mc.takedown(dev); | 596 | engine->mc.takedown(dev); |
548 | out_gpuobj: | 597 | out_gpuobj: |
@@ -556,6 +605,8 @@ out_gpuobj_early: | |||
556 | nouveau_gpuobj_late_takedown(dev); | 605 | nouveau_gpuobj_late_takedown(dev); |
557 | out_bios: | 606 | out_bios: |
558 | nouveau_bios_takedown(dev); | 607 | nouveau_bios_takedown(dev); |
608 | out_display_early: | ||
609 | engine->display.late_takedown(dev); | ||
559 | out: | 610 | out: |
560 | vga_client_register(dev->pdev, NULL, NULL, NULL); | 611 | vga_client_register(dev->pdev, NULL, NULL, NULL); |
561 | return ret; | 612 | return ret; |
@@ -566,45 +617,39 @@ static void nouveau_card_takedown(struct drm_device *dev) | |||
566 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 617 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
567 | struct nouveau_engine *engine = &dev_priv->engine; | 618 | struct nouveau_engine *engine = &dev_priv->engine; |
568 | 619 | ||
569 | NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); | 620 | nouveau_backlight_exit(dev); |
570 | |||
571 | if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) { | ||
572 | |||
573 | nouveau_backlight_exit(dev); | ||
574 | |||
575 | if (dev_priv->channel) { | ||
576 | nouveau_channel_free(dev_priv->channel); | ||
577 | dev_priv->channel = NULL; | ||
578 | } | ||
579 | 621 | ||
580 | if (!nouveau_noaccel) { | 622 | if (dev_priv->channel) { |
581 | engine->fifo.takedown(dev); | 623 | nouveau_channel_free(dev_priv->channel); |
582 | engine->graph.takedown(dev); | 624 | dev_priv->channel = NULL; |
583 | } | 625 | } |
584 | engine->fb.takedown(dev); | ||
585 | engine->timer.takedown(dev); | ||
586 | engine->mc.takedown(dev); | ||
587 | 626 | ||
588 | mutex_lock(&dev->struct_mutex); | 627 | if (!nouveau_noaccel) { |
589 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); | 628 | engine->fifo.takedown(dev); |
590 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); | 629 | engine->graph.takedown(dev); |
591 | mutex_unlock(&dev->struct_mutex); | 630 | } |
592 | nouveau_sgdma_takedown(dev); | 631 | engine->fb.takedown(dev); |
632 | engine->timer.takedown(dev); | ||
633 | engine->gpio.takedown(dev); | ||
634 | engine->mc.takedown(dev); | ||
635 | engine->display.late_takedown(dev); | ||
593 | 636 | ||
594 | nouveau_gpuobj_takedown(dev); | 637 | mutex_lock(&dev->struct_mutex); |
595 | nouveau_mem_close(dev); | 638 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); |
596 | engine->instmem.takedown(dev); | 639 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); |
640 | mutex_unlock(&dev->struct_mutex); | ||
641 | nouveau_sgdma_takedown(dev); | ||
597 | 642 | ||
598 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 643 | nouveau_gpuobj_takedown(dev); |
599 | drm_irq_uninstall(dev); | 644 | nouveau_mem_close(dev); |
645 | engine->instmem.takedown(dev); | ||
600 | 646 | ||
601 | nouveau_gpuobj_late_takedown(dev); | 647 | drm_irq_uninstall(dev); |
602 | nouveau_bios_takedown(dev); | ||
603 | 648 | ||
604 | vga_client_register(dev->pdev, NULL, NULL, NULL); | 649 | nouveau_gpuobj_late_takedown(dev); |
650 | nouveau_bios_takedown(dev); | ||
605 | 651 | ||
606 | dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN; | 652 | vga_client_register(dev->pdev, NULL, NULL, NULL); |
607 | } | ||
608 | } | 653 | } |
609 | 654 | ||
610 | /* here a client dies, release the stuff that was allocated for its | 655 | /* here a client dies, release the stuff that was allocated for its |
@@ -691,6 +736,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) | |||
691 | struct drm_nouveau_private *dev_priv; | 736 | struct drm_nouveau_private *dev_priv; |
692 | uint32_t reg0; | 737 | uint32_t reg0; |
693 | resource_size_t mmio_start_offs; | 738 | resource_size_t mmio_start_offs; |
739 | int ret; | ||
694 | 740 | ||
695 | dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); | 741 | dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); |
696 | if (!dev_priv) | 742 | if (!dev_priv) |
@@ -699,7 +745,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) | |||
699 | dev_priv->dev = dev; | 745 | dev_priv->dev = dev; |
700 | 746 | ||
701 | dev_priv->flags = flags & NOUVEAU_FLAGS; | 747 | dev_priv->flags = flags & NOUVEAU_FLAGS; |
702 | dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN; | ||
703 | 748 | ||
704 | NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", | 749 | NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", |
705 | dev->pci_vendor, dev->pci_device, dev->pdev->class); | 750 | dev->pci_vendor, dev->pci_device, dev->pdev->class); |
@@ -773,11 +818,9 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) | |||
773 | NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n", | 818 | NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n", |
774 | dev_priv->card_type, reg0); | 819 | dev_priv->card_type, reg0); |
775 | 820 | ||
776 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 821 | ret = nouveau_remove_conflicting_drivers(dev); |
777 | int ret = nouveau_remove_conflicting_drivers(dev); | 822 | if (ret) |
778 | if (ret) | 823 | return ret; |
779 | return ret; | ||
780 | } | ||
781 | 824 | ||
782 | /* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */ | 825 | /* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */ |
783 | if (dev_priv->card_type >= NV_40) { | 826 | if (dev_priv->card_type >= NV_40) { |
@@ -812,46 +855,26 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) | |||
812 | dev_priv->flags |= NV_NFORCE2; | 855 | dev_priv->flags |= NV_NFORCE2; |
813 | 856 | ||
814 | /* For kernel modesetting, init card now and bring up fbcon */ | 857 | /* For kernel modesetting, init card now and bring up fbcon */ |
815 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 858 | ret = nouveau_card_init(dev); |
816 | int ret = nouveau_card_init(dev); | 859 | if (ret) |
817 | if (ret) | 860 | return ret; |
818 | return ret; | ||
819 | } | ||
820 | 861 | ||
821 | return 0; | 862 | return 0; |
822 | } | 863 | } |
823 | 864 | ||
824 | static void nouveau_close(struct drm_device *dev) | ||
825 | { | ||
826 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
827 | |||
828 | /* In the case of an error dev_priv may not be allocated yet */ | ||
829 | if (dev_priv) | ||
830 | nouveau_card_takedown(dev); | ||
831 | } | ||
832 | |||
833 | /* KMS: we need mmio at load time, not when the first drm client opens. */ | ||
834 | void nouveau_lastclose(struct drm_device *dev) | 865 | void nouveau_lastclose(struct drm_device *dev) |
835 | { | 866 | { |
836 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
837 | return; | ||
838 | |||
839 | nouveau_close(dev); | ||
840 | } | 867 | } |
841 | 868 | ||
842 | int nouveau_unload(struct drm_device *dev) | 869 | int nouveau_unload(struct drm_device *dev) |
843 | { | 870 | { |
844 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 871 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
872 | struct nouveau_engine *engine = &dev_priv->engine; | ||
845 | 873 | ||
846 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 874 | drm_kms_helper_poll_fini(dev); |
847 | drm_kms_helper_poll_fini(dev); | 875 | nouveau_fbcon_fini(dev); |
848 | nouveau_fbcon_fini(dev); | 876 | engine->display.destroy(dev); |
849 | if (dev_priv->card_type >= NV_50) | 877 | nouveau_card_takedown(dev); |
850 | nv50_display_destroy(dev); | ||
851 | else | ||
852 | nv04_display_destroy(dev); | ||
853 | nouveau_close(dev); | ||
854 | } | ||
855 | 878 | ||
856 | iounmap(dev_priv->mmio); | 879 | iounmap(dev_priv->mmio); |
857 | iounmap(dev_priv->ramin); | 880 | iounmap(dev_priv->ramin); |
@@ -867,8 +890,6 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, | |||
867 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 890 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
868 | struct drm_nouveau_getparam *getparam = data; | 891 | struct drm_nouveau_getparam *getparam = data; |
869 | 892 | ||
870 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
871 | |||
872 | switch (getparam->param) { | 893 | switch (getparam->param) { |
873 | case NOUVEAU_GETPARAM_CHIPSET_ID: | 894 | case NOUVEAU_GETPARAM_CHIPSET_ID: |
874 | getparam->value = dev_priv->chipset; | 895 | getparam->value = dev_priv->chipset; |
@@ -937,8 +958,6 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data, | |||
937 | { | 958 | { |
938 | struct drm_nouveau_setparam *setparam = data; | 959 | struct drm_nouveau_setparam *setparam = data; |
939 | 960 | ||
940 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
941 | |||
942 | switch (setparam->param) { | 961 | switch (setparam->param) { |
943 | default: | 962 | default: |
944 | NV_ERROR(dev, "unknown parameter %lld\n", setparam->param); | 963 | NV_ERROR(dev, "unknown parameter %lld\n", setparam->param); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index c385d50f041b..bd35f930568c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c | |||
@@ -42,13 +42,13 @@ nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma) | |||
42 | } | 42 | } |
43 | 43 | ||
44 | static int | 44 | static int |
45 | nouveau_ttm_mem_global_init(struct ttm_global_reference *ref) | 45 | nouveau_ttm_mem_global_init(struct drm_global_reference *ref) |
46 | { | 46 | { |
47 | return ttm_mem_global_init(ref->object); | 47 | return ttm_mem_global_init(ref->object); |
48 | } | 48 | } |
49 | 49 | ||
50 | static void | 50 | static void |
51 | nouveau_ttm_mem_global_release(struct ttm_global_reference *ref) | 51 | nouveau_ttm_mem_global_release(struct drm_global_reference *ref) |
52 | { | 52 | { |
53 | ttm_mem_global_release(ref->object); | 53 | ttm_mem_global_release(ref->object); |
54 | } | 54 | } |
@@ -56,16 +56,16 @@ nouveau_ttm_mem_global_release(struct ttm_global_reference *ref) | |||
56 | int | 56 | int |
57 | nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv) | 57 | nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv) |
58 | { | 58 | { |
59 | struct ttm_global_reference *global_ref; | 59 | struct drm_global_reference *global_ref; |
60 | int ret; | 60 | int ret; |
61 | 61 | ||
62 | global_ref = &dev_priv->ttm.mem_global_ref; | 62 | global_ref = &dev_priv->ttm.mem_global_ref; |
63 | global_ref->global_type = TTM_GLOBAL_TTM_MEM; | 63 | global_ref->global_type = DRM_GLOBAL_TTM_MEM; |
64 | global_ref->size = sizeof(struct ttm_mem_global); | 64 | global_ref->size = sizeof(struct ttm_mem_global); |
65 | global_ref->init = &nouveau_ttm_mem_global_init; | 65 | global_ref->init = &nouveau_ttm_mem_global_init; |
66 | global_ref->release = &nouveau_ttm_mem_global_release; | 66 | global_ref->release = &nouveau_ttm_mem_global_release; |
67 | 67 | ||
68 | ret = ttm_global_item_ref(global_ref); | 68 | ret = drm_global_item_ref(global_ref); |
69 | if (unlikely(ret != 0)) { | 69 | if (unlikely(ret != 0)) { |
70 | DRM_ERROR("Failed setting up TTM memory accounting\n"); | 70 | DRM_ERROR("Failed setting up TTM memory accounting\n"); |
71 | dev_priv->ttm.mem_global_ref.release = NULL; | 71 | dev_priv->ttm.mem_global_ref.release = NULL; |
@@ -74,15 +74,15 @@ nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv) | |||
74 | 74 | ||
75 | dev_priv->ttm.bo_global_ref.mem_glob = global_ref->object; | 75 | dev_priv->ttm.bo_global_ref.mem_glob = global_ref->object; |
76 | global_ref = &dev_priv->ttm.bo_global_ref.ref; | 76 | global_ref = &dev_priv->ttm.bo_global_ref.ref; |
77 | global_ref->global_type = TTM_GLOBAL_TTM_BO; | 77 | global_ref->global_type = DRM_GLOBAL_TTM_BO; |
78 | global_ref->size = sizeof(struct ttm_bo_global); | 78 | global_ref->size = sizeof(struct ttm_bo_global); |
79 | global_ref->init = &ttm_bo_global_init; | 79 | global_ref->init = &ttm_bo_global_init; |
80 | global_ref->release = &ttm_bo_global_release; | 80 | global_ref->release = &ttm_bo_global_release; |
81 | 81 | ||
82 | ret = ttm_global_item_ref(global_ref); | 82 | ret = drm_global_item_ref(global_ref); |
83 | if (unlikely(ret != 0)) { | 83 | if (unlikely(ret != 0)) { |
84 | DRM_ERROR("Failed setting up TTM BO subsystem\n"); | 84 | DRM_ERROR("Failed setting up TTM BO subsystem\n"); |
85 | ttm_global_item_unref(&dev_priv->ttm.mem_global_ref); | 85 | drm_global_item_unref(&dev_priv->ttm.mem_global_ref); |
86 | dev_priv->ttm.mem_global_ref.release = NULL; | 86 | dev_priv->ttm.mem_global_ref.release = NULL; |
87 | return ret; | 87 | return ret; |
88 | } | 88 | } |
@@ -96,8 +96,8 @@ nouveau_ttm_global_release(struct drm_nouveau_private *dev_priv) | |||
96 | if (dev_priv->ttm.mem_global_ref.release == NULL) | 96 | if (dev_priv->ttm.mem_global_ref.release == NULL) |
97 | return; | 97 | return; |
98 | 98 | ||
99 | ttm_global_item_unref(&dev_priv->ttm.bo_global_ref.ref); | 99 | drm_global_item_unref(&dev_priv->ttm.bo_global_ref.ref); |
100 | ttm_global_item_unref(&dev_priv->ttm.mem_global_ref); | 100 | drm_global_item_unref(&dev_priv->ttm.mem_global_ref); |
101 | dev_priv->ttm.mem_global_ref.release = NULL; | 101 | dev_priv->ttm.mem_global_ref.release = NULL; |
102 | } | 102 | } |
103 | 103 | ||
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index eba687f1099e..1c20c08ce67c 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c | |||
@@ -157,6 +157,7 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
157 | { | 157 | { |
158 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 158 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
159 | struct drm_device *dev = crtc->dev; | 159 | struct drm_device *dev = crtc->dev; |
160 | struct drm_connector *connector; | ||
160 | unsigned char seq1 = 0, crtc17 = 0; | 161 | unsigned char seq1 = 0, crtc17 = 0; |
161 | unsigned char crtc1A; | 162 | unsigned char crtc1A; |
162 | 163 | ||
@@ -211,6 +212,10 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
211 | NVVgaSeqReset(dev, nv_crtc->index, false); | 212 | NVVgaSeqReset(dev, nv_crtc->index, false); |
212 | 213 | ||
213 | NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A); | 214 | NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A); |
215 | |||
216 | /* Update connector polling modes */ | ||
217 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
218 | nouveau_connector_set_polling(connector); | ||
214 | } | 219 | } |
215 | 220 | ||
216 | static bool | 221 | static bool |
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index 1cb19e3acb55..ea3627041ecf 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c | |||
@@ -220,6 +220,7 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) | |||
220 | { | 220 | { |
221 | struct drm_device *dev = encoder->dev; | 221 | struct drm_device *dev = encoder->dev; |
222 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 222 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
223 | struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio; | ||
223 | struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; | 224 | struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; |
224 | uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder); | 225 | uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder); |
225 | uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, | 226 | uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, |
@@ -251,22 +252,21 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) | |||
251 | nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf); | 252 | nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf); |
252 | } | 253 | } |
253 | 254 | ||
254 | saved_gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1); | 255 | saved_gpio1 = gpio->get(dev, DCB_GPIO_TVDAC1); |
255 | saved_gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0); | 256 | saved_gpio0 = gpio->get(dev, DCB_GPIO_TVDAC0); |
256 | 257 | ||
257 | nv17_gpio_set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV); | 258 | gpio->set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV); |
258 | nv17_gpio_set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV); | 259 | gpio->set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV); |
259 | 260 | ||
260 | msleep(4); | 261 | msleep(4); |
261 | 262 | ||
262 | saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); | 263 | saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); |
263 | head = (saved_routput & 0x100) >> 8; | 264 | head = (saved_routput & 0x100) >> 8; |
264 | #if 0 | 265 | |
265 | /* if there's a spare crtc, using it will minimise flicker for the case | 266 | /* if there's a spare crtc, using it will minimise flicker */ |
266 | * where the in-use crtc is in use by an off-chip tmds encoder */ | 267 | if (!(NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX) & 0xC0)) |
267 | if (xf86_config->crtc[head]->enabled && !xf86_config->crtc[head ^ 1]->enabled) | ||
268 | head ^= 1; | 268 | head ^= 1; |
269 | #endif | 269 | |
270 | /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */ | 270 | /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */ |
271 | routput = (saved_routput & 0xfffffece) | head << 8; | 271 | routput = (saved_routput & 0xfffffece) | head << 8; |
272 | 272 | ||
@@ -304,8 +304,8 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) | |||
304 | nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4); | 304 | nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4); |
305 | nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2); | 305 | nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2); |
306 | 306 | ||
307 | nv17_gpio_set(dev, DCB_GPIO_TVDAC1, saved_gpio1); | 307 | gpio->set(dev, DCB_GPIO_TVDAC1, saved_gpio1); |
308 | nv17_gpio_set(dev, DCB_GPIO_TVDAC0, saved_gpio0); | 308 | gpio->set(dev, DCB_GPIO_TVDAC0, saved_gpio0); |
309 | 309 | ||
310 | return sample; | 310 | return sample; |
311 | } | 311 | } |
@@ -315,9 +315,12 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | |||
315 | { | 315 | { |
316 | struct drm_device *dev = encoder->dev; | 316 | struct drm_device *dev = encoder->dev; |
317 | struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; | 317 | struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; |
318 | uint32_t sample = nv17_dac_sample_load(encoder); | ||
319 | 318 | ||
320 | if (sample & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { | 319 | if (nv04_dac_in_use(encoder)) |
320 | return connector_status_disconnected; | ||
321 | |||
322 | if (nv17_dac_sample_load(encoder) & | ||
323 | NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { | ||
321 | NV_INFO(dev, "Load detected on output %c\n", | 324 | NV_INFO(dev, "Load detected on output %c\n", |
322 | '@' + ffs(dcb->or)); | 325 | '@' + ffs(dcb->or)); |
323 | return connector_status_connected; | 326 | return connector_status_connected; |
@@ -330,6 +333,9 @@ static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, | |||
330 | struct drm_display_mode *mode, | 333 | struct drm_display_mode *mode, |
331 | struct drm_display_mode *adjusted_mode) | 334 | struct drm_display_mode *adjusted_mode) |
332 | { | 335 | { |
336 | if (nv04_dac_in_use(encoder)) | ||
337 | return false; | ||
338 | |||
333 | return true; | 339 | return true; |
334 | } | 340 | } |
335 | 341 | ||
@@ -428,6 +434,17 @@ void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable) | |||
428 | } | 434 | } |
429 | } | 435 | } |
430 | 436 | ||
437 | /* Check if the DAC corresponding to 'encoder' is being used by | ||
438 | * someone else. */ | ||
439 | bool nv04_dac_in_use(struct drm_encoder *encoder) | ||
440 | { | ||
441 | struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; | ||
442 | struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; | ||
443 | |||
444 | return nv_gf4_disp_arch(encoder->dev) && | ||
445 | (dev_priv->dac_users[ffs(dcb->or) - 1] & ~(1 << dcb->index)); | ||
446 | } | ||
447 | |||
431 | static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) | 448 | static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) |
432 | { | 449 | { |
433 | struct drm_device *dev = encoder->dev; | 450 | struct drm_device *dev = encoder->dev; |
@@ -501,11 +518,13 @@ static const struct drm_encoder_funcs nv04_dac_funcs = { | |||
501 | .destroy = nv04_dac_destroy, | 518 | .destroy = nv04_dac_destroy, |
502 | }; | 519 | }; |
503 | 520 | ||
504 | int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry) | 521 | int |
522 | nv04_dac_create(struct drm_connector *connector, struct dcb_entry *entry) | ||
505 | { | 523 | { |
506 | const struct drm_encoder_helper_funcs *helper; | 524 | const struct drm_encoder_helper_funcs *helper; |
507 | struct drm_encoder *encoder; | ||
508 | struct nouveau_encoder *nv_encoder = NULL; | 525 | struct nouveau_encoder *nv_encoder = NULL; |
526 | struct drm_device *dev = connector->dev; | ||
527 | struct drm_encoder *encoder; | ||
509 | 528 | ||
510 | nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); | 529 | nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); |
511 | if (!nv_encoder) | 530 | if (!nv_encoder) |
@@ -527,5 +546,6 @@ int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry) | |||
527 | encoder->possible_crtcs = entry->heads; | 546 | encoder->possible_crtcs = entry->heads; |
528 | encoder->possible_clones = 0; | 547 | encoder->possible_clones = 0; |
529 | 548 | ||
549 | drm_mode_connector_attach_encoder(connector, encoder); | ||
530 | return 0; | 550 | return 0; |
531 | } | 551 | } |
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index 41634d4752fe..3311f3a8c818 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
@@ -413,10 +413,6 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
413 | struct dcb_entry *dcbe = nv_encoder->dcb; | 413 | struct dcb_entry *dcbe = nv_encoder->dcb; |
414 | int head = nouveau_crtc(encoder->crtc)->index; | 414 | int head = nouveau_crtc(encoder->crtc)->index; |
415 | 415 | ||
416 | NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", | ||
417 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), | ||
418 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | ||
419 | |||
420 | if (dcbe->type == OUTPUT_TMDS) | 416 | if (dcbe->type == OUTPUT_TMDS) |
421 | run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); | 417 | run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); |
422 | else if (dcbe->type == OUTPUT_LVDS) | 418 | else if (dcbe->type == OUTPUT_LVDS) |
@@ -584,11 +580,12 @@ static const struct drm_encoder_funcs nv04_dfp_funcs = { | |||
584 | .destroy = nv04_dfp_destroy, | 580 | .destroy = nv04_dfp_destroy, |
585 | }; | 581 | }; |
586 | 582 | ||
587 | int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry) | 583 | int |
584 | nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry) | ||
588 | { | 585 | { |
589 | const struct drm_encoder_helper_funcs *helper; | 586 | const struct drm_encoder_helper_funcs *helper; |
590 | struct drm_encoder *encoder; | ||
591 | struct nouveau_encoder *nv_encoder = NULL; | 587 | struct nouveau_encoder *nv_encoder = NULL; |
588 | struct drm_encoder *encoder; | ||
592 | int type; | 589 | int type; |
593 | 590 | ||
594 | switch (entry->type) { | 591 | switch (entry->type) { |
@@ -613,11 +610,12 @@ int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry) | |||
613 | nv_encoder->dcb = entry; | 610 | nv_encoder->dcb = entry; |
614 | nv_encoder->or = ffs(entry->or) - 1; | 611 | nv_encoder->or = ffs(entry->or) - 1; |
615 | 612 | ||
616 | drm_encoder_init(dev, encoder, &nv04_dfp_funcs, type); | 613 | drm_encoder_init(connector->dev, encoder, &nv04_dfp_funcs, type); |
617 | drm_encoder_helper_add(encoder, helper); | 614 | drm_encoder_helper_add(encoder, helper); |
618 | 615 | ||
619 | encoder->possible_crtcs = entry->heads; | 616 | encoder->possible_crtcs = entry->heads; |
620 | encoder->possible_clones = 0; | 617 | encoder->possible_clones = 0; |
621 | 618 | ||
619 | drm_mode_connector_attach_encoder(connector, encoder); | ||
622 | return 0; | 620 | return 0; |
623 | } | 621 | } |
diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index c7898b4f6dfb..9e28cf772e3c 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c | |||
@@ -32,8 +32,6 @@ | |||
32 | #include "nouveau_encoder.h" | 32 | #include "nouveau_encoder.h" |
33 | #include "nouveau_connector.h" | 33 | #include "nouveau_connector.h" |
34 | 34 | ||
35 | #define MULTIPLE_ENCODERS(e) (e & (e - 1)) | ||
36 | |||
37 | static void | 35 | static void |
38 | nv04_display_store_initial_head_owner(struct drm_device *dev) | 36 | nv04_display_store_initial_head_owner(struct drm_device *dev) |
39 | { | 37 | { |
@@ -41,7 +39,7 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) | |||
41 | 39 | ||
42 | if (dev_priv->chipset != 0x11) { | 40 | if (dev_priv->chipset != 0x11) { |
43 | dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44); | 41 | dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44); |
44 | goto ownerknown; | 42 | return; |
45 | } | 43 | } |
46 | 44 | ||
47 | /* reading CR44 is broken on nv11, so we attempt to infer it */ | 45 | /* reading CR44 is broken on nv11, so we attempt to infer it */ |
@@ -52,8 +50,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) | |||
52 | bool tvA = false; | 50 | bool tvA = false; |
53 | bool tvB = false; | 51 | bool tvB = false; |
54 | 52 | ||
55 | NVLockVgaCrtcs(dev, false); | ||
56 | |||
57 | slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) & | 53 | slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) & |
58 | 0x80; | 54 | 0x80; |
59 | if (slaved_on_B) | 55 | if (slaved_on_B) |
@@ -66,8 +62,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) | |||
66 | tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) & | 62 | tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) & |
67 | MASK(NV_CIO_CRE_LCD_LCD_SELECT)); | 63 | MASK(NV_CIO_CRE_LCD_LCD_SELECT)); |
68 | 64 | ||
69 | NVLockVgaCrtcs(dev, true); | ||
70 | |||
71 | if (slaved_on_A && !tvA) | 65 | if (slaved_on_A && !tvA) |
72 | dev_priv->crtc_owner = 0x0; | 66 | dev_priv->crtc_owner = 0x0; |
73 | else if (slaved_on_B && !tvB) | 67 | else if (slaved_on_B && !tvB) |
@@ -79,14 +73,40 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) | |||
79 | else | 73 | else |
80 | dev_priv->crtc_owner = 0x0; | 74 | dev_priv->crtc_owner = 0x0; |
81 | } | 75 | } |
76 | } | ||
77 | |||
78 | int | ||
79 | nv04_display_early_init(struct drm_device *dev) | ||
80 | { | ||
81 | /* Make the I2C buses accessible. */ | ||
82 | if (!nv_gf4_disp_arch(dev)) { | ||
83 | uint32_t pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE); | ||
84 | |||
85 | if (!(pmc_enable & 1)) | ||
86 | nv_wr32(dev, NV03_PMC_ENABLE, pmc_enable | 1); | ||
87 | } | ||
82 | 88 | ||
83 | ownerknown: | 89 | /* Unlock the VGA CRTCs. */ |
84 | NV_INFO(dev, "Initial CRTC_OWNER is %d\n", dev_priv->crtc_owner); | 90 | NVLockVgaCrtcs(dev, false); |
91 | |||
92 | /* Make sure the CRTCs aren't in slaved mode. */ | ||
93 | if (nv_two_heads(dev)) { | ||
94 | nv04_display_store_initial_head_owner(dev); | ||
95 | NVSetOwner(dev, 0); | ||
96 | } | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | void | ||
102 | nv04_display_late_takedown(struct drm_device *dev) | ||
103 | { | ||
104 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
105 | |||
106 | if (nv_two_heads(dev)) | ||
107 | NVSetOwner(dev, dev_priv->crtc_owner); | ||
85 | 108 | ||
86 | /* we need to ensure the heads are not tied henceforth, or reading any | 109 | NVLockVgaCrtcs(dev, true); |
87 | * 8 bit reg on head B will fail | ||
88 | * setting a single arbitrary head solves that */ | ||
89 | NVSetOwner(dev, 0); | ||
90 | } | 110 | } |
91 | 111 | ||
92 | int | 112 | int |
@@ -94,14 +114,13 @@ nv04_display_create(struct drm_device *dev) | |||
94 | { | 114 | { |
95 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 115 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
96 | struct dcb_table *dcb = &dev_priv->vbios.dcb; | 116 | struct dcb_table *dcb = &dev_priv->vbios.dcb; |
117 | struct drm_connector *connector, *ct; | ||
97 | struct drm_encoder *encoder; | 118 | struct drm_encoder *encoder; |
98 | struct drm_crtc *crtc; | 119 | struct drm_crtc *crtc; |
99 | int i, ret; | 120 | int i, ret; |
100 | 121 | ||
101 | NV_DEBUG_KMS(dev, "\n"); | 122 | NV_DEBUG_KMS(dev, "\n"); |
102 | 123 | ||
103 | if (nv_two_heads(dev)) | ||
104 | nv04_display_store_initial_head_owner(dev); | ||
105 | nouveau_hw_save_vga_fonts(dev, 1); | 124 | nouveau_hw_save_vga_fonts(dev, 1); |
106 | 125 | ||
107 | drm_mode_config_init(dev); | 126 | drm_mode_config_init(dev); |
@@ -132,19 +151,23 @@ nv04_display_create(struct drm_device *dev) | |||
132 | for (i = 0; i < dcb->entries; i++) { | 151 | for (i = 0; i < dcb->entries; i++) { |
133 | struct dcb_entry *dcbent = &dcb->entry[i]; | 152 | struct dcb_entry *dcbent = &dcb->entry[i]; |
134 | 153 | ||
154 | connector = nouveau_connector_create(dev, dcbent->connector); | ||
155 | if (IS_ERR(connector)) | ||
156 | continue; | ||
157 | |||
135 | switch (dcbent->type) { | 158 | switch (dcbent->type) { |
136 | case OUTPUT_ANALOG: | 159 | case OUTPUT_ANALOG: |
137 | ret = nv04_dac_create(dev, dcbent); | 160 | ret = nv04_dac_create(connector, dcbent); |
138 | break; | 161 | break; |
139 | case OUTPUT_LVDS: | 162 | case OUTPUT_LVDS: |
140 | case OUTPUT_TMDS: | 163 | case OUTPUT_TMDS: |
141 | ret = nv04_dfp_create(dev, dcbent); | 164 | ret = nv04_dfp_create(connector, dcbent); |
142 | break; | 165 | break; |
143 | case OUTPUT_TV: | 166 | case OUTPUT_TV: |
144 | if (dcbent->location == DCB_LOC_ON_CHIP) | 167 | if (dcbent->location == DCB_LOC_ON_CHIP) |
145 | ret = nv17_tv_create(dev, dcbent); | 168 | ret = nv17_tv_create(connector, dcbent); |
146 | else | 169 | else |
147 | ret = nv04_tv_create(dev, dcbent); | 170 | ret = nv04_tv_create(connector, dcbent); |
148 | break; | 171 | break; |
149 | default: | 172 | default: |
150 | NV_WARN(dev, "DCB type %d not known\n", dcbent->type); | 173 | NV_WARN(dev, "DCB type %d not known\n", dcbent->type); |
@@ -155,12 +178,16 @@ nv04_display_create(struct drm_device *dev) | |||
155 | continue; | 178 | continue; |
156 | } | 179 | } |
157 | 180 | ||
158 | for (i = 0; i < dcb->connector.entries; i++) | 181 | list_for_each_entry_safe(connector, ct, |
159 | nouveau_connector_create(dev, &dcb->connector.entry[i]); | 182 | &dev->mode_config.connector_list, head) { |
183 | if (!connector->encoder_ids[0]) { | ||
184 | NV_WARN(dev, "%s has no encoders, removing\n", | ||
185 | drm_get_connector_name(connector)); | ||
186 | connector->funcs->destroy(connector); | ||
187 | } | ||
188 | } | ||
160 | 189 | ||
161 | /* Save previous state */ | 190 | /* Save previous state */ |
162 | NVLockVgaCrtcs(dev, false); | ||
163 | |||
164 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | 191 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) |
165 | crtc->funcs->save(crtc); | 192 | crtc->funcs->save(crtc); |
166 | 193 | ||
@@ -191,8 +218,6 @@ nv04_display_destroy(struct drm_device *dev) | |||
191 | } | 218 | } |
192 | 219 | ||
193 | /* Restore state */ | 220 | /* Restore state */ |
194 | NVLockVgaCrtcs(dev, false); | ||
195 | |||
196 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 221 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
197 | struct drm_encoder_helper_funcs *func = encoder->helper_private; | 222 | struct drm_encoder_helper_funcs *func = encoder->helper_private; |
198 | 223 | ||
@@ -207,15 +232,12 @@ nv04_display_destroy(struct drm_device *dev) | |||
207 | nouveau_hw_save_vga_fonts(dev, 0); | 232 | nouveau_hw_save_vga_fonts(dev, 0); |
208 | } | 233 | } |
209 | 234 | ||
210 | void | 235 | int |
211 | nv04_display_restore(struct drm_device *dev) | 236 | nv04_display_init(struct drm_device *dev) |
212 | { | 237 | { |
213 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
214 | struct drm_encoder *encoder; | 238 | struct drm_encoder *encoder; |
215 | struct drm_crtc *crtc; | 239 | struct drm_crtc *crtc; |
216 | 240 | ||
217 | NVLockVgaCrtcs(dev, false); | ||
218 | |||
219 | /* meh.. modeset apparently doesn't setup all the regs and depends | 241 | /* meh.. modeset apparently doesn't setup all the regs and depends |
220 | * on pre-existing state, for now load the state of the card *before* | 242 | * on pre-existing state, for now load the state of the card *before* |
221 | * nouveau was loaded, and then do a modeset. | 243 | * nouveau was loaded, and then do a modeset. |
@@ -233,12 +255,6 @@ nv04_display_restore(struct drm_device *dev) | |||
233 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | 255 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) |
234 | crtc->funcs->restore(crtc); | 256 | crtc->funcs->restore(crtc); |
235 | 257 | ||
236 | if (nv_two_heads(dev)) { | 258 | return 0; |
237 | NV_INFO(dev, "Restoring CRTC_OWNER to %d.\n", | ||
238 | dev_priv->crtc_owner); | ||
239 | NVSetOwner(dev, dev_priv->crtc_owner); | ||
240 | } | ||
241 | |||
242 | NVLockVgaCrtcs(dev, true); | ||
243 | } | 259 | } |
244 | 260 | ||
diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c index 66fe55983b6e..06cedd99c26a 100644 --- a/drivers/gpu/drm/nouveau/nv04_fifo.c +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c | |||
@@ -112,6 +112,12 @@ nv04_fifo_channel_id(struct drm_device *dev) | |||
112 | NV03_PFIFO_CACHE1_PUSH1_CHID_MASK; | 112 | NV03_PFIFO_CACHE1_PUSH1_CHID_MASK; |
113 | } | 113 | } |
114 | 114 | ||
115 | #ifdef __BIG_ENDIAN | ||
116 | #define DMA_FETCH_ENDIANNESS NV_PFIFO_CACHE1_BIG_ENDIAN | ||
117 | #else | ||
118 | #define DMA_FETCH_ENDIANNESS 0 | ||
119 | #endif | ||
120 | |||
115 | int | 121 | int |
116 | nv04_fifo_create_context(struct nouveau_channel *chan) | 122 | nv04_fifo_create_context(struct nouveau_channel *chan) |
117 | { | 123 | { |
@@ -131,18 +137,13 @@ nv04_fifo_create_context(struct nouveau_channel *chan) | |||
131 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | 137 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
132 | 138 | ||
133 | /* Setup initial state */ | 139 | /* Setup initial state */ |
134 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
135 | RAMFC_WR(DMA_PUT, chan->pushbuf_base); | 140 | RAMFC_WR(DMA_PUT, chan->pushbuf_base); |
136 | RAMFC_WR(DMA_GET, chan->pushbuf_base); | 141 | RAMFC_WR(DMA_GET, chan->pushbuf_base); |
137 | RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4); | 142 | RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4); |
138 | RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | | 143 | RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | |
139 | NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | | 144 | NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | |
140 | NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | | 145 | NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | |
141 | #ifdef __BIG_ENDIAN | 146 | DMA_FETCH_ENDIANNESS)); |
142 | NV_PFIFO_CACHE1_BIG_ENDIAN | | ||
143 | #endif | ||
144 | 0)); | ||
145 | dev_priv->engine.instmem.finish_access(dev); | ||
146 | 147 | ||
147 | /* enable the fifo dma operation */ | 148 | /* enable the fifo dma operation */ |
148 | nv_wr32(dev, NV04_PFIFO_MODE, | 149 | nv_wr32(dev, NV04_PFIFO_MODE, |
@@ -169,8 +170,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid) | |||
169 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 170 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
170 | uint32_t fc = NV04_RAMFC(chid), tmp; | 171 | uint32_t fc = NV04_RAMFC(chid), tmp; |
171 | 172 | ||
172 | dev_priv->engine.instmem.prepare_access(dev, false); | ||
173 | |||
174 | nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); | 173 | nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); |
175 | nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); | 174 | nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); |
176 | tmp = nv_ri32(dev, fc + 8); | 175 | tmp = nv_ri32(dev, fc + 8); |
@@ -181,8 +180,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid) | |||
181 | nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 20)); | 180 | nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 20)); |
182 | nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 24)); | 181 | nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 24)); |
183 | 182 | ||
184 | dev_priv->engine.instmem.finish_access(dev); | ||
185 | |||
186 | nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); | 183 | nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); |
187 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); | 184 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); |
188 | } | 185 | } |
@@ -223,7 +220,6 @@ nv04_fifo_unload_context(struct drm_device *dev) | |||
223 | return -EINVAL; | 220 | return -EINVAL; |
224 | } | 221 | } |
225 | 222 | ||
226 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
227 | RAMFC_WR(DMA_PUT, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); | 223 | RAMFC_WR(DMA_PUT, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); |
228 | RAMFC_WR(DMA_GET, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); | 224 | RAMFC_WR(DMA_GET, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); |
229 | tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16; | 225 | tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16; |
@@ -233,7 +229,6 @@ nv04_fifo_unload_context(struct drm_device *dev) | |||
233 | RAMFC_WR(DMA_FETCH, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH)); | 229 | RAMFC_WR(DMA_FETCH, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH)); |
234 | RAMFC_WR(ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE)); | 230 | RAMFC_WR(ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE)); |
235 | RAMFC_WR(PULL1_ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1)); | 231 | RAMFC_WR(PULL1_ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1)); |
236 | dev_priv->engine.instmem.finish_access(dev); | ||
237 | 232 | ||
238 | nv04_fifo_do_load_context(dev, pfifo->channels - 1); | 233 | nv04_fifo_do_load_context(dev, pfifo->channels - 1); |
239 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); | 234 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); |
@@ -297,6 +292,7 @@ nv04_fifo_init(struct drm_device *dev) | |||
297 | 292 | ||
298 | nv04_fifo_init_intr(dev); | 293 | nv04_fifo_init_intr(dev); |
299 | pfifo->enable(dev); | 294 | pfifo->enable(dev); |
295 | pfifo->reassign(dev, true); | ||
300 | 296 | ||
301 | for (i = 0; i < dev_priv->engine.fifo.channels; i++) { | 297 | for (i = 0; i < dev_priv->engine.fifo.channels; i++) { |
302 | if (dev_priv->fifos[i]) { | 298 | if (dev_priv->fifos[i]) { |
diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index 618355e9cdd5..c8973421b635 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c | |||
@@ -342,7 +342,7 @@ static uint32_t nv04_graph_ctx_regs[] = { | |||
342 | }; | 342 | }; |
343 | 343 | ||
344 | struct graph_state { | 344 | struct graph_state { |
345 | int nv04[ARRAY_SIZE(nv04_graph_ctx_regs)]; | 345 | uint32_t nv04[ARRAY_SIZE(nv04_graph_ctx_regs)]; |
346 | }; | 346 | }; |
347 | 347 | ||
348 | struct nouveau_channel * | 348 | struct nouveau_channel * |
@@ -527,8 +527,7 @@ static int | |||
527 | nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass, | 527 | nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass, |
528 | int mthd, uint32_t data) | 528 | int mthd, uint32_t data) |
529 | { | 529 | { |
530 | chan->fence.last_sequence_irq = data; | 530 | atomic_set(&chan->fence.last_sequence_irq, data); |
531 | nouveau_fence_handler(chan->dev, chan->id); | ||
532 | return 0; | 531 | return 0; |
533 | } | 532 | } |
534 | 533 | ||
diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c index a3b9563a6f60..4408232d33f1 100644 --- a/drivers/gpu/drm/nouveau/nv04_instmem.c +++ b/drivers/gpu/drm/nouveau/nv04_instmem.c | |||
@@ -49,10 +49,8 @@ nv04_instmem_determine_amount(struct drm_device *dev) | |||
49 | NV_DEBUG(dev, "RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram >> 10); | 49 | NV_DEBUG(dev, "RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram >> 10); |
50 | 50 | ||
51 | /* Clear all of it, except the BIOS image that's in the first 64KiB */ | 51 | /* Clear all of it, except the BIOS image that's in the first 64KiB */ |
52 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
53 | for (i = 64 * 1024; i < dev_priv->ramin_rsvd_vram; i += 4) | 52 | for (i = 64 * 1024; i < dev_priv->ramin_rsvd_vram; i += 4) |
54 | nv_wi32(dev, i, 0x00000000); | 53 | nv_wi32(dev, i, 0x00000000); |
55 | dev_priv->engine.instmem.finish_access(dev); | ||
56 | } | 54 | } |
57 | 55 | ||
58 | static void | 56 | static void |
@@ -106,7 +104,7 @@ int nv04_instmem_init(struct drm_device *dev) | |||
106 | { | 104 | { |
107 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 105 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
108 | uint32_t offset; | 106 | uint32_t offset; |
109 | int ret = 0; | 107 | int ret; |
110 | 108 | ||
111 | nv04_instmem_determine_amount(dev); | 109 | nv04_instmem_determine_amount(dev); |
112 | nv04_instmem_configure_fixed_tables(dev); | 110 | nv04_instmem_configure_fixed_tables(dev); |
@@ -129,14 +127,14 @@ int nv04_instmem_init(struct drm_device *dev) | |||
129 | offset = 0x40000; | 127 | offset = 0x40000; |
130 | } | 128 | } |
131 | 129 | ||
132 | ret = nouveau_mem_init_heap(&dev_priv->ramin_heap, | 130 | ret = drm_mm_init(&dev_priv->ramin_heap, offset, |
133 | offset, dev_priv->ramin_rsvd_vram - offset); | 131 | dev_priv->ramin_rsvd_vram - offset); |
134 | if (ret) { | 132 | if (ret) { |
135 | dev_priv->ramin_heap = NULL; | 133 | NV_ERROR(dev, "Failed to init RAMIN heap: %d\n", ret); |
136 | NV_ERROR(dev, "Failed to init RAMIN heap\n"); | 134 | return ret; |
137 | } | 135 | } |
138 | 136 | ||
139 | return ret; | 137 | return 0; |
140 | } | 138 | } |
141 | 139 | ||
142 | void | 140 | void |
@@ -186,12 +184,7 @@ nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) | |||
186 | } | 184 | } |
187 | 185 | ||
188 | void | 186 | void |
189 | nv04_instmem_prepare_access(struct drm_device *dev, bool write) | 187 | nv04_instmem_flush(struct drm_device *dev) |
190 | { | ||
191 | } | ||
192 | |||
193 | void | ||
194 | nv04_instmem_finish_access(struct drm_device *dev) | ||
195 | { | 188 | { |
196 | } | 189 | } |
197 | 190 | ||
diff --git a/drivers/gpu/drm/nouveau/nv04_mc.c b/drivers/gpu/drm/nouveau/nv04_mc.c index 617ed1e05269..2af43a1cb2ec 100644 --- a/drivers/gpu/drm/nouveau/nv04_mc.c +++ b/drivers/gpu/drm/nouveau/nv04_mc.c | |||
@@ -11,6 +11,10 @@ nv04_mc_init(struct drm_device *dev) | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); | 13 | nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); |
14 | |||
15 | /* Disable PROM access. */ | ||
16 | nv_wr32(dev, NV_PBUS_PCI_NV_20, NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED); | ||
17 | |||
14 | return 0; | 18 | return 0; |
15 | } | 19 | } |
16 | 20 | ||
diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c index c4e3404337d4..94e299cef0b2 100644 --- a/drivers/gpu/drm/nouveau/nv04_tv.c +++ b/drivers/gpu/drm/nouveau/nv04_tv.c | |||
@@ -34,69 +34,26 @@ | |||
34 | 34 | ||
35 | #include "i2c/ch7006.h" | 35 | #include "i2c/ch7006.h" |
36 | 36 | ||
37 | static struct { | 37 | static struct i2c_board_info nv04_tv_encoder_info[] = { |
38 | struct i2c_board_info board_info; | ||
39 | struct drm_encoder_funcs funcs; | ||
40 | struct drm_encoder_helper_funcs hfuncs; | ||
41 | void *params; | ||
42 | |||
43 | } nv04_tv_encoder_info[] = { | ||
44 | { | 38 | { |
45 | .board_info = { I2C_BOARD_INFO("ch7006", 0x75) }, | 39 | I2C_BOARD_INFO("ch7006", 0x75), |
46 | .params = &(struct ch7006_encoder_params) { | 40 | .platform_data = &(struct ch7006_encoder_params) { |
47 | CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER, | 41 | CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER, |
48 | 0, 0, 0, | 42 | 0, 0, 0, |
49 | CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED, | 43 | CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED, |
50 | CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC | 44 | CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC |
51 | }, | 45 | } |
52 | }, | 46 | }, |
47 | { } | ||
53 | }; | 48 | }; |
54 | 49 | ||
55 | static bool probe_i2c_addr(struct i2c_adapter *adapter, int addr) | ||
56 | { | ||
57 | struct i2c_msg msg = { | ||
58 | .addr = addr, | ||
59 | .len = 0, | ||
60 | }; | ||
61 | |||
62 | return i2c_transfer(adapter, &msg, 1) == 1; | ||
63 | } | ||
64 | |||
65 | int nv04_tv_identify(struct drm_device *dev, int i2c_index) | 50 | int nv04_tv_identify(struct drm_device *dev, int i2c_index) |
66 | { | 51 | { |
67 | struct nouveau_i2c_chan *i2c; | 52 | return nouveau_i2c_identify(dev, "TV encoder", |
68 | bool was_locked; | 53 | nv04_tv_encoder_info, i2c_index); |
69 | int i, ret; | ||
70 | |||
71 | NV_TRACE(dev, "Probing TV encoders on I2C bus: %d\n", i2c_index); | ||
72 | |||
73 | i2c = nouveau_i2c_find(dev, i2c_index); | ||
74 | if (!i2c) | ||
75 | return -ENODEV; | ||
76 | |||
77 | was_locked = NVLockVgaCrtcs(dev, false); | ||
78 | |||
79 | for (i = 0; i < ARRAY_SIZE(nv04_tv_encoder_info); i++) { | ||
80 | if (probe_i2c_addr(&i2c->adapter, | ||
81 | nv04_tv_encoder_info[i].board_info.addr)) { | ||
82 | ret = i; | ||
83 | break; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | if (i < ARRAY_SIZE(nv04_tv_encoder_info)) { | ||
88 | NV_TRACE(dev, "Detected TV encoder: %s\n", | ||
89 | nv04_tv_encoder_info[i].board_info.type); | ||
90 | |||
91 | } else { | ||
92 | NV_TRACE(dev, "No TV encoders found.\n"); | ||
93 | i = -ENODEV; | ||
94 | } | ||
95 | |||
96 | NVLockVgaCrtcs(dev, was_locked); | ||
97 | return i; | ||
98 | } | 54 | } |
99 | 55 | ||
56 | |||
100 | #define PLLSEL_TV_CRTC1_MASK \ | 57 | #define PLLSEL_TV_CRTC1_MASK \ |
101 | (NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1 \ | 58 | (NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1 \ |
102 | | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1) | 59 | | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1) |
@@ -214,30 +171,32 @@ static void nv04_tv_commit(struct drm_encoder *encoder) | |||
214 | 171 | ||
215 | static void nv04_tv_destroy(struct drm_encoder *encoder) | 172 | static void nv04_tv_destroy(struct drm_encoder *encoder) |
216 | { | 173 | { |
217 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
218 | |||
219 | to_encoder_slave(encoder)->slave_funcs->destroy(encoder); | 174 | to_encoder_slave(encoder)->slave_funcs->destroy(encoder); |
220 | 175 | ||
221 | drm_encoder_cleanup(encoder); | 176 | drm_encoder_cleanup(encoder); |
222 | 177 | ||
223 | kfree(nv_encoder); | 178 | kfree(encoder->helper_private); |
179 | kfree(nouveau_encoder(encoder)); | ||
224 | } | 180 | } |
225 | 181 | ||
226 | int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) | 182 | static const struct drm_encoder_funcs nv04_tv_funcs = { |
183 | .destroy = nv04_tv_destroy, | ||
184 | }; | ||
185 | |||
186 | int | ||
187 | nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry) | ||
227 | { | 188 | { |
228 | struct nouveau_encoder *nv_encoder; | 189 | struct nouveau_encoder *nv_encoder; |
229 | struct drm_encoder *encoder; | 190 | struct drm_encoder *encoder; |
230 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 191 | struct drm_device *dev = connector->dev; |
231 | struct i2c_adapter *adap; | 192 | struct drm_encoder_helper_funcs *hfuncs; |
232 | struct drm_encoder_funcs *funcs = NULL; | 193 | struct drm_encoder_slave_funcs *sfuncs; |
233 | struct drm_encoder_helper_funcs *hfuncs = NULL; | 194 | struct nouveau_i2c_chan *i2c = |
234 | struct drm_encoder_slave_funcs *sfuncs = NULL; | 195 | nouveau_i2c_find(dev, entry->i2c_index); |
235 | int i2c_index = entry->i2c_index; | ||
236 | int type, ret; | 196 | int type, ret; |
237 | bool was_locked; | ||
238 | 197 | ||
239 | /* Ensure that we can talk to this encoder */ | 198 | /* Ensure that we can talk to this encoder */ |
240 | type = nv04_tv_identify(dev, i2c_index); | 199 | type = nv04_tv_identify(dev, entry->i2c_index); |
241 | if (type < 0) | 200 | if (type < 0) |
242 | return type; | 201 | return type; |
243 | 202 | ||
@@ -246,41 +205,32 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) | |||
246 | if (!nv_encoder) | 205 | if (!nv_encoder) |
247 | return -ENOMEM; | 206 | return -ENOMEM; |
248 | 207 | ||
208 | hfuncs = kzalloc(sizeof(*hfuncs), GFP_KERNEL); | ||
209 | if (!hfuncs) { | ||
210 | ret = -ENOMEM; | ||
211 | goto fail_free; | ||
212 | } | ||
213 | |||
249 | /* Initialize the common members */ | 214 | /* Initialize the common members */ |
250 | encoder = to_drm_encoder(nv_encoder); | 215 | encoder = to_drm_encoder(nv_encoder); |
251 | 216 | ||
252 | funcs = &nv04_tv_encoder_info[type].funcs; | 217 | drm_encoder_init(dev, encoder, &nv04_tv_funcs, DRM_MODE_ENCODER_TVDAC); |
253 | hfuncs = &nv04_tv_encoder_info[type].hfuncs; | ||
254 | |||
255 | drm_encoder_init(dev, encoder, funcs, DRM_MODE_ENCODER_TVDAC); | ||
256 | drm_encoder_helper_add(encoder, hfuncs); | 218 | drm_encoder_helper_add(encoder, hfuncs); |
257 | 219 | ||
258 | encoder->possible_crtcs = entry->heads; | 220 | encoder->possible_crtcs = entry->heads; |
259 | encoder->possible_clones = 0; | 221 | encoder->possible_clones = 0; |
260 | |||
261 | nv_encoder->dcb = entry; | 222 | nv_encoder->dcb = entry; |
262 | nv_encoder->or = ffs(entry->or) - 1; | 223 | nv_encoder->or = ffs(entry->or) - 1; |
263 | 224 | ||
264 | /* Run the slave-specific initialization */ | 225 | /* Run the slave-specific initialization */ |
265 | adap = &dev_priv->vbios.dcb.i2c[i2c_index].chan->adapter; | 226 | ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), |
266 | 227 | &i2c->adapter, &nv04_tv_encoder_info[type]); | |
267 | was_locked = NVLockVgaCrtcs(dev, false); | ||
268 | |||
269 | ret = drm_i2c_encoder_init(encoder->dev, to_encoder_slave(encoder), adap, | ||
270 | &nv04_tv_encoder_info[type].board_info); | ||
271 | |||
272 | NVLockVgaCrtcs(dev, was_locked); | ||
273 | |||
274 | if (ret < 0) | 228 | if (ret < 0) |
275 | goto fail; | 229 | goto fail_cleanup; |
276 | 230 | ||
277 | /* Fill the function pointers */ | 231 | /* Fill the function pointers */ |
278 | sfuncs = to_encoder_slave(encoder)->slave_funcs; | 232 | sfuncs = to_encoder_slave(encoder)->slave_funcs; |
279 | 233 | ||
280 | *funcs = (struct drm_encoder_funcs) { | ||
281 | .destroy = nv04_tv_destroy, | ||
282 | }; | ||
283 | |||
284 | *hfuncs = (struct drm_encoder_helper_funcs) { | 234 | *hfuncs = (struct drm_encoder_helper_funcs) { |
285 | .dpms = nv04_tv_dpms, | 235 | .dpms = nv04_tv_dpms, |
286 | .save = sfuncs->save, | 236 | .save = sfuncs->save, |
@@ -292,14 +242,17 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) | |||
292 | .detect = sfuncs->detect, | 242 | .detect = sfuncs->detect, |
293 | }; | 243 | }; |
294 | 244 | ||
295 | /* Set the slave encoder configuration */ | 245 | /* Attach it to the specified connector. */ |
296 | sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params); | 246 | sfuncs->set_config(encoder, nv04_tv_encoder_info[type].platform_data); |
247 | sfuncs->create_resources(encoder, connector); | ||
248 | drm_mode_connector_attach_encoder(connector, encoder); | ||
297 | 249 | ||
298 | return 0; | 250 | return 0; |
299 | 251 | ||
300 | fail: | 252 | fail_cleanup: |
301 | drm_encoder_cleanup(encoder); | 253 | drm_encoder_cleanup(encoder); |
302 | 254 | kfree(hfuncs); | |
255 | fail_free: | ||
303 | kfree(nv_encoder); | 256 | kfree(nv_encoder); |
304 | return ret; | 257 | return ret; |
305 | } | 258 | } |
diff --git a/drivers/gpu/drm/nouveau/nv10_fifo.c b/drivers/gpu/drm/nouveau/nv10_fifo.c index 7aeabf262bc0..7a4069cf5d0b 100644 --- a/drivers/gpu/drm/nouveau/nv10_fifo.c +++ b/drivers/gpu/drm/nouveau/nv10_fifo.c | |||
@@ -55,7 +55,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan) | |||
55 | /* Fill entries that are seen filled in dumps of nvidia driver just | 55 | /* Fill entries that are seen filled in dumps of nvidia driver just |
56 | * after channel's is put into DMA mode | 56 | * after channel's is put into DMA mode |
57 | */ | 57 | */ |
58 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
59 | nv_wi32(dev, fc + 0, chan->pushbuf_base); | 58 | nv_wi32(dev, fc + 0, chan->pushbuf_base); |
60 | nv_wi32(dev, fc + 4, chan->pushbuf_base); | 59 | nv_wi32(dev, fc + 4, chan->pushbuf_base); |
61 | nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4); | 60 | nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4); |
@@ -66,7 +65,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan) | |||
66 | NV_PFIFO_CACHE1_BIG_ENDIAN | | 65 | NV_PFIFO_CACHE1_BIG_ENDIAN | |
67 | #endif | 66 | #endif |
68 | 0); | 67 | 0); |
69 | dev_priv->engine.instmem.finish_access(dev); | ||
70 | 68 | ||
71 | /* enable the fifo dma operation */ | 69 | /* enable the fifo dma operation */ |
72 | nv_wr32(dev, NV04_PFIFO_MODE, | 70 | nv_wr32(dev, NV04_PFIFO_MODE, |
@@ -91,8 +89,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid) | |||
91 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 89 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
92 | uint32_t fc = NV10_RAMFC(chid), tmp; | 90 | uint32_t fc = NV10_RAMFC(chid), tmp; |
93 | 91 | ||
94 | dev_priv->engine.instmem.prepare_access(dev, false); | ||
95 | |||
96 | nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); | 92 | nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); |
97 | nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); | 93 | nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); |
98 | nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); | 94 | nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); |
@@ -117,8 +113,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid) | |||
117 | nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 48)); | 113 | nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 48)); |
118 | 114 | ||
119 | out: | 115 | out: |
120 | dev_priv->engine.instmem.finish_access(dev); | ||
121 | |||
122 | nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); | 116 | nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); |
123 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); | 117 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); |
124 | } | 118 | } |
@@ -155,8 +149,6 @@ nv10_fifo_unload_context(struct drm_device *dev) | |||
155 | return 0; | 149 | return 0; |
156 | fc = NV10_RAMFC(chid); | 150 | fc = NV10_RAMFC(chid); |
157 | 151 | ||
158 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
159 | |||
160 | nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); | 152 | nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); |
161 | nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); | 153 | nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); |
162 | nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); | 154 | nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); |
@@ -179,8 +171,6 @@ nv10_fifo_unload_context(struct drm_device *dev) | |||
179 | nv_wi32(dev, fc + 48, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); | 171 | nv_wi32(dev, fc + 48, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); |
180 | 172 | ||
181 | out: | 173 | out: |
182 | dev_priv->engine.instmem.finish_access(dev); | ||
183 | |||
184 | nv10_fifo_do_load_context(dev, pfifo->channels - 1); | 174 | nv10_fifo_do_load_context(dev, pfifo->channels - 1); |
185 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); | 175 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); |
186 | return 0; | 176 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/nv17_gpio.c b/drivers/gpu/drm/nouveau/nv10_gpio.c index 2e58c331e9b7..007fc29e2f86 100644 --- a/drivers/gpu/drm/nouveau/nv17_gpio.c +++ b/drivers/gpu/drm/nouveau/nv10_gpio.c | |||
@@ -55,7 +55,7 @@ get_gpio_location(struct dcb_gpio_entry *ent, uint32_t *reg, uint32_t *shift, | |||
55 | } | 55 | } |
56 | 56 | ||
57 | int | 57 | int |
58 | nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag) | 58 | nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag) |
59 | { | 59 | { |
60 | struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); | 60 | struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); |
61 | uint32_t reg, shift, mask, value; | 61 | uint32_t reg, shift, mask, value; |
@@ -72,7 +72,7 @@ nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag) | |||
72 | } | 72 | } |
73 | 73 | ||
74 | int | 74 | int |
75 | nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state) | 75 | nv10_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state) |
76 | { | 76 | { |
77 | struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); | 77 | struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); |
78 | uint32_t reg, shift, mask, value; | 78 | uint32_t reg, shift, mask, value; |
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 74c880374fb9..44fefb0c7083 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c | |||
@@ -37,6 +37,7 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) | |||
37 | { | 37 | { |
38 | struct drm_device *dev = encoder->dev; | 38 | struct drm_device *dev = encoder->dev; |
39 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 39 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
40 | struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio; | ||
40 | uint32_t testval, regoffset = nv04_dac_output_offset(encoder); | 41 | uint32_t testval, regoffset = nv04_dac_output_offset(encoder); |
41 | uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end, | 42 | uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end, |
42 | fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c; | 43 | fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c; |
@@ -52,8 +53,8 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) | |||
52 | head = (dacclk & 0x100) >> 8; | 53 | head = (dacclk & 0x100) >> 8; |
53 | 54 | ||
54 | /* Save the previous state. */ | 55 | /* Save the previous state. */ |
55 | gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1); | 56 | gpio1 = gpio->get(dev, DCB_GPIO_TVDAC1); |
56 | gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0); | 57 | gpio0 = gpio->get(dev, DCB_GPIO_TVDAC0); |
57 | fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL); | 58 | fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL); |
58 | fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START); | 59 | fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START); |
59 | fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END); | 60 | fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END); |
@@ -64,8 +65,8 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) | |||
64 | ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c); | 65 | ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c); |
65 | 66 | ||
66 | /* Prepare the DAC for load detection. */ | 67 | /* Prepare the DAC for load detection. */ |
67 | nv17_gpio_set(dev, DCB_GPIO_TVDAC1, true); | 68 | gpio->set(dev, DCB_GPIO_TVDAC1, true); |
68 | nv17_gpio_set(dev, DCB_GPIO_TVDAC0, true); | 69 | gpio->set(dev, DCB_GPIO_TVDAC0, true); |
69 | 70 | ||
70 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343); | 71 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343); |
71 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047); | 72 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047); |
@@ -110,12 +111,27 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) | |||
110 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end); | 111 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end); |
111 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start); | 112 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start); |
112 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal); | 113 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal); |
113 | nv17_gpio_set(dev, DCB_GPIO_TVDAC1, gpio1); | 114 | gpio->set(dev, DCB_GPIO_TVDAC1, gpio1); |
114 | nv17_gpio_set(dev, DCB_GPIO_TVDAC0, gpio0); | 115 | gpio->set(dev, DCB_GPIO_TVDAC0, gpio0); |
115 | 116 | ||
116 | return sample; | 117 | return sample; |
117 | } | 118 | } |
118 | 119 | ||
120 | static bool | ||
121 | get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) | ||
122 | { | ||
123 | /* Zotac FX5200 */ | ||
124 | if (dev->pdev->device == 0x0322 && | ||
125 | dev->pdev->subsystem_vendor == 0x19da && | ||
126 | (dev->pdev->subsystem_device == 0x1035 || | ||
127 | dev->pdev->subsystem_device == 0x2035)) { | ||
128 | *pin_mask = 0xc; | ||
129 | return false; | ||
130 | } | ||
131 | |||
132 | return true; | ||
133 | } | ||
134 | |||
119 | static enum drm_connector_status | 135 | static enum drm_connector_status |
120 | nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) | 136 | nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) |
121 | { | 137 | { |
@@ -124,12 +140,20 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) | |||
124 | struct drm_mode_config *conf = &dev->mode_config; | 140 | struct drm_mode_config *conf = &dev->mode_config; |
125 | struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); | 141 | struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); |
126 | struct dcb_entry *dcb = tv_enc->base.dcb; | 142 | struct dcb_entry *dcb = tv_enc->base.dcb; |
143 | bool reliable = get_tv_detect_quirks(dev, &tv_enc->pin_mask); | ||
127 | 144 | ||
128 | if (dev_priv->chipset == 0x42 || | 145 | if (nv04_dac_in_use(encoder)) |
129 | dev_priv->chipset == 0x43) | 146 | return connector_status_disconnected; |
130 | tv_enc->pin_mask = nv42_tv_sample_load(encoder) >> 28 & 0xe; | 147 | |
131 | else | 148 | if (reliable) { |
132 | tv_enc->pin_mask = nv17_dac_sample_load(encoder) >> 28 & 0xe; | 149 | if (dev_priv->chipset == 0x42 || |
150 | dev_priv->chipset == 0x43) | ||
151 | tv_enc->pin_mask = | ||
152 | nv42_tv_sample_load(encoder) >> 28 & 0xe; | ||
153 | else | ||
154 | tv_enc->pin_mask = | ||
155 | nv17_dac_sample_load(encoder) >> 28 & 0xe; | ||
156 | } | ||
133 | 157 | ||
134 | switch (tv_enc->pin_mask) { | 158 | switch (tv_enc->pin_mask) { |
135 | case 0x2: | 159 | case 0x2: |
@@ -154,7 +178,9 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) | |||
154 | conf->tv_subconnector_property, | 178 | conf->tv_subconnector_property, |
155 | tv_enc->subconnector); | 179 | tv_enc->subconnector); |
156 | 180 | ||
157 | if (tv_enc->subconnector) { | 181 | if (!reliable) { |
182 | return connector_status_unknown; | ||
183 | } else if (tv_enc->subconnector) { | ||
158 | NV_INFO(dev, "Load detected on output %c\n", | 184 | NV_INFO(dev, "Load detected on output %c\n", |
159 | '@' + ffs(dcb->or)); | 185 | '@' + ffs(dcb->or)); |
160 | return connector_status_connected; | 186 | return connector_status_connected; |
@@ -296,6 +322,9 @@ static bool nv17_tv_mode_fixup(struct drm_encoder *encoder, | |||
296 | { | 322 | { |
297 | struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); | 323 | struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); |
298 | 324 | ||
325 | if (nv04_dac_in_use(encoder)) | ||
326 | return false; | ||
327 | |||
299 | if (tv_norm->kind == CTV_ENC_MODE) | 328 | if (tv_norm->kind == CTV_ENC_MODE) |
300 | adjusted_mode->clock = tv_norm->ctv_enc_mode.mode.clock; | 329 | adjusted_mode->clock = tv_norm->ctv_enc_mode.mode.clock; |
301 | else | 330 | else |
@@ -307,6 +336,8 @@ static bool nv17_tv_mode_fixup(struct drm_encoder *encoder, | |||
307 | static void nv17_tv_dpms(struct drm_encoder *encoder, int mode) | 336 | static void nv17_tv_dpms(struct drm_encoder *encoder, int mode) |
308 | { | 337 | { |
309 | struct drm_device *dev = encoder->dev; | 338 | struct drm_device *dev = encoder->dev; |
339 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
340 | struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio; | ||
310 | struct nv17_tv_state *regs = &to_tv_enc(encoder)->state; | 341 | struct nv17_tv_state *regs = &to_tv_enc(encoder)->state; |
311 | struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); | 342 | struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); |
312 | 343 | ||
@@ -331,8 +362,8 @@ static void nv17_tv_dpms(struct drm_encoder *encoder, int mode) | |||
331 | 362 | ||
332 | nv_load_ptv(dev, regs, 200); | 363 | nv_load_ptv(dev, regs, 200); |
333 | 364 | ||
334 | nv17_gpio_set(dev, DCB_GPIO_TVDAC1, mode == DRM_MODE_DPMS_ON); | 365 | gpio->set(dev, DCB_GPIO_TVDAC1, mode == DRM_MODE_DPMS_ON); |
335 | nv17_gpio_set(dev, DCB_GPIO_TVDAC0, mode == DRM_MODE_DPMS_ON); | 366 | gpio->set(dev, DCB_GPIO_TVDAC0, mode == DRM_MODE_DPMS_ON); |
336 | 367 | ||
337 | nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); | 368 | nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); |
338 | } | 369 | } |
@@ -744,8 +775,10 @@ static struct drm_encoder_funcs nv17_tv_funcs = { | |||
744 | .destroy = nv17_tv_destroy, | 775 | .destroy = nv17_tv_destroy, |
745 | }; | 776 | }; |
746 | 777 | ||
747 | int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry) | 778 | int |
779 | nv17_tv_create(struct drm_connector *connector, struct dcb_entry *entry) | ||
748 | { | 780 | { |
781 | struct drm_device *dev = connector->dev; | ||
749 | struct drm_encoder *encoder; | 782 | struct drm_encoder *encoder; |
750 | struct nv17_tv_encoder *tv_enc = NULL; | 783 | struct nv17_tv_encoder *tv_enc = NULL; |
751 | 784 | ||
@@ -774,5 +807,7 @@ int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry) | |||
774 | encoder->possible_crtcs = entry->heads; | 807 | encoder->possible_crtcs = entry->heads; |
775 | encoder->possible_clones = 0; | 808 | encoder->possible_clones = 0; |
776 | 809 | ||
810 | nv17_tv_create_resources(encoder, connector); | ||
811 | drm_mode_connector_attach_encoder(connector, encoder); | ||
777 | return 0; | 812 | return 0; |
778 | } | 813 | } |
diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index d6fc0a82f03d..17f309b36c91 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c | |||
@@ -370,68 +370,54 @@ nv20_graph_create_context(struct nouveau_channel *chan) | |||
370 | { | 370 | { |
371 | struct drm_device *dev = chan->dev; | 371 | struct drm_device *dev = chan->dev; |
372 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 372 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
373 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
373 | void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *); | 374 | void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *); |
374 | unsigned int ctx_size; | ||
375 | unsigned int idoffs = 0x28/4; | 375 | unsigned int idoffs = 0x28/4; |
376 | int ret; | 376 | int ret; |
377 | 377 | ||
378 | switch (dev_priv->chipset) { | 378 | switch (dev_priv->chipset) { |
379 | case 0x20: | 379 | case 0x20: |
380 | ctx_size = NV20_GRCTX_SIZE; | ||
381 | ctx_init = nv20_graph_context_init; | 380 | ctx_init = nv20_graph_context_init; |
382 | idoffs = 0; | 381 | idoffs = 0; |
383 | break; | 382 | break; |
384 | case 0x25: | 383 | case 0x25: |
385 | case 0x28: | 384 | case 0x28: |
386 | ctx_size = NV25_GRCTX_SIZE; | ||
387 | ctx_init = nv25_graph_context_init; | 385 | ctx_init = nv25_graph_context_init; |
388 | break; | 386 | break; |
389 | case 0x2a: | 387 | case 0x2a: |
390 | ctx_size = NV2A_GRCTX_SIZE; | ||
391 | ctx_init = nv2a_graph_context_init; | 388 | ctx_init = nv2a_graph_context_init; |
392 | idoffs = 0; | 389 | idoffs = 0; |
393 | break; | 390 | break; |
394 | case 0x30: | 391 | case 0x30: |
395 | case 0x31: | 392 | case 0x31: |
396 | ctx_size = NV30_31_GRCTX_SIZE; | ||
397 | ctx_init = nv30_31_graph_context_init; | 393 | ctx_init = nv30_31_graph_context_init; |
398 | break; | 394 | break; |
399 | case 0x34: | 395 | case 0x34: |
400 | ctx_size = NV34_GRCTX_SIZE; | ||
401 | ctx_init = nv34_graph_context_init; | 396 | ctx_init = nv34_graph_context_init; |
402 | break; | 397 | break; |
403 | case 0x35: | 398 | case 0x35: |
404 | case 0x36: | 399 | case 0x36: |
405 | ctx_size = NV35_36_GRCTX_SIZE; | ||
406 | ctx_init = nv35_36_graph_context_init; | 400 | ctx_init = nv35_36_graph_context_init; |
407 | break; | 401 | break; |
408 | default: | 402 | default: |
409 | ctx_size = 0; | 403 | BUG_ON(1); |
410 | ctx_init = nv35_36_graph_context_init; | ||
411 | NV_ERROR(dev, "Please contact the devs if you want your NV%x" | ||
412 | " card to work\n", dev_priv->chipset); | ||
413 | return -ENOSYS; | ||
414 | break; | ||
415 | } | 404 | } |
416 | 405 | ||
417 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16, | 406 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size, |
418 | NVOBJ_FLAG_ZERO_ALLOC, | 407 | 16, NVOBJ_FLAG_ZERO_ALLOC, |
419 | &chan->ramin_grctx); | 408 | &chan->ramin_grctx); |
420 | if (ret) | 409 | if (ret) |
421 | return ret; | 410 | return ret; |
422 | 411 | ||
423 | /* Initialise default context values */ | 412 | /* Initialise default context values */ |
424 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
425 | ctx_init(dev, chan->ramin_grctx->gpuobj); | 413 | ctx_init(dev, chan->ramin_grctx->gpuobj); |
426 | 414 | ||
427 | /* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */ | 415 | /* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */ |
428 | nv_wo32(dev, chan->ramin_grctx->gpuobj, idoffs, | 416 | nv_wo32(dev, chan->ramin_grctx->gpuobj, idoffs, |
429 | (chan->id << 24) | 0x1); /* CTX_USER */ | 417 | (chan->id << 24) | 0x1); /* CTX_USER */ |
430 | 418 | ||
431 | nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, | 419 | nv_wo32(dev, pgraph->ctx_table->gpuobj, chan->id, |
432 | chan->ramin_grctx->instance >> 4); | 420 | chan->ramin_grctx->instance >> 4); |
433 | |||
434 | dev_priv->engine.instmem.finish_access(dev); | ||
435 | return 0; | 421 | return 0; |
436 | } | 422 | } |
437 | 423 | ||
@@ -440,13 +426,12 @@ nv20_graph_destroy_context(struct nouveau_channel *chan) | |||
440 | { | 426 | { |
441 | struct drm_device *dev = chan->dev; | 427 | struct drm_device *dev = chan->dev; |
442 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 428 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
429 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
443 | 430 | ||
444 | if (chan->ramin_grctx) | 431 | if (chan->ramin_grctx) |
445 | nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); | 432 | nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); |
446 | 433 | ||
447 | dev_priv->engine.instmem.prepare_access(dev, true); | 434 | nv_wo32(dev, pgraph->ctx_table->gpuobj, chan->id, 0); |
448 | nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, 0); | ||
449 | dev_priv->engine.instmem.finish_access(dev); | ||
450 | } | 435 | } |
451 | 436 | ||
452 | int | 437 | int |
@@ -538,29 +523,44 @@ nv20_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, | |||
538 | int | 523 | int |
539 | nv20_graph_init(struct drm_device *dev) | 524 | nv20_graph_init(struct drm_device *dev) |
540 | { | 525 | { |
541 | struct drm_nouveau_private *dev_priv = | 526 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
542 | (struct drm_nouveau_private *)dev->dev_private; | 527 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; |
543 | uint32_t tmp, vramsz; | 528 | uint32_t tmp, vramsz; |
544 | int ret, i; | 529 | int ret, i; |
545 | 530 | ||
531 | switch (dev_priv->chipset) { | ||
532 | case 0x20: | ||
533 | pgraph->grctx_size = NV20_GRCTX_SIZE; | ||
534 | break; | ||
535 | case 0x25: | ||
536 | case 0x28: | ||
537 | pgraph->grctx_size = NV25_GRCTX_SIZE; | ||
538 | break; | ||
539 | case 0x2a: | ||
540 | pgraph->grctx_size = NV2A_GRCTX_SIZE; | ||
541 | break; | ||
542 | default: | ||
543 | NV_ERROR(dev, "unknown chipset, disabling acceleration\n"); | ||
544 | pgraph->accel_blocked = true; | ||
545 | return 0; | ||
546 | } | ||
547 | |||
546 | nv_wr32(dev, NV03_PMC_ENABLE, | 548 | nv_wr32(dev, NV03_PMC_ENABLE, |
547 | nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); | 549 | nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); |
548 | nv_wr32(dev, NV03_PMC_ENABLE, | 550 | nv_wr32(dev, NV03_PMC_ENABLE, |
549 | nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); | 551 | nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); |
550 | 552 | ||
551 | if (!dev_priv->ctx_table) { | 553 | if (!pgraph->ctx_table) { |
552 | /* Create Context Pointer Table */ | 554 | /* Create Context Pointer Table */ |
553 | dev_priv->ctx_table_size = 32 * 4; | 555 | ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 32 * 4, 16, |
554 | ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, | ||
555 | dev_priv->ctx_table_size, 16, | ||
556 | NVOBJ_FLAG_ZERO_ALLOC, | 556 | NVOBJ_FLAG_ZERO_ALLOC, |
557 | &dev_priv->ctx_table); | 557 | &pgraph->ctx_table); |
558 | if (ret) | 558 | if (ret) |
559 | return ret; | 559 | return ret; |
560 | } | 560 | } |
561 | 561 | ||
562 | nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, | 562 | nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, |
563 | dev_priv->ctx_table->instance >> 4); | 563 | pgraph->ctx_table->instance >> 4); |
564 | 564 | ||
565 | nv20_graph_rdi(dev); | 565 | nv20_graph_rdi(dev); |
566 | 566 | ||
@@ -616,7 +616,7 @@ nv20_graph_init(struct drm_device *dev) | |||
616 | nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp); | 616 | nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp); |
617 | 617 | ||
618 | /* begin RAM config */ | 618 | /* begin RAM config */ |
619 | vramsz = drm_get_resource_len(dev, 0) - 1; | 619 | vramsz = pci_resource_len(dev->pdev, 0) - 1; |
620 | nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); | 620 | nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); |
621 | nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1)); | 621 | nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1)); |
622 | nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000); | 622 | nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000); |
@@ -644,34 +644,52 @@ void | |||
644 | nv20_graph_takedown(struct drm_device *dev) | 644 | nv20_graph_takedown(struct drm_device *dev) |
645 | { | 645 | { |
646 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 646 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
647 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
647 | 648 | ||
648 | nouveau_gpuobj_ref_del(dev, &dev_priv->ctx_table); | 649 | nouveau_gpuobj_ref_del(dev, &pgraph->ctx_table); |
649 | } | 650 | } |
650 | 651 | ||
651 | int | 652 | int |
652 | nv30_graph_init(struct drm_device *dev) | 653 | nv30_graph_init(struct drm_device *dev) |
653 | { | 654 | { |
654 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 655 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
656 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
655 | int ret, i; | 657 | int ret, i; |
656 | 658 | ||
659 | switch (dev_priv->chipset) { | ||
660 | case 0x30: | ||
661 | case 0x31: | ||
662 | pgraph->grctx_size = NV30_31_GRCTX_SIZE; | ||
663 | break; | ||
664 | case 0x34: | ||
665 | pgraph->grctx_size = NV34_GRCTX_SIZE; | ||
666 | break; | ||
667 | case 0x35: | ||
668 | case 0x36: | ||
669 | pgraph->grctx_size = NV35_36_GRCTX_SIZE; | ||
670 | break; | ||
671 | default: | ||
672 | NV_ERROR(dev, "unknown chipset, disabling acceleration\n"); | ||
673 | pgraph->accel_blocked = true; | ||
674 | return 0; | ||
675 | } | ||
676 | |||
657 | nv_wr32(dev, NV03_PMC_ENABLE, | 677 | nv_wr32(dev, NV03_PMC_ENABLE, |
658 | nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); | 678 | nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); |
659 | nv_wr32(dev, NV03_PMC_ENABLE, | 679 | nv_wr32(dev, NV03_PMC_ENABLE, |
660 | nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); | 680 | nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); |
661 | 681 | ||
662 | if (!dev_priv->ctx_table) { | 682 | if (!pgraph->ctx_table) { |
663 | /* Create Context Pointer Table */ | 683 | /* Create Context Pointer Table */ |
664 | dev_priv->ctx_table_size = 32 * 4; | 684 | ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 32 * 4, 16, |
665 | ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, | ||
666 | dev_priv->ctx_table_size, 16, | ||
667 | NVOBJ_FLAG_ZERO_ALLOC, | 685 | NVOBJ_FLAG_ZERO_ALLOC, |
668 | &dev_priv->ctx_table); | 686 | &pgraph->ctx_table); |
669 | if (ret) | 687 | if (ret) |
670 | return ret; | 688 | return ret; |
671 | } | 689 | } |
672 | 690 | ||
673 | nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, | 691 | nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, |
674 | dev_priv->ctx_table->instance >> 4); | 692 | pgraph->ctx_table->instance >> 4); |
675 | 693 | ||
676 | nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); | 694 | nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); |
677 | nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); | 695 | nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); |
@@ -717,7 +735,7 @@ nv30_graph_init(struct drm_device *dev) | |||
717 | nv_wr32(dev, 0x0040075c , 0x00000001); | 735 | nv_wr32(dev, 0x0040075c , 0x00000001); |
718 | 736 | ||
719 | /* begin RAM config */ | 737 | /* begin RAM config */ |
720 | /* vramsz = drm_get_resource_len(dev, 0) - 1; */ | 738 | /* vramsz = pci_resource_len(dev->pdev, 0) - 1; */ |
721 | nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); | 739 | nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); |
722 | nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1)); | 740 | nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1)); |
723 | if (dev_priv->chipset != 0x34) { | 741 | if (dev_priv->chipset != 0x34) { |
diff --git a/drivers/gpu/drm/nouveau/nv30_fb.c b/drivers/gpu/drm/nouveau/nv30_fb.c new file mode 100644 index 000000000000..9d35c8b3b839 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv30_fb.c | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Francisco Jerez. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining | ||
6 | * a copy of this software and associated documentation files (the | ||
7 | * "Software"), to deal in the Software without restriction, including | ||
8 | * without limitation the rights to use, copy, modify, merge, publish, | ||
9 | * distribute, sublicense, and/or sell copies of the Software, and to | ||
10 | * permit persons to whom the Software is furnished to do so, subject to | ||
11 | * the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice (including the | ||
14 | * next paragraph) shall be included in all copies or substantial | ||
15 | * portions of the Software. | ||
16 | * | ||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
20 | * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||
21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include "drmP.h" | ||
28 | #include "drm.h" | ||
29 | #include "nouveau_drv.h" | ||
30 | #include "nouveau_drm.h" | ||
31 | |||
32 | static int | ||
33 | calc_ref(int b, int l, int i) | ||
34 | { | ||
35 | int j, x = 0; | ||
36 | |||
37 | for (j = 0; j < 4; j++) { | ||
38 | int n = (b >> (8 * j) & 0xf); | ||
39 | int m = (l >> (8 * i) & 0xff) + 2 * (n & 0x8 ? n - 0x10 : n); | ||
40 | |||
41 | x |= (0x80 | (m & 0x1f)) << (8 * j); | ||
42 | } | ||
43 | |||
44 | return x; | ||
45 | } | ||
46 | |||
47 | int | ||
48 | nv30_fb_init(struct drm_device *dev) | ||
49 | { | ||
50 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
51 | struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; | ||
52 | int i, j; | ||
53 | |||
54 | pfb->num_tiles = NV10_PFB_TILE__SIZE; | ||
55 | |||
56 | /* Turn all the tiling regions off. */ | ||
57 | for (i = 0; i < pfb->num_tiles; i++) | ||
58 | pfb->set_region_tiling(dev, i, 0, 0, 0); | ||
59 | |||
60 | /* Init the memory timing regs at 0x10037c/0x1003ac */ | ||
61 | if (dev_priv->chipset == 0x30 || | ||
62 | dev_priv->chipset == 0x31 || | ||
63 | dev_priv->chipset == 0x35) { | ||
64 | /* Related to ROP count */ | ||
65 | int n = (dev_priv->chipset == 0x31 ? 2 : 4); | ||
66 | int b = (dev_priv->chipset > 0x30 ? | ||
67 | nv_rd32(dev, 0x122c) & 0xf : 0); | ||
68 | int l = nv_rd32(dev, 0x1003d0); | ||
69 | |||
70 | for (i = 0; i < n; i++) { | ||
71 | for (j = 0; j < 3; j++) | ||
72 | nv_wr32(dev, 0x10037c + 0xc * i + 0x4 * j, | ||
73 | calc_ref(b, l, j)); | ||
74 | |||
75 | for (j = 0; j < 2; j++) | ||
76 | nv_wr32(dev, 0x1003ac + 0x8 * i + 0x4 * j, | ||
77 | calc_ref(b, l, j)); | ||
78 | } | ||
79 | } | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | void | ||
85 | nv30_fb_takedown(struct drm_device *dev) | ||
86 | { | ||
87 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c index 500ccfd3a0b8..2b67f1835c39 100644 --- a/drivers/gpu/drm/nouveau/nv40_fifo.c +++ b/drivers/gpu/drm/nouveau/nv40_fifo.c | |||
@@ -48,7 +48,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan) | |||
48 | 48 | ||
49 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | 49 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
50 | 50 | ||
51 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
52 | nv_wi32(dev, fc + 0, chan->pushbuf_base); | 51 | nv_wi32(dev, fc + 0, chan->pushbuf_base); |
53 | nv_wi32(dev, fc + 4, chan->pushbuf_base); | 52 | nv_wi32(dev, fc + 4, chan->pushbuf_base); |
54 | nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4); | 53 | nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4); |
@@ -61,7 +60,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan) | |||
61 | 0x30000000 /* no idea.. */); | 60 | 0x30000000 /* no idea.. */); |
62 | nv_wi32(dev, fc + 56, chan->ramin_grctx->instance >> 4); | 61 | nv_wi32(dev, fc + 56, chan->ramin_grctx->instance >> 4); |
63 | nv_wi32(dev, fc + 60, 0x0001FFFF); | 62 | nv_wi32(dev, fc + 60, 0x0001FFFF); |
64 | dev_priv->engine.instmem.finish_access(dev); | ||
65 | 63 | ||
66 | /* enable the fifo dma operation */ | 64 | /* enable the fifo dma operation */ |
67 | nv_wr32(dev, NV04_PFIFO_MODE, | 65 | nv_wr32(dev, NV04_PFIFO_MODE, |
@@ -89,8 +87,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid) | |||
89 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 87 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
90 | uint32_t fc = NV40_RAMFC(chid), tmp, tmp2; | 88 | uint32_t fc = NV40_RAMFC(chid), tmp, tmp2; |
91 | 89 | ||
92 | dev_priv->engine.instmem.prepare_access(dev, false); | ||
93 | |||
94 | nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); | 90 | nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); |
95 | nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); | 91 | nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); |
96 | nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); | 92 | nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); |
@@ -127,8 +123,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid) | |||
127 | nv_wr32(dev, 0x2088, nv_ri32(dev, fc + 76)); | 123 | nv_wr32(dev, 0x2088, nv_ri32(dev, fc + 76)); |
128 | nv_wr32(dev, 0x3300, nv_ri32(dev, fc + 80)); | 124 | nv_wr32(dev, 0x3300, nv_ri32(dev, fc + 80)); |
129 | 125 | ||
130 | dev_priv->engine.instmem.finish_access(dev); | ||
131 | |||
132 | nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); | 126 | nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); |
133 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); | 127 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); |
134 | } | 128 | } |
@@ -166,7 +160,6 @@ nv40_fifo_unload_context(struct drm_device *dev) | |||
166 | return 0; | 160 | return 0; |
167 | fc = NV40_RAMFC(chid); | 161 | fc = NV40_RAMFC(chid); |
168 | 162 | ||
169 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
170 | nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); | 163 | nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); |
171 | nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); | 164 | nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); |
172 | nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); | 165 | nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); |
@@ -200,7 +193,6 @@ nv40_fifo_unload_context(struct drm_device *dev) | |||
200 | tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16); | 193 | tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16); |
201 | nv_wi32(dev, fc + 72, tmp); | 194 | nv_wi32(dev, fc + 72, tmp); |
202 | #endif | 195 | #endif |
203 | dev_priv->engine.instmem.finish_access(dev); | ||
204 | 196 | ||
205 | nv40_fifo_do_load_context(dev, pfifo->channels - 1); | 197 | nv40_fifo_do_load_context(dev, pfifo->channels - 1); |
206 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, | 198 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, |
diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 704a25d04ac9..fd7d2b501316 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c | |||
@@ -58,6 +58,7 @@ nv40_graph_create_context(struct nouveau_channel *chan) | |||
58 | struct drm_device *dev = chan->dev; | 58 | struct drm_device *dev = chan->dev; |
59 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 59 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
60 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | 60 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; |
61 | struct nouveau_grctx ctx = {}; | ||
61 | int ret; | 62 | int ret; |
62 | 63 | ||
63 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size, | 64 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size, |
@@ -67,20 +68,13 @@ nv40_graph_create_context(struct nouveau_channel *chan) | |||
67 | return ret; | 68 | return ret; |
68 | 69 | ||
69 | /* Initialise default context values */ | 70 | /* Initialise default context values */ |
70 | dev_priv->engine.instmem.prepare_access(dev, true); | 71 | ctx.dev = chan->dev; |
71 | if (!pgraph->ctxprog) { | 72 | ctx.mode = NOUVEAU_GRCTX_VALS; |
72 | struct nouveau_grctx ctx = {}; | 73 | ctx.data = chan->ramin_grctx->gpuobj; |
73 | 74 | nv40_grctx_init(&ctx); | |
74 | ctx.dev = chan->dev; | 75 | |
75 | ctx.mode = NOUVEAU_GRCTX_VALS; | ||
76 | ctx.data = chan->ramin_grctx->gpuobj; | ||
77 | nv40_grctx_init(&ctx); | ||
78 | } else { | ||
79 | nouveau_grctx_vals_load(dev, chan->ramin_grctx->gpuobj); | ||
80 | } | ||
81 | nv_wo32(dev, chan->ramin_grctx->gpuobj, 0, | 76 | nv_wo32(dev, chan->ramin_grctx->gpuobj, 0, |
82 | chan->ramin_grctx->gpuobj->im_pramin->start); | 77 | chan->ramin_grctx->gpuobj->im_pramin->start); |
83 | dev_priv->engine.instmem.finish_access(dev); | ||
84 | return 0; | 78 | return 0; |
85 | } | 79 | } |
86 | 80 | ||
@@ -238,7 +232,8 @@ nv40_graph_init(struct drm_device *dev) | |||
238 | struct drm_nouveau_private *dev_priv = | 232 | struct drm_nouveau_private *dev_priv = |
239 | (struct drm_nouveau_private *)dev->dev_private; | 233 | (struct drm_nouveau_private *)dev->dev_private; |
240 | struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; | 234 | struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; |
241 | uint32_t vramsz; | 235 | struct nouveau_grctx ctx = {}; |
236 | uint32_t vramsz, *cp; | ||
242 | int i, j; | 237 | int i, j; |
243 | 238 | ||
244 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & | 239 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & |
@@ -246,32 +241,22 @@ nv40_graph_init(struct drm_device *dev) | |||
246 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | | 241 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | |
247 | NV_PMC_ENABLE_PGRAPH); | 242 | NV_PMC_ENABLE_PGRAPH); |
248 | 243 | ||
249 | if (nouveau_ctxfw) { | 244 | cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL); |
250 | nouveau_grctx_prog_load(dev); | 245 | if (!cp) |
251 | dev_priv->engine.graph.grctx_size = 175 * 1024; | 246 | return -ENOMEM; |
252 | } | ||
253 | 247 | ||
254 | if (!dev_priv->engine.graph.ctxprog) { | 248 | ctx.dev = dev; |
255 | struct nouveau_grctx ctx = {}; | 249 | ctx.mode = NOUVEAU_GRCTX_PROG; |
256 | uint32_t *cp; | 250 | ctx.data = cp; |
251 | ctx.ctxprog_max = 256; | ||
252 | nv40_grctx_init(&ctx); | ||
253 | dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; | ||
257 | 254 | ||
258 | cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL); | 255 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); |
259 | if (!cp) | 256 | for (i = 0; i < ctx.ctxprog_len; i++) |
260 | return -ENOMEM; | 257 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); |
261 | 258 | ||
262 | ctx.dev = dev; | 259 | kfree(cp); |
263 | ctx.mode = NOUVEAU_GRCTX_PROG; | ||
264 | ctx.data = cp; | ||
265 | ctx.ctxprog_max = 256; | ||
266 | nv40_grctx_init(&ctx); | ||
267 | dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; | ||
268 | |||
269 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); | ||
270 | for (i = 0; i < ctx.ctxprog_len; i++) | ||
271 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); | ||
272 | |||
273 | kfree(cp); | ||
274 | } | ||
275 | 260 | ||
276 | /* No context present currently */ | 261 | /* No context present currently */ |
277 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); | 262 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); |
@@ -367,7 +352,7 @@ nv40_graph_init(struct drm_device *dev) | |||
367 | nv40_graph_set_region_tiling(dev, i, 0, 0, 0); | 352 | nv40_graph_set_region_tiling(dev, i, 0, 0, 0); |
368 | 353 | ||
369 | /* begin RAM config */ | 354 | /* begin RAM config */ |
370 | vramsz = drm_get_resource_len(dev, 0) - 1; | 355 | vramsz = pci_resource_len(dev->pdev, 0) - 1; |
371 | switch (dev_priv->chipset) { | 356 | switch (dev_priv->chipset) { |
372 | case 0x40: | 357 | case 0x40: |
373 | nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); | 358 | nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); |
@@ -407,7 +392,6 @@ nv40_graph_init(struct drm_device *dev) | |||
407 | 392 | ||
408 | void nv40_graph_takedown(struct drm_device *dev) | 393 | void nv40_graph_takedown(struct drm_device *dev) |
409 | { | 394 | { |
410 | nouveau_grctx_fini(dev); | ||
411 | } | 395 | } |
412 | 396 | ||
413 | struct nouveau_pgraph_object_class nv40_graph_grclass[] = { | 397 | struct nouveau_pgraph_object_class nv40_graph_grclass[] = { |
diff --git a/drivers/gpu/drm/nouveau/nv40_mc.c b/drivers/gpu/drm/nouveau/nv40_mc.c index 2a3495e848e9..e4e72c12ab6a 100644 --- a/drivers/gpu/drm/nouveau/nv40_mc.c +++ b/drivers/gpu/drm/nouveau/nv40_mc.c | |||
@@ -19,7 +19,7 @@ nv40_mc_init(struct drm_device *dev) | |||
19 | case 0x46: /* G72 */ | 19 | case 0x46: /* G72 */ |
20 | case 0x4e: | 20 | case 0x4e: |
21 | case 0x4c: /* C51_G7X */ | 21 | case 0x4c: /* C51_G7X */ |
22 | tmp = nv_rd32(dev, NV40_PFB_020C); | 22 | tmp = nv_rd32(dev, NV04_PFB_FIFO_DATA); |
23 | nv_wr32(dev, NV40_PMC_1700, tmp); | 23 | nv_wr32(dev, NV40_PMC_1700, tmp); |
24 | nv_wr32(dev, NV40_PMC_1704, 0); | 24 | nv_wr32(dev, NV40_PMC_1704, 0); |
25 | nv_wr32(dev, NV40_PMC_1708, 0); | 25 | nv_wr32(dev, NV40_PMC_1708, 0); |
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index b4e4a3b05eae..5d11ea101666 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c | |||
@@ -440,47 +440,15 @@ nv50_crtc_prepare(struct drm_crtc *crtc) | |||
440 | { | 440 | { |
441 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 441 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
442 | struct drm_device *dev = crtc->dev; | 442 | struct drm_device *dev = crtc->dev; |
443 | struct drm_encoder *encoder; | ||
444 | uint32_t dac = 0, sor = 0; | ||
445 | 443 | ||
446 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); | 444 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); |
447 | 445 | ||
448 | /* Disconnect all unused encoders. */ | ||
449 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
450 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
451 | |||
452 | if (!drm_helper_encoder_in_use(encoder)) | ||
453 | continue; | ||
454 | |||
455 | if (nv_encoder->dcb->type == OUTPUT_ANALOG || | ||
456 | nv_encoder->dcb->type == OUTPUT_TV) | ||
457 | dac |= (1 << nv_encoder->or); | ||
458 | else | ||
459 | sor |= (1 << nv_encoder->or); | ||
460 | } | ||
461 | |||
462 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
463 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
464 | |||
465 | if (nv_encoder->dcb->type == OUTPUT_ANALOG || | ||
466 | nv_encoder->dcb->type == OUTPUT_TV) { | ||
467 | if (dac & (1 << nv_encoder->or)) | ||
468 | continue; | ||
469 | } else { | ||
470 | if (sor & (1 << nv_encoder->or)) | ||
471 | continue; | ||
472 | } | ||
473 | |||
474 | nv_encoder->disconnect(nv_encoder); | ||
475 | } | ||
476 | |||
477 | nv50_crtc_blank(nv_crtc, true); | 446 | nv50_crtc_blank(nv_crtc, true); |
478 | } | 447 | } |
479 | 448 | ||
480 | static void | 449 | static void |
481 | nv50_crtc_commit(struct drm_crtc *crtc) | 450 | nv50_crtc_commit(struct drm_crtc *crtc) |
482 | { | 451 | { |
483 | struct drm_crtc *crtc2; | ||
484 | struct drm_device *dev = crtc->dev; | 452 | struct drm_device *dev = crtc->dev; |
485 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 453 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
486 | struct nouveau_channel *evo = dev_priv->evo; | 454 | struct nouveau_channel *evo = dev_priv->evo; |
@@ -491,20 +459,14 @@ nv50_crtc_commit(struct drm_crtc *crtc) | |||
491 | 459 | ||
492 | nv50_crtc_blank(nv_crtc, false); | 460 | nv50_crtc_blank(nv_crtc, false); |
493 | 461 | ||
494 | /* Explicitly blank all unused crtc's. */ | ||
495 | list_for_each_entry(crtc2, &dev->mode_config.crtc_list, head) { | ||
496 | if (!drm_helper_crtc_in_use(crtc2)) | ||
497 | nv50_crtc_blank(nouveau_crtc(crtc2), true); | ||
498 | } | ||
499 | |||
500 | ret = RING_SPACE(evo, 2); | 462 | ret = RING_SPACE(evo, 2); |
501 | if (ret) { | 463 | if (ret) { |
502 | NV_ERROR(dev, "no space while committing crtc\n"); | 464 | NV_ERROR(dev, "no space while committing crtc\n"); |
503 | return; | 465 | return; |
504 | } | 466 | } |
505 | BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); | 467 | BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); |
506 | OUT_RING(evo, 0); | 468 | OUT_RING (evo, 0); |
507 | FIRE_RING(evo); | 469 | FIRE_RING (evo); |
508 | } | 470 | } |
509 | 471 | ||
510 | static bool | 472 | static bool |
diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index 1fd9537beff6..1bc085962945 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c | |||
@@ -37,22 +37,31 @@ | |||
37 | #include "nv50_display.h" | 37 | #include "nv50_display.h" |
38 | 38 | ||
39 | static void | 39 | static void |
40 | nv50_dac_disconnect(struct nouveau_encoder *nv_encoder) | 40 | nv50_dac_disconnect(struct drm_encoder *encoder) |
41 | { | 41 | { |
42 | struct drm_device *dev = to_drm_encoder(nv_encoder)->dev; | 42 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
43 | struct drm_device *dev = encoder->dev; | ||
43 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 44 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
44 | struct nouveau_channel *evo = dev_priv->evo; | 45 | struct nouveau_channel *evo = dev_priv->evo; |
45 | int ret; | 46 | int ret; |
46 | 47 | ||
48 | if (!nv_encoder->crtc) | ||
49 | return; | ||
50 | nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true); | ||
51 | |||
47 | NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or); | 52 | NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or); |
48 | 53 | ||
49 | ret = RING_SPACE(evo, 2); | 54 | ret = RING_SPACE(evo, 4); |
50 | if (ret) { | 55 | if (ret) { |
51 | NV_ERROR(dev, "no space while disconnecting DAC\n"); | 56 | NV_ERROR(dev, "no space while disconnecting DAC\n"); |
52 | return; | 57 | return; |
53 | } | 58 | } |
54 | BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1); | 59 | BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1); |
55 | OUT_RING(evo, 0); | 60 | OUT_RING (evo, 0); |
61 | BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); | ||
62 | OUT_RING (evo, 0); | ||
63 | |||
64 | nv_encoder->crtc = NULL; | ||
56 | } | 65 | } |
57 | 66 | ||
58 | static enum drm_connector_status | 67 | static enum drm_connector_status |
@@ -213,7 +222,8 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
213 | uint32_t mode_ctl = 0, mode_ctl2 = 0; | 222 | uint32_t mode_ctl = 0, mode_ctl2 = 0; |
214 | int ret; | 223 | int ret; |
215 | 224 | ||
216 | NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or); | 225 | NV_DEBUG_KMS(dev, "or %d type %d crtc %d\n", |
226 | nv_encoder->or, nv_encoder->dcb->type, crtc->index); | ||
217 | 227 | ||
218 | nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON); | 228 | nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON); |
219 | 229 | ||
@@ -243,6 +253,14 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
243 | BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2); | 253 | BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2); |
244 | OUT_RING(evo, mode_ctl); | 254 | OUT_RING(evo, mode_ctl); |
245 | OUT_RING(evo, mode_ctl2); | 255 | OUT_RING(evo, mode_ctl2); |
256 | |||
257 | nv_encoder->crtc = encoder->crtc; | ||
258 | } | ||
259 | |||
260 | static struct drm_crtc * | ||
261 | nv50_dac_crtc_get(struct drm_encoder *encoder) | ||
262 | { | ||
263 | return nouveau_encoder(encoder)->crtc; | ||
246 | } | 264 | } |
247 | 265 | ||
248 | static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { | 266 | static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { |
@@ -253,7 +271,9 @@ static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { | |||
253 | .prepare = nv50_dac_prepare, | 271 | .prepare = nv50_dac_prepare, |
254 | .commit = nv50_dac_commit, | 272 | .commit = nv50_dac_commit, |
255 | .mode_set = nv50_dac_mode_set, | 273 | .mode_set = nv50_dac_mode_set, |
256 | .detect = nv50_dac_detect | 274 | .get_crtc = nv50_dac_crtc_get, |
275 | .detect = nv50_dac_detect, | ||
276 | .disable = nv50_dac_disconnect | ||
257 | }; | 277 | }; |
258 | 278 | ||
259 | static void | 279 | static void |
@@ -275,14 +295,11 @@ static const struct drm_encoder_funcs nv50_dac_encoder_funcs = { | |||
275 | }; | 295 | }; |
276 | 296 | ||
277 | int | 297 | int |
278 | nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry) | 298 | nv50_dac_create(struct drm_connector *connector, struct dcb_entry *entry) |
279 | { | 299 | { |
280 | struct nouveau_encoder *nv_encoder; | 300 | struct nouveau_encoder *nv_encoder; |
281 | struct drm_encoder *encoder; | 301 | struct drm_encoder *encoder; |
282 | 302 | ||
283 | NV_DEBUG_KMS(dev, "\n"); | ||
284 | NV_INFO(dev, "Detected a DAC output\n"); | ||
285 | |||
286 | nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); | 303 | nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); |
287 | if (!nv_encoder) | 304 | if (!nv_encoder) |
288 | return -ENOMEM; | 305 | return -ENOMEM; |
@@ -291,14 +308,14 @@ nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry) | |||
291 | nv_encoder->dcb = entry; | 308 | nv_encoder->dcb = entry; |
292 | nv_encoder->or = ffs(entry->or) - 1; | 309 | nv_encoder->or = ffs(entry->or) - 1; |
293 | 310 | ||
294 | nv_encoder->disconnect = nv50_dac_disconnect; | 311 | drm_encoder_init(connector->dev, encoder, &nv50_dac_encoder_funcs, |
295 | |||
296 | drm_encoder_init(dev, encoder, &nv50_dac_encoder_funcs, | ||
297 | DRM_MODE_ENCODER_DAC); | 312 | DRM_MODE_ENCODER_DAC); |
298 | drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs); | 313 | drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs); |
299 | 314 | ||
300 | encoder->possible_crtcs = entry->heads; | 315 | encoder->possible_crtcs = entry->heads; |
301 | encoder->possible_clones = 0; | 316 | encoder->possible_clones = 0; |
317 | |||
318 | drm_mode_connector_attach_encoder(connector, encoder); | ||
302 | return 0; | 319 | return 0; |
303 | } | 320 | } |
304 | 321 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 580a5d10be93..f13ad0de9c8f 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -71,14 +71,13 @@ nv50_evo_dmaobj_new(struct nouveau_channel *evo, uint32_t class, uint32_t name, | |||
71 | return ret; | 71 | return ret; |
72 | } | 72 | } |
73 | 73 | ||
74 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
75 | nv_wo32(dev, obj, 0, (tile_flags << 22) | (magic_flags << 16) | class); | 74 | nv_wo32(dev, obj, 0, (tile_flags << 22) | (magic_flags << 16) | class); |
76 | nv_wo32(dev, obj, 1, limit); | 75 | nv_wo32(dev, obj, 1, limit); |
77 | nv_wo32(dev, obj, 2, offset); | 76 | nv_wo32(dev, obj, 2, offset); |
78 | nv_wo32(dev, obj, 3, 0x00000000); | 77 | nv_wo32(dev, obj, 3, 0x00000000); |
79 | nv_wo32(dev, obj, 4, 0x00000000); | 78 | nv_wo32(dev, obj, 4, 0x00000000); |
80 | nv_wo32(dev, obj, 5, 0x00010000); | 79 | nv_wo32(dev, obj, 5, 0x00010000); |
81 | dev_priv->engine.instmem.finish_access(dev); | 80 | dev_priv->engine.instmem.flush(dev); |
82 | 81 | ||
83 | return 0; | 82 | return 0; |
84 | } | 83 | } |
@@ -110,8 +109,8 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan) | |||
110 | return ret; | 109 | return ret; |
111 | } | 110 | } |
112 | 111 | ||
113 | ret = nouveau_mem_init_heap(&chan->ramin_heap, chan->ramin->gpuobj-> | 112 | ret = drm_mm_init(&chan->ramin_heap, |
114 | im_pramin->start, 32768); | 113 | chan->ramin->gpuobj->im_pramin->start, 32768); |
115 | if (ret) { | 114 | if (ret) { |
116 | NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret); | 115 | NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret); |
117 | nv50_evo_channel_del(pchan); | 116 | nv50_evo_channel_del(pchan); |
@@ -179,13 +178,25 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan) | |||
179 | } | 178 | } |
180 | 179 | ||
181 | int | 180 | int |
181 | nv50_display_early_init(struct drm_device *dev) | ||
182 | { | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | void | ||
187 | nv50_display_late_takedown(struct drm_device *dev) | ||
188 | { | ||
189 | } | ||
190 | |||
191 | int | ||
182 | nv50_display_init(struct drm_device *dev) | 192 | nv50_display_init(struct drm_device *dev) |
183 | { | 193 | { |
184 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 194 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
185 | struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; | 195 | struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; |
196 | struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; | ||
186 | struct nouveau_channel *evo = dev_priv->evo; | 197 | struct nouveau_channel *evo = dev_priv->evo; |
187 | struct drm_connector *connector; | 198 | struct drm_connector *connector; |
188 | uint32_t val, ram_amount, hpd_en[2]; | 199 | uint32_t val, ram_amount; |
189 | uint64_t start; | 200 | uint64_t start; |
190 | int ret, i; | 201 | int ret, i; |
191 | 202 | ||
@@ -366,26 +377,13 @@ nv50_display_init(struct drm_device *dev) | |||
366 | NV50_PDISPLAY_INTR_EN_CLK_UNK40)); | 377 | NV50_PDISPLAY_INTR_EN_CLK_UNK40)); |
367 | 378 | ||
368 | /* enable hotplug interrupts */ | 379 | /* enable hotplug interrupts */ |
369 | hpd_en[0] = hpd_en[1] = 0; | ||
370 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 380 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
371 | struct nouveau_connector *conn = nouveau_connector(connector); | 381 | struct nouveau_connector *conn = nouveau_connector(connector); |
372 | struct dcb_gpio_entry *gpio; | ||
373 | 382 | ||
374 | if (conn->dcb->gpio_tag == 0xff) | 383 | if (conn->dcb->gpio_tag == 0xff) |
375 | continue; | 384 | continue; |
376 | 385 | ||
377 | gpio = nouveau_bios_gpio_entry(dev, conn->dcb->gpio_tag); | 386 | pgpio->irq_enable(dev, conn->dcb->gpio_tag, true); |
378 | if (!gpio) | ||
379 | continue; | ||
380 | |||
381 | hpd_en[gpio->line >> 4] |= (0x00010001 << (gpio->line & 0xf)); | ||
382 | } | ||
383 | |||
384 | nv_wr32(dev, 0xe054, 0xffffffff); | ||
385 | nv_wr32(dev, 0xe050, hpd_en[0]); | ||
386 | if (dev_priv->chipset >= 0x90) { | ||
387 | nv_wr32(dev, 0xe074, 0xffffffff); | ||
388 | nv_wr32(dev, 0xe070, hpd_en[1]); | ||
389 | } | 387 | } |
390 | 388 | ||
391 | return 0; | 389 | return 0; |
@@ -465,6 +463,7 @@ int nv50_display_create(struct drm_device *dev) | |||
465 | { | 463 | { |
466 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 464 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
467 | struct dcb_table *dcb = &dev_priv->vbios.dcb; | 465 | struct dcb_table *dcb = &dev_priv->vbios.dcb; |
466 | struct drm_connector *connector, *ct; | ||
468 | int ret, i; | 467 | int ret, i; |
469 | 468 | ||
470 | NV_DEBUG_KMS(dev, "\n"); | 469 | NV_DEBUG_KMS(dev, "\n"); |
@@ -507,14 +506,18 @@ int nv50_display_create(struct drm_device *dev) | |||
507 | continue; | 506 | continue; |
508 | } | 507 | } |
509 | 508 | ||
509 | connector = nouveau_connector_create(dev, entry->connector); | ||
510 | if (IS_ERR(connector)) | ||
511 | continue; | ||
512 | |||
510 | switch (entry->type) { | 513 | switch (entry->type) { |
511 | case OUTPUT_TMDS: | 514 | case OUTPUT_TMDS: |
512 | case OUTPUT_LVDS: | 515 | case OUTPUT_LVDS: |
513 | case OUTPUT_DP: | 516 | case OUTPUT_DP: |
514 | nv50_sor_create(dev, entry); | 517 | nv50_sor_create(connector, entry); |
515 | break; | 518 | break; |
516 | case OUTPUT_ANALOG: | 519 | case OUTPUT_ANALOG: |
517 | nv50_dac_create(dev, entry); | 520 | nv50_dac_create(connector, entry); |
518 | break; | 521 | break; |
519 | default: | 522 | default: |
520 | NV_WARN(dev, "DCB encoder %d unknown\n", entry->type); | 523 | NV_WARN(dev, "DCB encoder %d unknown\n", entry->type); |
@@ -522,11 +525,13 @@ int nv50_display_create(struct drm_device *dev) | |||
522 | } | 525 | } |
523 | } | 526 | } |
524 | 527 | ||
525 | for (i = 0 ; i < dcb->connector.entries; i++) { | 528 | list_for_each_entry_safe(connector, ct, |
526 | if (i != 0 && dcb->connector.entry[i].index2 == | 529 | &dev->mode_config.connector_list, head) { |
527 | dcb->connector.entry[i - 1].index2) | 530 | if (!connector->encoder_ids[0]) { |
528 | continue; | 531 | NV_WARN(dev, "%s has no encoders, removing\n", |
529 | nouveau_connector_create(dev, &dcb->connector.entry[i]); | 532 | drm_get_connector_name(connector)); |
533 | connector->funcs->destroy(connector); | ||
534 | } | ||
530 | } | 535 | } |
531 | 536 | ||
532 | ret = nv50_display_init(dev); | 537 | ret = nv50_display_init(dev); |
@@ -538,7 +543,8 @@ int nv50_display_create(struct drm_device *dev) | |||
538 | return 0; | 543 | return 0; |
539 | } | 544 | } |
540 | 545 | ||
541 | int nv50_display_destroy(struct drm_device *dev) | 546 | void |
547 | nv50_display_destroy(struct drm_device *dev) | ||
542 | { | 548 | { |
543 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 549 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
544 | 550 | ||
@@ -548,135 +554,30 @@ int nv50_display_destroy(struct drm_device *dev) | |||
548 | 554 | ||
549 | nv50_display_disable(dev); | 555 | nv50_display_disable(dev); |
550 | nv50_evo_channel_del(&dev_priv->evo); | 556 | nv50_evo_channel_del(&dev_priv->evo); |
551 | |||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | static inline uint32_t | ||
556 | nv50_display_mode_ctrl(struct drm_device *dev, bool sor, int or) | ||
557 | { | ||
558 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
559 | uint32_t mc; | ||
560 | |||
561 | if (sor) { | ||
562 | if (dev_priv->chipset < 0x90 || | ||
563 | dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0) | ||
564 | mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(or)); | ||
565 | else | ||
566 | mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(or)); | ||
567 | } else { | ||
568 | mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(or)); | ||
569 | } | ||
570 | |||
571 | return mc; | ||
572 | } | ||
573 | |||
574 | static int | ||
575 | nv50_display_irq_head(struct drm_device *dev, int *phead, | ||
576 | struct dcb_entry **pdcbent) | ||
577 | { | ||
578 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
579 | uint32_t unk30 = nv_rd32(dev, NV50_PDISPLAY_UNK30_CTRL); | ||
580 | uint32_t dac = 0, sor = 0; | ||
581 | int head, i, or = 0, type = OUTPUT_ANY; | ||
582 | |||
583 | /* We're assuming that head 0 *or* head 1 will be active here, | ||
584 | * and not both. I'm not sure if the hw will even signal both | ||
585 | * ever, but it definitely shouldn't for us as we commit each | ||
586 | * CRTC separately, and submission will be blocked by the GPU | ||
587 | * until we handle each in turn. | ||
588 | */ | ||
589 | NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); | ||
590 | head = ffs((unk30 >> 9) & 3) - 1; | ||
591 | if (head < 0) | ||
592 | return -EINVAL; | ||
593 | |||
594 | /* This assumes CRTCs are never bound to multiple encoders, which | ||
595 | * should be the case. | ||
596 | */ | ||
597 | for (i = 0; i < 3 && type == OUTPUT_ANY; i++) { | ||
598 | uint32_t mc = nv50_display_mode_ctrl(dev, false, i); | ||
599 | if (!(mc & (1 << head))) | ||
600 | continue; | ||
601 | |||
602 | switch ((mc >> 8) & 0xf) { | ||
603 | case 0: type = OUTPUT_ANALOG; break; | ||
604 | case 1: type = OUTPUT_TV; break; | ||
605 | default: | ||
606 | NV_ERROR(dev, "unknown dac mode_ctrl: 0x%08x\n", dac); | ||
607 | return -1; | ||
608 | } | ||
609 | |||
610 | or = i; | ||
611 | } | ||
612 | |||
613 | for (i = 0; i < 4 && type == OUTPUT_ANY; i++) { | ||
614 | uint32_t mc = nv50_display_mode_ctrl(dev, true, i); | ||
615 | if (!(mc & (1 << head))) | ||
616 | continue; | ||
617 | |||
618 | switch ((mc >> 8) & 0xf) { | ||
619 | case 0: type = OUTPUT_LVDS; break; | ||
620 | case 1: type = OUTPUT_TMDS; break; | ||
621 | case 2: type = OUTPUT_TMDS; break; | ||
622 | case 5: type = OUTPUT_TMDS; break; | ||
623 | case 8: type = OUTPUT_DP; break; | ||
624 | case 9: type = OUTPUT_DP; break; | ||
625 | default: | ||
626 | NV_ERROR(dev, "unknown sor mode_ctrl: 0x%08x\n", sor); | ||
627 | return -1; | ||
628 | } | ||
629 | |||
630 | or = i; | ||
631 | } | ||
632 | |||
633 | NV_DEBUG_KMS(dev, "type %d, or %d\n", type, or); | ||
634 | if (type == OUTPUT_ANY) { | ||
635 | NV_ERROR(dev, "unknown encoder!!\n"); | ||
636 | return -1; | ||
637 | } | ||
638 | |||
639 | for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { | ||
640 | struct dcb_entry *dcbent = &dev_priv->vbios.dcb.entry[i]; | ||
641 | |||
642 | if (dcbent->type != type) | ||
643 | continue; | ||
644 | |||
645 | if (!(dcbent->or & (1 << or))) | ||
646 | continue; | ||
647 | |||
648 | *phead = head; | ||
649 | *pdcbent = dcbent; | ||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | NV_ERROR(dev, "no DCB entry for %d %d\n", dac != 0, or); | ||
654 | return 0; | ||
655 | } | 557 | } |
656 | 558 | ||
657 | static uint32_t | 559 | static u16 |
658 | nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent, | 560 | nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb, |
659 | int pxclk) | 561 | u32 mc, int pxclk) |
660 | { | 562 | { |
661 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 563 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
662 | struct nouveau_connector *nv_connector = NULL; | 564 | struct nouveau_connector *nv_connector = NULL; |
663 | struct drm_encoder *encoder; | 565 | struct drm_encoder *encoder; |
664 | struct nvbios *bios = &dev_priv->vbios; | 566 | struct nvbios *bios = &dev_priv->vbios; |
665 | uint32_t mc, script = 0, or; | 567 | u32 script = 0, or; |
666 | 568 | ||
667 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 569 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
668 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 570 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
669 | 571 | ||
670 | if (nv_encoder->dcb != dcbent) | 572 | if (nv_encoder->dcb != dcb) |
671 | continue; | 573 | continue; |
672 | 574 | ||
673 | nv_connector = nouveau_encoder_connector_get(nv_encoder); | 575 | nv_connector = nouveau_encoder_connector_get(nv_encoder); |
674 | break; | 576 | break; |
675 | } | 577 | } |
676 | 578 | ||
677 | or = ffs(dcbent->or) - 1; | 579 | or = ffs(dcb->or) - 1; |
678 | mc = nv50_display_mode_ctrl(dev, dcbent->type != OUTPUT_ANALOG, or); | 580 | switch (dcb->type) { |
679 | switch (dcbent->type) { | ||
680 | case OUTPUT_LVDS: | 581 | case OUTPUT_LVDS: |
681 | script = (mc >> 8) & 0xf; | 582 | script = (mc >> 8) & 0xf; |
682 | if (bios->fp_no_ddc) { | 583 | if (bios->fp_no_ddc) { |
@@ -767,17 +668,88 @@ nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr) | |||
767 | static void | 668 | static void |
768 | nv50_display_unk10_handler(struct drm_device *dev) | 669 | nv50_display_unk10_handler(struct drm_device *dev) |
769 | { | 670 | { |
770 | struct dcb_entry *dcbent; | 671 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
771 | int head, ret; | 672 | u32 unk30 = nv_rd32(dev, 0x610030), mc; |
673 | int i, crtc, or, type = OUTPUT_ANY; | ||
772 | 674 | ||
773 | ret = nv50_display_irq_head(dev, &head, &dcbent); | 675 | NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); |
774 | if (ret) | 676 | dev_priv->evo_irq.dcb = NULL; |
775 | goto ack; | ||
776 | 677 | ||
777 | nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8); | 678 | nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8); |
778 | 679 | ||
779 | nouveau_bios_run_display_table(dev, dcbent, 0, -1); | 680 | /* Determine which CRTC we're dealing with, only 1 ever will be |
681 | * signalled at the same time with the current nouveau code. | ||
682 | */ | ||
683 | crtc = ffs((unk30 & 0x00000060) >> 5) - 1; | ||
684 | if (crtc < 0) | ||
685 | goto ack; | ||
686 | |||
687 | /* Nothing needs to be done for the encoder */ | ||
688 | crtc = ffs((unk30 & 0x00000180) >> 7) - 1; | ||
689 | if (crtc < 0) | ||
690 | goto ack; | ||
780 | 691 | ||
692 | /* Find which encoder was connected to the CRTC */ | ||
693 | for (i = 0; type == OUTPUT_ANY && i < 3; i++) { | ||
694 | mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_C(i)); | ||
695 | NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc); | ||
696 | if (!(mc & (1 << crtc))) | ||
697 | continue; | ||
698 | |||
699 | switch ((mc & 0x00000f00) >> 8) { | ||
700 | case 0: type = OUTPUT_ANALOG; break; | ||
701 | case 1: type = OUTPUT_TV; break; | ||
702 | default: | ||
703 | NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc); | ||
704 | goto ack; | ||
705 | } | ||
706 | |||
707 | or = i; | ||
708 | } | ||
709 | |||
710 | for (i = 0; type == OUTPUT_ANY && i < 4; i++) { | ||
711 | if (dev_priv->chipset < 0x90 || | ||
712 | dev_priv->chipset == 0x92 || | ||
713 | dev_priv->chipset == 0xa0) | ||
714 | mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(i)); | ||
715 | else | ||
716 | mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(i)); | ||
717 | |||
718 | NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc); | ||
719 | if (!(mc & (1 << crtc))) | ||
720 | continue; | ||
721 | |||
722 | switch ((mc & 0x00000f00) >> 8) { | ||
723 | case 0: type = OUTPUT_LVDS; break; | ||
724 | case 1: type = OUTPUT_TMDS; break; | ||
725 | case 2: type = OUTPUT_TMDS; break; | ||
726 | case 5: type = OUTPUT_TMDS; break; | ||
727 | case 8: type = OUTPUT_DP; break; | ||
728 | case 9: type = OUTPUT_DP; break; | ||
729 | default: | ||
730 | NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc); | ||
731 | goto ack; | ||
732 | } | ||
733 | |||
734 | or = i; | ||
735 | } | ||
736 | |||
737 | /* There was no encoder to disable */ | ||
738 | if (type == OUTPUT_ANY) | ||
739 | goto ack; | ||
740 | |||
741 | /* Disable the encoder */ | ||
742 | for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { | ||
743 | struct dcb_entry *dcb = &dev_priv->vbios.dcb.entry[i]; | ||
744 | |||
745 | if (dcb->type == type && (dcb->or & (1 << or))) { | ||
746 | nouveau_bios_run_display_table(dev, dcb, 0, -1); | ||
747 | dev_priv->evo_irq.dcb = dcb; | ||
748 | goto ack; | ||
749 | } | ||
750 | } | ||
751 | |||
752 | NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc); | ||
781 | ack: | 753 | ack: |
782 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10); | 754 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10); |
783 | nv_wr32(dev, 0x610030, 0x80000000); | 755 | nv_wr32(dev, 0x610030, 0x80000000); |
@@ -817,33 +789,103 @@ nv50_display_unk20_dp_hack(struct drm_device *dev, struct dcb_entry *dcb) | |||
817 | static void | 789 | static void |
818 | nv50_display_unk20_handler(struct drm_device *dev) | 790 | nv50_display_unk20_handler(struct drm_device *dev) |
819 | { | 791 | { |
820 | struct dcb_entry *dcbent; | 792 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
821 | uint32_t tmp, pclk, script; | 793 | u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc; |
822 | int head, or, ret; | 794 | struct dcb_entry *dcb; |
795 | int i, crtc, or, type = OUTPUT_ANY; | ||
823 | 796 | ||
824 | ret = nv50_display_irq_head(dev, &head, &dcbent); | 797 | NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); |
825 | if (ret) | 798 | dcb = dev_priv->evo_irq.dcb; |
799 | if (dcb) { | ||
800 | nouveau_bios_run_display_table(dev, dcb, 0, -2); | ||
801 | dev_priv->evo_irq.dcb = NULL; | ||
802 | } | ||
803 | |||
804 | /* CRTC clock change requested? */ | ||
805 | crtc = ffs((unk30 & 0x00000600) >> 9) - 1; | ||
806 | if (crtc >= 0) { | ||
807 | pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)); | ||
808 | pclk &= 0x003fffff; | ||
809 | |||
810 | nv50_crtc_set_clock(dev, crtc, pclk); | ||
811 | |||
812 | tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc)); | ||
813 | tmp &= ~0x000000f; | ||
814 | nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc), tmp); | ||
815 | } | ||
816 | |||
817 | /* Nothing needs to be done for the encoder */ | ||
818 | crtc = ffs((unk30 & 0x00000180) >> 7) - 1; | ||
819 | if (crtc < 0) | ||
826 | goto ack; | 820 | goto ack; |
827 | or = ffs(dcbent->or) - 1; | 821 | pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)) & 0x003fffff; |
828 | pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff; | ||
829 | script = nv50_display_script_select(dev, dcbent, pclk); | ||
830 | 822 | ||
831 | NV_DEBUG_KMS(dev, "head %d pxclk: %dKHz\n", head, pclk); | 823 | /* Find which encoder is connected to the CRTC */ |
824 | for (i = 0; type == OUTPUT_ANY && i < 3; i++) { | ||
825 | mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(i)); | ||
826 | NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc); | ||
827 | if (!(mc & (1 << crtc))) | ||
828 | continue; | ||
832 | 829 | ||
833 | if (dcbent->type != OUTPUT_DP) | 830 | switch ((mc & 0x00000f00) >> 8) { |
834 | nouveau_bios_run_display_table(dev, dcbent, 0, -2); | 831 | case 0: type = OUTPUT_ANALOG; break; |
832 | case 1: type = OUTPUT_TV; break; | ||
833 | default: | ||
834 | NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc); | ||
835 | goto ack; | ||
836 | } | ||
835 | 837 | ||
836 | nv50_crtc_set_clock(dev, head, pclk); | 838 | or = i; |
839 | } | ||
837 | 840 | ||
838 | nouveau_bios_run_display_table(dev, dcbent, script, pclk); | 841 | for (i = 0; type == OUTPUT_ANY && i < 4; i++) { |
842 | if (dev_priv->chipset < 0x90 || | ||
843 | dev_priv->chipset == 0x92 || | ||
844 | dev_priv->chipset == 0xa0) | ||
845 | mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(i)); | ||
846 | else | ||
847 | mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(i)); | ||
839 | 848 | ||
840 | nv50_display_unk20_dp_hack(dev, dcbent); | 849 | NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc); |
850 | if (!(mc & (1 << crtc))) | ||
851 | continue; | ||
852 | |||
853 | switch ((mc & 0x00000f00) >> 8) { | ||
854 | case 0: type = OUTPUT_LVDS; break; | ||
855 | case 1: type = OUTPUT_TMDS; break; | ||
856 | case 2: type = OUTPUT_TMDS; break; | ||
857 | case 5: type = OUTPUT_TMDS; break; | ||
858 | case 8: type = OUTPUT_DP; break; | ||
859 | case 9: type = OUTPUT_DP; break; | ||
860 | default: | ||
861 | NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc); | ||
862 | goto ack; | ||
863 | } | ||
864 | |||
865 | or = i; | ||
866 | } | ||
867 | |||
868 | if (type == OUTPUT_ANY) | ||
869 | goto ack; | ||
870 | |||
871 | /* Enable the encoder */ | ||
872 | for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { | ||
873 | dcb = &dev_priv->vbios.dcb.entry[i]; | ||
874 | if (dcb->type == type && (dcb->or & (1 << or))) | ||
875 | break; | ||
876 | } | ||
877 | |||
878 | if (i == dev_priv->vbios.dcb.entries) { | ||
879 | NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc); | ||
880 | goto ack; | ||
881 | } | ||
841 | 882 | ||
842 | tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head)); | 883 | script = nv50_display_script_select(dev, dcb, mc, pclk); |
843 | tmp &= ~0x000000f; | 884 | nouveau_bios_run_display_table(dev, dcb, script, pclk); |
844 | nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head), tmp); | ||
845 | 885 | ||
846 | if (dcbent->type != OUTPUT_ANALOG) { | 886 | nv50_display_unk20_dp_hack(dev, dcb); |
887 | |||
888 | if (dcb->type != OUTPUT_ANALOG) { | ||
847 | tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or)); | 889 | tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or)); |
848 | tmp &= ~0x00000f0f; | 890 | tmp &= ~0x00000f0f; |
849 | if (script & 0x0100) | 891 | if (script & 0x0100) |
@@ -853,24 +895,61 @@ nv50_display_unk20_handler(struct drm_device *dev) | |||
853 | nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0); | 895 | nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0); |
854 | } | 896 | } |
855 | 897 | ||
898 | dev_priv->evo_irq.dcb = dcb; | ||
899 | dev_priv->evo_irq.pclk = pclk; | ||
900 | dev_priv->evo_irq.script = script; | ||
901 | |||
856 | ack: | 902 | ack: |
857 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20); | 903 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20); |
858 | nv_wr32(dev, 0x610030, 0x80000000); | 904 | nv_wr32(dev, 0x610030, 0x80000000); |
859 | } | 905 | } |
860 | 906 | ||
907 | /* If programming a TMDS output on a SOR that can also be configured for | ||
908 | * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off. | ||
909 | * | ||
910 | * It looks like the VBIOS TMDS scripts make an attempt at this, however, | ||
911 | * the VBIOS scripts on at least one board I have only switch it off on | ||
912 | * link 0, causing a blank display if the output has previously been | ||
913 | * programmed for DisplayPort. | ||
914 | */ | ||
915 | static void | ||
916 | nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb) | ||
917 | { | ||
918 | int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1); | ||
919 | struct drm_encoder *encoder; | ||
920 | u32 tmp; | ||
921 | |||
922 | if (dcb->type != OUTPUT_TMDS) | ||
923 | return; | ||
924 | |||
925 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
926 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
927 | |||
928 | if (nv_encoder->dcb->type == OUTPUT_DP && | ||
929 | nv_encoder->dcb->or & (1 << or)) { | ||
930 | tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link)); | ||
931 | tmp &= ~NV50_SOR_DP_CTRL_ENABLED; | ||
932 | nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp); | ||
933 | break; | ||
934 | } | ||
935 | } | ||
936 | } | ||
937 | |||
861 | static void | 938 | static void |
862 | nv50_display_unk40_handler(struct drm_device *dev) | 939 | nv50_display_unk40_handler(struct drm_device *dev) |
863 | { | 940 | { |
864 | struct dcb_entry *dcbent; | 941 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
865 | int head, pclk, script, ret; | 942 | struct dcb_entry *dcb = dev_priv->evo_irq.dcb; |
943 | u16 script = dev_priv->evo_irq.script; | ||
944 | u32 unk30 = nv_rd32(dev, 0x610030), pclk = dev_priv->evo_irq.pclk; | ||
866 | 945 | ||
867 | ret = nv50_display_irq_head(dev, &head, &dcbent); | 946 | NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); |
868 | if (ret) | 947 | dev_priv->evo_irq.dcb = NULL; |
948 | if (!dcb) | ||
869 | goto ack; | 949 | goto ack; |
870 | pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff; | ||
871 | script = nv50_display_script_select(dev, dcbent, pclk); | ||
872 | 950 | ||
873 | nouveau_bios_run_display_table(dev, dcbent, script, -pclk); | 951 | nouveau_bios_run_display_table(dev, dcb, script, -pclk); |
952 | nv50_display_unk40_dp_set_tmds(dev, dcb); | ||
874 | 953 | ||
875 | ack: | 954 | ack: |
876 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40); | 955 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40); |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h index 581d405ac014..c551f0b85ee0 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.h +++ b/drivers/gpu/drm/nouveau/nv50_display.h | |||
@@ -38,9 +38,11 @@ | |||
38 | void nv50_display_irq_handler(struct drm_device *dev); | 38 | void nv50_display_irq_handler(struct drm_device *dev); |
39 | void nv50_display_irq_handler_bh(struct work_struct *work); | 39 | void nv50_display_irq_handler_bh(struct work_struct *work); |
40 | void nv50_display_irq_hotplug_bh(struct work_struct *work); | 40 | void nv50_display_irq_hotplug_bh(struct work_struct *work); |
41 | int nv50_display_init(struct drm_device *dev); | 41 | int nv50_display_early_init(struct drm_device *dev); |
42 | void nv50_display_late_takedown(struct drm_device *dev); | ||
42 | int nv50_display_create(struct drm_device *dev); | 43 | int nv50_display_create(struct drm_device *dev); |
43 | int nv50_display_destroy(struct drm_device *dev); | 44 | int nv50_display_init(struct drm_device *dev); |
45 | void nv50_display_destroy(struct drm_device *dev); | ||
44 | int nv50_crtc_blank(struct nouveau_crtc *, bool blank); | 46 | int nv50_crtc_blank(struct nouveau_crtc *, bool blank); |
45 | int nv50_crtc_set_clock(struct drm_device *, int head, int pclk); | 47 | int nv50_crtc_set_clock(struct drm_device *, int head, int pclk); |
46 | 48 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index e20c0e2474f3..fb0281ae8f90 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c | |||
@@ -28,41 +28,33 @@ | |||
28 | #include "drm.h" | 28 | #include "drm.h" |
29 | #include "nouveau_drv.h" | 29 | #include "nouveau_drv.h" |
30 | 30 | ||
31 | struct nv50_fifo_priv { | ||
32 | struct nouveau_gpuobj_ref *thingo[2]; | ||
33 | int cur_thingo; | ||
34 | }; | ||
35 | |||
36 | #define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) | ||
37 | |||
38 | static void | 31 | static void |
39 | nv50_fifo_init_thingo(struct drm_device *dev) | 32 | nv50_fifo_playlist_update(struct drm_device *dev) |
40 | { | 33 | { |
41 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 34 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
42 | struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv; | 35 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; |
43 | struct nouveau_gpuobj_ref *cur; | 36 | struct nouveau_gpuobj_ref *cur; |
44 | int i, nr; | 37 | int i, nr; |
45 | 38 | ||
46 | NV_DEBUG(dev, "\n"); | 39 | NV_DEBUG(dev, "\n"); |
47 | 40 | ||
48 | cur = priv->thingo[priv->cur_thingo]; | 41 | cur = pfifo->playlist[pfifo->cur_playlist]; |
49 | priv->cur_thingo = !priv->cur_thingo; | 42 | pfifo->cur_playlist = !pfifo->cur_playlist; |
50 | 43 | ||
51 | /* We never schedule channel 0 or 127 */ | 44 | /* We never schedule channel 0 or 127 */ |
52 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
53 | for (i = 1, nr = 0; i < 127; i++) { | 45 | for (i = 1, nr = 0; i < 127; i++) { |
54 | if (dev_priv->fifos[i] && dev_priv->fifos[i]->ramfc) | 46 | if (dev_priv->fifos[i] && dev_priv->fifos[i]->ramfc) |
55 | nv_wo32(dev, cur->gpuobj, nr++, i); | 47 | nv_wo32(dev, cur->gpuobj, nr++, i); |
56 | } | 48 | } |
57 | dev_priv->engine.instmem.finish_access(dev); | 49 | dev_priv->engine.instmem.flush(dev); |
58 | 50 | ||
59 | nv_wr32(dev, 0x32f4, cur->instance >> 12); | 51 | nv_wr32(dev, 0x32f4, cur->instance >> 12); |
60 | nv_wr32(dev, 0x32ec, nr); | 52 | nv_wr32(dev, 0x32ec, nr); |
61 | nv_wr32(dev, 0x2500, 0x101); | 53 | nv_wr32(dev, 0x2500, 0x101); |
62 | } | 54 | } |
63 | 55 | ||
64 | static int | 56 | static void |
65 | nv50_fifo_channel_enable(struct drm_device *dev, int channel, bool nt) | 57 | nv50_fifo_channel_enable(struct drm_device *dev, int channel) |
66 | { | 58 | { |
67 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 59 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
68 | struct nouveau_channel *chan = dev_priv->fifos[channel]; | 60 | struct nouveau_channel *chan = dev_priv->fifos[channel]; |
@@ -70,37 +62,28 @@ nv50_fifo_channel_enable(struct drm_device *dev, int channel, bool nt) | |||
70 | 62 | ||
71 | NV_DEBUG(dev, "ch%d\n", channel); | 63 | NV_DEBUG(dev, "ch%d\n", channel); |
72 | 64 | ||
73 | if (!chan->ramfc) | 65 | if (dev_priv->chipset == 0x50) |
74 | return -EINVAL; | ||
75 | |||
76 | if (IS_G80) | ||
77 | inst = chan->ramfc->instance >> 12; | 66 | inst = chan->ramfc->instance >> 12; |
78 | else | 67 | else |
79 | inst = chan->ramfc->instance >> 8; | 68 | inst = chan->ramfc->instance >> 8; |
80 | nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), | ||
81 | inst | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED); | ||
82 | 69 | ||
83 | if (!nt) | 70 | nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst | |
84 | nv50_fifo_init_thingo(dev); | 71 | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED); |
85 | return 0; | ||
86 | } | 72 | } |
87 | 73 | ||
88 | static void | 74 | static void |
89 | nv50_fifo_channel_disable(struct drm_device *dev, int channel, bool nt) | 75 | nv50_fifo_channel_disable(struct drm_device *dev, int channel) |
90 | { | 76 | { |
91 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 77 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
92 | uint32_t inst; | 78 | uint32_t inst; |
93 | 79 | ||
94 | NV_DEBUG(dev, "ch%d, nt=%d\n", channel, nt); | 80 | NV_DEBUG(dev, "ch%d\n", channel); |
95 | 81 | ||
96 | if (IS_G80) | 82 | if (dev_priv->chipset == 0x50) |
97 | inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80; | 83 | inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80; |
98 | else | 84 | else |
99 | inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84; | 85 | inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84; |
100 | nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst); | 86 | nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst); |
101 | |||
102 | if (!nt) | ||
103 | nv50_fifo_init_thingo(dev); | ||
104 | } | 87 | } |
105 | 88 | ||
106 | static void | 89 | static void |
@@ -133,12 +116,12 @@ nv50_fifo_init_context_table(struct drm_device *dev) | |||
133 | 116 | ||
134 | for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) { | 117 | for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) { |
135 | if (dev_priv->fifos[i]) | 118 | if (dev_priv->fifos[i]) |
136 | nv50_fifo_channel_enable(dev, i, true); | 119 | nv50_fifo_channel_enable(dev, i); |
137 | else | 120 | else |
138 | nv50_fifo_channel_disable(dev, i, true); | 121 | nv50_fifo_channel_disable(dev, i); |
139 | } | 122 | } |
140 | 123 | ||
141 | nv50_fifo_init_thingo(dev); | 124 | nv50_fifo_playlist_update(dev); |
142 | } | 125 | } |
143 | 126 | ||
144 | static void | 127 | static void |
@@ -162,41 +145,38 @@ nv50_fifo_init_regs(struct drm_device *dev) | |||
162 | nv_wr32(dev, 0x3270, 0); | 145 | nv_wr32(dev, 0x3270, 0); |
163 | 146 | ||
164 | /* Enable dummy channels setup by nv50_instmem.c */ | 147 | /* Enable dummy channels setup by nv50_instmem.c */ |
165 | nv50_fifo_channel_enable(dev, 0, true); | 148 | nv50_fifo_channel_enable(dev, 0); |
166 | nv50_fifo_channel_enable(dev, 127, true); | 149 | nv50_fifo_channel_enable(dev, 127); |
167 | } | 150 | } |
168 | 151 | ||
169 | int | 152 | int |
170 | nv50_fifo_init(struct drm_device *dev) | 153 | nv50_fifo_init(struct drm_device *dev) |
171 | { | 154 | { |
172 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 155 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
173 | struct nv50_fifo_priv *priv; | 156 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; |
174 | int ret; | 157 | int ret; |
175 | 158 | ||
176 | NV_DEBUG(dev, "\n"); | 159 | NV_DEBUG(dev, "\n"); |
177 | 160 | ||
178 | priv = dev_priv->engine.fifo.priv; | 161 | if (pfifo->playlist[0]) { |
179 | if (priv) { | 162 | pfifo->cur_playlist = !pfifo->cur_playlist; |
180 | priv->cur_thingo = !priv->cur_thingo; | ||
181 | goto just_reset; | 163 | goto just_reset; |
182 | } | 164 | } |
183 | 165 | ||
184 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
185 | if (!priv) | ||
186 | return -ENOMEM; | ||
187 | dev_priv->engine.fifo.priv = priv; | ||
188 | |||
189 | ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, | 166 | ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, |
190 | NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[0]); | 167 | NVOBJ_FLAG_ZERO_ALLOC, |
168 | &pfifo->playlist[0]); | ||
191 | if (ret) { | 169 | if (ret) { |
192 | NV_ERROR(dev, "error creating thingo0: %d\n", ret); | 170 | NV_ERROR(dev, "error creating playlist 0: %d\n", ret); |
193 | return ret; | 171 | return ret; |
194 | } | 172 | } |
195 | 173 | ||
196 | ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, | 174 | ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, |
197 | NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[1]); | 175 | NVOBJ_FLAG_ZERO_ALLOC, |
176 | &pfifo->playlist[1]); | ||
198 | if (ret) { | 177 | if (ret) { |
199 | NV_ERROR(dev, "error creating thingo1: %d\n", ret); | 178 | nouveau_gpuobj_ref_del(dev, &pfifo->playlist[0]); |
179 | NV_ERROR(dev, "error creating playlist 1: %d\n", ret); | ||
200 | return ret; | 180 | return ret; |
201 | } | 181 | } |
202 | 182 | ||
@@ -216,18 +196,15 @@ void | |||
216 | nv50_fifo_takedown(struct drm_device *dev) | 196 | nv50_fifo_takedown(struct drm_device *dev) |
217 | { | 197 | { |
218 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 198 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
219 | struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv; | 199 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; |
220 | 200 | ||
221 | NV_DEBUG(dev, "\n"); | 201 | NV_DEBUG(dev, "\n"); |
222 | 202 | ||
223 | if (!priv) | 203 | if (!pfifo->playlist[0]) |
224 | return; | 204 | return; |
225 | 205 | ||
226 | nouveau_gpuobj_ref_del(dev, &priv->thingo[0]); | 206 | nouveau_gpuobj_ref_del(dev, &pfifo->playlist[0]); |
227 | nouveau_gpuobj_ref_del(dev, &priv->thingo[1]); | 207 | nouveau_gpuobj_ref_del(dev, &pfifo->playlist[1]); |
228 | |||
229 | dev_priv->engine.fifo.priv = NULL; | ||
230 | kfree(priv); | ||
231 | } | 208 | } |
232 | 209 | ||
233 | int | 210 | int |
@@ -248,7 +225,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan) | |||
248 | 225 | ||
249 | NV_DEBUG(dev, "ch%d\n", chan->id); | 226 | NV_DEBUG(dev, "ch%d\n", chan->id); |
250 | 227 | ||
251 | if (IS_G80) { | 228 | if (dev_priv->chipset == 0x50) { |
252 | uint32_t ramin_poffset = chan->ramin->gpuobj->im_pramin->start; | 229 | uint32_t ramin_poffset = chan->ramin->gpuobj->im_pramin->start; |
253 | uint32_t ramin_voffset = chan->ramin->gpuobj->im_backing_start; | 230 | uint32_t ramin_voffset = chan->ramin->gpuobj->im_backing_start; |
254 | 231 | ||
@@ -281,10 +258,10 @@ nv50_fifo_create_context(struct nouveau_channel *chan) | |||
281 | 258 | ||
282 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | 259 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
283 | 260 | ||
284 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
285 | |||
286 | nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4); | 261 | nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4); |
287 | nv_wo32(dev, ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4)); | 262 | nv_wo32(dev, ramfc, 0x80/4, (0 << 27) /* 4KiB */ | |
263 | (4 << 24) /* SEARCH_FULL */ | | ||
264 | (chan->ramht->instance >> 4)); | ||
288 | nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff); | 265 | nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff); |
289 | nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff); | 266 | nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff); |
290 | nv_wo32(dev, ramfc, 0x40/4, 0x00000000); | 267 | nv_wo32(dev, ramfc, 0x40/4, 0x00000000); |
@@ -295,7 +272,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan) | |||
295 | chan->dma.ib_base * 4); | 272 | chan->dma.ib_base * 4); |
296 | nv_wo32(dev, ramfc, 0x54/4, drm_order(chan->dma.ib_max + 1) << 16); | 273 | nv_wo32(dev, ramfc, 0x54/4, drm_order(chan->dma.ib_max + 1) << 16); |
297 | 274 | ||
298 | if (!IS_G80) { | 275 | if (dev_priv->chipset != 0x50) { |
299 | nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id); | 276 | nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id); |
300 | nv_wo32(dev, chan->ramin->gpuobj, 1, | 277 | nv_wo32(dev, chan->ramin->gpuobj, 1, |
301 | chan->ramfc->instance >> 8); | 278 | chan->ramfc->instance >> 8); |
@@ -304,16 +281,10 @@ nv50_fifo_create_context(struct nouveau_channel *chan) | |||
304 | nv_wo32(dev, ramfc, 0x98/4, chan->ramin->instance >> 12); | 281 | nv_wo32(dev, ramfc, 0x98/4, chan->ramin->instance >> 12); |
305 | } | 282 | } |
306 | 283 | ||
307 | dev_priv->engine.instmem.finish_access(dev); | 284 | dev_priv->engine.instmem.flush(dev); |
308 | |||
309 | ret = nv50_fifo_channel_enable(dev, chan->id, false); | ||
310 | if (ret) { | ||
311 | NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret); | ||
312 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | ||
313 | nouveau_gpuobj_ref_del(dev, &chan->ramfc); | ||
314 | return ret; | ||
315 | } | ||
316 | 285 | ||
286 | nv50_fifo_channel_enable(dev, chan->id); | ||
287 | nv50_fifo_playlist_update(dev); | ||
317 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | 288 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); |
318 | return 0; | 289 | return 0; |
319 | } | 290 | } |
@@ -328,11 +299,12 @@ nv50_fifo_destroy_context(struct nouveau_channel *chan) | |||
328 | 299 | ||
329 | /* This will ensure the channel is seen as disabled. */ | 300 | /* This will ensure the channel is seen as disabled. */ |
330 | chan->ramfc = NULL; | 301 | chan->ramfc = NULL; |
331 | nv50_fifo_channel_disable(dev, chan->id, false); | 302 | nv50_fifo_channel_disable(dev, chan->id); |
332 | 303 | ||
333 | /* Dummy channel, also used on ch 127 */ | 304 | /* Dummy channel, also used on ch 127 */ |
334 | if (chan->id == 0) | 305 | if (chan->id == 0) |
335 | nv50_fifo_channel_disable(dev, 127, false); | 306 | nv50_fifo_channel_disable(dev, 127); |
307 | nv50_fifo_playlist_update(dev); | ||
336 | 308 | ||
337 | nouveau_gpuobj_ref_del(dev, &ramfc); | 309 | nouveau_gpuobj_ref_del(dev, &ramfc); |
338 | nouveau_gpuobj_ref_del(dev, &chan->cache); | 310 | nouveau_gpuobj_ref_del(dev, &chan->cache); |
@@ -349,8 +321,6 @@ nv50_fifo_load_context(struct nouveau_channel *chan) | |||
349 | 321 | ||
350 | NV_DEBUG(dev, "ch%d\n", chan->id); | 322 | NV_DEBUG(dev, "ch%d\n", chan->id); |
351 | 323 | ||
352 | dev_priv->engine.instmem.prepare_access(dev, false); | ||
353 | |||
354 | nv_wr32(dev, 0x3330, nv_ro32(dev, ramfc, 0x00/4)); | 324 | nv_wr32(dev, 0x3330, nv_ro32(dev, ramfc, 0x00/4)); |
355 | nv_wr32(dev, 0x3334, nv_ro32(dev, ramfc, 0x04/4)); | 325 | nv_wr32(dev, 0x3334, nv_ro32(dev, ramfc, 0x04/4)); |
356 | nv_wr32(dev, 0x3240, nv_ro32(dev, ramfc, 0x08/4)); | 326 | nv_wr32(dev, 0x3240, nv_ro32(dev, ramfc, 0x08/4)); |
@@ -396,7 +366,7 @@ nv50_fifo_load_context(struct nouveau_channel *chan) | |||
396 | nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); | 366 | nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); |
397 | 367 | ||
398 | /* guessing that all the 0x34xx regs aren't on NV50 */ | 368 | /* guessing that all the 0x34xx regs aren't on NV50 */ |
399 | if (!IS_G80) { | 369 | if (dev_priv->chipset != 0x50) { |
400 | nv_wr32(dev, 0x340c, nv_ro32(dev, ramfc, 0x88/4)); | 370 | nv_wr32(dev, 0x340c, nv_ro32(dev, ramfc, 0x88/4)); |
401 | nv_wr32(dev, 0x3400, nv_ro32(dev, ramfc, 0x8c/4)); | 371 | nv_wr32(dev, 0x3400, nv_ro32(dev, ramfc, 0x8c/4)); |
402 | nv_wr32(dev, 0x3404, nv_ro32(dev, ramfc, 0x90/4)); | 372 | nv_wr32(dev, 0x3404, nv_ro32(dev, ramfc, 0x90/4)); |
@@ -404,8 +374,6 @@ nv50_fifo_load_context(struct nouveau_channel *chan) | |||
404 | nv_wr32(dev, 0x3410, nv_ro32(dev, ramfc, 0x98/4)); | 374 | nv_wr32(dev, 0x3410, nv_ro32(dev, ramfc, 0x98/4)); |
405 | } | 375 | } |
406 | 376 | ||
407 | dev_priv->engine.instmem.finish_access(dev); | ||
408 | |||
409 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16)); | 377 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16)); |
410 | return 0; | 378 | return 0; |
411 | } | 379 | } |
@@ -434,8 +402,6 @@ nv50_fifo_unload_context(struct drm_device *dev) | |||
434 | ramfc = chan->ramfc->gpuobj; | 402 | ramfc = chan->ramfc->gpuobj; |
435 | cache = chan->cache->gpuobj; | 403 | cache = chan->cache->gpuobj; |
436 | 404 | ||
437 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
438 | |||
439 | nv_wo32(dev, ramfc, 0x00/4, nv_rd32(dev, 0x3330)); | 405 | nv_wo32(dev, ramfc, 0x00/4, nv_rd32(dev, 0x3330)); |
440 | nv_wo32(dev, ramfc, 0x04/4, nv_rd32(dev, 0x3334)); | 406 | nv_wo32(dev, ramfc, 0x04/4, nv_rd32(dev, 0x3334)); |
441 | nv_wo32(dev, ramfc, 0x08/4, nv_rd32(dev, 0x3240)); | 407 | nv_wo32(dev, ramfc, 0x08/4, nv_rd32(dev, 0x3240)); |
@@ -482,7 +448,7 @@ nv50_fifo_unload_context(struct drm_device *dev) | |||
482 | } | 448 | } |
483 | 449 | ||
484 | /* guessing that all the 0x34xx regs aren't on NV50 */ | 450 | /* guessing that all the 0x34xx regs aren't on NV50 */ |
485 | if (!IS_G80) { | 451 | if (dev_priv->chipset != 0x50) { |
486 | nv_wo32(dev, ramfc, 0x84/4, ptr >> 1); | 452 | nv_wo32(dev, ramfc, 0x84/4, ptr >> 1); |
487 | nv_wo32(dev, ramfc, 0x88/4, nv_rd32(dev, 0x340c)); | 453 | nv_wo32(dev, ramfc, 0x88/4, nv_rd32(dev, 0x340c)); |
488 | nv_wo32(dev, ramfc, 0x8c/4, nv_rd32(dev, 0x3400)); | 454 | nv_wo32(dev, ramfc, 0x8c/4, nv_rd32(dev, 0x3400)); |
@@ -491,7 +457,7 @@ nv50_fifo_unload_context(struct drm_device *dev) | |||
491 | nv_wo32(dev, ramfc, 0x98/4, nv_rd32(dev, 0x3410)); | 457 | nv_wo32(dev, ramfc, 0x98/4, nv_rd32(dev, 0x3410)); |
492 | } | 458 | } |
493 | 459 | ||
494 | dev_priv->engine.instmem.finish_access(dev); | 460 | dev_priv->engine.instmem.flush(dev); |
495 | 461 | ||
496 | /*XXX: probably reload ch127 (NULL) state back too */ | 462 | /*XXX: probably reload ch127 (NULL) state back too */ |
497 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, 127); | 463 | nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, 127); |
diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c index bb47ad737267..b2fab2bf3d61 100644 --- a/drivers/gpu/drm/nouveau/nv50_gpio.c +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c | |||
@@ -74,3 +74,38 @@ nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state) | |||
74 | nv_wr32(dev, r, v); | 74 | nv_wr32(dev, r, v); |
75 | return 0; | 75 | return 0; |
76 | } | 76 | } |
77 | |||
78 | void | ||
79 | nv50_gpio_irq_enable(struct drm_device *dev, enum dcb_gpio_tag tag, bool on) | ||
80 | { | ||
81 | struct dcb_gpio_entry *gpio; | ||
82 | u32 reg, mask; | ||
83 | |||
84 | gpio = nouveau_bios_gpio_entry(dev, tag); | ||
85 | if (!gpio) { | ||
86 | NV_ERROR(dev, "gpio tag 0x%02x not found\n", tag); | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | reg = gpio->line < 16 ? 0xe050 : 0xe070; | ||
91 | mask = 0x00010001 << (gpio->line & 0xf); | ||
92 | |||
93 | nv_wr32(dev, reg + 4, mask); | ||
94 | nv_mask(dev, reg + 0, mask, on ? mask : 0); | ||
95 | } | ||
96 | |||
97 | int | ||
98 | nv50_gpio_init(struct drm_device *dev) | ||
99 | { | ||
100 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
101 | |||
102 | /* disable, and ack any pending gpio interrupts */ | ||
103 | nv_wr32(dev, 0xe050, 0x00000000); | ||
104 | nv_wr32(dev, 0xe054, 0xffffffff); | ||
105 | if (dev_priv->chipset >= 0x90) { | ||
106 | nv_wr32(dev, 0xe070, 0x00000000); | ||
107 | nv_wr32(dev, 0xe074, 0xffffffff); | ||
108 | } | ||
109 | |||
110 | return 0; | ||
111 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index b203d06f601f..1413028e1580 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
@@ -30,8 +30,6 @@ | |||
30 | 30 | ||
31 | #include "nouveau_grctx.h" | 31 | #include "nouveau_grctx.h" |
32 | 32 | ||
33 | #define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) | ||
34 | |||
35 | static void | 33 | static void |
36 | nv50_graph_init_reset(struct drm_device *dev) | 34 | nv50_graph_init_reset(struct drm_device *dev) |
37 | { | 35 | { |
@@ -103,37 +101,33 @@ static int | |||
103 | nv50_graph_init_ctxctl(struct drm_device *dev) | 101 | nv50_graph_init_ctxctl(struct drm_device *dev) |
104 | { | 102 | { |
105 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 103 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
104 | struct nouveau_grctx ctx = {}; | ||
105 | uint32_t *cp; | ||
106 | int i; | ||
106 | 107 | ||
107 | NV_DEBUG(dev, "\n"); | 108 | NV_DEBUG(dev, "\n"); |
108 | 109 | ||
109 | if (nouveau_ctxfw) { | 110 | cp = kmalloc(512 * 4, GFP_KERNEL); |
110 | nouveau_grctx_prog_load(dev); | 111 | if (!cp) { |
111 | dev_priv->engine.graph.grctx_size = 0x70000; | 112 | NV_ERROR(dev, "failed to allocate ctxprog\n"); |
113 | dev_priv->engine.graph.accel_blocked = true; | ||
114 | return 0; | ||
112 | } | 115 | } |
113 | if (!dev_priv->engine.graph.ctxprog) { | 116 | |
114 | struct nouveau_grctx ctx = {}; | 117 | ctx.dev = dev; |
115 | uint32_t *cp = kmalloc(512 * 4, GFP_KERNEL); | 118 | ctx.mode = NOUVEAU_GRCTX_PROG; |
116 | int i; | 119 | ctx.data = cp; |
117 | if (!cp) { | 120 | ctx.ctxprog_max = 512; |
118 | NV_ERROR(dev, "Couldn't alloc ctxprog! Disabling acceleration.\n"); | 121 | if (!nv50_grctx_init(&ctx)) { |
119 | dev_priv->engine.graph.accel_blocked = true; | 122 | dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; |
120 | return 0; | 123 | |
121 | } | 124 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); |
122 | ctx.dev = dev; | 125 | for (i = 0; i < ctx.ctxprog_len; i++) |
123 | ctx.mode = NOUVEAU_GRCTX_PROG; | 126 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); |
124 | ctx.data = cp; | 127 | } else { |
125 | ctx.ctxprog_max = 512; | 128 | dev_priv->engine.graph.accel_blocked = true; |
126 | if (!nv50_grctx_init(&ctx)) { | ||
127 | dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; | ||
128 | |||
129 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); | ||
130 | for (i = 0; i < ctx.ctxprog_len; i++) | ||
131 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); | ||
132 | } else { | ||
133 | dev_priv->engine.graph.accel_blocked = true; | ||
134 | } | ||
135 | kfree(cp); | ||
136 | } | 129 | } |
130 | kfree(cp); | ||
137 | 131 | ||
138 | nv_wr32(dev, 0x400320, 4); | 132 | nv_wr32(dev, 0x400320, 4); |
139 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); | 133 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); |
@@ -164,7 +158,6 @@ void | |||
164 | nv50_graph_takedown(struct drm_device *dev) | 158 | nv50_graph_takedown(struct drm_device *dev) |
165 | { | 159 | { |
166 | NV_DEBUG(dev, "\n"); | 160 | NV_DEBUG(dev, "\n"); |
167 | nouveau_grctx_fini(dev); | ||
168 | } | 161 | } |
169 | 162 | ||
170 | void | 163 | void |
@@ -212,8 +205,9 @@ nv50_graph_create_context(struct nouveau_channel *chan) | |||
212 | struct drm_device *dev = chan->dev; | 205 | struct drm_device *dev = chan->dev; |
213 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 206 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
214 | struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; | 207 | struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; |
215 | struct nouveau_gpuobj *ctx; | 208 | struct nouveau_gpuobj *obj; |
216 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | 209 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; |
210 | struct nouveau_grctx ctx = {}; | ||
217 | int hdr, ret; | 211 | int hdr, ret; |
218 | 212 | ||
219 | NV_DEBUG(dev, "ch%d\n", chan->id); | 213 | NV_DEBUG(dev, "ch%d\n", chan->id); |
@@ -223,10 +217,9 @@ nv50_graph_create_context(struct nouveau_channel *chan) | |||
223 | NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); | 217 | NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); |
224 | if (ret) | 218 | if (ret) |
225 | return ret; | 219 | return ret; |
226 | ctx = chan->ramin_grctx->gpuobj; | 220 | obj = chan->ramin_grctx->gpuobj; |
227 | 221 | ||
228 | hdr = IS_G80 ? 0x200 : 0x20; | 222 | hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20; |
229 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
230 | nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002); | 223 | nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002); |
231 | nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance + | 224 | nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance + |
232 | pgraph->grctx_size - 1); | 225 | pgraph->grctx_size - 1); |
@@ -234,21 +227,15 @@ nv50_graph_create_context(struct nouveau_channel *chan) | |||
234 | nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0); | 227 | nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0); |
235 | nv_wo32(dev, ramin, (hdr + 0x10)/4, 0); | 228 | nv_wo32(dev, ramin, (hdr + 0x10)/4, 0); |
236 | nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000); | 229 | nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000); |
237 | dev_priv->engine.instmem.finish_access(dev); | ||
238 | |||
239 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
240 | if (!pgraph->ctxprog) { | ||
241 | struct nouveau_grctx ctx = {}; | ||
242 | ctx.dev = chan->dev; | ||
243 | ctx.mode = NOUVEAU_GRCTX_VALS; | ||
244 | ctx.data = chan->ramin_grctx->gpuobj; | ||
245 | nv50_grctx_init(&ctx); | ||
246 | } else { | ||
247 | nouveau_grctx_vals_load(dev, ctx); | ||
248 | } | ||
249 | nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); | ||
250 | dev_priv->engine.instmem.finish_access(dev); | ||
251 | 230 | ||
231 | ctx.dev = chan->dev; | ||
232 | ctx.mode = NOUVEAU_GRCTX_VALS; | ||
233 | ctx.data = obj; | ||
234 | nv50_grctx_init(&ctx); | ||
235 | |||
236 | nv_wo32(dev, obj, 0x00000/4, chan->ramin->instance >> 12); | ||
237 | |||
238 | dev_priv->engine.instmem.flush(dev); | ||
252 | return 0; | 239 | return 0; |
253 | } | 240 | } |
254 | 241 | ||
@@ -257,17 +244,16 @@ nv50_graph_destroy_context(struct nouveau_channel *chan) | |||
257 | { | 244 | { |
258 | struct drm_device *dev = chan->dev; | 245 | struct drm_device *dev = chan->dev; |
259 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 246 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
260 | int i, hdr = IS_G80 ? 0x200 : 0x20; | 247 | int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20; |
261 | 248 | ||
262 | NV_DEBUG(dev, "ch%d\n", chan->id); | 249 | NV_DEBUG(dev, "ch%d\n", chan->id); |
263 | 250 | ||
264 | if (!chan->ramin || !chan->ramin->gpuobj) | 251 | if (!chan->ramin || !chan->ramin->gpuobj) |
265 | return; | 252 | return; |
266 | 253 | ||
267 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
268 | for (i = hdr; i < hdr + 24; i += 4) | 254 | for (i = hdr; i < hdr + 24; i += 4) |
269 | nv_wo32(dev, chan->ramin->gpuobj, i/4, 0); | 255 | nv_wo32(dev, chan->ramin->gpuobj, i/4, 0); |
270 | dev_priv->engine.instmem.finish_access(dev); | 256 | dev_priv->engine.instmem.flush(dev); |
271 | 257 | ||
272 | nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); | 258 | nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); |
273 | } | 259 | } |
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 5f21df31f3aa..37c7b48ab24a 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c | |||
@@ -35,8 +35,6 @@ struct nv50_instmem_priv { | |||
35 | struct nouveau_gpuobj_ref *pramin_pt; | 35 | struct nouveau_gpuobj_ref *pramin_pt; |
36 | struct nouveau_gpuobj_ref *pramin_bar; | 36 | struct nouveau_gpuobj_ref *pramin_bar; |
37 | struct nouveau_gpuobj_ref *fb_bar; | 37 | struct nouveau_gpuobj_ref *fb_bar; |
38 | |||
39 | bool last_access_wr; | ||
40 | }; | 38 | }; |
41 | 39 | ||
42 | #define NV50_INSTMEM_PAGE_SHIFT 12 | 40 | #define NV50_INSTMEM_PAGE_SHIFT 12 |
@@ -147,7 +145,7 @@ nv50_instmem_init(struct drm_device *dev) | |||
147 | if (ret) | 145 | if (ret) |
148 | return ret; | 146 | return ret; |
149 | 147 | ||
150 | if (nouveau_mem_init_heap(&chan->ramin_heap, c_base, c_size - c_base)) | 148 | if (drm_mm_init(&chan->ramin_heap, c_base, c_size - c_base)) |
151 | return -ENOMEM; | 149 | return -ENOMEM; |
152 | 150 | ||
153 | /* RAMFC + zero channel's PRAMIN up to start of VM pagedir */ | 151 | /* RAMFC + zero channel's PRAMIN up to start of VM pagedir */ |
@@ -241,7 +239,7 @@ nv50_instmem_init(struct drm_device *dev) | |||
241 | return ret; | 239 | return ret; |
242 | BAR0_WI32(priv->fb_bar->gpuobj, 0x00, 0x7fc00000); | 240 | BAR0_WI32(priv->fb_bar->gpuobj, 0x00, 0x7fc00000); |
243 | BAR0_WI32(priv->fb_bar->gpuobj, 0x04, 0x40000000 + | 241 | BAR0_WI32(priv->fb_bar->gpuobj, 0x04, 0x40000000 + |
244 | drm_get_resource_len(dev, 1) - 1); | 242 | pci_resource_len(dev->pdev, 1) - 1); |
245 | BAR0_WI32(priv->fb_bar->gpuobj, 0x08, 0x40000000); | 243 | BAR0_WI32(priv->fb_bar->gpuobj, 0x08, 0x40000000); |
246 | BAR0_WI32(priv->fb_bar->gpuobj, 0x0c, 0x00000000); | 244 | BAR0_WI32(priv->fb_bar->gpuobj, 0x0c, 0x00000000); |
247 | BAR0_WI32(priv->fb_bar->gpuobj, 0x10, 0x00000000); | 245 | BAR0_WI32(priv->fb_bar->gpuobj, 0x10, 0x00000000); |
@@ -262,23 +260,18 @@ nv50_instmem_init(struct drm_device *dev) | |||
262 | 260 | ||
263 | /* Assume that praying isn't enough, check that we can re-read the | 261 | /* Assume that praying isn't enough, check that we can re-read the |
264 | * entire fake channel back from the PRAMIN BAR */ | 262 | * entire fake channel back from the PRAMIN BAR */ |
265 | dev_priv->engine.instmem.prepare_access(dev, false); | ||
266 | for (i = 0; i < c_size; i += 4) { | 263 | for (i = 0; i < c_size; i += 4) { |
267 | if (nv_rd32(dev, NV_RAMIN + i) != nv_ri32(dev, i)) { | 264 | if (nv_rd32(dev, NV_RAMIN + i) != nv_ri32(dev, i)) { |
268 | NV_ERROR(dev, "Error reading back PRAMIN at 0x%08x\n", | 265 | NV_ERROR(dev, "Error reading back PRAMIN at 0x%08x\n", |
269 | i); | 266 | i); |
270 | dev_priv->engine.instmem.finish_access(dev); | ||
271 | return -EINVAL; | 267 | return -EINVAL; |
272 | } | 268 | } |
273 | } | 269 | } |
274 | dev_priv->engine.instmem.finish_access(dev); | ||
275 | 270 | ||
276 | nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, save_nv001700); | 271 | nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, save_nv001700); |
277 | 272 | ||
278 | /* Global PRAMIN heap */ | 273 | /* Global PRAMIN heap */ |
279 | if (nouveau_mem_init_heap(&dev_priv->ramin_heap, | 274 | if (drm_mm_init(&dev_priv->ramin_heap, c_size, dev_priv->ramin_size - c_size)) { |
280 | c_size, dev_priv->ramin_size - c_size)) { | ||
281 | dev_priv->ramin_heap = NULL; | ||
282 | NV_ERROR(dev, "Failed to init RAMIN heap\n"); | 275 | NV_ERROR(dev, "Failed to init RAMIN heap\n"); |
283 | } | 276 | } |
284 | 277 | ||
@@ -321,7 +314,7 @@ nv50_instmem_takedown(struct drm_device *dev) | |||
321 | nouveau_gpuobj_del(dev, &chan->vm_pd); | 314 | nouveau_gpuobj_del(dev, &chan->vm_pd); |
322 | nouveau_gpuobj_ref_del(dev, &chan->ramfc); | 315 | nouveau_gpuobj_ref_del(dev, &chan->ramfc); |
323 | nouveau_gpuobj_ref_del(dev, &chan->ramin); | 316 | nouveau_gpuobj_ref_del(dev, &chan->ramin); |
324 | nouveau_mem_takedown(&chan->ramin_heap); | 317 | drm_mm_takedown(&chan->ramin_heap); |
325 | 318 | ||
326 | dev_priv->fifos[0] = dev_priv->fifos[127] = NULL; | 319 | dev_priv->fifos[0] = dev_priv->fifos[127] = NULL; |
327 | kfree(chan); | 320 | kfree(chan); |
@@ -436,14 +429,14 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) | |||
436 | if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) | 429 | if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) |
437 | return -EINVAL; | 430 | return -EINVAL; |
438 | 431 | ||
439 | NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n", | 432 | NV_DEBUG(dev, "st=0x%lx sz=0x%lx\n", |
440 | gpuobj->im_pramin->start, gpuobj->im_pramin->size); | 433 | gpuobj->im_pramin->start, gpuobj->im_pramin->size); |
441 | 434 | ||
442 | pte = (gpuobj->im_pramin->start >> 12) << 1; | 435 | pte = (gpuobj->im_pramin->start >> 12) << 1; |
443 | pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; | 436 | pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; |
444 | vram = gpuobj->im_backing_start; | 437 | vram = gpuobj->im_backing_start; |
445 | 438 | ||
446 | NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n", | 439 | NV_DEBUG(dev, "pramin=0x%lx, pte=%d, pte_end=%d\n", |
447 | gpuobj->im_pramin->start, pte, pte_end); | 440 | gpuobj->im_pramin->start, pte, pte_end); |
448 | NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start); | 441 | NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start); |
449 | 442 | ||
@@ -453,27 +446,15 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) | |||
453 | vram |= 0x30; | 446 | vram |= 0x30; |
454 | } | 447 | } |
455 | 448 | ||
456 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
457 | while (pte < pte_end) { | 449 | while (pte < pte_end) { |
458 | nv_wo32(dev, pramin_pt, pte++, lower_32_bits(vram)); | 450 | nv_wo32(dev, pramin_pt, pte++, lower_32_bits(vram)); |
459 | nv_wo32(dev, pramin_pt, pte++, upper_32_bits(vram)); | 451 | nv_wo32(dev, pramin_pt, pte++, upper_32_bits(vram)); |
460 | vram += NV50_INSTMEM_PAGE_SIZE; | 452 | vram += NV50_INSTMEM_PAGE_SIZE; |
461 | } | 453 | } |
462 | dev_priv->engine.instmem.finish_access(dev); | 454 | dev_priv->engine.instmem.flush(dev); |
463 | |||
464 | nv_wr32(dev, 0x100c80, 0x00040001); | ||
465 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
466 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (1)\n"); | ||
467 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
468 | return -EBUSY; | ||
469 | } | ||
470 | 455 | ||
471 | nv_wr32(dev, 0x100c80, 0x00060001); | 456 | nv50_vm_flush(dev, 4); |
472 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | 457 | nv50_vm_flush(dev, 6); |
473 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
474 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
475 | return -EBUSY; | ||
476 | } | ||
477 | 458 | ||
478 | gpuobj->im_bound = 1; | 459 | gpuobj->im_bound = 1; |
479 | return 0; | 460 | return 0; |
@@ -492,36 +473,37 @@ nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) | |||
492 | pte = (gpuobj->im_pramin->start >> 12) << 1; | 473 | pte = (gpuobj->im_pramin->start >> 12) << 1; |
493 | pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; | 474 | pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; |
494 | 475 | ||
495 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
496 | while (pte < pte_end) { | 476 | while (pte < pte_end) { |
497 | nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000); | 477 | nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000); |
498 | nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000); | 478 | nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000); |
499 | } | 479 | } |
500 | dev_priv->engine.instmem.finish_access(dev); | 480 | dev_priv->engine.instmem.flush(dev); |
501 | 481 | ||
502 | gpuobj->im_bound = 0; | 482 | gpuobj->im_bound = 0; |
503 | return 0; | 483 | return 0; |
504 | } | 484 | } |
505 | 485 | ||
506 | void | 486 | void |
507 | nv50_instmem_prepare_access(struct drm_device *dev, bool write) | 487 | nv50_instmem_flush(struct drm_device *dev) |
508 | { | 488 | { |
509 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 489 | nv_wr32(dev, 0x00330c, 0x00000001); |
510 | struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; | 490 | if (!nv_wait(0x00330c, 0x00000002, 0x00000000)) |
511 | 491 | NV_ERROR(dev, "PRAMIN flush timeout\n"); | |
512 | priv->last_access_wr = write; | ||
513 | } | 492 | } |
514 | 493 | ||
515 | void | 494 | void |
516 | nv50_instmem_finish_access(struct drm_device *dev) | 495 | nv84_instmem_flush(struct drm_device *dev) |
517 | { | 496 | { |
518 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 497 | nv_wr32(dev, 0x070000, 0x00000001); |
519 | struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; | 498 | if (!nv_wait(0x070000, 0x00000002, 0x00000000)) |
499 | NV_ERROR(dev, "PRAMIN flush timeout\n"); | ||
500 | } | ||
520 | 501 | ||
521 | if (priv->last_access_wr) { | 502 | void |
522 | nv_wr32(dev, 0x070000, 0x00000001); | 503 | nv50_vm_flush(struct drm_device *dev, int engine) |
523 | if (!nv_wait(0x070000, 0x00000001, 0x00000000)) | 504 | { |
524 | NV_ERROR(dev, "PRAMIN flush timeout\n"); | 505 | nv_wr32(dev, 0x100c80, (engine << 16) | 1); |
525 | } | 506 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) |
507 | NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); | ||
526 | } | 508 | } |
527 | 509 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index 812778db76ac..bcd4cf84a7e6 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c | |||
@@ -37,52 +37,32 @@ | |||
37 | #include "nv50_display.h" | 37 | #include "nv50_display.h" |
38 | 38 | ||
39 | static void | 39 | static void |
40 | nv50_sor_disconnect(struct nouveau_encoder *nv_encoder) | 40 | nv50_sor_disconnect(struct drm_encoder *encoder) |
41 | { | 41 | { |
42 | struct drm_device *dev = to_drm_encoder(nv_encoder)->dev; | 42 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
43 | struct drm_device *dev = encoder->dev; | ||
43 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 44 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
44 | struct nouveau_channel *evo = dev_priv->evo; | 45 | struct nouveau_channel *evo = dev_priv->evo; |
45 | int ret; | 46 | int ret; |
46 | 47 | ||
48 | if (!nv_encoder->crtc) | ||
49 | return; | ||
50 | nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true); | ||
51 | |||
47 | NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or); | 52 | NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or); |
48 | 53 | ||
49 | ret = RING_SPACE(evo, 2); | 54 | ret = RING_SPACE(evo, 4); |
50 | if (ret) { | 55 | if (ret) { |
51 | NV_ERROR(dev, "no space while disconnecting SOR\n"); | 56 | NV_ERROR(dev, "no space while disconnecting SOR\n"); |
52 | return; | 57 | return; |
53 | } | 58 | } |
54 | BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); | 59 | BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); |
55 | OUT_RING(evo, 0); | 60 | OUT_RING (evo, 0); |
56 | } | 61 | BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); |
57 | 62 | OUT_RING (evo, 0); | |
58 | static void | ||
59 | nv50_sor_dp_link_train(struct drm_encoder *encoder) | ||
60 | { | ||
61 | struct drm_device *dev = encoder->dev; | ||
62 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
63 | struct bit_displayport_encoder_table *dpe; | ||
64 | int dpe_headerlen; | ||
65 | |||
66 | dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen); | ||
67 | if (!dpe) { | ||
68 | NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or); | ||
69 | return; | ||
70 | } | ||
71 | 63 | ||
72 | if (dpe->script0) { | 64 | nv_encoder->crtc = NULL; |
73 | NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); | 65 | nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; |
74 | nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0), | ||
75 | nv_encoder->dcb); | ||
76 | } | ||
77 | |||
78 | if (!nouveau_dp_link_train(encoder)) | ||
79 | NV_ERROR(dev, "SOR-%d: link training failed\n", nv_encoder->or); | ||
80 | |||
81 | if (dpe->script1) { | ||
82 | NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or); | ||
83 | nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1), | ||
84 | nv_encoder->dcb); | ||
85 | } | ||
86 | } | 66 | } |
87 | 67 | ||
88 | static void | 68 | static void |
@@ -94,14 +74,16 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) | |||
94 | uint32_t val; | 74 | uint32_t val; |
95 | int or = nv_encoder->or; | 75 | int or = nv_encoder->or; |
96 | 76 | ||
97 | NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode); | 77 | NV_DEBUG_KMS(dev, "or %d type %d mode %d\n", or, nv_encoder->dcb->type, mode); |
98 | 78 | ||
99 | nv_encoder->last_dpms = mode; | 79 | nv_encoder->last_dpms = mode; |
100 | list_for_each_entry(enc, &dev->mode_config.encoder_list, head) { | 80 | list_for_each_entry(enc, &dev->mode_config.encoder_list, head) { |
101 | struct nouveau_encoder *nvenc = nouveau_encoder(enc); | 81 | struct nouveau_encoder *nvenc = nouveau_encoder(enc); |
102 | 82 | ||
103 | if (nvenc == nv_encoder || | 83 | if (nvenc == nv_encoder || |
104 | nvenc->disconnect != nv50_sor_disconnect || | 84 | (nvenc->dcb->type != OUTPUT_TMDS && |
85 | nvenc->dcb->type != OUTPUT_LVDS && | ||
86 | nvenc->dcb->type != OUTPUT_DP) || | ||
105 | nvenc->dcb->or != nv_encoder->dcb->or) | 87 | nvenc->dcb->or != nv_encoder->dcb->or) |
106 | continue; | 88 | continue; |
107 | 89 | ||
@@ -133,8 +115,22 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) | |||
133 | nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or))); | 115 | nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or))); |
134 | } | 116 | } |
135 | 117 | ||
136 | if (nv_encoder->dcb->type == OUTPUT_DP && mode == DRM_MODE_DPMS_ON) | 118 | if (nv_encoder->dcb->type == OUTPUT_DP) { |
137 | nv50_sor_dp_link_train(encoder); | 119 | struct nouveau_i2c_chan *auxch; |
120 | |||
121 | auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | ||
122 | if (!auxch) | ||
123 | return; | ||
124 | |||
125 | if (mode == DRM_MODE_DPMS_ON) { | ||
126 | u8 status = DP_SET_POWER_D0; | ||
127 | nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1); | ||
128 | nouveau_dp_link_train(encoder); | ||
129 | } else { | ||
130 | u8 status = DP_SET_POWER_D3; | ||
131 | nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1); | ||
132 | } | ||
133 | } | ||
138 | } | 134 | } |
139 | 135 | ||
140 | static void | 136 | static void |
@@ -196,7 +192,8 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
196 | uint32_t mode_ctl = 0; | 192 | uint32_t mode_ctl = 0; |
197 | int ret; | 193 | int ret; |
198 | 194 | ||
199 | NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or); | 195 | NV_DEBUG_KMS(dev, "or %d type %d -> crtc %d\n", |
196 | nv_encoder->or, nv_encoder->dcb->type, crtc->index); | ||
200 | 197 | ||
201 | nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON); | 198 | nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON); |
202 | 199 | ||
@@ -239,6 +236,14 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
239 | } | 236 | } |
240 | BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); | 237 | BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); |
241 | OUT_RING(evo, mode_ctl); | 238 | OUT_RING(evo, mode_ctl); |
239 | |||
240 | nv_encoder->crtc = encoder->crtc; | ||
241 | } | ||
242 | |||
243 | static struct drm_crtc * | ||
244 | nv50_sor_crtc_get(struct drm_encoder *encoder) | ||
245 | { | ||
246 | return nouveau_encoder(encoder)->crtc; | ||
242 | } | 247 | } |
243 | 248 | ||
244 | static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = { | 249 | static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = { |
@@ -249,7 +254,9 @@ static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = { | |||
249 | .prepare = nv50_sor_prepare, | 254 | .prepare = nv50_sor_prepare, |
250 | .commit = nv50_sor_commit, | 255 | .commit = nv50_sor_commit, |
251 | .mode_set = nv50_sor_mode_set, | 256 | .mode_set = nv50_sor_mode_set, |
252 | .detect = NULL | 257 | .get_crtc = nv50_sor_crtc_get, |
258 | .detect = NULL, | ||
259 | .disable = nv50_sor_disconnect | ||
253 | }; | 260 | }; |
254 | 261 | ||
255 | static void | 262 | static void |
@@ -272,32 +279,22 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = { | |||
272 | }; | 279 | }; |
273 | 280 | ||
274 | int | 281 | int |
275 | nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) | 282 | nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry) |
276 | { | 283 | { |
277 | struct nouveau_encoder *nv_encoder = NULL; | 284 | struct nouveau_encoder *nv_encoder = NULL; |
285 | struct drm_device *dev = connector->dev; | ||
278 | struct drm_encoder *encoder; | 286 | struct drm_encoder *encoder; |
279 | bool dum; | ||
280 | int type; | 287 | int type; |
281 | 288 | ||
282 | NV_DEBUG_KMS(dev, "\n"); | 289 | NV_DEBUG_KMS(dev, "\n"); |
283 | 290 | ||
284 | switch (entry->type) { | 291 | switch (entry->type) { |
285 | case OUTPUT_TMDS: | 292 | case OUTPUT_TMDS: |
286 | NV_INFO(dev, "Detected a TMDS output\n"); | 293 | case OUTPUT_DP: |
287 | type = DRM_MODE_ENCODER_TMDS; | 294 | type = DRM_MODE_ENCODER_TMDS; |
288 | break; | 295 | break; |
289 | case OUTPUT_LVDS: | 296 | case OUTPUT_LVDS: |
290 | NV_INFO(dev, "Detected a LVDS output\n"); | ||
291 | type = DRM_MODE_ENCODER_LVDS; | 297 | type = DRM_MODE_ENCODER_LVDS; |
292 | |||
293 | if (nouveau_bios_parse_lvds_table(dev, 0, &dum, &dum)) { | ||
294 | NV_ERROR(dev, "Failed parsing LVDS table\n"); | ||
295 | return -EINVAL; | ||
296 | } | ||
297 | break; | ||
298 | case OUTPUT_DP: | ||
299 | NV_INFO(dev, "Detected a DP output\n"); | ||
300 | type = DRM_MODE_ENCODER_TMDS; | ||
301 | break; | 298 | break; |
302 | default: | 299 | default: |
303 | return -EINVAL; | 300 | return -EINVAL; |
@@ -310,8 +307,7 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) | |||
310 | 307 | ||
311 | nv_encoder->dcb = entry; | 308 | nv_encoder->dcb = entry; |
312 | nv_encoder->or = ffs(entry->or) - 1; | 309 | nv_encoder->or = ffs(entry->or) - 1; |
313 | 310 | nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; | |
314 | nv_encoder->disconnect = nv50_sor_disconnect; | ||
315 | 311 | ||
316 | drm_encoder_init(dev, encoder, &nv50_sor_encoder_funcs, type); | 312 | drm_encoder_init(dev, encoder, &nv50_sor_encoder_funcs, type); |
317 | drm_encoder_helper_add(encoder, &nv50_sor_helper_funcs); | 313 | drm_encoder_helper_add(encoder, &nv50_sor_helper_funcs); |
@@ -342,5 +338,6 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) | |||
342 | nv_encoder->dp.mc_unknown = 5; | 338 | nv_encoder->dp.mc_unknown = 5; |
343 | } | 339 | } |
344 | 340 | ||
341 | drm_mode_connector_attach_encoder(connector, encoder); | ||
345 | return 0; | 342 | return 0; |
346 | } | 343 | } |
diff --git a/drivers/gpu/drm/nouveau/nvreg.h b/drivers/gpu/drm/nouveau/nvreg.h index 5998c35237b0..ad64673ace1f 100644 --- a/drivers/gpu/drm/nouveau/nvreg.h +++ b/drivers/gpu/drm/nouveau/nvreg.h | |||
@@ -147,28 +147,6 @@ | |||
147 | # define NV_VIO_GX_DONT_CARE_INDEX 0x07 | 147 | # define NV_VIO_GX_DONT_CARE_INDEX 0x07 |
148 | # define NV_VIO_GX_BIT_MASK_INDEX 0x08 | 148 | # define NV_VIO_GX_BIT_MASK_INDEX 0x08 |
149 | 149 | ||
150 | #define NV_PFB_BOOT_0 0x00100000 | ||
151 | #define NV_PFB_CFG0 0x00100200 | ||
152 | #define NV_PFB_CFG1 0x00100204 | ||
153 | #define NV_PFB_CSTATUS 0x0010020C | ||
154 | #define NV_PFB_REFCTRL 0x00100210 | ||
155 | # define NV_PFB_REFCTRL_VALID_1 (1 << 31) | ||
156 | #define NV_PFB_PAD 0x0010021C | ||
157 | # define NV_PFB_PAD_CKE_NORMAL (1 << 0) | ||
158 | #define NV_PFB_TILE_NV10 0x00100240 | ||
159 | #define NV_PFB_TILE_SIZE_NV10 0x00100244 | ||
160 | #define NV_PFB_REF 0x001002D0 | ||
161 | # define NV_PFB_REF_CMD_REFRESH (1 << 0) | ||
162 | #define NV_PFB_PRE 0x001002D4 | ||
163 | # define NV_PFB_PRE_CMD_PRECHARGE (1 << 0) | ||
164 | #define NV_PFB_CLOSE_PAGE2 0x0010033C | ||
165 | #define NV_PFB_TILE_NV40 0x00100600 | ||
166 | #define NV_PFB_TILE_SIZE_NV40 0x00100604 | ||
167 | |||
168 | #define NV_PEXTDEV_BOOT_0 0x00101000 | ||
169 | # define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT (8 << 12) | ||
170 | #define NV_PEXTDEV_BOOT_3 0x0010100c | ||
171 | |||
172 | #define NV_PCRTC_INTR_0 0x00600100 | 150 | #define NV_PCRTC_INTR_0 0x00600100 |
173 | # define NV_PCRTC_INTR_0_VBLANK (1 << 0) | 151 | # define NV_PCRTC_INTR_0_VBLANK (1 << 0) |
174 | #define NV_PCRTC_INTR_EN_0 0x00600140 | 152 | #define NV_PCRTC_INTR_EN_0 0x00600140 |
diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c index e671d0e74d4c..570e190710bd 100644 --- a/drivers/gpu/drm/r128/r128_cce.c +++ b/drivers/gpu/drm/r128/r128_cce.c | |||
@@ -44,7 +44,7 @@ | |||
44 | 44 | ||
45 | MODULE_FIRMWARE(FIRMWARE_NAME); | 45 | MODULE_FIRMWARE(FIRMWARE_NAME); |
46 | 46 | ||
47 | static int R128_READ_PLL(struct drm_device * dev, int addr) | 47 | static int R128_READ_PLL(struct drm_device *dev, int addr) |
48 | { | 48 | { |
49 | drm_r128_private_t *dev_priv = dev->dev_private; | 49 | drm_r128_private_t *dev_priv = dev->dev_private; |
50 | 50 | ||
@@ -53,7 +53,7 @@ static int R128_READ_PLL(struct drm_device * dev, int addr) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | #if R128_FIFO_DEBUG | 55 | #if R128_FIFO_DEBUG |
56 | static void r128_status(drm_r128_private_t * dev_priv) | 56 | static void r128_status(drm_r128_private_t *dev_priv) |
57 | { | 57 | { |
58 | printk("GUI_STAT = 0x%08x\n", | 58 | printk("GUI_STAT = 0x%08x\n", |
59 | (unsigned int)R128_READ(R128_GUI_STAT)); | 59 | (unsigned int)R128_READ(R128_GUI_STAT)); |
@@ -74,7 +74,7 @@ static void r128_status(drm_r128_private_t * dev_priv) | |||
74 | * Engine, FIFO control | 74 | * Engine, FIFO control |
75 | */ | 75 | */ |
76 | 76 | ||
77 | static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv) | 77 | static int r128_do_pixcache_flush(drm_r128_private_t *dev_priv) |
78 | { | 78 | { |
79 | u32 tmp; | 79 | u32 tmp; |
80 | int i; | 80 | int i; |
@@ -83,9 +83,8 @@ static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv) | |||
83 | R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp); | 83 | R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp); |
84 | 84 | ||
85 | for (i = 0; i < dev_priv->usec_timeout; i++) { | 85 | for (i = 0; i < dev_priv->usec_timeout; i++) { |
86 | if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) { | 86 | if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) |
87 | return 0; | 87 | return 0; |
88 | } | ||
89 | DRM_UDELAY(1); | 88 | DRM_UDELAY(1); |
90 | } | 89 | } |
91 | 90 | ||
@@ -95,7 +94,7 @@ static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv) | |||
95 | return -EBUSY; | 94 | return -EBUSY; |
96 | } | 95 | } |
97 | 96 | ||
98 | static int r128_do_wait_for_fifo(drm_r128_private_t * dev_priv, int entries) | 97 | static int r128_do_wait_for_fifo(drm_r128_private_t *dev_priv, int entries) |
99 | { | 98 | { |
100 | int i; | 99 | int i; |
101 | 100 | ||
@@ -112,7 +111,7 @@ static int r128_do_wait_for_fifo(drm_r128_private_t * dev_priv, int entries) | |||
112 | return -EBUSY; | 111 | return -EBUSY; |
113 | } | 112 | } |
114 | 113 | ||
115 | static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv) | 114 | static int r128_do_wait_for_idle(drm_r128_private_t *dev_priv) |
116 | { | 115 | { |
117 | int i, ret; | 116 | int i, ret; |
118 | 117 | ||
@@ -189,7 +188,7 @@ out_release: | |||
189 | * prior to a wait for idle, as it informs the engine that the command | 188 | * prior to a wait for idle, as it informs the engine that the command |
190 | * stream is ending. | 189 | * stream is ending. |
191 | */ | 190 | */ |
192 | static void r128_do_cce_flush(drm_r128_private_t * dev_priv) | 191 | static void r128_do_cce_flush(drm_r128_private_t *dev_priv) |
193 | { | 192 | { |
194 | u32 tmp; | 193 | u32 tmp; |
195 | 194 | ||
@@ -199,7 +198,7 @@ static void r128_do_cce_flush(drm_r128_private_t * dev_priv) | |||
199 | 198 | ||
200 | /* Wait for the CCE to go idle. | 199 | /* Wait for the CCE to go idle. |
201 | */ | 200 | */ |
202 | int r128_do_cce_idle(drm_r128_private_t * dev_priv) | 201 | int r128_do_cce_idle(drm_r128_private_t *dev_priv) |
203 | { | 202 | { |
204 | int i; | 203 | int i; |
205 | 204 | ||
@@ -225,7 +224,7 @@ int r128_do_cce_idle(drm_r128_private_t * dev_priv) | |||
225 | 224 | ||
226 | /* Start the Concurrent Command Engine. | 225 | /* Start the Concurrent Command Engine. |
227 | */ | 226 | */ |
228 | static void r128_do_cce_start(drm_r128_private_t * dev_priv) | 227 | static void r128_do_cce_start(drm_r128_private_t *dev_priv) |
229 | { | 228 | { |
230 | r128_do_wait_for_idle(dev_priv); | 229 | r128_do_wait_for_idle(dev_priv); |
231 | 230 | ||
@@ -242,7 +241,7 @@ static void r128_do_cce_start(drm_r128_private_t * dev_priv) | |||
242 | * commands, so you must wait for the CCE command stream to complete | 241 | * commands, so you must wait for the CCE command stream to complete |
243 | * before calling this routine. | 242 | * before calling this routine. |
244 | */ | 243 | */ |
245 | static void r128_do_cce_reset(drm_r128_private_t * dev_priv) | 244 | static void r128_do_cce_reset(drm_r128_private_t *dev_priv) |
246 | { | 245 | { |
247 | R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0); | 246 | R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0); |
248 | R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0); | 247 | R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0); |
@@ -253,7 +252,7 @@ static void r128_do_cce_reset(drm_r128_private_t * dev_priv) | |||
253 | * commands, so you must flush the command stream and wait for the CCE | 252 | * commands, so you must flush the command stream and wait for the CCE |
254 | * to go idle before calling this routine. | 253 | * to go idle before calling this routine. |
255 | */ | 254 | */ |
256 | static void r128_do_cce_stop(drm_r128_private_t * dev_priv) | 255 | static void r128_do_cce_stop(drm_r128_private_t *dev_priv) |
257 | { | 256 | { |
258 | R128_WRITE(R128_PM4_MICRO_CNTL, 0); | 257 | R128_WRITE(R128_PM4_MICRO_CNTL, 0); |
259 | R128_WRITE(R128_PM4_BUFFER_CNTL, | 258 | R128_WRITE(R128_PM4_BUFFER_CNTL, |
@@ -264,7 +263,7 @@ static void r128_do_cce_stop(drm_r128_private_t * dev_priv) | |||
264 | 263 | ||
265 | /* Reset the engine. This will stop the CCE if it is running. | 264 | /* Reset the engine. This will stop the CCE if it is running. |
266 | */ | 265 | */ |
267 | static int r128_do_engine_reset(struct drm_device * dev) | 266 | static int r128_do_engine_reset(struct drm_device *dev) |
268 | { | 267 | { |
269 | drm_r128_private_t *dev_priv = dev->dev_private; | 268 | drm_r128_private_t *dev_priv = dev->dev_private; |
270 | u32 clock_cntl_index, mclk_cntl, gen_reset_cntl; | 269 | u32 clock_cntl_index, mclk_cntl, gen_reset_cntl; |
@@ -301,8 +300,8 @@ static int r128_do_engine_reset(struct drm_device * dev) | |||
301 | return 0; | 300 | return 0; |
302 | } | 301 | } |
303 | 302 | ||
304 | static void r128_cce_init_ring_buffer(struct drm_device * dev, | 303 | static void r128_cce_init_ring_buffer(struct drm_device *dev, |
305 | drm_r128_private_t * dev_priv) | 304 | drm_r128_private_t *dev_priv) |
306 | { | 305 | { |
307 | u32 ring_start; | 306 | u32 ring_start; |
308 | u32 tmp; | 307 | u32 tmp; |
@@ -340,7 +339,7 @@ static void r128_cce_init_ring_buffer(struct drm_device * dev, | |||
340 | R128_WRITE(R128_BUS_CNTL, tmp); | 339 | R128_WRITE(R128_BUS_CNTL, tmp); |
341 | } | 340 | } |
342 | 341 | ||
343 | static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) | 342 | static int r128_do_init_cce(struct drm_device *dev, drm_r128_init_t *init) |
344 | { | 343 | { |
345 | drm_r128_private_t *dev_priv; | 344 | drm_r128_private_t *dev_priv; |
346 | int rc; | 345 | int rc; |
@@ -588,7 +587,7 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) | |||
588 | return rc; | 587 | return rc; |
589 | } | 588 | } |
590 | 589 | ||
591 | int r128_do_cleanup_cce(struct drm_device * dev) | 590 | int r128_do_cleanup_cce(struct drm_device *dev) |
592 | { | 591 | { |
593 | 592 | ||
594 | /* Make sure interrupts are disabled here because the uninstall ioctl | 593 | /* Make sure interrupts are disabled here because the uninstall ioctl |
@@ -682,9 +681,8 @@ int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv | |||
682 | /* Flush any pending CCE commands. This ensures any outstanding | 681 | /* Flush any pending CCE commands. This ensures any outstanding |
683 | * commands are exectuted by the engine before we turn it off. | 682 | * commands are exectuted by the engine before we turn it off. |
684 | */ | 683 | */ |
685 | if (stop->flush) { | 684 | if (stop->flush) |
686 | r128_do_cce_flush(dev_priv); | 685 | r128_do_cce_flush(dev_priv); |
687 | } | ||
688 | 686 | ||
689 | /* If we fail to make the engine go idle, we return an error | 687 | /* If we fail to make the engine go idle, we return an error |
690 | * code so that the DRM ioctl wrapper can try again. | 688 | * code so that the DRM ioctl wrapper can try again. |
@@ -735,9 +733,8 @@ int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv | |||
735 | 733 | ||
736 | DEV_INIT_TEST_WITH_RETURN(dev_priv); | 734 | DEV_INIT_TEST_WITH_RETURN(dev_priv); |
737 | 735 | ||
738 | if (dev_priv->cce_running) { | 736 | if (dev_priv->cce_running) |
739 | r128_do_cce_flush(dev_priv); | 737 | r128_do_cce_flush(dev_priv); |
740 | } | ||
741 | 738 | ||
742 | return r128_do_cce_idle(dev_priv); | 739 | return r128_do_cce_idle(dev_priv); |
743 | } | 740 | } |
@@ -765,7 +762,7 @@ int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
765 | #define R128_BUFFER_FREE 0 | 762 | #define R128_BUFFER_FREE 0 |
766 | 763 | ||
767 | #if 0 | 764 | #if 0 |
768 | static int r128_freelist_init(struct drm_device * dev) | 765 | static int r128_freelist_init(struct drm_device *dev) |
769 | { | 766 | { |
770 | struct drm_device_dma *dma = dev->dma; | 767 | struct drm_device_dma *dma = dev->dma; |
771 | drm_r128_private_t *dev_priv = dev->dev_private; | 768 | drm_r128_private_t *dev_priv = dev->dev_private; |
@@ -848,7 +845,7 @@ static struct drm_buf *r128_freelist_get(struct drm_device * dev) | |||
848 | return NULL; | 845 | return NULL; |
849 | } | 846 | } |
850 | 847 | ||
851 | void r128_freelist_reset(struct drm_device * dev) | 848 | void r128_freelist_reset(struct drm_device *dev) |
852 | { | 849 | { |
853 | struct drm_device_dma *dma = dev->dma; | 850 | struct drm_device_dma *dma = dev->dma; |
854 | int i; | 851 | int i; |
@@ -864,7 +861,7 @@ void r128_freelist_reset(struct drm_device * dev) | |||
864 | * CCE command submission | 861 | * CCE command submission |
865 | */ | 862 | */ |
866 | 863 | ||
867 | int r128_wait_ring(drm_r128_private_t * dev_priv, int n) | 864 | int r128_wait_ring(drm_r128_private_t *dev_priv, int n) |
868 | { | 865 | { |
869 | drm_r128_ring_buffer_t *ring = &dev_priv->ring; | 866 | drm_r128_ring_buffer_t *ring = &dev_priv->ring; |
870 | int i; | 867 | int i; |
@@ -881,9 +878,9 @@ int r128_wait_ring(drm_r128_private_t * dev_priv, int n) | |||
881 | return -EBUSY; | 878 | return -EBUSY; |
882 | } | 879 | } |
883 | 880 | ||
884 | static int r128_cce_get_buffers(struct drm_device * dev, | 881 | static int r128_cce_get_buffers(struct drm_device *dev, |
885 | struct drm_file *file_priv, | 882 | struct drm_file *file_priv, |
886 | struct drm_dma * d) | 883 | struct drm_dma *d) |
887 | { | 884 | { |
888 | int i; | 885 | int i; |
889 | struct drm_buf *buf; | 886 | struct drm_buf *buf; |
@@ -933,9 +930,8 @@ int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_p | |||
933 | 930 | ||
934 | d->granted_count = 0; | 931 | d->granted_count = 0; |
935 | 932 | ||
936 | if (d->request_count) { | 933 | if (d->request_count) |
937 | ret = r128_cce_get_buffers(dev, file_priv, d); | 934 | ret = r128_cce_get_buffers(dev, file_priv, d); |
938 | } | ||
939 | 935 | ||
940 | return ret; | 936 | return ret; |
941 | } | 937 | } |
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c index b806fdcc7170..1e2971f13aa1 100644 --- a/drivers/gpu/drm/r128/r128_drv.c +++ b/drivers/gpu/drm/r128/r128_drv.c | |||
@@ -85,7 +85,7 @@ static struct drm_driver driver = { | |||
85 | .patchlevel = DRIVER_PATCHLEVEL, | 85 | .patchlevel = DRIVER_PATCHLEVEL, |
86 | }; | 86 | }; |
87 | 87 | ||
88 | int r128_driver_load(struct drm_device * dev, unsigned long flags) | 88 | int r128_driver_load(struct drm_device *dev, unsigned long flags) |
89 | { | 89 | { |
90 | return drm_vblank_init(dev, 1); | 90 | return drm_vblank_init(dev, 1); |
91 | } | 91 | } |
diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h index 3c60829d82e9..930c71b2fb5e 100644 --- a/drivers/gpu/drm/r128/r128_drv.h +++ b/drivers/gpu/drm/r128/r128_drv.h | |||
@@ -53,7 +53,7 @@ | |||
53 | #define DRIVER_MINOR 5 | 53 | #define DRIVER_MINOR 5 |
54 | #define DRIVER_PATCHLEVEL 0 | 54 | #define DRIVER_PATCHLEVEL 0 |
55 | 55 | ||
56 | #define GET_RING_HEAD(dev_priv) R128_READ( R128_PM4_BUFFER_DL_RPTR ) | 56 | #define GET_RING_HEAD(dev_priv) R128_READ(R128_PM4_BUFFER_DL_RPTR) |
57 | 57 | ||
58 | typedef struct drm_r128_freelist { | 58 | typedef struct drm_r128_freelist { |
59 | unsigned int age; | 59 | unsigned int age; |
@@ -144,23 +144,23 @@ extern int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file | |||
144 | extern int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); | 144 | extern int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); |
145 | extern int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); | 145 | extern int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); |
146 | 146 | ||
147 | extern void r128_freelist_reset(struct drm_device * dev); | 147 | extern void r128_freelist_reset(struct drm_device *dev); |
148 | 148 | ||
149 | extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n); | 149 | extern int r128_wait_ring(drm_r128_private_t *dev_priv, int n); |
150 | 150 | ||
151 | extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); | 151 | extern int r128_do_cce_idle(drm_r128_private_t *dev_priv); |
152 | extern int r128_do_cleanup_cce(struct drm_device * dev); | 152 | extern int r128_do_cleanup_cce(struct drm_device *dev); |
153 | 153 | ||
154 | extern int r128_enable_vblank(struct drm_device *dev, int crtc); | 154 | extern int r128_enable_vblank(struct drm_device *dev, int crtc); |
155 | extern void r128_disable_vblank(struct drm_device *dev, int crtc); | 155 | extern void r128_disable_vblank(struct drm_device *dev, int crtc); |
156 | extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc); | 156 | extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc); |
157 | extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); | 157 | extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); |
158 | extern void r128_driver_irq_preinstall(struct drm_device * dev); | 158 | extern void r128_driver_irq_preinstall(struct drm_device *dev); |
159 | extern int r128_driver_irq_postinstall(struct drm_device *dev); | 159 | extern int r128_driver_irq_postinstall(struct drm_device *dev); |
160 | extern void r128_driver_irq_uninstall(struct drm_device * dev); | 160 | extern void r128_driver_irq_uninstall(struct drm_device *dev); |
161 | extern void r128_driver_lastclose(struct drm_device * dev); | 161 | extern void r128_driver_lastclose(struct drm_device *dev); |
162 | extern int r128_driver_load(struct drm_device * dev, unsigned long flags); | 162 | extern int r128_driver_load(struct drm_device *dev, unsigned long flags); |
163 | extern void r128_driver_preclose(struct drm_device * dev, | 163 | extern void r128_driver_preclose(struct drm_device *dev, |
164 | struct drm_file *file_priv); | 164 | struct drm_file *file_priv); |
165 | 165 | ||
166 | extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, | 166 | extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, |
@@ -390,27 +390,27 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, | |||
390 | 390 | ||
391 | #define R128_PCIGART_TABLE_SIZE 32768 | 391 | #define R128_PCIGART_TABLE_SIZE 32768 |
392 | 392 | ||
393 | #define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) | 393 | #define R128_READ(reg) DRM_READ32(dev_priv->mmio, (reg)) |
394 | #define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) | 394 | #define R128_WRITE(reg, val) DRM_WRITE32(dev_priv->mmio, (reg), (val)) |
395 | #define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) | 395 | #define R128_READ8(reg) DRM_READ8(dev_priv->mmio, (reg)) |
396 | #define R128_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) | 396 | #define R128_WRITE8(reg, val) DRM_WRITE8(dev_priv->mmio, (reg), (val)) |
397 | 397 | ||
398 | #define R128_WRITE_PLL(addr,val) \ | 398 | #define R128_WRITE_PLL(addr, val) \ |
399 | do { \ | 399 | do { \ |
400 | R128_WRITE8(R128_CLOCK_CNTL_INDEX, \ | 400 | R128_WRITE8(R128_CLOCK_CNTL_INDEX, \ |
401 | ((addr) & 0x1f) | R128_PLL_WR_EN); \ | 401 | ((addr) & 0x1f) | R128_PLL_WR_EN); \ |
402 | R128_WRITE(R128_CLOCK_CNTL_DATA, (val)); \ | 402 | R128_WRITE(R128_CLOCK_CNTL_DATA, (val)); \ |
403 | } while (0) | 403 | } while (0) |
404 | 404 | ||
405 | #define CCE_PACKET0( reg, n ) (R128_CCE_PACKET0 | \ | 405 | #define CCE_PACKET0(reg, n) (R128_CCE_PACKET0 | \ |
406 | ((n) << 16) | ((reg) >> 2)) | 406 | ((n) << 16) | ((reg) >> 2)) |
407 | #define CCE_PACKET1( reg0, reg1 ) (R128_CCE_PACKET1 | \ | 407 | #define CCE_PACKET1(reg0, reg1) (R128_CCE_PACKET1 | \ |
408 | (((reg1) >> 2) << 11) | ((reg0) >> 2)) | 408 | (((reg1) >> 2) << 11) | ((reg0) >> 2)) |
409 | #define CCE_PACKET2() (R128_CCE_PACKET2) | 409 | #define CCE_PACKET2() (R128_CCE_PACKET2) |
410 | #define CCE_PACKET3( pkt, n ) (R128_CCE_PACKET3 | \ | 410 | #define CCE_PACKET3(pkt, n) (R128_CCE_PACKET3 | \ |
411 | (pkt) | ((n) << 16)) | 411 | (pkt) | ((n) << 16)) |
412 | 412 | ||
413 | static __inline__ void r128_update_ring_snapshot(drm_r128_private_t * dev_priv) | 413 | static __inline__ void r128_update_ring_snapshot(drm_r128_private_t *dev_priv) |
414 | { | 414 | { |
415 | drm_r128_ring_buffer_t *ring = &dev_priv->ring; | 415 | drm_r128_ring_buffer_t *ring = &dev_priv->ring; |
416 | ring->space = (GET_RING_HEAD(dev_priv) - ring->tail) * sizeof(u32); | 416 | ring->space = (GET_RING_HEAD(dev_priv) - ring->tail) * sizeof(u32); |
@@ -430,37 +430,38 @@ do { \ | |||
430 | } \ | 430 | } \ |
431 | } while (0) | 431 | } while (0) |
432 | 432 | ||
433 | #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ | 433 | #define RING_SPACE_TEST_WITH_RETURN(dev_priv) \ |
434 | do { \ | 434 | do { \ |
435 | drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \ | 435 | drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \ |
436 | if ( ring->space < ring->high_mark ) { \ | 436 | if (ring->space < ring->high_mark) { \ |
437 | for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \ | 437 | for (i = 0 ; i < dev_priv->usec_timeout ; i++) { \ |
438 | r128_update_ring_snapshot( dev_priv ); \ | 438 | r128_update_ring_snapshot(dev_priv); \ |
439 | if ( ring->space >= ring->high_mark ) \ | 439 | if (ring->space >= ring->high_mark) \ |
440 | goto __ring_space_done; \ | 440 | goto __ring_space_done; \ |
441 | DRM_UDELAY(1); \ | 441 | DRM_UDELAY(1); \ |
442 | } \ | 442 | } \ |
443 | DRM_ERROR( "ring space check failed!\n" ); \ | 443 | DRM_ERROR("ring space check failed!\n"); \ |
444 | return -EBUSY; \ | 444 | return -EBUSY; \ |
445 | } \ | 445 | } \ |
446 | __ring_space_done: \ | 446 | __ring_space_done: \ |
447 | ; \ | 447 | ; \ |
448 | } while (0) | 448 | } while (0) |
449 | 449 | ||
450 | #define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ | 450 | #define VB_AGE_TEST_WITH_RETURN(dev_priv) \ |
451 | do { \ | 451 | do { \ |
452 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; \ | 452 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; \ |
453 | if ( sarea_priv->last_dispatch >= R128_MAX_VB_AGE ) { \ | 453 | if (sarea_priv->last_dispatch >= R128_MAX_VB_AGE) { \ |
454 | int __ret = r128_do_cce_idle( dev_priv ); \ | 454 | int __ret = r128_do_cce_idle(dev_priv); \ |
455 | if ( __ret ) return __ret; \ | 455 | if (__ret) \ |
456 | return __ret; \ | ||
456 | sarea_priv->last_dispatch = 0; \ | 457 | sarea_priv->last_dispatch = 0; \ |
457 | r128_freelist_reset( dev ); \ | 458 | r128_freelist_reset(dev); \ |
458 | } \ | 459 | } \ |
459 | } while (0) | 460 | } while (0) |
460 | 461 | ||
461 | #define R128_WAIT_UNTIL_PAGE_FLIPPED() do { \ | 462 | #define R128_WAIT_UNTIL_PAGE_FLIPPED() do { \ |
462 | OUT_RING( CCE_PACKET0( R128_WAIT_UNTIL, 0 ) ); \ | 463 | OUT_RING(CCE_PACKET0(R128_WAIT_UNTIL, 0)); \ |
463 | OUT_RING( R128_EVENT_CRTC_OFFSET ); \ | 464 | OUT_RING(R128_EVENT_CRTC_OFFSET); \ |
464 | } while (0) | 465 | } while (0) |
465 | 466 | ||
466 | /* ================================================================ | 467 | /* ================================================================ |
@@ -472,13 +473,12 @@ do { \ | |||
472 | #define RING_LOCALS \ | 473 | #define RING_LOCALS \ |
473 | int write, _nr; unsigned int tail_mask; volatile u32 *ring; | 474 | int write, _nr; unsigned int tail_mask; volatile u32 *ring; |
474 | 475 | ||
475 | #define BEGIN_RING( n ) do { \ | 476 | #define BEGIN_RING(n) do { \ |
476 | if ( R128_VERBOSE ) { \ | 477 | if (R128_VERBOSE) \ |
477 | DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ | 478 | DRM_INFO("BEGIN_RING(%d)\n", (n)); \ |
478 | } \ | 479 | if (dev_priv->ring.space <= (n) * sizeof(u32)) { \ |
479 | if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ | ||
480 | COMMIT_RING(); \ | 480 | COMMIT_RING(); \ |
481 | r128_wait_ring( dev_priv, (n) * sizeof(u32) ); \ | 481 | r128_wait_ring(dev_priv, (n) * sizeof(u32)); \ |
482 | } \ | 482 | } \ |
483 | _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ | 483 | _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ |
484 | ring = dev_priv->ring.start; \ | 484 | ring = dev_priv->ring.start; \ |
@@ -494,40 +494,36 @@ do { \ | |||
494 | #define R128_BROKEN_CCE 1 | 494 | #define R128_BROKEN_CCE 1 |
495 | 495 | ||
496 | #define ADVANCE_RING() do { \ | 496 | #define ADVANCE_RING() do { \ |
497 | if ( R128_VERBOSE ) { \ | 497 | if (R128_VERBOSE) \ |
498 | DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ | 498 | DRM_INFO("ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ |
499 | write, dev_priv->ring.tail ); \ | 499 | write, dev_priv->ring.tail); \ |
500 | } \ | 500 | if (R128_BROKEN_CCE && write < 32) \ |
501 | if ( R128_BROKEN_CCE && write < 32 ) { \ | 501 | memcpy(dev_priv->ring.end, \ |
502 | memcpy( dev_priv->ring.end, \ | 502 | dev_priv->ring.start, \ |
503 | dev_priv->ring.start, \ | 503 | write * sizeof(u32)); \ |
504 | write * sizeof(u32) ); \ | 504 | if (((dev_priv->ring.tail + _nr) & tail_mask) != write) \ |
505 | } \ | ||
506 | if (((dev_priv->ring.tail + _nr) & tail_mask) != write) { \ | ||
507 | DRM_ERROR( \ | 505 | DRM_ERROR( \ |
508 | "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ | 506 | "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ |
509 | ((dev_priv->ring.tail + _nr) & tail_mask), \ | 507 | ((dev_priv->ring.tail + _nr) & tail_mask), \ |
510 | write, __LINE__); \ | 508 | write, __LINE__); \ |
511 | } else \ | 509 | else \ |
512 | dev_priv->ring.tail = write; \ | 510 | dev_priv->ring.tail = write; \ |
513 | } while (0) | 511 | } while (0) |
514 | 512 | ||
515 | #define COMMIT_RING() do { \ | 513 | #define COMMIT_RING() do { \ |
516 | if ( R128_VERBOSE ) { \ | 514 | if (R128_VERBOSE) \ |
517 | DRM_INFO( "COMMIT_RING() tail=0x%06x\n", \ | 515 | DRM_INFO("COMMIT_RING() tail=0x%06x\n", \ |
518 | dev_priv->ring.tail ); \ | 516 | dev_priv->ring.tail); \ |
519 | } \ | ||
520 | DRM_MEMORYBARRIER(); \ | 517 | DRM_MEMORYBARRIER(); \ |
521 | R128_WRITE( R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail ); \ | 518 | R128_WRITE(R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail); \ |
522 | R128_READ( R128_PM4_BUFFER_DL_WPTR ); \ | 519 | R128_READ(R128_PM4_BUFFER_DL_WPTR); \ |
523 | } while (0) | 520 | } while (0) |
524 | 521 | ||
525 | #define OUT_RING( x ) do { \ | 522 | #define OUT_RING(x) do { \ |
526 | if ( R128_VERBOSE ) { \ | 523 | if (R128_VERBOSE) \ |
527 | DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \ | 524 | DRM_INFO(" OUT_RING( 0x%08x ) at 0x%x\n", \ |
528 | (unsigned int)(x), write ); \ | 525 | (unsigned int)(x), write); \ |
529 | } \ | 526 | ring[write++] = cpu_to_le32(x); \ |
530 | ring[write++] = cpu_to_le32( x ); \ | ||
531 | write &= tail_mask; \ | 527 | write &= tail_mask; \ |
532 | } while (0) | 528 | } while (0) |
533 | 529 | ||
diff --git a/drivers/gpu/drm/r128/r128_irq.c b/drivers/gpu/drm/r128/r128_irq.c index 69810fb8ac49..429d5a02695f 100644 --- a/drivers/gpu/drm/r128/r128_irq.c +++ b/drivers/gpu/drm/r128/r128_irq.c | |||
@@ -90,7 +90,7 @@ void r128_disable_vblank(struct drm_device *dev, int crtc) | |||
90 | */ | 90 | */ |
91 | } | 91 | } |
92 | 92 | ||
93 | void r128_driver_irq_preinstall(struct drm_device * dev) | 93 | void r128_driver_irq_preinstall(struct drm_device *dev) |
94 | { | 94 | { |
95 | drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; | 95 | drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; |
96 | 96 | ||
@@ -105,7 +105,7 @@ int r128_driver_irq_postinstall(struct drm_device *dev) | |||
105 | return 0; | 105 | return 0; |
106 | } | 106 | } |
107 | 107 | ||
108 | void r128_driver_irq_uninstall(struct drm_device * dev) | 108 | void r128_driver_irq_uninstall(struct drm_device *dev) |
109 | { | 109 | { |
110 | drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; | 110 | drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; |
111 | if (!dev_priv) | 111 | if (!dev_priv) |
diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c index af2665cf4718..077af1f2f9b4 100644 --- a/drivers/gpu/drm/r128/r128_state.c +++ b/drivers/gpu/drm/r128/r128_state.c | |||
@@ -37,8 +37,8 @@ | |||
37 | * CCE hardware state programming functions | 37 | * CCE hardware state programming functions |
38 | */ | 38 | */ |
39 | 39 | ||
40 | static void r128_emit_clip_rects(drm_r128_private_t * dev_priv, | 40 | static void r128_emit_clip_rects(drm_r128_private_t *dev_priv, |
41 | struct drm_clip_rect * boxes, int count) | 41 | struct drm_clip_rect *boxes, int count) |
42 | { | 42 | { |
43 | u32 aux_sc_cntl = 0x00000000; | 43 | u32 aux_sc_cntl = 0x00000000; |
44 | RING_LOCALS; | 44 | RING_LOCALS; |
@@ -80,7 +80,7 @@ static void r128_emit_clip_rects(drm_r128_private_t * dev_priv, | |||
80 | ADVANCE_RING(); | 80 | ADVANCE_RING(); |
81 | } | 81 | } |
82 | 82 | ||
83 | static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv) | 83 | static __inline__ void r128_emit_core(drm_r128_private_t *dev_priv) |
84 | { | 84 | { |
85 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; | 85 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; |
86 | drm_r128_context_regs_t *ctx = &sarea_priv->context_state; | 86 | drm_r128_context_regs_t *ctx = &sarea_priv->context_state; |
@@ -95,7 +95,7 @@ static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv) | |||
95 | ADVANCE_RING(); | 95 | ADVANCE_RING(); |
96 | } | 96 | } |
97 | 97 | ||
98 | static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv) | 98 | static __inline__ void r128_emit_context(drm_r128_private_t *dev_priv) |
99 | { | 99 | { |
100 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; | 100 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; |
101 | drm_r128_context_regs_t *ctx = &sarea_priv->context_state; | 101 | drm_r128_context_regs_t *ctx = &sarea_priv->context_state; |
@@ -121,7 +121,7 @@ static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv) | |||
121 | ADVANCE_RING(); | 121 | ADVANCE_RING(); |
122 | } | 122 | } |
123 | 123 | ||
124 | static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv) | 124 | static __inline__ void r128_emit_setup(drm_r128_private_t *dev_priv) |
125 | { | 125 | { |
126 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; | 126 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; |
127 | drm_r128_context_regs_t *ctx = &sarea_priv->context_state; | 127 | drm_r128_context_regs_t *ctx = &sarea_priv->context_state; |
@@ -137,7 +137,7 @@ static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv) | |||
137 | ADVANCE_RING(); | 137 | ADVANCE_RING(); |
138 | } | 138 | } |
139 | 139 | ||
140 | static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv) | 140 | static __inline__ void r128_emit_masks(drm_r128_private_t *dev_priv) |
141 | { | 141 | { |
142 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; | 142 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; |
143 | drm_r128_context_regs_t *ctx = &sarea_priv->context_state; | 143 | drm_r128_context_regs_t *ctx = &sarea_priv->context_state; |
@@ -156,7 +156,7 @@ static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv) | |||
156 | ADVANCE_RING(); | 156 | ADVANCE_RING(); |
157 | } | 157 | } |
158 | 158 | ||
159 | static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv) | 159 | static __inline__ void r128_emit_window(drm_r128_private_t *dev_priv) |
160 | { | 160 | { |
161 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; | 161 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; |
162 | drm_r128_context_regs_t *ctx = &sarea_priv->context_state; | 162 | drm_r128_context_regs_t *ctx = &sarea_priv->context_state; |
@@ -171,7 +171,7 @@ static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv) | |||
171 | ADVANCE_RING(); | 171 | ADVANCE_RING(); |
172 | } | 172 | } |
173 | 173 | ||
174 | static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv) | 174 | static __inline__ void r128_emit_tex0(drm_r128_private_t *dev_priv) |
175 | { | 175 | { |
176 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; | 176 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; |
177 | drm_r128_context_regs_t *ctx = &sarea_priv->context_state; | 177 | drm_r128_context_regs_t *ctx = &sarea_priv->context_state; |
@@ -187,9 +187,8 @@ static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv) | |||
187 | OUT_RING(tex->tex_cntl); | 187 | OUT_RING(tex->tex_cntl); |
188 | OUT_RING(tex->tex_combine_cntl); | 188 | OUT_RING(tex->tex_combine_cntl); |
189 | OUT_RING(ctx->tex_size_pitch_c); | 189 | OUT_RING(ctx->tex_size_pitch_c); |
190 | for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) { | 190 | for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) |
191 | OUT_RING(tex->tex_offset[i]); | 191 | OUT_RING(tex->tex_offset[i]); |
192 | } | ||
193 | 192 | ||
194 | OUT_RING(CCE_PACKET0(R128_CONSTANT_COLOR_C, 1)); | 193 | OUT_RING(CCE_PACKET0(R128_CONSTANT_COLOR_C, 1)); |
195 | OUT_RING(ctx->constant_color_c); | 194 | OUT_RING(ctx->constant_color_c); |
@@ -198,7 +197,7 @@ static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv) | |||
198 | ADVANCE_RING(); | 197 | ADVANCE_RING(); |
199 | } | 198 | } |
200 | 199 | ||
201 | static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv) | 200 | static __inline__ void r128_emit_tex1(drm_r128_private_t *dev_priv) |
202 | { | 201 | { |
203 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; | 202 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; |
204 | drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1]; | 203 | drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1]; |
@@ -211,9 +210,8 @@ static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv) | |||
211 | OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS)); | 210 | OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS)); |
212 | OUT_RING(tex->tex_cntl); | 211 | OUT_RING(tex->tex_cntl); |
213 | OUT_RING(tex->tex_combine_cntl); | 212 | OUT_RING(tex->tex_combine_cntl); |
214 | for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) { | 213 | for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) |
215 | OUT_RING(tex->tex_offset[i]); | 214 | OUT_RING(tex->tex_offset[i]); |
216 | } | ||
217 | 215 | ||
218 | OUT_RING(CCE_PACKET0(R128_SEC_TEXTURE_BORDER_COLOR_C, 0)); | 216 | OUT_RING(CCE_PACKET0(R128_SEC_TEXTURE_BORDER_COLOR_C, 0)); |
219 | OUT_RING(tex->tex_border_color); | 217 | OUT_RING(tex->tex_border_color); |
@@ -221,7 +219,7 @@ static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv) | |||
221 | ADVANCE_RING(); | 219 | ADVANCE_RING(); |
222 | } | 220 | } |
223 | 221 | ||
224 | static void r128_emit_state(drm_r128_private_t * dev_priv) | 222 | static void r128_emit_state(drm_r128_private_t *dev_priv) |
225 | { | 223 | { |
226 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; | 224 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; |
227 | unsigned int dirty = sarea_priv->dirty; | 225 | unsigned int dirty = sarea_priv->dirty; |
@@ -274,7 +272,7 @@ static void r128_emit_state(drm_r128_private_t * dev_priv) | |||
274 | * Performance monitoring functions | 272 | * Performance monitoring functions |
275 | */ | 273 | */ |
276 | 274 | ||
277 | static void r128_clear_box(drm_r128_private_t * dev_priv, | 275 | static void r128_clear_box(drm_r128_private_t *dev_priv, |
278 | int x, int y, int w, int h, int r, int g, int b) | 276 | int x, int y, int w, int h, int r, int g, int b) |
279 | { | 277 | { |
280 | u32 pitch, offset; | 278 | u32 pitch, offset; |
@@ -321,13 +319,12 @@ static void r128_clear_box(drm_r128_private_t * dev_priv, | |||
321 | ADVANCE_RING(); | 319 | ADVANCE_RING(); |
322 | } | 320 | } |
323 | 321 | ||
324 | static void r128_cce_performance_boxes(drm_r128_private_t * dev_priv) | 322 | static void r128_cce_performance_boxes(drm_r128_private_t *dev_priv) |
325 | { | 323 | { |
326 | if (atomic_read(&dev_priv->idle_count) == 0) { | 324 | if (atomic_read(&dev_priv->idle_count) == 0) |
327 | r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0); | 325 | r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0); |
328 | } else { | 326 | else |
329 | atomic_set(&dev_priv->idle_count, 0); | 327 | atomic_set(&dev_priv->idle_count, 0); |
330 | } | ||
331 | } | 328 | } |
332 | 329 | ||
333 | #endif | 330 | #endif |
@@ -352,8 +349,8 @@ static void r128_print_dirty(const char *msg, unsigned int flags) | |||
352 | (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : ""); | 349 | (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : ""); |
353 | } | 350 | } |
354 | 351 | ||
355 | static void r128_cce_dispatch_clear(struct drm_device * dev, | 352 | static void r128_cce_dispatch_clear(struct drm_device *dev, |
356 | drm_r128_clear_t * clear) | 353 | drm_r128_clear_t *clear) |
357 | { | 354 | { |
358 | drm_r128_private_t *dev_priv = dev->dev_private; | 355 | drm_r128_private_t *dev_priv = dev->dev_private; |
359 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; | 356 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; |
@@ -458,7 +455,7 @@ static void r128_cce_dispatch_clear(struct drm_device * dev, | |||
458 | } | 455 | } |
459 | } | 456 | } |
460 | 457 | ||
461 | static void r128_cce_dispatch_swap(struct drm_device * dev) | 458 | static void r128_cce_dispatch_swap(struct drm_device *dev) |
462 | { | 459 | { |
463 | drm_r128_private_t *dev_priv = dev->dev_private; | 460 | drm_r128_private_t *dev_priv = dev->dev_private; |
464 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; | 461 | drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; |
@@ -524,7 +521,7 @@ static void r128_cce_dispatch_swap(struct drm_device * dev) | |||
524 | ADVANCE_RING(); | 521 | ADVANCE_RING(); |
525 | } | 522 | } |
526 | 523 | ||
527 | static void r128_cce_dispatch_flip(struct drm_device * dev) | 524 | static void r128_cce_dispatch_flip(struct drm_device *dev) |
528 | { | 525 | { |
529 | drm_r128_private_t *dev_priv = dev->dev_private; | 526 | drm_r128_private_t *dev_priv = dev->dev_private; |
530 | RING_LOCALS; | 527 | RING_LOCALS; |
@@ -542,11 +539,10 @@ static void r128_cce_dispatch_flip(struct drm_device * dev) | |||
542 | R128_WAIT_UNTIL_PAGE_FLIPPED(); | 539 | R128_WAIT_UNTIL_PAGE_FLIPPED(); |
543 | OUT_RING(CCE_PACKET0(R128_CRTC_OFFSET, 0)); | 540 | OUT_RING(CCE_PACKET0(R128_CRTC_OFFSET, 0)); |
544 | 541 | ||
545 | if (dev_priv->current_page == 0) { | 542 | if (dev_priv->current_page == 0) |
546 | OUT_RING(dev_priv->back_offset); | 543 | OUT_RING(dev_priv->back_offset); |
547 | } else { | 544 | else |
548 | OUT_RING(dev_priv->front_offset); | 545 | OUT_RING(dev_priv->front_offset); |
549 | } | ||
550 | 546 | ||
551 | ADVANCE_RING(); | 547 | ADVANCE_RING(); |
552 | 548 | ||
@@ -566,7 +562,7 @@ static void r128_cce_dispatch_flip(struct drm_device * dev) | |||
566 | ADVANCE_RING(); | 562 | ADVANCE_RING(); |
567 | } | 563 | } |
568 | 564 | ||
569 | static void r128_cce_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf) | 565 | static void r128_cce_dispatch_vertex(struct drm_device *dev, struct drm_buf *buf) |
570 | { | 566 | { |
571 | drm_r128_private_t *dev_priv = dev->dev_private; | 567 | drm_r128_private_t *dev_priv = dev->dev_private; |
572 | drm_r128_buf_priv_t *buf_priv = buf->dev_private; | 568 | drm_r128_buf_priv_t *buf_priv = buf->dev_private; |
@@ -585,9 +581,8 @@ static void r128_cce_dispatch_vertex(struct drm_device * dev, struct drm_buf * b | |||
585 | if (buf->used) { | 581 | if (buf->used) { |
586 | buf_priv->dispatched = 1; | 582 | buf_priv->dispatched = 1; |
587 | 583 | ||
588 | if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) { | 584 | if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) |
589 | r128_emit_state(dev_priv); | 585 | r128_emit_state(dev_priv); |
590 | } | ||
591 | 586 | ||
592 | do { | 587 | do { |
593 | /* Emit the next set of up to three cliprects */ | 588 | /* Emit the next set of up to three cliprects */ |
@@ -636,8 +631,8 @@ static void r128_cce_dispatch_vertex(struct drm_device * dev, struct drm_buf * b | |||
636 | sarea_priv->nbox = 0; | 631 | sarea_priv->nbox = 0; |
637 | } | 632 | } |
638 | 633 | ||
639 | static void r128_cce_dispatch_indirect(struct drm_device * dev, | 634 | static void r128_cce_dispatch_indirect(struct drm_device *dev, |
640 | struct drm_buf * buf, int start, int end) | 635 | struct drm_buf *buf, int start, int end) |
641 | { | 636 | { |
642 | drm_r128_private_t *dev_priv = dev->dev_private; | 637 | drm_r128_private_t *dev_priv = dev->dev_private; |
643 | drm_r128_buf_priv_t *buf_priv = buf->dev_private; | 638 | drm_r128_buf_priv_t *buf_priv = buf->dev_private; |
@@ -691,8 +686,8 @@ static void r128_cce_dispatch_indirect(struct drm_device * dev, | |||
691 | dev_priv->sarea_priv->last_dispatch++; | 686 | dev_priv->sarea_priv->last_dispatch++; |
692 | } | 687 | } |
693 | 688 | ||
694 | static void r128_cce_dispatch_indices(struct drm_device * dev, | 689 | static void r128_cce_dispatch_indices(struct drm_device *dev, |
695 | struct drm_buf * buf, | 690 | struct drm_buf *buf, |
696 | int start, int end, int count) | 691 | int start, int end, int count) |
697 | { | 692 | { |
698 | drm_r128_private_t *dev_priv = dev->dev_private; | 693 | drm_r128_private_t *dev_priv = dev->dev_private; |
@@ -713,9 +708,8 @@ static void r128_cce_dispatch_indices(struct drm_device * dev, | |||
713 | if (start != end) { | 708 | if (start != end) { |
714 | buf_priv->dispatched = 1; | 709 | buf_priv->dispatched = 1; |
715 | 710 | ||
716 | if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) { | 711 | if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) |
717 | r128_emit_state(dev_priv); | 712 | r128_emit_state(dev_priv); |
718 | } | ||
719 | 713 | ||
720 | dwords = (end - start + 3) / sizeof(u32); | 714 | dwords = (end - start + 3) / sizeof(u32); |
721 | 715 | ||
@@ -775,9 +769,9 @@ static void r128_cce_dispatch_indices(struct drm_device * dev, | |||
775 | sarea_priv->nbox = 0; | 769 | sarea_priv->nbox = 0; |
776 | } | 770 | } |
777 | 771 | ||
778 | static int r128_cce_dispatch_blit(struct drm_device * dev, | 772 | static int r128_cce_dispatch_blit(struct drm_device *dev, |
779 | struct drm_file *file_priv, | 773 | struct drm_file *file_priv, |
780 | drm_r128_blit_t * blit) | 774 | drm_r128_blit_t *blit) |
781 | { | 775 | { |
782 | drm_r128_private_t *dev_priv = dev->dev_private; | 776 | drm_r128_private_t *dev_priv = dev->dev_private; |
783 | struct drm_device_dma *dma = dev->dma; | 777 | struct drm_device_dma *dma = dev->dma; |
@@ -887,8 +881,8 @@ static int r128_cce_dispatch_blit(struct drm_device * dev, | |||
887 | * have hardware stencil support. | 881 | * have hardware stencil support. |
888 | */ | 882 | */ |
889 | 883 | ||
890 | static int r128_cce_dispatch_write_span(struct drm_device * dev, | 884 | static int r128_cce_dispatch_write_span(struct drm_device *dev, |
891 | drm_r128_depth_t * depth) | 885 | drm_r128_depth_t *depth) |
892 | { | 886 | { |
893 | drm_r128_private_t *dev_priv = dev->dev_private; | 887 | drm_r128_private_t *dev_priv = dev->dev_private; |
894 | int count, x, y; | 888 | int count, x, y; |
@@ -902,12 +896,10 @@ static int r128_cce_dispatch_write_span(struct drm_device * dev, | |||
902 | if (count > 4096 || count <= 0) | 896 | if (count > 4096 || count <= 0) |
903 | return -EMSGSIZE; | 897 | return -EMSGSIZE; |
904 | 898 | ||
905 | if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) { | 899 | if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) |
906 | return -EFAULT; | 900 | return -EFAULT; |
907 | } | 901 | if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) |
908 | if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) { | ||
909 | return -EFAULT; | 902 | return -EFAULT; |
910 | } | ||
911 | 903 | ||
912 | buffer_size = depth->n * sizeof(u32); | 904 | buffer_size = depth->n * sizeof(u32); |
913 | buffer = kmalloc(buffer_size, GFP_KERNEL); | 905 | buffer = kmalloc(buffer_size, GFP_KERNEL); |
@@ -983,8 +975,8 @@ static int r128_cce_dispatch_write_span(struct drm_device * dev, | |||
983 | return 0; | 975 | return 0; |
984 | } | 976 | } |
985 | 977 | ||
986 | static int r128_cce_dispatch_write_pixels(struct drm_device * dev, | 978 | static int r128_cce_dispatch_write_pixels(struct drm_device *dev, |
987 | drm_r128_depth_t * depth) | 979 | drm_r128_depth_t *depth) |
988 | { | 980 | { |
989 | drm_r128_private_t *dev_priv = dev->dev_private; | 981 | drm_r128_private_t *dev_priv = dev->dev_private; |
990 | int count, *x, *y; | 982 | int count, *x, *y; |
@@ -1001,9 +993,8 @@ static int r128_cce_dispatch_write_pixels(struct drm_device * dev, | |||
1001 | xbuf_size = count * sizeof(*x); | 993 | xbuf_size = count * sizeof(*x); |
1002 | ybuf_size = count * sizeof(*y); | 994 | ybuf_size = count * sizeof(*y); |
1003 | x = kmalloc(xbuf_size, GFP_KERNEL); | 995 | x = kmalloc(xbuf_size, GFP_KERNEL); |
1004 | if (x == NULL) { | 996 | if (x == NULL) |
1005 | return -ENOMEM; | 997 | return -ENOMEM; |
1006 | } | ||
1007 | y = kmalloc(ybuf_size, GFP_KERNEL); | 998 | y = kmalloc(ybuf_size, GFP_KERNEL); |
1008 | if (y == NULL) { | 999 | if (y == NULL) { |
1009 | kfree(x); | 1000 | kfree(x); |
@@ -1105,8 +1096,8 @@ static int r128_cce_dispatch_write_pixels(struct drm_device * dev, | |||
1105 | return 0; | 1096 | return 0; |
1106 | } | 1097 | } |
1107 | 1098 | ||
1108 | static int r128_cce_dispatch_read_span(struct drm_device * dev, | 1099 | static int r128_cce_dispatch_read_span(struct drm_device *dev, |
1109 | drm_r128_depth_t * depth) | 1100 | drm_r128_depth_t *depth) |
1110 | { | 1101 | { |
1111 | drm_r128_private_t *dev_priv = dev->dev_private; | 1102 | drm_r128_private_t *dev_priv = dev->dev_private; |
1112 | int count, x, y; | 1103 | int count, x, y; |
@@ -1117,12 +1108,10 @@ static int r128_cce_dispatch_read_span(struct drm_device * dev, | |||
1117 | if (count > 4096 || count <= 0) | 1108 | if (count > 4096 || count <= 0) |
1118 | return -EMSGSIZE; | 1109 | return -EMSGSIZE; |
1119 | 1110 | ||
1120 | if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) { | 1111 | if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) |
1121 | return -EFAULT; | 1112 | return -EFAULT; |
1122 | } | 1113 | if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) |
1123 | if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) { | ||
1124 | return -EFAULT; | 1114 | return -EFAULT; |
1125 | } | ||
1126 | 1115 | ||
1127 | BEGIN_RING(7); | 1116 | BEGIN_RING(7); |
1128 | 1117 | ||
@@ -1148,8 +1137,8 @@ static int r128_cce_dispatch_read_span(struct drm_device * dev, | |||
1148 | return 0; | 1137 | return 0; |
1149 | } | 1138 | } |
1150 | 1139 | ||
1151 | static int r128_cce_dispatch_read_pixels(struct drm_device * dev, | 1140 | static int r128_cce_dispatch_read_pixels(struct drm_device *dev, |
1152 | drm_r128_depth_t * depth) | 1141 | drm_r128_depth_t *depth) |
1153 | { | 1142 | { |
1154 | drm_r128_private_t *dev_priv = dev->dev_private; | 1143 | drm_r128_private_t *dev_priv = dev->dev_private; |
1155 | int count, *x, *y; | 1144 | int count, *x, *y; |
@@ -1161,16 +1150,14 @@ static int r128_cce_dispatch_read_pixels(struct drm_device * dev, | |||
1161 | if (count > 4096 || count <= 0) | 1150 | if (count > 4096 || count <= 0) |
1162 | return -EMSGSIZE; | 1151 | return -EMSGSIZE; |
1163 | 1152 | ||
1164 | if (count > dev_priv->depth_pitch) { | 1153 | if (count > dev_priv->depth_pitch) |
1165 | count = dev_priv->depth_pitch; | 1154 | count = dev_priv->depth_pitch; |
1166 | } | ||
1167 | 1155 | ||
1168 | xbuf_size = count * sizeof(*x); | 1156 | xbuf_size = count * sizeof(*x); |
1169 | ybuf_size = count * sizeof(*y); | 1157 | ybuf_size = count * sizeof(*y); |
1170 | x = kmalloc(xbuf_size, GFP_KERNEL); | 1158 | x = kmalloc(xbuf_size, GFP_KERNEL); |
1171 | if (x == NULL) { | 1159 | if (x == NULL) |
1172 | return -ENOMEM; | 1160 | return -ENOMEM; |
1173 | } | ||
1174 | y = kmalloc(ybuf_size, GFP_KERNEL); | 1161 | y = kmalloc(ybuf_size, GFP_KERNEL); |
1175 | if (y == NULL) { | 1162 | if (y == NULL) { |
1176 | kfree(x); | 1163 | kfree(x); |
@@ -1220,7 +1207,7 @@ static int r128_cce_dispatch_read_pixels(struct drm_device * dev, | |||
1220 | * Polygon stipple | 1207 | * Polygon stipple |
1221 | */ | 1208 | */ |
1222 | 1209 | ||
1223 | static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple) | 1210 | static void r128_cce_dispatch_stipple(struct drm_device *dev, u32 *stipple) |
1224 | { | 1211 | { |
1225 | drm_r128_private_t *dev_priv = dev->dev_private; | 1212 | drm_r128_private_t *dev_priv = dev->dev_private; |
1226 | int i; | 1213 | int i; |
@@ -1230,9 +1217,8 @@ static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple) | |||
1230 | BEGIN_RING(33); | 1217 | BEGIN_RING(33); |
1231 | 1218 | ||
1232 | OUT_RING(CCE_PACKET0(R128_BRUSH_DATA0, 31)); | 1219 | OUT_RING(CCE_PACKET0(R128_BRUSH_DATA0, 31)); |
1233 | for (i = 0; i < 32; i++) { | 1220 | for (i = 0; i < 32; i++) |
1234 | OUT_RING(stipple[i]); | 1221 | OUT_RING(stipple[i]); |
1235 | } | ||
1236 | 1222 | ||
1237 | ADVANCE_RING(); | 1223 | ADVANCE_RING(); |
1238 | } | 1224 | } |
@@ -1269,7 +1255,7 @@ static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *f | |||
1269 | return 0; | 1255 | return 0; |
1270 | } | 1256 | } |
1271 | 1257 | ||
1272 | static int r128_do_init_pageflip(struct drm_device * dev) | 1258 | static int r128_do_init_pageflip(struct drm_device *dev) |
1273 | { | 1259 | { |
1274 | drm_r128_private_t *dev_priv = dev->dev_private; | 1260 | drm_r128_private_t *dev_priv = dev->dev_private; |
1275 | DRM_DEBUG("\n"); | 1261 | DRM_DEBUG("\n"); |
@@ -1288,7 +1274,7 @@ static int r128_do_init_pageflip(struct drm_device * dev) | |||
1288 | return 0; | 1274 | return 0; |
1289 | } | 1275 | } |
1290 | 1276 | ||
1291 | static int r128_do_cleanup_pageflip(struct drm_device * dev) | 1277 | static int r128_do_cleanup_pageflip(struct drm_device *dev) |
1292 | { | 1278 | { |
1293 | drm_r128_private_t *dev_priv = dev->dev_private; | 1279 | drm_r128_private_t *dev_priv = dev->dev_private; |
1294 | DRM_DEBUG("\n"); | 1280 | DRM_DEBUG("\n"); |
@@ -1645,17 +1631,16 @@ static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *fi | |||
1645 | return 0; | 1631 | return 0; |
1646 | } | 1632 | } |
1647 | 1633 | ||
1648 | void r128_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) | 1634 | void r128_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) |
1649 | { | 1635 | { |
1650 | if (dev->dev_private) { | 1636 | if (dev->dev_private) { |
1651 | drm_r128_private_t *dev_priv = dev->dev_private; | 1637 | drm_r128_private_t *dev_priv = dev->dev_private; |
1652 | if (dev_priv->page_flipping) { | 1638 | if (dev_priv->page_flipping) |
1653 | r128_do_cleanup_pageflip(dev); | 1639 | r128_do_cleanup_pageflip(dev); |
1654 | } | ||
1655 | } | 1640 | } |
1656 | } | 1641 | } |
1657 | 1642 | ||
1658 | void r128_driver_lastclose(struct drm_device * dev) | 1643 | void r128_driver_lastclose(struct drm_device *dev) |
1659 | { | 1644 | { |
1660 | r128_do_cleanup_cce(dev); | 1645 | r128_do_cleanup_cce(dev); |
1661 | } | 1646 | } |
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 84b1f2729d43..aebe00875041 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -69,5 +69,6 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ | |||
69 | 69 | ||
70 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o | 70 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
71 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o | 71 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o |
72 | radeon-$(CONFIG_ACPI) += radeon_acpi.o | ||
72 | 73 | ||
73 | obj-$(CONFIG_DRM_RADEON)+= radeon.o | 74 | obj-$(CONFIG_DRM_RADEON)+= radeon.o |
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 1d569830ed99..8e421f644a54 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -108,12 +108,11 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | |||
108 | base++; | 108 | base++; |
109 | break; | 109 | break; |
110 | case ATOM_IIO_READ: | 110 | case ATOM_IIO_READ: |
111 | temp = ctx->card->reg_read(ctx->card, CU16(base + 1)); | 111 | temp = ctx->card->ioreg_read(ctx->card, CU16(base + 1)); |
112 | base += 3; | 112 | base += 3; |
113 | break; | 113 | break; |
114 | case ATOM_IIO_WRITE: | 114 | case ATOM_IIO_WRITE: |
115 | (void)ctx->card->reg_read(ctx->card, CU16(base + 1)); | 115 | ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp); |
116 | ctx->card->reg_write(ctx->card, CU16(base + 1), temp); | ||
117 | base += 3; | 116 | base += 3; |
118 | break; | 117 | break; |
119 | case ATOM_IIO_CLEAR: | 118 | case ATOM_IIO_CLEAR: |
@@ -715,8 +714,8 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg) | |||
715 | cjiffies = jiffies; | 714 | cjiffies = jiffies; |
716 | if (time_after(cjiffies, ctx->last_jump_jiffies)) { | 715 | if (time_after(cjiffies, ctx->last_jump_jiffies)) { |
717 | cjiffies -= ctx->last_jump_jiffies; | 716 | cjiffies -= ctx->last_jump_jiffies; |
718 | if ((jiffies_to_msecs(cjiffies) > 1000)) { | 717 | if ((jiffies_to_msecs(cjiffies) > 5000)) { |
719 | DRM_ERROR("atombios stuck in loop for more than 1sec aborting\n"); | 718 | DRM_ERROR("atombios stuck in loop for more than 5secs aborting\n"); |
720 | ctx->abort = true; | 719 | ctx->abort = true; |
721 | } | 720 | } |
722 | } else { | 721 | } else { |
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index cd1b64ab5ca7..a589a55b223e 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h | |||
@@ -113,6 +113,8 @@ struct card_info { | |||
113 | struct drm_device *dev; | 113 | struct drm_device *dev; |
114 | void (* reg_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ | 114 | void (* reg_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ |
115 | uint32_t (* reg_read)(struct card_info *, uint32_t); /* filled by driver */ | 115 | uint32_t (* reg_read)(struct card_info *, uint32_t); /* filled by driver */ |
116 | void (* ioreg_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ | ||
117 | uint32_t (* ioreg_read)(struct card_info *, uint32_t); /* filled by driver */ | ||
116 | void (* mc_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ | 118 | void (* mc_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ |
117 | uint32_t (* mc_read)(struct card_info *, uint32_t); /* filled by driver */ | 119 | uint32_t (* mc_read)(struct card_info *, uint32_t); /* filled by driver */ |
118 | void (* pll_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ | 120 | void (* pll_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 8c2d6478a221..12ad512bd3d3 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -44,10 +44,6 @@ static void atombios_overscan_setup(struct drm_crtc *crtc, | |||
44 | 44 | ||
45 | memset(&args, 0, sizeof(args)); | 45 | memset(&args, 0, sizeof(args)); |
46 | 46 | ||
47 | args.usOverscanRight = 0; | ||
48 | args.usOverscanLeft = 0; | ||
49 | args.usOverscanBottom = 0; | ||
50 | args.usOverscanTop = 0; | ||
51 | args.ucCRTC = radeon_crtc->crtc_id; | 47 | args.ucCRTC = radeon_crtc->crtc_id; |
52 | 48 | ||
53 | switch (radeon_crtc->rmx_type) { | 49 | switch (radeon_crtc->rmx_type) { |
@@ -56,7 +52,6 @@ static void atombios_overscan_setup(struct drm_crtc *crtc, | |||
56 | args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; | 52 | args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; |
57 | args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; | 53 | args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; |
58 | args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; | 54 | args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; |
59 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
60 | break; | 55 | break; |
61 | case RMX_ASPECT: | 56 | case RMX_ASPECT: |
62 | a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; | 57 | a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; |
@@ -69,17 +64,16 @@ static void atombios_overscan_setup(struct drm_crtc *crtc, | |||
69 | args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; | 64 | args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; |
70 | args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; | 65 | args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; |
71 | } | 66 | } |
72 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
73 | break; | 67 | break; |
74 | case RMX_FULL: | 68 | case RMX_FULL: |
75 | default: | 69 | default: |
76 | args.usOverscanRight = 0; | 70 | args.usOverscanRight = radeon_crtc->h_border; |
77 | args.usOverscanLeft = 0; | 71 | args.usOverscanLeft = radeon_crtc->h_border; |
78 | args.usOverscanBottom = 0; | 72 | args.usOverscanBottom = radeon_crtc->v_border; |
79 | args.usOverscanTop = 0; | 73 | args.usOverscanTop = radeon_crtc->v_border; |
80 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
81 | break; | 74 | break; |
82 | } | 75 | } |
76 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
83 | } | 77 | } |
84 | 78 | ||
85 | static void atombios_scaler_setup(struct drm_crtc *crtc) | 79 | static void atombios_scaler_setup(struct drm_crtc *crtc) |
@@ -282,22 +276,22 @@ atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, | |||
282 | u16 misc = 0; | 276 | u16 misc = 0; |
283 | 277 | ||
284 | memset(&args, 0, sizeof(args)); | 278 | memset(&args, 0, sizeof(args)); |
285 | args.usH_Size = cpu_to_le16(mode->crtc_hdisplay); | 279 | args.usH_Size = cpu_to_le16(mode->crtc_hdisplay - (radeon_crtc->h_border * 2)); |
286 | args.usH_Blanking_Time = | 280 | args.usH_Blanking_Time = |
287 | cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay); | 281 | cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay + (radeon_crtc->h_border * 2)); |
288 | args.usV_Size = cpu_to_le16(mode->crtc_vdisplay); | 282 | args.usV_Size = cpu_to_le16(mode->crtc_vdisplay - (radeon_crtc->v_border * 2)); |
289 | args.usV_Blanking_Time = | 283 | args.usV_Blanking_Time = |
290 | cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay); | 284 | cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay + (radeon_crtc->v_border * 2)); |
291 | args.usH_SyncOffset = | 285 | args.usH_SyncOffset = |
292 | cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay); | 286 | cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay + radeon_crtc->h_border); |
293 | args.usH_SyncWidth = | 287 | args.usH_SyncWidth = |
294 | cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); | 288 | cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); |
295 | args.usV_SyncOffset = | 289 | args.usV_SyncOffset = |
296 | cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay); | 290 | cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay + radeon_crtc->v_border); |
297 | args.usV_SyncWidth = | 291 | args.usV_SyncWidth = |
298 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); | 292 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); |
299 | /*args.ucH_Border = mode->hborder;*/ | 293 | args.ucH_Border = radeon_crtc->h_border; |
300 | /*args.ucV_Border = mode->vborder;*/ | 294 | args.ucV_Border = radeon_crtc->v_border; |
301 | 295 | ||
302 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | 296 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) |
303 | misc |= ATOM_VSYNC_POLARITY; | 297 | misc |= ATOM_VSYNC_POLARITY; |
@@ -669,56 +663,25 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc) | |||
669 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 663 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
670 | } | 664 | } |
671 | 665 | ||
672 | static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | 666 | static void atombios_crtc_program_pll(struct drm_crtc *crtc, |
667 | int crtc_id, | ||
668 | int pll_id, | ||
669 | u32 encoder_mode, | ||
670 | u32 encoder_id, | ||
671 | u32 clock, | ||
672 | u32 ref_div, | ||
673 | u32 fb_div, | ||
674 | u32 frac_fb_div, | ||
675 | u32 post_div) | ||
673 | { | 676 | { |
674 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
675 | struct drm_device *dev = crtc->dev; | 677 | struct drm_device *dev = crtc->dev; |
676 | struct radeon_device *rdev = dev->dev_private; | 678 | struct radeon_device *rdev = dev->dev_private; |
677 | struct drm_encoder *encoder = NULL; | ||
678 | struct radeon_encoder *radeon_encoder = NULL; | ||
679 | u8 frev, crev; | 679 | u8 frev, crev; |
680 | int index; | 680 | int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); |
681 | union set_pixel_clock args; | 681 | union set_pixel_clock args; |
682 | u32 pll_clock = mode->clock; | ||
683 | u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; | ||
684 | struct radeon_pll *pll; | ||
685 | u32 adjusted_clock; | ||
686 | int encoder_mode = 0; | ||
687 | 682 | ||
688 | memset(&args, 0, sizeof(args)); | 683 | memset(&args, 0, sizeof(args)); |
689 | 684 | ||
690 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
691 | if (encoder->crtc == crtc) { | ||
692 | radeon_encoder = to_radeon_encoder(encoder); | ||
693 | encoder_mode = atombios_get_encoder_mode(encoder); | ||
694 | break; | ||
695 | } | ||
696 | } | ||
697 | |||
698 | if (!radeon_encoder) | ||
699 | return; | ||
700 | |||
701 | switch (radeon_crtc->pll_id) { | ||
702 | case ATOM_PPLL1: | ||
703 | pll = &rdev->clock.p1pll; | ||
704 | break; | ||
705 | case ATOM_PPLL2: | ||
706 | pll = &rdev->clock.p2pll; | ||
707 | break; | ||
708 | case ATOM_DCPLL: | ||
709 | case ATOM_PPLL_INVALID: | ||
710 | default: | ||
711 | pll = &rdev->clock.dcpll; | ||
712 | break; | ||
713 | } | ||
714 | |||
715 | /* adjust pixel clock as needed */ | ||
716 | adjusted_clock = atombios_adjust_pll(crtc, mode, pll); | ||
717 | |||
718 | radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | ||
719 | &ref_div, &post_div); | ||
720 | |||
721 | index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); | ||
722 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, | 685 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, |
723 | &crev)) | 686 | &crev)) |
724 | return; | 687 | return; |
@@ -727,47 +690,49 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
727 | case 1: | 690 | case 1: |
728 | switch (crev) { | 691 | switch (crev) { |
729 | case 1: | 692 | case 1: |
730 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); | 693 | if (clock == ATOM_DISABLE) |
694 | return; | ||
695 | args.v1.usPixelClock = cpu_to_le16(clock / 10); | ||
731 | args.v1.usRefDiv = cpu_to_le16(ref_div); | 696 | args.v1.usRefDiv = cpu_to_le16(ref_div); |
732 | args.v1.usFbDiv = cpu_to_le16(fb_div); | 697 | args.v1.usFbDiv = cpu_to_le16(fb_div); |
733 | args.v1.ucFracFbDiv = frac_fb_div; | 698 | args.v1.ucFracFbDiv = frac_fb_div; |
734 | args.v1.ucPostDiv = post_div; | 699 | args.v1.ucPostDiv = post_div; |
735 | args.v1.ucPpll = radeon_crtc->pll_id; | 700 | args.v1.ucPpll = pll_id; |
736 | args.v1.ucCRTC = radeon_crtc->crtc_id; | 701 | args.v1.ucCRTC = crtc_id; |
737 | args.v1.ucRefDivSrc = 1; | 702 | args.v1.ucRefDivSrc = 1; |
738 | break; | 703 | break; |
739 | case 2: | 704 | case 2: |
740 | args.v2.usPixelClock = cpu_to_le16(mode->clock / 10); | 705 | args.v2.usPixelClock = cpu_to_le16(clock / 10); |
741 | args.v2.usRefDiv = cpu_to_le16(ref_div); | 706 | args.v2.usRefDiv = cpu_to_le16(ref_div); |
742 | args.v2.usFbDiv = cpu_to_le16(fb_div); | 707 | args.v2.usFbDiv = cpu_to_le16(fb_div); |
743 | args.v2.ucFracFbDiv = frac_fb_div; | 708 | args.v2.ucFracFbDiv = frac_fb_div; |
744 | args.v2.ucPostDiv = post_div; | 709 | args.v2.ucPostDiv = post_div; |
745 | args.v2.ucPpll = radeon_crtc->pll_id; | 710 | args.v2.ucPpll = pll_id; |
746 | args.v2.ucCRTC = radeon_crtc->crtc_id; | 711 | args.v2.ucCRTC = crtc_id; |
747 | args.v2.ucRefDivSrc = 1; | 712 | args.v2.ucRefDivSrc = 1; |
748 | break; | 713 | break; |
749 | case 3: | 714 | case 3: |
750 | args.v3.usPixelClock = cpu_to_le16(mode->clock / 10); | 715 | args.v3.usPixelClock = cpu_to_le16(clock / 10); |
751 | args.v3.usRefDiv = cpu_to_le16(ref_div); | 716 | args.v3.usRefDiv = cpu_to_le16(ref_div); |
752 | args.v3.usFbDiv = cpu_to_le16(fb_div); | 717 | args.v3.usFbDiv = cpu_to_le16(fb_div); |
753 | args.v3.ucFracFbDiv = frac_fb_div; | 718 | args.v3.ucFracFbDiv = frac_fb_div; |
754 | args.v3.ucPostDiv = post_div; | 719 | args.v3.ucPostDiv = post_div; |
755 | args.v3.ucPpll = radeon_crtc->pll_id; | 720 | args.v3.ucPpll = pll_id; |
756 | args.v3.ucMiscInfo = (radeon_crtc->pll_id << 2); | 721 | args.v3.ucMiscInfo = (pll_id << 2); |
757 | args.v3.ucTransmitterId = radeon_encoder->encoder_id; | 722 | args.v3.ucTransmitterId = encoder_id; |
758 | args.v3.ucEncoderMode = encoder_mode; | 723 | args.v3.ucEncoderMode = encoder_mode; |
759 | break; | 724 | break; |
760 | case 5: | 725 | case 5: |
761 | args.v5.ucCRTC = radeon_crtc->crtc_id; | 726 | args.v5.ucCRTC = crtc_id; |
762 | args.v5.usPixelClock = cpu_to_le16(mode->clock / 10); | 727 | args.v5.usPixelClock = cpu_to_le16(clock / 10); |
763 | args.v5.ucRefDiv = ref_div; | 728 | args.v5.ucRefDiv = ref_div; |
764 | args.v5.usFbDiv = cpu_to_le16(fb_div); | 729 | args.v5.usFbDiv = cpu_to_le16(fb_div); |
765 | args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); | 730 | args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); |
766 | args.v5.ucPostDiv = post_div; | 731 | args.v5.ucPostDiv = post_div; |
767 | args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */ | 732 | args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */ |
768 | args.v5.ucTransmitterID = radeon_encoder->encoder_id; | 733 | args.v5.ucTransmitterID = encoder_id; |
769 | args.v5.ucEncoderMode = encoder_mode; | 734 | args.v5.ucEncoderMode = encoder_mode; |
770 | args.v5.ucPpll = radeon_crtc->pll_id; | 735 | args.v5.ucPpll = pll_id; |
771 | break; | 736 | break; |
772 | default: | 737 | default: |
773 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); | 738 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
@@ -782,6 +747,56 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
782 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 747 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
783 | } | 748 | } |
784 | 749 | ||
750 | static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | ||
751 | { | ||
752 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
753 | struct drm_device *dev = crtc->dev; | ||
754 | struct radeon_device *rdev = dev->dev_private; | ||
755 | struct drm_encoder *encoder = NULL; | ||
756 | struct radeon_encoder *radeon_encoder = NULL; | ||
757 | u32 pll_clock = mode->clock; | ||
758 | u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; | ||
759 | struct radeon_pll *pll; | ||
760 | u32 adjusted_clock; | ||
761 | int encoder_mode = 0; | ||
762 | |||
763 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
764 | if (encoder->crtc == crtc) { | ||
765 | radeon_encoder = to_radeon_encoder(encoder); | ||
766 | encoder_mode = atombios_get_encoder_mode(encoder); | ||
767 | break; | ||
768 | } | ||
769 | } | ||
770 | |||
771 | if (!radeon_encoder) | ||
772 | return; | ||
773 | |||
774 | switch (radeon_crtc->pll_id) { | ||
775 | case ATOM_PPLL1: | ||
776 | pll = &rdev->clock.p1pll; | ||
777 | break; | ||
778 | case ATOM_PPLL2: | ||
779 | pll = &rdev->clock.p2pll; | ||
780 | break; | ||
781 | case ATOM_DCPLL: | ||
782 | case ATOM_PPLL_INVALID: | ||
783 | default: | ||
784 | pll = &rdev->clock.dcpll; | ||
785 | break; | ||
786 | } | ||
787 | |||
788 | /* adjust pixel clock as needed */ | ||
789 | adjusted_clock = atombios_adjust_pll(crtc, mode, pll); | ||
790 | |||
791 | radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | ||
792 | &ref_div, &post_div); | ||
793 | |||
794 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, | ||
795 | encoder_mode, radeon_encoder->encoder_id, mode->clock, | ||
796 | ref_div, fb_div, frac_fb_div, post_div); | ||
797 | |||
798 | } | ||
799 | |||
785 | static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 800 | static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
786 | struct drm_framebuffer *old_fb) | 801 | struct drm_framebuffer *old_fb) |
787 | { | 802 | { |
@@ -797,7 +812,7 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
797 | 812 | ||
798 | /* no fb bound */ | 813 | /* no fb bound */ |
799 | if (!crtc->fb) { | 814 | if (!crtc->fb) { |
800 | DRM_DEBUG("No FB bound\n"); | 815 | DRM_DEBUG_KMS("No FB bound\n"); |
801 | return 0; | 816 | return 0; |
802 | } | 817 | } |
803 | 818 | ||
@@ -841,6 +856,11 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
841 | return -EINVAL; | 856 | return -EINVAL; |
842 | } | 857 | } |
843 | 858 | ||
859 | if (tiling_flags & RADEON_TILING_MACRO) | ||
860 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); | ||
861 | else if (tiling_flags & RADEON_TILING_MICRO) | ||
862 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); | ||
863 | |||
844 | switch (radeon_crtc->crtc_id) { | 864 | switch (radeon_crtc->crtc_id) { |
845 | case 0: | 865 | case 0: |
846 | WREG32(AVIVO_D1VGA_CONTROL, 0); | 866 | WREG32(AVIVO_D1VGA_CONTROL, 0); |
@@ -931,7 +951,7 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
931 | 951 | ||
932 | /* no fb bound */ | 952 | /* no fb bound */ |
933 | if (!crtc->fb) { | 953 | if (!crtc->fb) { |
934 | DRM_DEBUG("No FB bound\n"); | 954 | DRM_DEBUG_KMS("No FB bound\n"); |
935 | return 0; | 955 | return 0; |
936 | } | 956 | } |
937 | 957 | ||
@@ -979,11 +999,18 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
979 | return -EINVAL; | 999 | return -EINVAL; |
980 | } | 1000 | } |
981 | 1001 | ||
982 | if (tiling_flags & RADEON_TILING_MACRO) | 1002 | if (rdev->family >= CHIP_R600) { |
983 | fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE; | 1003 | if (tiling_flags & RADEON_TILING_MACRO) |
1004 | fb_format |= R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1; | ||
1005 | else if (tiling_flags & RADEON_TILING_MICRO) | ||
1006 | fb_format |= R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1; | ||
1007 | } else { | ||
1008 | if (tiling_flags & RADEON_TILING_MACRO) | ||
1009 | fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE; | ||
984 | 1010 | ||
985 | if (tiling_flags & RADEON_TILING_MICRO) | 1011 | if (tiling_flags & RADEON_TILING_MICRO) |
986 | fb_format |= AVIVO_D1GRPH_TILED; | 1012 | fb_format |= AVIVO_D1GRPH_TILED; |
1013 | } | ||
987 | 1014 | ||
988 | if (radeon_crtc->crtc_id == 0) | 1015 | if (radeon_crtc->crtc_id == 0) |
989 | WREG32(AVIVO_D1VGA_CONTROL, 0); | 1016 | WREG32(AVIVO_D1VGA_CONTROL, 0); |
@@ -1143,10 +1170,8 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
1143 | atombios_crtc_set_pll(crtc, adjusted_mode); | 1170 | atombios_crtc_set_pll(crtc, adjusted_mode); |
1144 | atombios_enable_ss(crtc); | 1171 | atombios_enable_ss(crtc); |
1145 | 1172 | ||
1146 | if (ASIC_IS_DCE4(rdev)) | 1173 | if (ASIC_IS_AVIVO(rdev)) |
1147 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | 1174 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
1148 | else if (ASIC_IS_AVIVO(rdev)) | ||
1149 | atombios_crtc_set_timing(crtc, adjusted_mode); | ||
1150 | else { | 1175 | else { |
1151 | atombios_crtc_set_timing(crtc, adjusted_mode); | 1176 | atombios_crtc_set_timing(crtc, adjusted_mode); |
1152 | if (radeon_crtc->crtc_id == 0) | 1177 | if (radeon_crtc->crtc_id == 0) |
@@ -1191,6 +1216,24 @@ static void atombios_crtc_commit(struct drm_crtc *crtc) | |||
1191 | atombios_lock_crtc(crtc, ATOM_DISABLE); | 1216 | atombios_lock_crtc(crtc, ATOM_DISABLE); |
1192 | } | 1217 | } |
1193 | 1218 | ||
1219 | static void atombios_crtc_disable(struct drm_crtc *crtc) | ||
1220 | { | ||
1221 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1222 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | ||
1223 | |||
1224 | switch (radeon_crtc->pll_id) { | ||
1225 | case ATOM_PPLL1: | ||
1226 | case ATOM_PPLL2: | ||
1227 | /* disable the ppll */ | ||
1228 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, | ||
1229 | 0, 0, ATOM_DISABLE, 0, 0, 0, 0); | ||
1230 | break; | ||
1231 | default: | ||
1232 | break; | ||
1233 | } | ||
1234 | radeon_crtc->pll_id = -1; | ||
1235 | } | ||
1236 | |||
1194 | static const struct drm_crtc_helper_funcs atombios_helper_funcs = { | 1237 | static const struct drm_crtc_helper_funcs atombios_helper_funcs = { |
1195 | .dpms = atombios_crtc_dpms, | 1238 | .dpms = atombios_crtc_dpms, |
1196 | .mode_fixup = atombios_crtc_mode_fixup, | 1239 | .mode_fixup = atombios_crtc_mode_fixup, |
@@ -1199,6 +1242,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = { | |||
1199 | .prepare = atombios_crtc_prepare, | 1242 | .prepare = atombios_crtc_prepare, |
1200 | .commit = atombios_crtc_commit, | 1243 | .commit = atombios_crtc_commit, |
1201 | .load_lut = radeon_crtc_load_lut, | 1244 | .load_lut = radeon_crtc_load_lut, |
1245 | .disable = atombios_crtc_disable, | ||
1202 | }; | 1246 | }; |
1203 | 1247 | ||
1204 | void radeon_atombios_init_crtc(struct drm_device *dev, | 1248 | void radeon_atombios_init_crtc(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index abffb1499e22..36e0d4b545e6 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -296,7 +296,7 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], | |||
296 | u8 this_v = dp_get_adjust_request_voltage(link_status, lane); | 296 | u8 this_v = dp_get_adjust_request_voltage(link_status, lane); |
297 | u8 this_p = dp_get_adjust_request_pre_emphasis(link_status, lane); | 297 | u8 this_p = dp_get_adjust_request_pre_emphasis(link_status, lane); |
298 | 298 | ||
299 | DRM_DEBUG("requested signal parameters: lane %d voltage %s pre_emph %s\n", | 299 | DRM_DEBUG_KMS("requested signal parameters: lane %d voltage %s pre_emph %s\n", |
300 | lane, | 300 | lane, |
301 | voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT], | 301 | voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT], |
302 | pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); | 302 | pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); |
@@ -313,7 +313,7 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], | |||
313 | if (p >= dp_pre_emphasis_max(v)) | 313 | if (p >= dp_pre_emphasis_max(v)) |
314 | p = dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | 314 | p = dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; |
315 | 315 | ||
316 | DRM_DEBUG("using signal parameters: voltage %s pre_emph %s\n", | 316 | DRM_DEBUG_KMS("using signal parameters: voltage %s pre_emph %s\n", |
317 | voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT], | 317 | voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT], |
318 | pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); | 318 | pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); |
319 | 319 | ||
@@ -358,7 +358,7 @@ retry: | |||
358 | if (args.v1.ucReplyStatus && !args.v1.ucDataOutLen) { | 358 | if (args.v1.ucReplyStatus && !args.v1.ucDataOutLen) { |
359 | if (args.v1.ucReplyStatus == 0x20 && retry_count++ < 10) | 359 | if (args.v1.ucReplyStatus == 0x20 && retry_count++ < 10) |
360 | goto retry; | 360 | goto retry; |
361 | DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n", | 361 | DRM_DEBUG_KMS("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n", |
362 | req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], | 362 | req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], |
363 | chan->rec.i2c_id, args.v1.ucReplyStatus, retry_count); | 363 | chan->rec.i2c_id, args.v1.ucReplyStatus, retry_count); |
364 | return false; | 364 | return false; |
@@ -461,10 +461,10 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) | |||
461 | memcpy(dig_connector->dpcd, msg, 8); | 461 | memcpy(dig_connector->dpcd, msg, 8); |
462 | { | 462 | { |
463 | int i; | 463 | int i; |
464 | DRM_DEBUG("DPCD: "); | 464 | DRM_DEBUG_KMS("DPCD: "); |
465 | for (i = 0; i < 8; i++) | 465 | for (i = 0; i < 8; i++) |
466 | DRM_DEBUG("%02x ", msg[i]); | 466 | DRM_DEBUG_KMS("%02x ", msg[i]); |
467 | DRM_DEBUG("\n"); | 467 | DRM_DEBUG_KMS("\n"); |
468 | } | 468 | } |
469 | return true; | 469 | return true; |
470 | } | 470 | } |
@@ -512,7 +512,7 @@ static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector, | |||
512 | return false; | 512 | return false; |
513 | } | 513 | } |
514 | 514 | ||
515 | DRM_DEBUG("link status %02x %02x %02x %02x %02x %02x\n", | 515 | DRM_DEBUG_KMS("link status %02x %02x %02x %02x %02x %02x\n", |
516 | link_status[0], link_status[1], link_status[2], | 516 | link_status[0], link_status[1], link_status[2], |
517 | link_status[3], link_status[4], link_status[5]); | 517 | link_status[3], link_status[4], link_status[5]); |
518 | return true; | 518 | return true; |
@@ -695,7 +695,7 @@ void dp_link_train(struct drm_encoder *encoder, | |||
695 | if (!clock_recovery) | 695 | if (!clock_recovery) |
696 | DRM_ERROR("clock recovery failed\n"); | 696 | DRM_ERROR("clock recovery failed\n"); |
697 | else | 697 | else |
698 | DRM_DEBUG("clock recovery at voltage %d pre-emphasis %d\n", | 698 | DRM_DEBUG_KMS("clock recovery at voltage %d pre-emphasis %d\n", |
699 | train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, | 699 | train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, |
700 | (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >> | 700 | (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >> |
701 | DP_TRAIN_PRE_EMPHASIS_SHIFT); | 701 | DP_TRAIN_PRE_EMPHASIS_SHIFT); |
@@ -739,7 +739,7 @@ void dp_link_train(struct drm_encoder *encoder, | |||
739 | if (!channel_eq) | 739 | if (!channel_eq) |
740 | DRM_ERROR("channel eq failed\n"); | 740 | DRM_ERROR("channel eq failed\n"); |
741 | else | 741 | else |
742 | DRM_DEBUG("channel eq at voltage %d pre-emphasis %d\n", | 742 | DRM_DEBUG_KMS("channel eq at voltage %d pre-emphasis %d\n", |
743 | train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, | 743 | train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, |
744 | (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) | 744 | (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) |
745 | >> DP_TRAIN_PRE_EMPHASIS_SHIFT); | 745 | >> DP_TRAIN_PRE_EMPHASIS_SHIFT); |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 1caf625e472b..957d5067ad9c 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -39,6 +39,23 @@ | |||
39 | static void evergreen_gpu_init(struct radeon_device *rdev); | 39 | static void evergreen_gpu_init(struct radeon_device *rdev); |
40 | void evergreen_fini(struct radeon_device *rdev); | 40 | void evergreen_fini(struct radeon_device *rdev); |
41 | 41 | ||
42 | /* get temperature in millidegrees */ | ||
43 | u32 evergreen_get_temp(struct radeon_device *rdev) | ||
44 | { | ||
45 | u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> | ||
46 | ASIC_T_SHIFT; | ||
47 | u32 actual_temp = 0; | ||
48 | |||
49 | if ((temp >> 10) & 1) | ||
50 | actual_temp = 0; | ||
51 | else if ((temp >> 9) & 1) | ||
52 | actual_temp = 255; | ||
53 | else | ||
54 | actual_temp = (temp >> 1) & 0xff; | ||
55 | |||
56 | return actual_temp * 1000; | ||
57 | } | ||
58 | |||
42 | void evergreen_pm_misc(struct radeon_device *rdev) | 59 | void evergreen_pm_misc(struct radeon_device *rdev) |
43 | { | 60 | { |
44 | int req_ps_idx = rdev->pm.requested_power_state_index; | 61 | int req_ps_idx = rdev->pm.requested_power_state_index; |
@@ -1115,6 +1132,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1115 | rdev->config.evergreen.max_backends) & | 1132 | rdev->config.evergreen.max_backends) & |
1116 | EVERGREEN_MAX_BACKENDS_MASK)); | 1133 | EVERGREEN_MAX_BACKENDS_MASK)); |
1117 | 1134 | ||
1135 | rdev->config.evergreen.tile_config = gb_addr_config; | ||
1118 | WREG32(GB_BACKEND_MAP, gb_backend_map); | 1136 | WREG32(GB_BACKEND_MAP, gb_backend_map); |
1119 | WREG32(GB_ADDR_CONFIG, gb_addr_config); | 1137 | WREG32(GB_ADDR_CONFIG, gb_addr_config); |
1120 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); | 1138 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); |
@@ -1334,8 +1352,8 @@ int evergreen_mc_init(struct radeon_device *rdev) | |||
1334 | } | 1352 | } |
1335 | rdev->mc.vram_width = numchan * chansize; | 1353 | rdev->mc.vram_width = numchan * chansize; |
1336 | /* Could aper size report 0 ? */ | 1354 | /* Could aper size report 0 ? */ |
1337 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 1355 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); |
1338 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 1356 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); |
1339 | /* Setup GPU memory space */ | 1357 | /* Setup GPU memory space */ |
1340 | /* size in MB on evergreen */ | 1358 | /* size in MB on evergreen */ |
1341 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | 1359 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; |
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index e028c1cd9d9b..2330f3a36fd5 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h | |||
@@ -61,6 +61,11 @@ | |||
61 | # define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102 5 | 61 | # define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102 5 |
62 | # define EVERGREEN_GRPH_FORMAT_RGB111110 6 | 62 | # define EVERGREEN_GRPH_FORMAT_RGB111110 6 |
63 | # define EVERGREEN_GRPH_FORMAT_BGR101111 7 | 63 | # define EVERGREEN_GRPH_FORMAT_BGR101111 7 |
64 | # define EVERGREEN_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20) | ||
65 | # define EVERGREEN_GRPH_ARRAY_LINEAR_GENERAL 0 | ||
66 | # define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED 1 | ||
67 | # define EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1 2 | ||
68 | # define EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1 4 | ||
64 | #define EVERGREEN_GRPH_SWAP_CONTROL 0x680c | 69 | #define EVERGREEN_GRPH_SWAP_CONTROL 0x680c |
65 | # define EVERGREEN_GRPH_ENDIAN_SWAP(x) (((x) & 0x3) << 0) | 70 | # define EVERGREEN_GRPH_ENDIAN_SWAP(x) (((x) & 0x3) << 0) |
66 | # define EVERGREEN_GRPH_ENDIAN_NONE 0 | 71 | # define EVERGREEN_GRPH_ENDIAN_NONE 0 |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index a1cd621780e2..9b7532dd30f7 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -165,6 +165,11 @@ | |||
165 | #define SE_DB_BUSY (1 << 30) | 165 | #define SE_DB_BUSY (1 << 30) |
166 | #define SE_CB_BUSY (1 << 31) | 166 | #define SE_CB_BUSY (1 << 31) |
167 | 167 | ||
168 | #define CG_MULT_THERMAL_STATUS 0x740 | ||
169 | #define ASIC_T(x) ((x) << 16) | ||
170 | #define ASIC_T_MASK 0x7FF0000 | ||
171 | #define ASIC_T_SHIFT 16 | ||
172 | |||
168 | #define HDP_HOST_PATH_CNTL 0x2C00 | 173 | #define HDP_HOST_PATH_CNTL 0x2C00 |
169 | #define HDP_NONSURFACE_BASE 0x2C04 | 174 | #define HDP_NONSURFACE_BASE 0x2C04 |
170 | #define HDP_NONSURFACE_INFO 0x2C08 | 175 | #define HDP_NONSURFACE_INFO 0x2C08 |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index a89a15ab524d..e817a0bb5eb4 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -141,7 +141,7 @@ void r100_pm_get_dynpm_state(struct radeon_device *rdev) | |||
141 | /* only one clock mode per power state */ | 141 | /* only one clock mode per power state */ |
142 | rdev->pm.requested_clock_mode_index = 0; | 142 | rdev->pm.requested_clock_mode_index = 0; |
143 | 143 | ||
144 | DRM_DEBUG("Requested: e: %d m: %d p: %d\n", | 144 | DRM_DEBUG_DRIVER("Requested: e: %d m: %d p: %d\n", |
145 | rdev->pm.power_state[rdev->pm.requested_power_state_index]. | 145 | rdev->pm.power_state[rdev->pm.requested_power_state_index]. |
146 | clock_info[rdev->pm.requested_clock_mode_index].sclk, | 146 | clock_info[rdev->pm.requested_clock_mode_index].sclk, |
147 | rdev->pm.power_state[rdev->pm.requested_power_state_index]. | 147 | rdev->pm.power_state[rdev->pm.requested_power_state_index]. |
@@ -276,7 +276,7 @@ void r100_pm_misc(struct radeon_device *rdev) | |||
276 | rdev->pm.power_state[rdev->pm.current_power_state_index].pcie_lanes)) { | 276 | rdev->pm.power_state[rdev->pm.current_power_state_index].pcie_lanes)) { |
277 | radeon_set_pcie_lanes(rdev, | 277 | radeon_set_pcie_lanes(rdev, |
278 | ps->pcie_lanes); | 278 | ps->pcie_lanes); |
279 | DRM_DEBUG("Setting: p: %d\n", ps->pcie_lanes); | 279 | DRM_DEBUG_DRIVER("Setting: p: %d\n", ps->pcie_lanes); |
280 | } | 280 | } |
281 | } | 281 | } |
282 | 282 | ||
@@ -849,7 +849,7 @@ static int r100_cp_init_microcode(struct radeon_device *rdev) | |||
849 | const char *fw_name = NULL; | 849 | const char *fw_name = NULL; |
850 | int err; | 850 | int err; |
851 | 851 | ||
852 | DRM_DEBUG("\n"); | 852 | DRM_DEBUG_KMS("\n"); |
853 | 853 | ||
854 | pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); | 854 | pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); |
855 | err = IS_ERR(pdev); | 855 | err = IS_ERR(pdev); |
@@ -1803,6 +1803,11 @@ static int r100_packet3_check(struct radeon_cs_parser *p, | |||
1803 | return r; | 1803 | return r; |
1804 | break; | 1804 | break; |
1805 | /* triggers drawing using indices to vertex buffer */ | 1805 | /* triggers drawing using indices to vertex buffer */ |
1806 | case PACKET3_3D_CLEAR_HIZ: | ||
1807 | case PACKET3_3D_CLEAR_ZMASK: | ||
1808 | if (p->rdev->hyperz_filp != p->filp) | ||
1809 | return -EINVAL; | ||
1810 | break; | ||
1806 | case PACKET3_NOP: | 1811 | case PACKET3_NOP: |
1807 | break; | 1812 | break; |
1808 | default: | 1813 | default: |
@@ -2295,8 +2300,8 @@ void r100_vram_init_sizes(struct radeon_device *rdev) | |||
2295 | u64 config_aper_size; | 2300 | u64 config_aper_size; |
2296 | 2301 | ||
2297 | /* work out accessible VRAM */ | 2302 | /* work out accessible VRAM */ |
2298 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 2303 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); |
2299 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 2304 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); |
2300 | rdev->mc.visible_vram_size = r100_get_accessible_vram(rdev); | 2305 | rdev->mc.visible_vram_size = r100_get_accessible_vram(rdev); |
2301 | /* FIXME we don't use the second aperture yet when we could use it */ | 2306 | /* FIXME we don't use the second aperture yet when we could use it */ |
2302 | if (rdev->mc.visible_vram_size > rdev->mc.aper_size) | 2307 | if (rdev->mc.visible_vram_size > rdev->mc.aper_size) |
@@ -2364,11 +2369,10 @@ void r100_mc_init(struct radeon_device *rdev) | |||
2364 | */ | 2369 | */ |
2365 | void r100_pll_errata_after_index(struct radeon_device *rdev) | 2370 | void r100_pll_errata_after_index(struct radeon_device *rdev) |
2366 | { | 2371 | { |
2367 | if (!(rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) { | 2372 | if (rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS) { |
2368 | return; | 2373 | (void)RREG32(RADEON_CLOCK_CNTL_DATA); |
2374 | (void)RREG32(RADEON_CRTC_GEN_CNTL); | ||
2369 | } | 2375 | } |
2370 | (void)RREG32(RADEON_CLOCK_CNTL_DATA); | ||
2371 | (void)RREG32(RADEON_CRTC_GEN_CNTL); | ||
2372 | } | 2376 | } |
2373 | 2377 | ||
2374 | static void r100_pll_errata_after_data(struct radeon_device *rdev) | 2378 | static void r100_pll_errata_after_data(struct radeon_device *rdev) |
@@ -2643,7 +2647,7 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg, | |||
2643 | flags |= pitch / 8; | 2647 | flags |= pitch / 8; |
2644 | 2648 | ||
2645 | 2649 | ||
2646 | DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1); | 2650 | DRM_DEBUG_KMS("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1); |
2647 | WREG32(RADEON_SURFACE0_INFO + surf_index, flags); | 2651 | WREG32(RADEON_SURFACE0_INFO + surf_index, flags); |
2648 | WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset); | 2652 | WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset); |
2649 | WREG32(RADEON_SURFACE0_UPPER_BOUND + surf_index, offset + obj_size - 1); | 2653 | WREG32(RADEON_SURFACE0_UPPER_BOUND + surf_index, offset + obj_size - 1); |
@@ -3039,7 +3043,7 @@ void r100_bandwidth_update(struct radeon_device *rdev) | |||
3039 | } | 3043 | } |
3040 | #endif | 3044 | #endif |
3041 | 3045 | ||
3042 | DRM_DEBUG("GRPH_BUFFER_CNTL from to %x\n", | 3046 | DRM_DEBUG_KMS("GRPH_BUFFER_CNTL from to %x\n", |
3043 | /* (unsigned int)info->SavedReg->grph_buffer_cntl, */ | 3047 | /* (unsigned int)info->SavedReg->grph_buffer_cntl, */ |
3044 | (unsigned int)RREG32(RADEON_GRPH_BUFFER_CNTL)); | 3048 | (unsigned int)RREG32(RADEON_GRPH_BUFFER_CNTL)); |
3045 | } | 3049 | } |
@@ -3135,7 +3139,7 @@ void r100_bandwidth_update(struct radeon_device *rdev) | |||
3135 | WREG32(RS400_DISP1_REQ_CNTL1, 0x28FBC3AC); | 3139 | WREG32(RS400_DISP1_REQ_CNTL1, 0x28FBC3AC); |
3136 | } | 3140 | } |
3137 | 3141 | ||
3138 | DRM_DEBUG("GRPH2_BUFFER_CNTL from to %x\n", | 3142 | DRM_DEBUG_KMS("GRPH2_BUFFER_CNTL from to %x\n", |
3139 | (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL)); | 3143 | (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL)); |
3140 | } | 3144 | } |
3141 | } | 3145 | } |
@@ -3809,6 +3813,31 @@ void r100_fini(struct radeon_device *rdev) | |||
3809 | rdev->bios = NULL; | 3813 | rdev->bios = NULL; |
3810 | } | 3814 | } |
3811 | 3815 | ||
3816 | /* | ||
3817 | * Due to how kexec works, it can leave the hw fully initialised when it | ||
3818 | * boots the new kernel. However doing our init sequence with the CP and | ||
3819 | * WB stuff setup causes GPU hangs on the RN50 at least. So at startup | ||
3820 | * do some quick sanity checks and restore sane values to avoid this | ||
3821 | * problem. | ||
3822 | */ | ||
3823 | void r100_restore_sanity(struct radeon_device *rdev) | ||
3824 | { | ||
3825 | u32 tmp; | ||
3826 | |||
3827 | tmp = RREG32(RADEON_CP_CSQ_CNTL); | ||
3828 | if (tmp) { | ||
3829 | WREG32(RADEON_CP_CSQ_CNTL, 0); | ||
3830 | } | ||
3831 | tmp = RREG32(RADEON_CP_RB_CNTL); | ||
3832 | if (tmp) { | ||
3833 | WREG32(RADEON_CP_RB_CNTL, 0); | ||
3834 | } | ||
3835 | tmp = RREG32(RADEON_SCRATCH_UMSK); | ||
3836 | if (tmp) { | ||
3837 | WREG32(RADEON_SCRATCH_UMSK, 0); | ||
3838 | } | ||
3839 | } | ||
3840 | |||
3812 | int r100_init(struct radeon_device *rdev) | 3841 | int r100_init(struct radeon_device *rdev) |
3813 | { | 3842 | { |
3814 | int r; | 3843 | int r; |
@@ -3821,6 +3850,8 @@ int r100_init(struct radeon_device *rdev) | |||
3821 | radeon_scratch_init(rdev); | 3850 | radeon_scratch_init(rdev); |
3822 | /* Initialize surface registers */ | 3851 | /* Initialize surface registers */ |
3823 | radeon_surface_init(rdev); | 3852 | radeon_surface_init(rdev); |
3853 | /* sanity check some register to avoid hangs like after kexec */ | ||
3854 | r100_restore_sanity(rdev); | ||
3824 | /* TODO: disable VGA need to use VGA request */ | 3855 | /* TODO: disable VGA need to use VGA request */ |
3825 | /* BIOS*/ | 3856 | /* BIOS*/ |
3826 | if (!radeon_get_bios(rdev)) { | 3857 | if (!radeon_get_bios(rdev)) { |
diff --git a/drivers/gpu/drm/radeon/r100d.h b/drivers/gpu/drm/radeon/r100d.h index d016b16fa116..b121b6c678d4 100644 --- a/drivers/gpu/drm/radeon/r100d.h +++ b/drivers/gpu/drm/radeon/r100d.h | |||
@@ -48,10 +48,12 @@ | |||
48 | #define PACKET3_3D_DRAW_IMMD 0x29 | 48 | #define PACKET3_3D_DRAW_IMMD 0x29 |
49 | #define PACKET3_3D_DRAW_INDX 0x2A | 49 | #define PACKET3_3D_DRAW_INDX 0x2A |
50 | #define PACKET3_3D_LOAD_VBPNTR 0x2F | 50 | #define PACKET3_3D_LOAD_VBPNTR 0x2F |
51 | #define PACKET3_3D_CLEAR_ZMASK 0x32 | ||
51 | #define PACKET3_INDX_BUFFER 0x33 | 52 | #define PACKET3_INDX_BUFFER 0x33 |
52 | #define PACKET3_3D_DRAW_VBUF_2 0x34 | 53 | #define PACKET3_3D_DRAW_VBUF_2 0x34 |
53 | #define PACKET3_3D_DRAW_IMMD_2 0x35 | 54 | #define PACKET3_3D_DRAW_IMMD_2 0x35 |
54 | #define PACKET3_3D_DRAW_INDX_2 0x36 | 55 | #define PACKET3_3D_DRAW_INDX_2 0x36 |
56 | #define PACKET3_3D_CLEAR_HIZ 0x37 | ||
55 | #define PACKET3_BITBLT_MULTI 0x9B | 57 | #define PACKET3_BITBLT_MULTI 0x9B |
56 | 58 | ||
57 | #define PACKET0(reg, n) (CP_PACKET0 | \ | 59 | #define PACKET0(reg, n) (CP_PACKET0 | \ |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 19a7ef7ee344..c827738ad7dd 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -1048,14 +1048,47 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
1048 | /* RB3D_COLOR_CHANNEL_MASK */ | 1048 | /* RB3D_COLOR_CHANNEL_MASK */ |
1049 | track->color_channel_mask = idx_value; | 1049 | track->color_channel_mask = idx_value; |
1050 | break; | 1050 | break; |
1051 | case 0x4d1c: | 1051 | case 0x43a4: |
1052 | /* SC_HYPERZ_EN */ | ||
1053 | /* r300c emits this register - we need to disable hyperz for it | ||
1054 | * without complaining */ | ||
1055 | if (p->rdev->hyperz_filp != p->filp) { | ||
1056 | if (idx_value & 0x1) | ||
1057 | ib[idx] = idx_value & ~1; | ||
1058 | } | ||
1059 | break; | ||
1060 | case 0x4f1c: | ||
1052 | /* ZB_BW_CNTL */ | 1061 | /* ZB_BW_CNTL */ |
1053 | track->zb_cb_clear = !!(idx_value & (1 << 5)); | 1062 | track->zb_cb_clear = !!(idx_value & (1 << 5)); |
1063 | if (p->rdev->hyperz_filp != p->filp) { | ||
1064 | if (idx_value & (R300_HIZ_ENABLE | | ||
1065 | R300_RD_COMP_ENABLE | | ||
1066 | R300_WR_COMP_ENABLE | | ||
1067 | R300_FAST_FILL_ENABLE)) | ||
1068 | goto fail; | ||
1069 | } | ||
1054 | break; | 1070 | break; |
1055 | case 0x4e04: | 1071 | case 0x4e04: |
1056 | /* RB3D_BLENDCNTL */ | 1072 | /* RB3D_BLENDCNTL */ |
1057 | track->blend_read_enable = !!(idx_value & (1 << 2)); | 1073 | track->blend_read_enable = !!(idx_value & (1 << 2)); |
1058 | break; | 1074 | break; |
1075 | case 0x4f28: /* ZB_DEPTHCLEARVALUE */ | ||
1076 | break; | ||
1077 | case 0x4f30: /* ZB_MASK_OFFSET */ | ||
1078 | case 0x4f34: /* ZB_ZMASK_PITCH */ | ||
1079 | case 0x4f44: /* ZB_HIZ_OFFSET */ | ||
1080 | case 0x4f54: /* ZB_HIZ_PITCH */ | ||
1081 | if (idx_value && (p->rdev->hyperz_filp != p->filp)) | ||
1082 | goto fail; | ||
1083 | break; | ||
1084 | case 0x4028: | ||
1085 | if (idx_value && (p->rdev->hyperz_filp != p->filp)) | ||
1086 | goto fail; | ||
1087 | /* GB_Z_PEQ_CONFIG */ | ||
1088 | if (p->rdev->family >= CHIP_RV350) | ||
1089 | break; | ||
1090 | goto fail; | ||
1091 | break; | ||
1059 | case 0x4be8: | 1092 | case 0x4be8: |
1060 | /* valid register only on RV530 */ | 1093 | /* valid register only on RV530 */ |
1061 | if (p->rdev->family == CHIP_RV530) | 1094 | if (p->rdev->family == CHIP_RV530) |
@@ -1066,8 +1099,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
1066 | } | 1099 | } |
1067 | return 0; | 1100 | return 0; |
1068 | fail: | 1101 | fail: |
1069 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", | 1102 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d (val=%08x)\n", |
1070 | reg, idx); | 1103 | reg, idx, idx_value); |
1071 | return -EINVAL; | 1104 | return -EINVAL; |
1072 | } | 1105 | } |
1073 | 1106 | ||
@@ -1161,6 +1194,11 @@ static int r300_packet3_check(struct radeon_cs_parser *p, | |||
1161 | return r; | 1194 | return r; |
1162 | } | 1195 | } |
1163 | break; | 1196 | break; |
1197 | case PACKET3_3D_CLEAR_HIZ: | ||
1198 | case PACKET3_3D_CLEAR_ZMASK: | ||
1199 | if (p->rdev->hyperz_filp != p->filp) | ||
1200 | return -EINVAL; | ||
1201 | break; | ||
1164 | case PACKET3_NOP: | 1202 | case PACKET3_NOP: |
1165 | break; | 1203 | break; |
1166 | default: | 1204 | default: |
@@ -1380,6 +1418,8 @@ int r300_init(struct radeon_device *rdev) | |||
1380 | /* Initialize surface registers */ | 1418 | /* Initialize surface registers */ |
1381 | radeon_surface_init(rdev); | 1419 | radeon_surface_init(rdev); |
1382 | /* TODO: disable VGA need to use VGA request */ | 1420 | /* TODO: disable VGA need to use VGA request */ |
1421 | /* restore some register to sane defaults */ | ||
1422 | r100_restore_sanity(rdev); | ||
1383 | /* BIOS*/ | 1423 | /* BIOS*/ |
1384 | if (!radeon_get_bios(rdev)) { | 1424 | if (!radeon_get_bios(rdev)) { |
1385 | if (ASIC_IS_AVIVO(rdev)) | 1425 | if (ASIC_IS_AVIVO(rdev)) |
diff --git a/drivers/gpu/drm/radeon/r300d.h b/drivers/gpu/drm/radeon/r300d.h index 968a33317fbf..0c036c60d9df 100644 --- a/drivers/gpu/drm/radeon/r300d.h +++ b/drivers/gpu/drm/radeon/r300d.h | |||
@@ -48,10 +48,12 @@ | |||
48 | #define PACKET3_3D_DRAW_IMMD 0x29 | 48 | #define PACKET3_3D_DRAW_IMMD 0x29 |
49 | #define PACKET3_3D_DRAW_INDX 0x2A | 49 | #define PACKET3_3D_DRAW_INDX 0x2A |
50 | #define PACKET3_3D_LOAD_VBPNTR 0x2F | 50 | #define PACKET3_3D_LOAD_VBPNTR 0x2F |
51 | #define PACKET3_3D_CLEAR_ZMASK 0x32 | ||
51 | #define PACKET3_INDX_BUFFER 0x33 | 52 | #define PACKET3_INDX_BUFFER 0x33 |
52 | #define PACKET3_3D_DRAW_VBUF_2 0x34 | 53 | #define PACKET3_3D_DRAW_VBUF_2 0x34 |
53 | #define PACKET3_3D_DRAW_IMMD_2 0x35 | 54 | #define PACKET3_3D_DRAW_IMMD_2 0x35 |
54 | #define PACKET3_3D_DRAW_INDX_2 0x36 | 55 | #define PACKET3_3D_DRAW_INDX_2 0x36 |
56 | #define PACKET3_3D_CLEAR_HIZ 0x37 | ||
55 | #define PACKET3_BITBLT_MULTI 0x9B | 57 | #define PACKET3_BITBLT_MULTI 0x9B |
56 | 58 | ||
57 | #define PACKET0(reg, n) (CP_PACKET0 | \ | 59 | #define PACKET0(reg, n) (CP_PACKET0 | \ |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index e6c89142bb4d..59f7bccc5be0 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
@@ -343,6 +343,8 @@ int r420_init(struct radeon_device *rdev) | |||
343 | /* Initialize surface registers */ | 343 | /* Initialize surface registers */ |
344 | radeon_surface_init(rdev); | 344 | radeon_surface_init(rdev); |
345 | /* TODO: disable VGA need to use VGA request */ | 345 | /* TODO: disable VGA need to use VGA request */ |
346 | /* restore some register to sane defaults */ | ||
347 | r100_restore_sanity(rdev); | ||
346 | /* BIOS*/ | 348 | /* BIOS*/ |
347 | if (!radeon_get_bios(rdev)) { | 349 | if (!radeon_get_bios(rdev)) { |
348 | if (ASIC_IS_AVIVO(rdev)) | 350 | if (ASIC_IS_AVIVO(rdev)) |
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index 93c9a2bbccf8..6ac1f604e29b 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h | |||
@@ -386,6 +386,11 @@ | |||
386 | # define AVIVO_D1GRPH_TILED (1 << 20) | 386 | # define AVIVO_D1GRPH_TILED (1 << 20) |
387 | # define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21) | 387 | # define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21) |
388 | 388 | ||
389 | # define R600_D1GRPH_ARRAY_MODE_LINEAR_GENERAL (0 << 20) | ||
390 | # define R600_D1GRPH_ARRAY_MODE_LINEAR_ALIGNED (1 << 20) | ||
391 | # define R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1 (2 << 20) | ||
392 | # define R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1 (4 << 20) | ||
393 | |||
389 | /* The R7xx *_HIGH surface regs are backwards; the D1 regs are in the D2 | 394 | /* The R7xx *_HIGH surface regs are backwards; the D1 regs are in the D2 |
390 | * block and vice versa. This applies to GRPH, CUR, etc. | 395 | * block and vice versa. This applies to GRPH, CUR, etc. |
391 | */ | 396 | */ |
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 694af7cc23ac..1458dee902dd 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
@@ -231,6 +231,8 @@ int r520_init(struct radeon_device *rdev) | |||
231 | radeon_scratch_init(rdev); | 231 | radeon_scratch_init(rdev); |
232 | /* Initialize surface registers */ | 232 | /* Initialize surface registers */ |
233 | radeon_surface_init(rdev); | 233 | radeon_surface_init(rdev); |
234 | /* restore some register to sane defaults */ | ||
235 | r100_restore_sanity(rdev); | ||
234 | /* TODO: disable VGA need to use VGA request */ | 236 | /* TODO: disable VGA need to use VGA request */ |
235 | /* BIOS*/ | 237 | /* BIOS*/ |
236 | if (!radeon_get_bios(rdev)) { | 238 | if (!radeon_get_bios(rdev)) { |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index e100f69faeec..d0ebae9dde25 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -92,6 +92,21 @@ void r600_gpu_init(struct radeon_device *rdev); | |||
92 | void r600_fini(struct radeon_device *rdev); | 92 | void r600_fini(struct radeon_device *rdev); |
93 | void r600_irq_disable(struct radeon_device *rdev); | 93 | void r600_irq_disable(struct radeon_device *rdev); |
94 | 94 | ||
95 | /* get temperature in millidegrees */ | ||
96 | u32 rv6xx_get_temp(struct radeon_device *rdev) | ||
97 | { | ||
98 | u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >> | ||
99 | ASIC_T_SHIFT; | ||
100 | u32 actual_temp = 0; | ||
101 | |||
102 | if ((temp >> 7) & 1) | ||
103 | actual_temp = 0; | ||
104 | else | ||
105 | actual_temp = (temp >> 1) & 0xff; | ||
106 | |||
107 | return actual_temp * 1000; | ||
108 | } | ||
109 | |||
95 | void r600_pm_get_dynpm_state(struct radeon_device *rdev) | 110 | void r600_pm_get_dynpm_state(struct radeon_device *rdev) |
96 | { | 111 | { |
97 | int i; | 112 | int i; |
@@ -256,7 +271,7 @@ void r600_pm_get_dynpm_state(struct radeon_device *rdev) | |||
256 | } | 271 | } |
257 | } | 272 | } |
258 | 273 | ||
259 | DRM_DEBUG("Requested: e: %d m: %d p: %d\n", | 274 | DRM_DEBUG_DRIVER("Requested: e: %d m: %d p: %d\n", |
260 | rdev->pm.power_state[rdev->pm.requested_power_state_index]. | 275 | rdev->pm.power_state[rdev->pm.requested_power_state_index]. |
261 | clock_info[rdev->pm.requested_clock_mode_index].sclk, | 276 | clock_info[rdev->pm.requested_clock_mode_index].sclk, |
262 | rdev->pm.power_state[rdev->pm.requested_power_state_index]. | 277 | rdev->pm.power_state[rdev->pm.requested_power_state_index]. |
@@ -571,7 +586,7 @@ void r600_pm_misc(struct radeon_device *rdev) | |||
571 | if (voltage->voltage != rdev->pm.current_vddc) { | 586 | if (voltage->voltage != rdev->pm.current_vddc) { |
572 | radeon_atom_set_voltage(rdev, voltage->voltage); | 587 | radeon_atom_set_voltage(rdev, voltage->voltage); |
573 | rdev->pm.current_vddc = voltage->voltage; | 588 | rdev->pm.current_vddc = voltage->voltage; |
574 | DRM_DEBUG("Setting: v: %d\n", voltage->voltage); | 589 | DRM_DEBUG_DRIVER("Setting: v: %d\n", voltage->voltage); |
575 | } | 590 | } |
576 | } | 591 | } |
577 | } | 592 | } |
@@ -869,7 +884,17 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
869 | u32 tmp; | 884 | u32 tmp; |
870 | 885 | ||
871 | /* flush hdp cache so updates hit vram */ | 886 | /* flush hdp cache so updates hit vram */ |
872 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | 887 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { |
888 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | ||
889 | u32 tmp; | ||
890 | |||
891 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | ||
892 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | ||
893 | */ | ||
894 | WREG32(HDP_DEBUG1, 0); | ||
895 | tmp = readl((void __iomem *)ptr); | ||
896 | } else | ||
897 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
873 | 898 | ||
874 | WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12); | 899 | WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12); |
875 | WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12); | 900 | WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12); |
@@ -1217,8 +1242,8 @@ int r600_mc_init(struct radeon_device *rdev) | |||
1217 | } | 1242 | } |
1218 | rdev->mc.vram_width = numchan * chansize; | 1243 | rdev->mc.vram_width = numchan * chansize; |
1219 | /* Could aper size report 0 ? */ | 1244 | /* Could aper size report 0 ? */ |
1220 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 1245 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); |
1221 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 1246 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); |
1222 | /* Setup GPU memory space */ | 1247 | /* Setup GPU memory space */ |
1223 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); | 1248 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); |
1224 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 1249 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
@@ -1609,7 +1634,7 @@ void r600_gpu_init(struct radeon_device *rdev) | |||
1609 | r600_count_pipe_bits((cc_rb_backend_disable & | 1634 | r600_count_pipe_bits((cc_rb_backend_disable & |
1610 | R6XX_MAX_BACKENDS_MASK) >> 16)), | 1635 | R6XX_MAX_BACKENDS_MASK) >> 16)), |
1611 | (cc_rb_backend_disable >> 16)); | 1636 | (cc_rb_backend_disable >> 16)); |
1612 | 1637 | rdev->config.r600.tile_config = tiling_config; | |
1613 | tiling_config |= BACKEND_MAP(backend_map); | 1638 | tiling_config |= BACKEND_MAP(backend_map); |
1614 | WREG32(GB_TILING_CONFIG, tiling_config); | 1639 | WREG32(GB_TILING_CONFIG, tiling_config); |
1615 | WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff); | 1640 | WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff); |
@@ -3512,5 +3537,15 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev) | |||
3512 | */ | 3537 | */ |
3513 | void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | 3538 | void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) |
3514 | { | 3539 | { |
3515 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | 3540 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
3541 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | ||
3542 | */ | ||
3543 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { | ||
3544 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | ||
3545 | u32 tmp; | ||
3546 | |||
3547 | WREG32(HDP_DEBUG1, 0); | ||
3548 | tmp = readl((void __iomem *)ptr); | ||
3549 | } else | ||
3550 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
3516 | } | 3551 | } |
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 2b26553c352c..b5443fe1c1d1 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c | |||
@@ -63,7 +63,8 @@ int r600_audio_bits_per_sample(struct radeon_device *rdev) | |||
63 | case 0x4: return 32; | 63 | case 0x4: return 32; |
64 | } | 64 | } |
65 | 65 | ||
66 | DRM_ERROR("Unknown bits per sample 0x%x using 16 instead.\n", (int)value); | 66 | dev_err(rdev->dev, "Unknown bits per sample 0x%x using 16 instead\n", |
67 | (int)value); | ||
67 | 68 | ||
68 | return 16; | 69 | return 16; |
69 | } | 70 | } |
@@ -150,7 +151,8 @@ static void r600_audio_update_hdmi(unsigned long param) | |||
150 | r600_hdmi_update_audio_settings(encoder); | 151 | r600_hdmi_update_audio_settings(encoder); |
151 | } | 152 | } |
152 | 153 | ||
153 | if(still_going) r600_audio_schedule_polling(rdev); | 154 | if (still_going) |
155 | r600_audio_schedule_polling(rdev); | ||
154 | } | 156 | } |
155 | 157 | ||
156 | /* | 158 | /* |
@@ -158,8 +160,9 @@ static void r600_audio_update_hdmi(unsigned long param) | |||
158 | */ | 160 | */ |
159 | static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable) | 161 | static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable) |
160 | { | 162 | { |
161 | DRM_INFO("%s audio support", enable ? "Enabling" : "Disabling"); | 163 | DRM_INFO("%s audio support\n", enable ? "Enabling" : "Disabling"); |
162 | WREG32_P(R600_AUDIO_ENABLE, enable ? 0x81000000 : 0x0, ~0x81000000); | 164 | WREG32_P(R600_AUDIO_ENABLE, enable ? 0x81000000 : 0x0, ~0x81000000); |
165 | rdev->audio_enabled = enable; | ||
163 | } | 166 | } |
164 | 167 | ||
165 | /* | 168 | /* |
@@ -195,12 +198,14 @@ void r600_audio_enable_polling(struct drm_encoder *encoder) | |||
195 | struct radeon_device *rdev = dev->dev_private; | 198 | struct radeon_device *rdev = dev->dev_private; |
196 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 199 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
197 | 200 | ||
198 | DRM_DEBUG("r600_audio_enable_polling: %d", radeon_encoder->audio_polling_active); | 201 | DRM_DEBUG("r600_audio_enable_polling: %d\n", |
202 | radeon_encoder->audio_polling_active); | ||
199 | if (radeon_encoder->audio_polling_active) | 203 | if (radeon_encoder->audio_polling_active) |
200 | return; | 204 | return; |
201 | 205 | ||
202 | radeon_encoder->audio_polling_active = 1; | 206 | radeon_encoder->audio_polling_active = 1; |
203 | mod_timer(&rdev->audio_timer, jiffies + 1); | 207 | if (rdev->audio_enabled) |
208 | mod_timer(&rdev->audio_timer, jiffies + 1); | ||
204 | } | 209 | } |
205 | 210 | ||
206 | /* | 211 | /* |
@@ -209,7 +214,8 @@ void r600_audio_enable_polling(struct drm_encoder *encoder) | |||
209 | void r600_audio_disable_polling(struct drm_encoder *encoder) | 214 | void r600_audio_disable_polling(struct drm_encoder *encoder) |
210 | { | 215 | { |
211 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 216 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
212 | DRM_DEBUG("r600_audio_disable_polling: %d", radeon_encoder->audio_polling_active); | 217 | DRM_DEBUG("r600_audio_disable_polling: %d\n", |
218 | radeon_encoder->audio_polling_active); | ||
213 | radeon_encoder->audio_polling_active = 0; | 219 | radeon_encoder->audio_polling_active = 0; |
214 | } | 220 | } |
215 | 221 | ||
@@ -236,7 +242,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) | |||
236 | WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301); | 242 | WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301); |
237 | break; | 243 | break; |
238 | default: | 244 | default: |
239 | DRM_ERROR("Unsupported encoder type 0x%02X\n", | 245 | dev_err(rdev->dev, "Unsupported encoder type 0x%02X\n", |
240 | radeon_encoder->encoder_id); | 246 | radeon_encoder->encoder_id); |
241 | return; | 247 | return; |
242 | } | 248 | } |
@@ -266,7 +272,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) | |||
266 | */ | 272 | */ |
267 | void r600_audio_fini(struct radeon_device *rdev) | 273 | void r600_audio_fini(struct radeon_device *rdev) |
268 | { | 274 | { |
269 | if (!radeon_audio || !r600_audio_chipset_supported(rdev)) | 275 | if (!rdev->audio_enabled) |
270 | return; | 276 | return; |
271 | 277 | ||
272 | del_timer(&rdev->audio_timer); | 278 | del_timer(&rdev->audio_timer); |
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index 0271b53fa2dd..e8151c1d55b2 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c | |||
@@ -39,37 +39,45 @@ | |||
39 | 39 | ||
40 | const u32 r6xx_default_state[] = | 40 | const u32 r6xx_default_state[] = |
41 | { | 41 | { |
42 | 0xc0002400, | 42 | 0xc0002400, /* START_3D_CMDBUF */ |
43 | 0x00000000, | 43 | 0x00000000, |
44 | 0xc0012800, | 44 | |
45 | 0xc0012800, /* CONTEXT_CONTROL */ | ||
45 | 0x80000000, | 46 | 0x80000000, |
46 | 0x80000000, | 47 | 0x80000000, |
48 | |||
47 | 0xc0016800, | 49 | 0xc0016800, |
48 | 0x00000010, | 50 | 0x00000010, |
49 | 0x00008000, | 51 | 0x00008000, /* WAIT_UNTIL */ |
52 | |||
50 | 0xc0016800, | 53 | 0xc0016800, |
51 | 0x00000542, | 54 | 0x00000542, |
52 | 0x07000003, | 55 | 0x07000003, /* TA_CNTL_AUX */ |
56 | |||
53 | 0xc0016800, | 57 | 0xc0016800, |
54 | 0x000005c5, | 58 | 0x000005c5, |
55 | 0x00000000, | 59 | 0x00000000, /* VC_ENHANCE */ |
60 | |||
56 | 0xc0016800, | 61 | 0xc0016800, |
57 | 0x00000363, | 62 | 0x00000363, |
58 | 0x00000000, | 63 | 0x00000000, /* SQ_DYN_GPR_CNTL_PS_FLUSH_REQ */ |
64 | |||
59 | 0xc0016800, | 65 | 0xc0016800, |
60 | 0x0000060c, | 66 | 0x0000060c, |
61 | 0x82000000, | 67 | 0x82000000, /* DB_DEBUG */ |
68 | |||
62 | 0xc0016800, | 69 | 0xc0016800, |
63 | 0x0000060e, | 70 | 0x0000060e, |
64 | 0x01020204, | 71 | 0x01020204, /* DB_WATERMARKS */ |
65 | 0xc0016f00, | 72 | |
66 | 0x00000000, | 73 | 0xc0026f00, |
67 | 0x00000000, | ||
68 | 0xc0016f00, | ||
69 | 0x00000001, | ||
70 | 0x00000000, | 74 | 0x00000000, |
75 | 0x00000000, /* SQ_VTX_BASE_VTX_LOC */ | ||
76 | 0x00000000, /* SQ_VTX_START_INST_LOC */ | ||
77 | |||
71 | 0xc0096900, | 78 | 0xc0096900, |
72 | 0x0000022a, | 79 | 0x0000022a, |
80 | 0x00000000, /* SQ_ESGS_RING_ITEMSIZE */ | ||
73 | 0x00000000, | 81 | 0x00000000, |
74 | 0x00000000, | 82 | 0x00000000, |
75 | 0x00000000, | 83 | 0x00000000, |
@@ -78,515 +86,317 @@ const u32 r6xx_default_state[] = | |||
78 | 0x00000000, | 86 | 0x00000000, |
79 | 0x00000000, | 87 | 0x00000000, |
80 | 0x00000000, | 88 | 0x00000000, |
81 | 0x00000000, | 89 | |
82 | 0xc0016900, | 90 | 0xc0016900, |
83 | 0x00000004, | 91 | 0x00000004, |
84 | 0x00000000, | 92 | 0x00000000, /* DB_DEPTH_INFO */ |
85 | 0xc0016900, | 93 | |
94 | 0xc0026900, | ||
86 | 0x0000000a, | 95 | 0x0000000a, |
87 | 0x00000000, | 96 | 0x00000000, /* DB_STENCIL_CLEAR */ |
88 | 0xc0016900, | 97 | 0x00000000, /* DB_DEPTH_CLEAR */ |
89 | 0x0000000b, | 98 | |
90 | 0x00000000, | ||
91 | 0xc0016900, | ||
92 | 0x0000010c, | ||
93 | 0x00000000, | ||
94 | 0xc0016900, | ||
95 | 0x0000010d, | ||
96 | 0x00000000, | ||
97 | 0xc0016900, | 99 | 0xc0016900, |
98 | 0x00000200, | 100 | 0x00000200, |
99 | 0x00000000, | 101 | 0x00000000, /* DB_DEPTH_CONTROL */ |
100 | 0xc0016900, | 102 | |
103 | 0xc0026900, | ||
101 | 0x00000343, | 104 | 0x00000343, |
102 | 0x00000060, | 105 | 0x00000060, /* DB_RENDER_CONTROL */ |
103 | 0xc0016900, | 106 | 0x00000040, /* DB_RENDER_OVERRIDE */ |
104 | 0x00000344, | 107 | |
105 | 0x00000040, | ||
106 | 0xc0016900, | 108 | 0xc0016900, |
107 | 0x00000351, | 109 | 0x00000351, |
108 | 0x0000aa00, | 110 | 0x0000aa00, /* DB_ALPHA_TO_MASK */ |
109 | 0xc0016900, | 111 | |
110 | 0x00000104, | 112 | 0xc00f6900, |
111 | 0x00000000, | 113 | 0x00000100, |
112 | 0xc0016900, | 114 | 0x00000800, /* VGT_MAX_VTX_INDX */ |
113 | 0x0000010e, | 115 | 0x00000000, /* VGT_MIN_VTX_INDX */ |
114 | 0x00000000, | 116 | 0x00000000, /* VGT_INDX_OFFSET */ |
115 | 0xc0046900, | 117 | 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ |
116 | 0x00000105, | 118 | 0x00000000, /* SX_ALPHA_TEST_CONTROL */ |
117 | 0x00000000, | 119 | 0x00000000, /* CB_BLEND_RED */ |
118 | 0x00000000, | ||
119 | 0x00000000, | 120 | 0x00000000, |
120 | 0x00000000, | 121 | 0x00000000, |
121 | 0xc0036900, | ||
122 | 0x00000109, | ||
123 | 0x00000000, | 122 | 0x00000000, |
123 | 0x00000000, /* CB_FOG_RED */ | ||
124 | 0x00000000, | 124 | 0x00000000, |
125 | 0x00000000, | 125 | 0x00000000, |
126 | 0x00000000, /* DB_STENCILREFMASK */ | ||
127 | 0x00000000, /* DB_STENCILREFMASK_BF */ | ||
128 | 0x00000000, /* SX_ALPHA_REF */ | ||
129 | |||
126 | 0xc0046900, | 130 | 0xc0046900, |
127 | 0x0000030c, | 131 | 0x0000030c, |
128 | 0x01000000, | 132 | 0x01000000, /* CB_CLRCMP_CNTL */ |
129 | 0x00000000, | 133 | 0x00000000, |
130 | 0x00000000, | 134 | 0x00000000, |
131 | 0x00000000, | 135 | 0x00000000, |
136 | |||
132 | 0xc0046900, | 137 | 0xc0046900, |
133 | 0x00000048, | 138 | 0x00000048, |
134 | 0x3f800000, | 139 | 0x3f800000, /* CB_CLEAR_RED */ |
135 | 0x00000000, | 140 | 0x00000000, |
136 | 0x3f800000, | 141 | 0x3f800000, |
137 | 0x3f800000, | 142 | 0x3f800000, |
138 | 0xc0016900, | 143 | |
139 | 0x0000008e, | ||
140 | 0x0000000f, | ||
141 | 0xc0016900, | 144 | 0xc0016900, |
142 | 0x00000080, | 145 | 0x00000080, |
143 | 0x00000000, | 146 | 0x00000000, /* PA_SC_WINDOW_OFFSET */ |
144 | 0xc0016900, | 147 | |
148 | 0xc00a6900, | ||
145 | 0x00000083, | 149 | 0x00000083, |
146 | 0x0000ffff, | 150 | 0x0000ffff, /* PA_SC_CLIP_RECT_RULE */ |
147 | 0xc0016900, | 151 | 0x00000000, /* PA_SC_CLIPRECT_0_TL */ |
148 | 0x00000084, | ||
149 | 0x00000000, | ||
150 | 0xc0016900, | ||
151 | 0x00000085, | ||
152 | 0x20002000, | 152 | 0x20002000, |
153 | 0xc0016900, | ||
154 | 0x00000086, | ||
155 | 0x00000000, | 153 | 0x00000000, |
156 | 0xc0016900, | ||
157 | 0x00000087, | ||
158 | 0x20002000, | 154 | 0x20002000, |
159 | 0xc0016900, | ||
160 | 0x00000088, | ||
161 | 0x00000000, | 155 | 0x00000000, |
162 | 0xc0016900, | ||
163 | 0x00000089, | ||
164 | 0x20002000, | 156 | 0x20002000, |
165 | 0xc0016900, | ||
166 | 0x0000008a, | ||
167 | 0x00000000, | 157 | 0x00000000, |
168 | 0xc0016900, | ||
169 | 0x0000008b, | ||
170 | 0x20002000, | 158 | 0x20002000, |
171 | 0xc0016900, | 159 | 0x00000000, /* PA_SC_EDGERULE */ |
172 | 0x0000008c, | 160 | |
173 | 0x00000000, | 161 | 0xc0406900, |
174 | 0xc0016900, | ||
175 | 0x00000094, | 162 | 0x00000094, |
176 | 0x80000000, | 163 | 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ |
177 | 0xc0016900, | 164 | 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ |
178 | 0x00000095, | 165 | 0x80000000, /* PA_SC_VPORT_SCISSOR_1_TL */ |
179 | 0x20002000, | 166 | 0x20002000, |
180 | 0xc0026900, | ||
181 | 0x000000b4, | ||
182 | 0x00000000, | ||
183 | 0x3f800000, | ||
184 | 0xc0016900, | ||
185 | 0x00000096, | ||
186 | 0x80000000, | 167 | 0x80000000, |
187 | 0xc0016900, | ||
188 | 0x00000097, | ||
189 | 0x20002000, | 168 | 0x20002000, |
190 | 0xc0026900, | ||
191 | 0x000000b6, | ||
192 | 0x00000000, | ||
193 | 0x3f800000, | ||
194 | 0xc0016900, | ||
195 | 0x00000098, | ||
196 | 0x80000000, | 169 | 0x80000000, |
197 | 0xc0016900, | ||
198 | 0x00000099, | ||
199 | 0x20002000, | 170 | 0x20002000, |
200 | 0xc0026900, | ||
201 | 0x000000b8, | ||
202 | 0x00000000, | ||
203 | 0x3f800000, | ||
204 | 0xc0016900, | ||
205 | 0x0000009a, | ||
206 | 0x80000000, | 171 | 0x80000000, |
207 | 0xc0016900, | ||
208 | 0x0000009b, | ||
209 | 0x20002000, | 172 | 0x20002000, |
210 | 0xc0026900, | ||
211 | 0x000000ba, | ||
212 | 0x00000000, | ||
213 | 0x3f800000, | ||
214 | 0xc0016900, | ||
215 | 0x0000009c, | ||
216 | 0x80000000, | 173 | 0x80000000, |
217 | 0xc0016900, | ||
218 | 0x0000009d, | ||
219 | 0x20002000, | 174 | 0x20002000, |
220 | 0xc0026900, | ||
221 | 0x000000bc, | ||
222 | 0x00000000, | ||
223 | 0x3f800000, | ||
224 | 0xc0016900, | ||
225 | 0x0000009e, | ||
226 | 0x80000000, | 175 | 0x80000000, |
227 | 0xc0016900, | ||
228 | 0x0000009f, | ||
229 | 0x20002000, | 176 | 0x20002000, |
230 | 0xc0026900, | ||
231 | 0x000000be, | ||
232 | 0x00000000, | ||
233 | 0x3f800000, | ||
234 | 0xc0016900, | ||
235 | 0x000000a0, | ||
236 | 0x80000000, | 177 | 0x80000000, |
237 | 0xc0016900, | ||
238 | 0x000000a1, | ||
239 | 0x20002000, | 178 | 0x20002000, |
240 | 0xc0026900, | ||
241 | 0x000000c0, | ||
242 | 0x00000000, | ||
243 | 0x3f800000, | ||
244 | 0xc0016900, | ||
245 | 0x000000a2, | ||
246 | 0x80000000, | 179 | 0x80000000, |
247 | 0xc0016900, | ||
248 | 0x000000a3, | ||
249 | 0x20002000, | 180 | 0x20002000, |
250 | 0xc0026900, | ||
251 | 0x000000c2, | ||
252 | 0x00000000, | ||
253 | 0x3f800000, | ||
254 | 0xc0016900, | ||
255 | 0x000000a4, | ||
256 | 0x80000000, | 181 | 0x80000000, |
257 | 0xc0016900, | ||
258 | 0x000000a5, | ||
259 | 0x20002000, | 182 | 0x20002000, |
260 | 0xc0026900, | ||
261 | 0x000000c4, | ||
262 | 0x00000000, | ||
263 | 0x3f800000, | ||
264 | 0xc0016900, | ||
265 | 0x000000a6, | ||
266 | 0x80000000, | 183 | 0x80000000, |
267 | 0xc0016900, | ||
268 | 0x000000a7, | ||
269 | 0x20002000, | 184 | 0x20002000, |
270 | 0xc0026900, | ||
271 | 0x000000c6, | ||
272 | 0x00000000, | ||
273 | 0x3f800000, | ||
274 | 0xc0016900, | ||
275 | 0x000000a8, | ||
276 | 0x80000000, | 185 | 0x80000000, |
277 | 0xc0016900, | ||
278 | 0x000000a9, | ||
279 | 0x20002000, | 186 | 0x20002000, |
280 | 0xc0026900, | ||
281 | 0x000000c8, | ||
282 | 0x00000000, | ||
283 | 0x3f800000, | ||
284 | 0xc0016900, | ||
285 | 0x000000aa, | ||
286 | 0x80000000, | 187 | 0x80000000, |
287 | 0xc0016900, | ||
288 | 0x000000ab, | ||
289 | 0x20002000, | 188 | 0x20002000, |
290 | 0xc0026900, | ||
291 | 0x000000ca, | ||
292 | 0x00000000, | ||
293 | 0x3f800000, | ||
294 | 0xc0016900, | ||
295 | 0x000000ac, | ||
296 | 0x80000000, | 189 | 0x80000000, |
297 | 0xc0016900, | ||
298 | 0x000000ad, | ||
299 | 0x20002000, | 190 | 0x20002000, |
300 | 0xc0026900, | ||
301 | 0x000000cc, | ||
302 | 0x00000000, | ||
303 | 0x3f800000, | ||
304 | 0xc0016900, | ||
305 | 0x000000ae, | ||
306 | 0x80000000, | 191 | 0x80000000, |
307 | 0xc0016900, | ||
308 | 0x000000af, | ||
309 | 0x20002000, | 192 | 0x20002000, |
310 | 0xc0026900, | ||
311 | 0x000000ce, | ||
312 | 0x00000000, | ||
313 | 0x3f800000, | ||
314 | 0xc0016900, | ||
315 | 0x000000b0, | ||
316 | 0x80000000, | 193 | 0x80000000, |
317 | 0xc0016900, | ||
318 | 0x000000b1, | ||
319 | 0x20002000, | 194 | 0x20002000, |
320 | 0xc0026900, | 195 | 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ |
321 | 0x000000d0, | ||
322 | 0x00000000, | ||
323 | 0x3f800000, | 196 | 0x3f800000, |
324 | 0xc0016900, | ||
325 | 0x000000b2, | ||
326 | 0x80000000, | ||
327 | 0xc0016900, | ||
328 | 0x000000b3, | ||
329 | 0x20002000, | ||
330 | 0xc0026900, | ||
331 | 0x000000d2, | ||
332 | 0x00000000, | 197 | 0x00000000, |
333 | 0x3f800000, | 198 | 0x3f800000, |
334 | 0xc0016900, | ||
335 | 0x00000293, | ||
336 | 0x00004010, | ||
337 | 0xc0016900, | ||
338 | 0x00000300, | ||
339 | 0x00000000, | 199 | 0x00000000, |
340 | 0xc0016900, | 200 | 0x3f800000, |
341 | 0x00000301, | ||
342 | 0x00000000, | ||
343 | 0xc0016900, | ||
344 | 0x00000312, | ||
345 | 0xffffffff, | ||
346 | 0xc0016900, | ||
347 | 0x00000307, | ||
348 | 0x00000000, | 201 | 0x00000000, |
349 | 0xc0016900, | 202 | 0x3f800000, |
350 | 0x00000308, | ||
351 | 0x00000000, | 203 | 0x00000000, |
352 | 0xc0016900, | 204 | 0x3f800000, |
353 | 0x00000283, | ||
354 | 0x00000000, | 205 | 0x00000000, |
355 | 0xc0016900, | 206 | 0x3f800000, |
356 | 0x00000292, | ||
357 | 0x00000000, | 207 | 0x00000000, |
358 | 0xc0066900, | 208 | 0x3f800000, |
359 | 0x0000010f, | ||
360 | 0x00000000, | 209 | 0x00000000, |
210 | 0x3f800000, | ||
361 | 0x00000000, | 211 | 0x00000000, |
212 | 0x3f800000, | ||
362 | 0x00000000, | 213 | 0x00000000, |
214 | 0x3f800000, | ||
363 | 0x00000000, | 215 | 0x00000000, |
216 | 0x3f800000, | ||
364 | 0x00000000, | 217 | 0x00000000, |
218 | 0x3f800000, | ||
365 | 0x00000000, | 219 | 0x00000000, |
366 | 0xc0016900, | 220 | 0x3f800000, |
367 | 0x00000206, | ||
368 | 0x00000000, | 221 | 0x00000000, |
369 | 0xc0016900, | 222 | 0x3f800000, |
370 | 0x00000207, | ||
371 | 0x00000000, | 223 | 0x00000000, |
372 | 0xc0016900, | 224 | 0x3f800000, |
373 | 0x00000208, | ||
374 | 0x00000000, | 225 | 0x00000000, |
375 | 0xc0046900, | ||
376 | 0x00000303, | ||
377 | 0x3f800000, | 226 | 0x3f800000, |
227 | |||
228 | 0xc0026900, | ||
229 | 0x00000292, | ||
230 | 0x00000000, /* PA_SC_MPASS_PS_CNTL */ | ||
231 | 0x00004010, /* PA_SC_MODE_CNTL */ | ||
232 | |||
233 | 0xc0096900, | ||
234 | 0x00000300, | ||
235 | 0x00000000, /* PA_SC_LINE_CNTL */ | ||
236 | 0x00000000, /* PA_SC_AA_CONFIG */ | ||
237 | 0x0000002d, /* PA_SU_VTX_CNTL */ | ||
238 | 0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ | ||
378 | 0x3f800000, | 239 | 0x3f800000, |
379 | 0x3f800000, | 240 | 0x3f800000, |
380 | 0x3f800000, | 241 | 0x3f800000, |
381 | 0xc0016900, | 242 | 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ |
382 | 0x00000205, | ||
383 | 0x00000004, | ||
384 | 0xc0016900, | ||
385 | 0x00000280, | ||
386 | 0x00000000, | ||
387 | 0xc0016900, | ||
388 | 0x00000281, | ||
389 | 0x00000000, | 243 | 0x00000000, |
244 | |||
390 | 0xc0016900, | 245 | 0xc0016900, |
246 | 0x00000312, | ||
247 | 0xffffffff, /* PA_SC_AA_MASK */ | ||
248 | |||
249 | 0xc0066900, | ||
391 | 0x0000037e, | 250 | 0x0000037e, |
392 | 0x00000000, | 251 | 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ |
393 | 0xc0016900, | 252 | 0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */ |
394 | 0x00000382, | 253 | 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_SCALE */ |
395 | 0x00000000, | 254 | 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_OFFSET */ |
396 | 0xc0016900, | 255 | 0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */ |
397 | 0x00000380, | 256 | 0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */ |
398 | 0x00000000, | 257 | |
399 | 0xc0016900, | 258 | 0xc0046900, |
400 | 0x00000383, | ||
401 | 0x00000000, | ||
402 | 0xc0016900, | ||
403 | 0x00000381, | ||
404 | 0x00000000, | ||
405 | 0xc0016900, | ||
406 | 0x00000282, | ||
407 | 0x00000008, | ||
408 | 0xc0016900, | ||
409 | 0x00000302, | ||
410 | 0x0000002d, | ||
411 | 0xc0016900, | ||
412 | 0x0000037f, | ||
413 | 0x00000000, | ||
414 | 0xc0016900, | ||
415 | 0x000001b2, | ||
416 | 0x00000000, | ||
417 | 0xc0016900, | ||
418 | 0x000001b6, | 259 | 0x000001b6, |
419 | 0x00000000, | 260 | 0x00000000, /* SPI_INPUT_Z */ |
420 | 0xc0016900, | 261 | 0x00000000, /* SPI_FOG_CNTL */ |
421 | 0x000001b7, | 262 | 0x00000000, /* SPI_FOG_FUNC_SCALE */ |
422 | 0x00000000, | 263 | 0x00000000, /* SPI_FOG_FUNC_BIAS */ |
423 | 0xc0016900, | 264 | |
424 | 0x000001b8, | ||
425 | 0x00000000, | ||
426 | 0xc0016900, | ||
427 | 0x000001b9, | ||
428 | 0x00000000, | ||
429 | 0xc0016900, | 265 | 0xc0016900, |
430 | 0x00000225, | 266 | 0x00000225, |
431 | 0x00000000, | 267 | 0x00000000, /* SQ_PGM_START_FS */ |
268 | |||
432 | 0xc0016900, | 269 | 0xc0016900, |
433 | 0x00000229, | 270 | 0x00000229, |
434 | 0x00000000, | 271 | 0x00000000, /* SQ_PGM_RESOURCES_FS */ |
272 | |||
435 | 0xc0016900, | 273 | 0xc0016900, |
436 | 0x00000237, | 274 | 0x00000237, |
437 | 0x00000000, | 275 | 0x00000000, /* SQ_PGM_CF_OFFSET_FS */ |
438 | 0xc0016900, | 276 | |
439 | 0x00000100, | 277 | 0xc0026900, |
440 | 0x00000800, | ||
441 | 0xc0016900, | ||
442 | 0x00000101, | ||
443 | 0x00000000, | ||
444 | 0xc0016900, | ||
445 | 0x00000102, | ||
446 | 0x00000000, | ||
447 | 0xc0016900, | ||
448 | 0x000002a8, | 278 | 0x000002a8, |
449 | 0x00000000, | 279 | 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ |
450 | 0xc0016900, | 280 | 0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */ |
451 | 0x000002a9, | 281 | |
452 | 0x00000000, | 282 | 0xc0116900, |
453 | 0xc0016900, | 283 | 0x00000280, |
454 | 0x00000103, | 284 | 0x00000000, /* PA_SU_POINT_SIZE */ |
455 | 0x00000000, | 285 | 0x00000000, /* PA_SU_POINT_MINMAX */ |
456 | 0xc0016900, | 286 | 0x00000008, /* PA_SU_LINE_CNTL */ |
457 | 0x00000284, | 287 | 0x00000000, /* PA_SC_LINE_STIPPLE */ |
458 | 0x00000000, | 288 | 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ |
459 | 0xc0016900, | 289 | 0x00000000, /* VGT_HOS_CNTL */ |
460 | 0x00000290, | 290 | 0x00000000, /* VGT_HOS_MAX_TESS_LEVEL */ |
461 | 0x00000000, | 291 | 0x00000000, /* VGT_HOS_MIN_TESS_LEVEL */ |
462 | 0xc0016900, | 292 | 0x00000000, /* VGT_HOS_REUSE_DEPTH */ |
463 | 0x00000285, | 293 | 0x00000000, /* VGT_GROUP_PRIM_TYPE */ |
464 | 0x00000000, | 294 | 0x00000000, /* VGT_GROUP_FIRST_DECR */ |
465 | 0xc0016900, | 295 | 0x00000000, /* VGT_GROUP_DECR */ |
466 | 0x00000286, | 296 | 0x00000000, /* VGT_GROUP_VECT_0_CNTL */ |
467 | 0x00000000, | 297 | 0x00000000, /* VGT_GROUP_VECT_1_CNTL */ |
468 | 0xc0016900, | 298 | 0x00000000, /* VGT_GROUP_VECT_0_FMT_CNTL */ |
469 | 0x00000287, | 299 | 0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */ |
470 | 0x00000000, | 300 | 0x00000000, /* VGT_GS_MODE */ |
471 | 0xc0016900, | 301 | |
472 | 0x00000288, | ||
473 | 0x00000000, | ||
474 | 0xc0016900, | ||
475 | 0x00000289, | ||
476 | 0x00000000, | ||
477 | 0xc0016900, | ||
478 | 0x0000028a, | ||
479 | 0x00000000, | ||
480 | 0xc0016900, | ||
481 | 0x0000028b, | ||
482 | 0x00000000, | ||
483 | 0xc0016900, | ||
484 | 0x0000028c, | ||
485 | 0x00000000, | ||
486 | 0xc0016900, | ||
487 | 0x0000028d, | ||
488 | 0x00000000, | ||
489 | 0xc0016900, | ||
490 | 0x0000028e, | ||
491 | 0x00000000, | ||
492 | 0xc0016900, | ||
493 | 0x0000028f, | ||
494 | 0x00000000, | ||
495 | 0xc0016900, | 302 | 0xc0016900, |
496 | 0x000002a1, | 303 | 0x000002a1, |
497 | 0x00000000, | 304 | 0x00000000, /* VGT_PRIMITIVEID_EN */ |
305 | |||
498 | 0xc0016900, | 306 | 0xc0016900, |
499 | 0x000002a5, | 307 | 0x000002a5, |
500 | 0x00000000, | 308 | 0x00000000, /* VGT_MULTI_PRIM_ID_RESET_EN */ |
501 | 0xc0016900, | 309 | |
310 | 0xc0036900, | ||
502 | 0x000002ac, | 311 | 0x000002ac, |
503 | 0x00000000, | 312 | 0x00000000, /* VGT_STRMOUT_EN */ |
504 | 0xc0016900, | 313 | 0x00000000, /* VGT_REUSE_OFF */ |
505 | 0x000002ad, | 314 | 0x00000000, /* VGT_VTX_CNT_EN */ |
506 | 0x00000000, | 315 | |
507 | 0xc0016900, | ||
508 | 0x000002ae, | ||
509 | 0x00000000, | ||
510 | 0xc0016900, | 316 | 0xc0016900, |
511 | 0x000002c8, | 317 | 0x000002c8, |
512 | 0x00000000, | 318 | 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ |
513 | 0xc0016900, | 319 | |
514 | 0x00000206, | 320 | 0xc0076900, |
515 | 0x00000100, | ||
516 | 0xc0016900, | ||
517 | 0x00000204, | ||
518 | 0x00010000, | ||
519 | 0xc0036e00, | ||
520 | 0x00000000, | ||
521 | 0x00000012, | ||
522 | 0x00000000, | ||
523 | 0x00000000, | ||
524 | 0xc0016900, | ||
525 | 0x0000008f, | ||
526 | 0x0000000f, | ||
527 | 0xc0016900, | ||
528 | 0x000001e8, | ||
529 | 0x00000001, | ||
530 | 0xc0016900, | ||
531 | 0x00000202, | 321 | 0x00000202, |
532 | 0x00cc0000, | 322 | 0x00cc0000, /* CB_COLOR_CONTROL */ |
323 | 0x00000210, /* DB_SHADER_CNTL */ | ||
324 | 0x00010000, /* PA_CL_CLIP_CNTL */ | ||
325 | 0x00000244, /* PA_SU_SC_MODE_CNTL */ | ||
326 | 0x00000100, /* PA_CL_VTE_CNTL */ | ||
327 | 0x00000000, /* PA_CL_VS_OUT_CNTL */ | ||
328 | 0x00000000, /* PA_CL_NANINF_CNTL */ | ||
329 | |||
330 | 0xc0026900, | ||
331 | 0x0000008e, | ||
332 | 0x0000000f, /* CB_TARGET_MASK */ | ||
333 | 0x0000000f, /* CB_SHADER_MASK */ | ||
334 | |||
533 | 0xc0016900, | 335 | 0xc0016900, |
534 | 0x00000205, | 336 | 0x000001e8, |
535 | 0x00000244, | 337 | 0x00000001, /* CB_SHADER_CONTROL */ |
338 | |||
536 | 0xc0016900, | 339 | 0xc0016900, |
537 | 0x00000203, | 340 | 0x00000185, |
538 | 0x00000210, | 341 | 0x00000000, /* SPI_VS_OUT_ID_0 */ |
342 | |||
539 | 0xc0016900, | 343 | 0xc0016900, |
344 | 0x00000191, | ||
345 | 0x00000b00, /* SPI_PS_INPUT_CNTL_0 */ | ||
346 | |||
347 | 0xc0056900, | ||
540 | 0x000001b1, | 348 | 0x000001b1, |
349 | 0x00000000, /* SPI_VS_OUT_CONFIG */ | ||
350 | 0x00000000, /* SPI_THREAD_GROUPING */ | ||
351 | 0x00000001, /* SPI_PS_IN_CONTROL_0 */ | ||
352 | 0x00000000, /* SPI_PS_IN_CONTROL_1 */ | ||
353 | 0x00000000, /* SPI_INTERP_CONTROL_0 */ | ||
354 | |||
355 | 0xc0036e00, /* SET_SAMPLER */ | ||
541 | 0x00000000, | 356 | 0x00000000, |
542 | 0xc0016900, | 357 | 0x00000012, |
543 | 0x00000185, | ||
544 | 0x00000000, | ||
545 | 0xc0016900, | ||
546 | 0x000001b3, | ||
547 | 0x00000001, | ||
548 | 0xc0016900, | ||
549 | 0x000001b4, | ||
550 | 0x00000000, | 358 | 0x00000000, |
551 | 0xc0016900, | ||
552 | 0x00000191, | ||
553 | 0x00000b00, | ||
554 | 0xc0016900, | ||
555 | 0x000001b5, | ||
556 | 0x00000000, | 359 | 0x00000000, |
557 | }; | 360 | }; |
558 | 361 | ||
559 | const u32 r7xx_default_state[] = | 362 | const u32 r7xx_default_state[] = |
560 | { | 363 | { |
561 | 0xc0012800, | 364 | 0xc0012800, /* CONTEXT_CONTROL */ |
562 | 0x80000000, | 365 | 0x80000000, |
563 | 0x80000000, | 366 | 0x80000000, |
367 | |||
564 | 0xc0016800, | 368 | 0xc0016800, |
565 | 0x00000010, | 369 | 0x00000010, |
566 | 0x00008000, | 370 | 0x00008000, /* WAIT_UNTIL */ |
371 | |||
567 | 0xc0016800, | 372 | 0xc0016800, |
568 | 0x00000542, | 373 | 0x00000542, |
569 | 0x07000002, | 374 | 0x07000002, /* TA_CNTL_AUX */ |
375 | |||
570 | 0xc0016800, | 376 | 0xc0016800, |
571 | 0x000005c5, | 377 | 0x000005c5, |
572 | 0x00000000, | 378 | 0x00000000, /* VC_ENHANCE */ |
379 | |||
573 | 0xc0016800, | 380 | 0xc0016800, |
574 | 0x00000363, | 381 | 0x00000363, |
575 | 0x00004000, | 382 | 0x00004000, /* SQ_DYN_GPR_CNTL_PS_FLUSH_REQ */ |
383 | |||
576 | 0xc0016800, | 384 | 0xc0016800, |
577 | 0x0000060c, | 385 | 0x0000060c, |
578 | 0x00000000, | 386 | 0x00000000, /* DB_DEBUG */ |
387 | |||
579 | 0xc0016800, | 388 | 0xc0016800, |
580 | 0x0000060e, | 389 | 0x0000060e, |
581 | 0x00420204, | 390 | 0x00420204, /* DB_WATERMARKS */ |
582 | 0xc0016f00, | 391 | |
583 | 0x00000000, | 392 | 0xc0026f00, |
584 | 0x00000000, | ||
585 | 0xc0016f00, | ||
586 | 0x00000001, | ||
587 | 0x00000000, | 393 | 0x00000000, |
394 | 0x00000000, /* SQ_VTX_BASE_VTX_LOC */ | ||
395 | 0x00000000, /* SQ_VTX_START_INST_LOC */ | ||
396 | |||
588 | 0xc0096900, | 397 | 0xc0096900, |
589 | 0x0000022a, | 398 | 0x0000022a, |
399 | 0x00000000, /* SQ_ESGS_RING_ITEMSIZE */ | ||
590 | 0x00000000, | 400 | 0x00000000, |
591 | 0x00000000, | 401 | 0x00000000, |
592 | 0x00000000, | 402 | 0x00000000, |
@@ -595,470 +405,269 @@ const u32 r7xx_default_state[] = | |||
595 | 0x00000000, | 405 | 0x00000000, |
596 | 0x00000000, | 406 | 0x00000000, |
597 | 0x00000000, | 407 | 0x00000000, |
598 | 0x00000000, | 408 | |
599 | 0xc0016900, | 409 | 0xc0016900, |
600 | 0x00000004, | 410 | 0x00000004, |
601 | 0x00000000, | 411 | 0x00000000, /* DB_DEPTH_INFO */ |
602 | 0xc0016900, | 412 | |
413 | 0xc0026900, | ||
603 | 0x0000000a, | 414 | 0x0000000a, |
604 | 0x00000000, | 415 | 0x00000000, /* DB_STENCIL_CLEAR */ |
605 | 0xc0016900, | 416 | 0x00000000, /* DB_DEPTH_CLEAR */ |
606 | 0x0000000b, | 417 | |
607 | 0x00000000, | ||
608 | 0xc0016900, | ||
609 | 0x0000010c, | ||
610 | 0x00000000, | ||
611 | 0xc0016900, | ||
612 | 0x0000010d, | ||
613 | 0x00000000, | ||
614 | 0xc0016900, | 418 | 0xc0016900, |
615 | 0x00000200, | 419 | 0x00000200, |
616 | 0x00000000, | 420 | 0x00000000, /* DB_DEPTH_CONTROL */ |
617 | 0xc0016900, | 421 | |
422 | 0xc0026900, | ||
618 | 0x00000343, | 423 | 0x00000343, |
619 | 0x00000060, | 424 | 0x00000060, /* DB_RENDER_CONTROL */ |
620 | 0xc0016900, | 425 | 0x00000000, /* DB_RENDER_OVERRIDE */ |
621 | 0x00000344, | 426 | |
622 | 0x00000000, | ||
623 | 0xc0016900, | 427 | 0xc0016900, |
624 | 0x00000351, | 428 | 0x00000351, |
625 | 0x0000aa00, | 429 | 0x0000aa00, /* DB_ALPHA_TO_MASK */ |
626 | 0xc0016900, | 430 | |
627 | 0x00000104, | 431 | 0xc0096900, |
628 | 0x00000000, | 432 | 0x00000100, |
629 | 0xc0016900, | 433 | 0x00000800, /* VGT_MAX_VTX_INDX */ |
630 | 0x0000010e, | 434 | 0x00000000, /* VGT_MIN_VTX_INDX */ |
631 | 0x00000000, | 435 | 0x00000000, /* VGT_INDX_OFFSET */ |
632 | 0xc0046900, | 436 | 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ |
633 | 0x00000105, | 437 | 0x00000000, /* SX_ALPHA_TEST_CONTROL */ |
634 | 0x00000000, | 438 | 0x00000000, /* CB_BLEND_RED */ |
635 | 0x00000000, | 439 | 0x00000000, |
636 | 0x00000000, | 440 | 0x00000000, |
637 | 0x00000000, | 441 | 0x00000000, |
442 | |||
443 | 0xc0036900, | ||
444 | 0x0000010c, | ||
445 | 0x00000000, /* DB_STENCILREFMASK */ | ||
446 | 0x00000000, /* DB_STENCILREFMASK_BF */ | ||
447 | 0x00000000, /* SX_ALPHA_REF */ | ||
448 | |||
638 | 0xc0046900, | 449 | 0xc0046900, |
639 | 0x0000030c, | 450 | 0x0000030c, /* CB_CLRCMP_CNTL */ |
640 | 0x01000000, | 451 | 0x01000000, |
641 | 0x00000000, | 452 | 0x00000000, |
642 | 0x00000000, | 453 | 0x00000000, |
643 | 0x00000000, | 454 | 0x00000000, |
644 | 0xc0016900, | 455 | |
645 | 0x0000008e, | ||
646 | 0x0000000f, | ||
647 | 0xc0016900, | 456 | 0xc0016900, |
648 | 0x00000080, | 457 | 0x00000080, |
649 | 0x00000000, | 458 | 0x00000000, /* PA_SC_WINDOW_OFFSET */ |
650 | 0xc0016900, | 459 | |
460 | 0xc00a6900, | ||
651 | 0x00000083, | 461 | 0x00000083, |
652 | 0x0000ffff, | 462 | 0x0000ffff, /* PA_SC_CLIP_RECT_RULE */ |
653 | 0xc0016900, | 463 | 0x00000000, /* PA_SC_CLIPRECT_0_TL */ |
654 | 0x00000084, | ||
655 | 0x00000000, | ||
656 | 0xc0016900, | ||
657 | 0x00000085, | ||
658 | 0x20002000, | 464 | 0x20002000, |
659 | 0xc0016900, | ||
660 | 0x00000086, | ||
661 | 0x00000000, | 465 | 0x00000000, |
662 | 0xc0016900, | ||
663 | 0x00000087, | ||
664 | 0x20002000, | 466 | 0x20002000, |
665 | 0xc0016900, | ||
666 | 0x00000088, | ||
667 | 0x00000000, | 467 | 0x00000000, |
668 | 0xc0016900, | ||
669 | 0x00000089, | ||
670 | 0x20002000, | 468 | 0x20002000, |
671 | 0xc0016900, | ||
672 | 0x0000008a, | ||
673 | 0x00000000, | 469 | 0x00000000, |
674 | 0xc0016900, | ||
675 | 0x0000008b, | ||
676 | 0x20002000, | 470 | 0x20002000, |
677 | 0xc0016900, | 471 | 0xaaaaaaaa, /* PA_SC_EDGERULE */ |
678 | 0x0000008c, | 472 | |
679 | 0xaaaaaaaa, | 473 | 0xc0406900, |
680 | 0xc0016900, | ||
681 | 0x00000094, | 474 | 0x00000094, |
682 | 0x80000000, | 475 | 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ |
683 | 0xc0016900, | 476 | 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ |
684 | 0x00000095, | 477 | 0x80000000, /* PA_SC_VPORT_SCISSOR_1_TL */ |
685 | 0x20002000, | 478 | 0x20002000, |
686 | 0xc0026900, | ||
687 | 0x000000b4, | ||
688 | 0x00000000, | ||
689 | 0x3f800000, | ||
690 | 0xc0016900, | ||
691 | 0x00000096, | ||
692 | 0x80000000, | 479 | 0x80000000, |
693 | 0xc0016900, | ||
694 | 0x00000097, | ||
695 | 0x20002000, | 480 | 0x20002000, |
696 | 0xc0026900, | ||
697 | 0x000000b6, | ||
698 | 0x00000000, | ||
699 | 0x3f800000, | ||
700 | 0xc0016900, | ||
701 | 0x00000098, | ||
702 | 0x80000000, | 481 | 0x80000000, |
703 | 0xc0016900, | ||
704 | 0x00000099, | ||
705 | 0x20002000, | 482 | 0x20002000, |
706 | 0xc0026900, | ||
707 | 0x000000b8, | ||
708 | 0x00000000, | ||
709 | 0x3f800000, | ||
710 | 0xc0016900, | ||
711 | 0x0000009a, | ||
712 | 0x80000000, | 483 | 0x80000000, |
713 | 0xc0016900, | ||
714 | 0x0000009b, | ||
715 | 0x20002000, | 484 | 0x20002000, |
716 | 0xc0026900, | ||
717 | 0x000000ba, | ||
718 | 0x00000000, | ||
719 | 0x3f800000, | ||
720 | 0xc0016900, | ||
721 | 0x0000009c, | ||
722 | 0x80000000, | 485 | 0x80000000, |
723 | 0xc0016900, | ||
724 | 0x0000009d, | ||
725 | 0x20002000, | 486 | 0x20002000, |
726 | 0xc0026900, | ||
727 | 0x000000bc, | ||
728 | 0x00000000, | ||
729 | 0x3f800000, | ||
730 | 0xc0016900, | ||
731 | 0x0000009e, | ||
732 | 0x80000000, | 487 | 0x80000000, |
733 | 0xc0016900, | ||
734 | 0x0000009f, | ||
735 | 0x20002000, | 488 | 0x20002000, |
736 | 0xc0026900, | ||
737 | 0x000000be, | ||
738 | 0x00000000, | ||
739 | 0x3f800000, | ||
740 | 0xc0016900, | ||
741 | 0x000000a0, | ||
742 | 0x80000000, | 489 | 0x80000000, |
743 | 0xc0016900, | ||
744 | 0x000000a1, | ||
745 | 0x20002000, | 490 | 0x20002000, |
746 | 0xc0026900, | ||
747 | 0x000000c0, | ||
748 | 0x00000000, | ||
749 | 0x3f800000, | ||
750 | 0xc0016900, | ||
751 | 0x000000a2, | ||
752 | 0x80000000, | 491 | 0x80000000, |
753 | 0xc0016900, | ||
754 | 0x000000a3, | ||
755 | 0x20002000, | 492 | 0x20002000, |
756 | 0xc0026900, | ||
757 | 0x000000c2, | ||
758 | 0x00000000, | ||
759 | 0x3f800000, | ||
760 | 0xc0016900, | ||
761 | 0x000000a4, | ||
762 | 0x80000000, | 493 | 0x80000000, |
763 | 0xc0016900, | ||
764 | 0x000000a5, | ||
765 | 0x20002000, | 494 | 0x20002000, |
766 | 0xc0026900, | ||
767 | 0x000000c4, | ||
768 | 0x00000000, | ||
769 | 0x3f800000, | ||
770 | 0xc0016900, | ||
771 | 0x000000a6, | ||
772 | 0x80000000, | 495 | 0x80000000, |
773 | 0xc0016900, | ||
774 | 0x000000a7, | ||
775 | 0x20002000, | 496 | 0x20002000, |
776 | 0xc0026900, | ||
777 | 0x000000c6, | ||
778 | 0x00000000, | ||
779 | 0x3f800000, | ||
780 | 0xc0016900, | ||
781 | 0x000000a8, | ||
782 | 0x80000000, | 497 | 0x80000000, |
783 | 0xc0016900, | ||
784 | 0x000000a9, | ||
785 | 0x20002000, | 498 | 0x20002000, |
786 | 0xc0026900, | ||
787 | 0x000000c8, | ||
788 | 0x00000000, | ||
789 | 0x3f800000, | ||
790 | 0xc0016900, | ||
791 | 0x000000aa, | ||
792 | 0x80000000, | 499 | 0x80000000, |
793 | 0xc0016900, | ||
794 | 0x000000ab, | ||
795 | 0x20002000, | 500 | 0x20002000, |
796 | 0xc0026900, | ||
797 | 0x000000ca, | ||
798 | 0x00000000, | ||
799 | 0x3f800000, | ||
800 | 0xc0016900, | ||
801 | 0x000000ac, | ||
802 | 0x80000000, | 501 | 0x80000000, |
803 | 0xc0016900, | ||
804 | 0x000000ad, | ||
805 | 0x20002000, | 502 | 0x20002000, |
806 | 0xc0026900, | ||
807 | 0x000000cc, | ||
808 | 0x00000000, | ||
809 | 0x3f800000, | ||
810 | 0xc0016900, | ||
811 | 0x000000ae, | ||
812 | 0x80000000, | 503 | 0x80000000, |
813 | 0xc0016900, | ||
814 | 0x000000af, | ||
815 | 0x20002000, | 504 | 0x20002000, |
816 | 0xc0026900, | ||
817 | 0x000000ce, | ||
818 | 0x00000000, | ||
819 | 0x3f800000, | ||
820 | 0xc0016900, | ||
821 | 0x000000b0, | ||
822 | 0x80000000, | 505 | 0x80000000, |
823 | 0xc0016900, | ||
824 | 0x000000b1, | ||
825 | 0x20002000, | 506 | 0x20002000, |
826 | 0xc0026900, | 507 | 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ |
827 | 0x000000d0, | ||
828 | 0x00000000, | ||
829 | 0x3f800000, | 508 | 0x3f800000, |
830 | 0xc0016900, | ||
831 | 0x000000b2, | ||
832 | 0x80000000, | ||
833 | 0xc0016900, | ||
834 | 0x000000b3, | ||
835 | 0x20002000, | ||
836 | 0xc0026900, | ||
837 | 0x000000d2, | ||
838 | 0x00000000, | 509 | 0x00000000, |
839 | 0x3f800000, | 510 | 0x3f800000, |
840 | 0xc0016900, | ||
841 | 0x00000293, | ||
842 | 0x00514000, | ||
843 | 0xc0016900, | ||
844 | 0x00000300, | ||
845 | 0x00000000, | ||
846 | 0xc0016900, | ||
847 | 0x00000301, | ||
848 | 0x00000000, | 511 | 0x00000000, |
849 | 0xc0016900, | 512 | 0x3f800000, |
850 | 0x00000312, | ||
851 | 0xffffffff, | ||
852 | 0xc0016900, | ||
853 | 0x00000307, | ||
854 | 0x00000000, | 513 | 0x00000000, |
855 | 0xc0016900, | 514 | 0x3f800000, |
856 | 0x00000308, | ||
857 | 0x00000000, | 515 | 0x00000000, |
858 | 0xc0016900, | 516 | 0x3f800000, |
859 | 0x00000283, | ||
860 | 0x00000000, | 517 | 0x00000000, |
861 | 0xc0016900, | 518 | 0x3f800000, |
862 | 0x00000292, | ||
863 | 0x00000000, | 519 | 0x00000000, |
864 | 0xc0066900, | 520 | 0x3f800000, |
865 | 0x0000010f, | ||
866 | 0x00000000, | 521 | 0x00000000, |
522 | 0x3f800000, | ||
867 | 0x00000000, | 523 | 0x00000000, |
524 | 0x3f800000, | ||
868 | 0x00000000, | 525 | 0x00000000, |
526 | 0x3f800000, | ||
869 | 0x00000000, | 527 | 0x00000000, |
528 | 0x3f800000, | ||
870 | 0x00000000, | 529 | 0x00000000, |
530 | 0x3f800000, | ||
871 | 0x00000000, | 531 | 0x00000000, |
872 | 0xc0016900, | 532 | 0x3f800000, |
873 | 0x00000206, | ||
874 | 0x00000000, | 533 | 0x00000000, |
875 | 0xc0016900, | 534 | 0x3f800000, |
876 | 0x00000207, | ||
877 | 0x00000000, | 535 | 0x00000000, |
878 | 0xc0016900, | 536 | 0x3f800000, |
879 | 0x00000208, | ||
880 | 0x00000000, | 537 | 0x00000000, |
881 | 0xc0046900, | ||
882 | 0x00000303, | ||
883 | 0x3f800000, | 538 | 0x3f800000, |
539 | |||
540 | 0xc0026900, | ||
541 | 0x00000292, | ||
542 | 0x00000000, /* PA_SC_MPASS_PS_CNTL */ | ||
543 | 0x00514000, /* PA_SC_MODE_CNTL */ | ||
544 | |||
545 | 0xc0096900, | ||
546 | 0x00000300, | ||
547 | 0x00000000, /* PA_SC_LINE_CNTL */ | ||
548 | 0x00000000, /* PA_SC_AA_CONFIG */ | ||
549 | 0x0000002d, /* PA_SU_VTX_CNTL */ | ||
550 | 0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ | ||
884 | 0x3f800000, | 551 | 0x3f800000, |
885 | 0x3f800000, | 552 | 0x3f800000, |
886 | 0x3f800000, | 553 | 0x3f800000, |
887 | 0xc0016900, | 554 | 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ |
888 | 0x00000205, | ||
889 | 0x00000004, | ||
890 | 0xc0016900, | ||
891 | 0x00000280, | ||
892 | 0x00000000, | ||
893 | 0xc0016900, | ||
894 | 0x00000281, | ||
895 | 0x00000000, | 555 | 0x00000000, |
556 | |||
896 | 0xc0016900, | 557 | 0xc0016900, |
558 | 0x00000312, | ||
559 | 0xffffffff, /* PA_SC_AA_MASK */ | ||
560 | |||
561 | 0xc0066900, | ||
897 | 0x0000037e, | 562 | 0x0000037e, |
898 | 0x00000000, | 563 | 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ |
899 | 0xc0016900, | 564 | 0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */ |
900 | 0x00000382, | 565 | 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_SCALE */ |
901 | 0x00000000, | 566 | 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_OFFSET */ |
902 | 0xc0016900, | 567 | 0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */ |
903 | 0x00000380, | 568 | 0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */ |
904 | 0x00000000, | 569 | |
905 | 0xc0016900, | 570 | 0xc0046900, |
906 | 0x00000383, | ||
907 | 0x00000000, | ||
908 | 0xc0016900, | ||
909 | 0x00000381, | ||
910 | 0x00000000, | ||
911 | 0xc0016900, | ||
912 | 0x00000282, | ||
913 | 0x00000008, | ||
914 | 0xc0016900, | ||
915 | 0x00000302, | ||
916 | 0x0000002d, | ||
917 | 0xc0016900, | ||
918 | 0x0000037f, | ||
919 | 0x00000000, | ||
920 | 0xc0016900, | ||
921 | 0x000001b2, | ||
922 | 0x00000001, | ||
923 | 0xc0016900, | ||
924 | 0x000001b6, | 571 | 0x000001b6, |
925 | 0x00000000, | 572 | 0x00000000, /* SPI_INPUT_Z */ |
926 | 0xc0016900, | 573 | 0x00000000, /* SPI_FOG_CNTL */ |
927 | 0x000001b7, | 574 | 0x00000000, /* SPI_FOG_FUNC_SCALE */ |
928 | 0x00000000, | 575 | 0x00000000, /* SPI_FOG_FUNC_BIAS */ |
929 | 0xc0016900, | 576 | |
930 | 0x000001b8, | ||
931 | 0x00000000, | ||
932 | 0xc0016900, | ||
933 | 0x000001b9, | ||
934 | 0x00000000, | ||
935 | 0xc0016900, | 577 | 0xc0016900, |
936 | 0x00000225, | 578 | 0x00000225, |
937 | 0x00000000, | 579 | 0x00000000, /* SQ_PGM_START_FS */ |
580 | |||
938 | 0xc0016900, | 581 | 0xc0016900, |
939 | 0x00000229, | 582 | 0x00000229, |
940 | 0x00000000, | 583 | 0x00000000, /* SQ_PGM_RESOURCES_FS */ |
584 | |||
941 | 0xc0016900, | 585 | 0xc0016900, |
942 | 0x00000237, | 586 | 0x00000237, |
943 | 0x00000000, | 587 | 0x00000000, /* SQ_PGM_CF_OFFSET_FS */ |
944 | 0xc0016900, | 588 | |
945 | 0x00000100, | 589 | 0xc0026900, |
946 | 0x00000800, | ||
947 | 0xc0016900, | ||
948 | 0x00000101, | ||
949 | 0x00000000, | ||
950 | 0xc0016900, | ||
951 | 0x00000102, | ||
952 | 0x00000000, | ||
953 | 0xc0016900, | ||
954 | 0x000002a8, | 590 | 0x000002a8, |
955 | 0x00000000, | 591 | 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ |
956 | 0xc0016900, | 592 | 0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */ |
957 | 0x000002a9, | 593 | |
958 | 0x00000000, | 594 | 0xc0116900, |
959 | 0xc0016900, | 595 | 0x00000280, |
960 | 0x00000103, | 596 | 0x00000000, /* PA_SU_POINT_SIZE */ |
961 | 0x00000000, | 597 | 0x00000000, /* PA_SU_POINT_MINMAX */ |
962 | 0xc0016900, | 598 | 0x00000008, /* PA_SU_LINE_CNTL */ |
963 | 0x00000284, | 599 | 0x00000000, /* PA_SC_LINE_STIPPLE */ |
964 | 0x00000000, | 600 | 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ |
965 | 0xc0016900, | 601 | 0x00000000, /* VGT_HOS_CNTL */ |
966 | 0x00000290, | 602 | 0x00000000, /* VGT_HOS_MAX_TESS_LEVEL */ |
967 | 0x00000000, | 603 | 0x00000000, /* VGT_HOS_MIN_TESS_LEVEL */ |
968 | 0xc0016900, | 604 | 0x00000000, /* VGT_HOS_REUSE_DEPTH */ |
969 | 0x00000285, | 605 | 0x00000000, /* VGT_GROUP_PRIM_TYPE */ |
970 | 0x00000000, | 606 | 0x00000000, /* VGT_GROUP_FIRST_DECR */ |
971 | 0xc0016900, | 607 | 0x00000000, /* VGT_GROUP_DECR */ |
972 | 0x00000286, | 608 | 0x00000000, /* VGT_GROUP_VECT_0_CNTL */ |
973 | 0x00000000, | 609 | 0x00000000, /* VGT_GROUP_VECT_1_CNTL */ |
974 | 0xc0016900, | 610 | 0x00000000, /* VGT_GROUP_VECT_0_FMT_CNTL */ |
975 | 0x00000287, | 611 | 0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */ |
976 | 0x00000000, | 612 | 0x00000000, /* VGT_GS_MODE */ |
977 | 0xc0016900, | 613 | |
978 | 0x00000288, | ||
979 | 0x00000000, | ||
980 | 0xc0016900, | ||
981 | 0x00000289, | ||
982 | 0x00000000, | ||
983 | 0xc0016900, | ||
984 | 0x0000028a, | ||
985 | 0x00000000, | ||
986 | 0xc0016900, | ||
987 | 0x0000028b, | ||
988 | 0x00000000, | ||
989 | 0xc0016900, | ||
990 | 0x0000028c, | ||
991 | 0x00000000, | ||
992 | 0xc0016900, | ||
993 | 0x0000028d, | ||
994 | 0x00000000, | ||
995 | 0xc0016900, | ||
996 | 0x0000028e, | ||
997 | 0x00000000, | ||
998 | 0xc0016900, | ||
999 | 0x0000028f, | ||
1000 | 0x00000000, | ||
1001 | 0xc0016900, | 614 | 0xc0016900, |
1002 | 0x000002a1, | 615 | 0x000002a1, |
1003 | 0x00000000, | 616 | 0x00000000, /* VGT_PRIMITIVEID_EN */ |
617 | |||
1004 | 0xc0016900, | 618 | 0xc0016900, |
1005 | 0x000002a5, | 619 | 0x000002a5, |
1006 | 0x00000000, | 620 | 0x00000000, /* VGT_MULTI_PRIM_ID_RESET_EN */ |
1007 | 0xc0016900, | 621 | |
622 | 0xc0036900, | ||
1008 | 0x000002ac, | 623 | 0x000002ac, |
1009 | 0x00000000, | 624 | 0x00000000, /* VGT_STRMOUT_EN */ |
1010 | 0xc0016900, | 625 | 0x00000000, /* VGT_REUSE_OFF */ |
1011 | 0x000002ad, | 626 | 0x00000000, /* VGT_VTX_CNT_EN */ |
1012 | 0x00000000, | 627 | |
1013 | 0xc0016900, | ||
1014 | 0x000002ae, | ||
1015 | 0x00000000, | ||
1016 | 0xc0016900, | 628 | 0xc0016900, |
1017 | 0x000002c8, | 629 | 0x000002c8, |
1018 | 0x00000000, | 630 | 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ |
1019 | 0xc0016900, | 631 | |
1020 | 0x00000206, | 632 | 0xc0076900, |
1021 | 0x00000100, | ||
1022 | 0xc0016900, | ||
1023 | 0x00000204, | ||
1024 | 0x00010000, | ||
1025 | 0xc0036e00, | ||
1026 | 0x00000000, | ||
1027 | 0x00000012, | ||
1028 | 0x00000000, | ||
1029 | 0x00000000, | ||
1030 | 0xc0016900, | ||
1031 | 0x0000008f, | ||
1032 | 0x0000000f, | ||
1033 | 0xc0016900, | ||
1034 | 0x000001e8, | ||
1035 | 0x00000001, | ||
1036 | 0xc0016900, | ||
1037 | 0x00000202, | 633 | 0x00000202, |
1038 | 0x00cc0000, | 634 | 0x00cc0000, /* CB_COLOR_CONTROL */ |
635 | 0x00000210, /* DB_SHADER_CNTL */ | ||
636 | 0x00010000, /* PA_CL_CLIP_CNTL */ | ||
637 | 0x00000244, /* PA_SU_SC_MODE_CNTL */ | ||
638 | 0x00000100, /* PA_CL_VTE_CNTL */ | ||
639 | 0x00000000, /* PA_CL_VS_OUT_CNTL */ | ||
640 | 0x00000000, /* PA_CL_NANINF_CNTL */ | ||
641 | |||
642 | 0xc0026900, | ||
643 | 0x0000008e, | ||
644 | 0x0000000f, /* CB_TARGET_MASK */ | ||
645 | 0x0000000f, /* CB_SHADER_MASK */ | ||
646 | |||
1039 | 0xc0016900, | 647 | 0xc0016900, |
1040 | 0x00000205, | 648 | 0x000001e8, |
1041 | 0x00000244, | 649 | 0x00000001, /* CB_SHADER_CONTROL */ |
650 | |||
1042 | 0xc0016900, | 651 | 0xc0016900, |
1043 | 0x00000203, | 652 | 0x00000185, |
1044 | 0x00000210, | 653 | 0x00000000, /* SPI_VS_OUT_ID_0 */ |
654 | |||
1045 | 0xc0016900, | 655 | 0xc0016900, |
656 | 0x00000191, | ||
657 | 0x00000b00, /* SPI_PS_INPUT_CNTL_0 */ | ||
658 | |||
659 | 0xc0056900, | ||
1046 | 0x000001b1, | 660 | 0x000001b1, |
661 | 0x00000000, /* SPI_VS_OUT_CONFIG */ | ||
662 | 0x00000001, /* SPI_THREAD_GROUPING */ | ||
663 | 0x00000001, /* SPI_PS_IN_CONTROL_0 */ | ||
664 | 0x00000000, /* SPI_PS_IN_CONTROL_1 */ | ||
665 | 0x00000000, /* SPI_INTERP_CONTROL_0 */ | ||
666 | |||
667 | 0xc0036e00, /* SET_SAMPLER */ | ||
1047 | 0x00000000, | 668 | 0x00000000, |
1048 | 0xc0016900, | 669 | 0x00000012, |
1049 | 0x00000185, | ||
1050 | 0x00000000, | ||
1051 | 0xc0016900, | ||
1052 | 0x000001b3, | ||
1053 | 0x00000001, | ||
1054 | 0xc0016900, | ||
1055 | 0x000001b4, | ||
1056 | 0x00000000, | 670 | 0x00000000, |
1057 | 0xc0016900, | ||
1058 | 0x00000191, | ||
1059 | 0x00000b00, | ||
1060 | 0xc0016900, | ||
1061 | 0x000001b5, | ||
1062 | 0x00000000, | 671 | 0x00000000, |
1063 | }; | 672 | }; |
1064 | 673 | ||
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 144c32d37136..c3ea212e0c3c 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * Alex Deucher | 25 | * Alex Deucher |
26 | * Jerome Glisse | 26 | * Jerome Glisse |
27 | */ | 27 | */ |
28 | #include <linux/kernel.h> | ||
28 | #include "drmP.h" | 29 | #include "drmP.h" |
29 | #include "radeon.h" | 30 | #include "radeon.h" |
30 | #include "r600d.h" | 31 | #include "r600d.h" |
@@ -166,7 +167,7 @@ static void r600_cs_track_init(struct r600_cs_track *track) | |||
166 | static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | 167 | static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) |
167 | { | 168 | { |
168 | struct r600_cs_track *track = p->track; | 169 | struct r600_cs_track *track = p->track; |
169 | u32 bpe = 0, pitch, slice_tile_max, size, tmp, height; | 170 | u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align; |
170 | volatile u32 *ib = p->ib->ptr; | 171 | volatile u32 *ib = p->ib->ptr; |
171 | 172 | ||
172 | if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { | 173 | if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { |
@@ -180,56 +181,57 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
180 | i, track->cb_color_info[i]); | 181 | i, track->cb_color_info[i]); |
181 | return -EINVAL; | 182 | return -EINVAL; |
182 | } | 183 | } |
183 | pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) << 3; | 184 | /* pitch is the number of 8x8 tiles per row */ |
185 | pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1; | ||
184 | slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1; | 186 | slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1; |
185 | if (!pitch) { | 187 | height = size / (pitch * 8 * bpe); |
186 | dev_warn(p->dev, "%s:%d cb pitch (%d) for %d invalid (0x%08X)\n", | ||
187 | __func__, __LINE__, pitch, i, track->cb_color_size[i]); | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | height = size / (pitch * bpe); | ||
191 | if (height > 8192) | 188 | if (height > 8192) |
192 | height = 8192; | 189 | height = 8192; |
190 | if (height > 7) | ||
191 | height &= ~0x7; | ||
193 | switch (G_0280A0_ARRAY_MODE(track->cb_color_info[i])) { | 192 | switch (G_0280A0_ARRAY_MODE(track->cb_color_info[i])) { |
194 | case V_0280A0_ARRAY_LINEAR_GENERAL: | 193 | case V_0280A0_ARRAY_LINEAR_GENERAL: |
194 | /* technically height & 0x7 */ | ||
195 | break; | ||
195 | case V_0280A0_ARRAY_LINEAR_ALIGNED: | 196 | case V_0280A0_ARRAY_LINEAR_ALIGNED: |
196 | if (pitch & 0x3f) { | 197 | pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8; |
197 | dev_warn(p->dev, "%s:%d cb pitch (%d x %d = %d) invalid\n", | 198 | if (!IS_ALIGNED(pitch, pitch_align)) { |
198 | __func__, __LINE__, pitch, bpe, pitch * bpe); | 199 | dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", |
200 | __func__, __LINE__, pitch); | ||
199 | return -EINVAL; | 201 | return -EINVAL; |
200 | } | 202 | } |
201 | if ((pitch * bpe) & (track->group_size - 1)) { | 203 | if (!IS_ALIGNED(height, 8)) { |
202 | dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", | 204 | dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", |
203 | __func__, __LINE__, pitch); | 205 | __func__, __LINE__, height); |
204 | return -EINVAL; | 206 | return -EINVAL; |
205 | } | 207 | } |
206 | break; | 208 | break; |
207 | case V_0280A0_ARRAY_1D_TILED_THIN1: | 209 | case V_0280A0_ARRAY_1D_TILED_THIN1: |
208 | if ((pitch * 8 * bpe * track->nsamples) & (track->group_size - 1)) { | 210 | pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe * track->nsamples))) / 8; |
211 | if (!IS_ALIGNED(pitch, pitch_align)) { | ||
209 | dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", | 212 | dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", |
210 | __func__, __LINE__, pitch); | 213 | __func__, __LINE__, pitch); |
214 | return -EINVAL; | ||
215 | } | ||
216 | if (!IS_ALIGNED(height, 8)) { | ||
217 | dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", | ||
218 | __func__, __LINE__, height); | ||
211 | return -EINVAL; | 219 | return -EINVAL; |
212 | } | 220 | } |
213 | height &= ~0x7; | ||
214 | if (!height) | ||
215 | height = 8; | ||
216 | break; | 221 | break; |
217 | case V_0280A0_ARRAY_2D_TILED_THIN1: | 222 | case V_0280A0_ARRAY_2D_TILED_THIN1: |
218 | if (pitch & ((8 * track->nbanks) - 1)) { | 223 | pitch_align = max((u32)track->nbanks, |
224 | (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks)); | ||
225 | if (!IS_ALIGNED(pitch, pitch_align)) { | ||
219 | dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", | 226 | dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", |
220 | __func__, __LINE__, pitch); | 227 | __func__, __LINE__, pitch); |
221 | return -EINVAL; | 228 | return -EINVAL; |
222 | } | 229 | } |
223 | tmp = pitch * 8 * bpe * track->nsamples; | 230 | if (!IS_ALIGNED((height / 8), track->nbanks)) { |
224 | tmp = tmp / track->nbanks; | 231 | dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", |
225 | if (tmp & (track->group_size - 1)) { | 232 | __func__, __LINE__, height); |
226 | dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", | ||
227 | __func__, __LINE__, pitch); | ||
228 | return -EINVAL; | 233 | return -EINVAL; |
229 | } | 234 | } |
230 | height &= ~((16 * track->npipes) - 1); | ||
231 | if (!height) | ||
232 | height = 16 * track->npipes; | ||
233 | break; | 235 | break; |
234 | default: | 236 | default: |
235 | dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, | 237 | dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, |
@@ -238,16 +240,20 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
238 | return -EINVAL; | 240 | return -EINVAL; |
239 | } | 241 | } |
240 | /* check offset */ | 242 | /* check offset */ |
241 | tmp = height * pitch; | 243 | tmp = height * pitch * 8 * bpe; |
242 | if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { | 244 | if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { |
243 | dev_warn(p->dev, "%s offset[%d] %d to big\n", __func__, i, track->cb_color_bo_offset[i]); | 245 | dev_warn(p->dev, "%s offset[%d] %d too big\n", __func__, i, track->cb_color_bo_offset[i]); |
246 | return -EINVAL; | ||
247 | } | ||
248 | if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) { | ||
249 | dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]); | ||
244 | return -EINVAL; | 250 | return -EINVAL; |
245 | } | 251 | } |
246 | /* limit max tile */ | 252 | /* limit max tile */ |
247 | tmp = (height * pitch) >> 6; | 253 | tmp = (height * pitch * 8) >> 6; |
248 | if (tmp < slice_tile_max) | 254 | if (tmp < slice_tile_max) |
249 | slice_tile_max = tmp; | 255 | slice_tile_max = tmp; |
250 | tmp = S_028060_PITCH_TILE_MAX((pitch >> 3) - 1) | | 256 | tmp = S_028060_PITCH_TILE_MAX(pitch - 1) | |
251 | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); | 257 | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); |
252 | ib[track->cb_color_size_idx[i]] = tmp; | 258 | ib[track->cb_color_size_idx[i]] = tmp; |
253 | return 0; | 259 | return 0; |
@@ -289,7 +295,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
289 | /* Check depth buffer */ | 295 | /* Check depth buffer */ |
290 | if (G_028800_STENCIL_ENABLE(track->db_depth_control) || | 296 | if (G_028800_STENCIL_ENABLE(track->db_depth_control) || |
291 | G_028800_Z_ENABLE(track->db_depth_control)) { | 297 | G_028800_Z_ENABLE(track->db_depth_control)) { |
292 | u32 nviews, bpe, ntiles; | 298 | u32 nviews, bpe, ntiles, pitch, pitch_align, height, size; |
293 | if (track->db_bo == NULL) { | 299 | if (track->db_bo == NULL) { |
294 | dev_warn(p->dev, "z/stencil with no depth buffer\n"); | 300 | dev_warn(p->dev, "z/stencil with no depth buffer\n"); |
295 | return -EINVAL; | 301 | return -EINVAL; |
@@ -332,6 +338,51 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
332 | } | 338 | } |
333 | ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF); | 339 | ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF); |
334 | } else { | 340 | } else { |
341 | size = radeon_bo_size(track->db_bo); | ||
342 | pitch = G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1; | ||
343 | height = size / (pitch * 8 * bpe); | ||
344 | height &= ~0x7; | ||
345 | if (!height) | ||
346 | height = 8; | ||
347 | |||
348 | switch (G_028010_ARRAY_MODE(track->db_depth_info)) { | ||
349 | case V_028010_ARRAY_1D_TILED_THIN1: | ||
350 | pitch_align = (max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8); | ||
351 | if (!IS_ALIGNED(pitch, pitch_align)) { | ||
352 | dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", | ||
353 | __func__, __LINE__, pitch); | ||
354 | return -EINVAL; | ||
355 | } | ||
356 | if (!IS_ALIGNED(height, 8)) { | ||
357 | dev_warn(p->dev, "%s:%d db height (%d) invalid\n", | ||
358 | __func__, __LINE__, height); | ||
359 | return -EINVAL; | ||
360 | } | ||
361 | break; | ||
362 | case V_028010_ARRAY_2D_TILED_THIN1: | ||
363 | pitch_align = max((u32)track->nbanks, | ||
364 | (u32)(((track->group_size / 8) / bpe) * track->nbanks)); | ||
365 | if (!IS_ALIGNED(pitch, pitch_align)) { | ||
366 | dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", | ||
367 | __func__, __LINE__, pitch); | ||
368 | return -EINVAL; | ||
369 | } | ||
370 | if ((height / 8) & (track->nbanks - 1)) { | ||
371 | dev_warn(p->dev, "%s:%d db height (%d) invalid\n", | ||
372 | __func__, __LINE__, height); | ||
373 | return -EINVAL; | ||
374 | } | ||
375 | break; | ||
376 | default: | ||
377 | dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, | ||
378 | G_028010_ARRAY_MODE(track->db_depth_info), | ||
379 | track->db_depth_info); | ||
380 | return -EINVAL; | ||
381 | } | ||
382 | if (!IS_ALIGNED(track->db_offset, track->group_size)) { | ||
383 | dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->db_offset); | ||
384 | return -EINVAL; | ||
385 | } | ||
335 | ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; | 386 | ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; |
336 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; | 387 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; |
337 | tmp = ntiles * bpe * 64 * nviews; | 388 | tmp = ntiles * bpe * 64 * nviews; |
@@ -724,7 +775,25 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx | |||
724 | track->db_depth_control = radeon_get_ib_value(p, idx); | 775 | track->db_depth_control = radeon_get_ib_value(p, idx); |
725 | break; | 776 | break; |
726 | case R_028010_DB_DEPTH_INFO: | 777 | case R_028010_DB_DEPTH_INFO: |
727 | track->db_depth_info = radeon_get_ib_value(p, idx); | 778 | if (r600_cs_packet_next_is_pkt3_nop(p)) { |
779 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
780 | if (r) { | ||
781 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
782 | "0x%04X\n", reg); | ||
783 | return -EINVAL; | ||
784 | } | ||
785 | track->db_depth_info = radeon_get_ib_value(p, idx); | ||
786 | ib[idx] &= C_028010_ARRAY_MODE; | ||
787 | track->db_depth_info &= C_028010_ARRAY_MODE; | ||
788 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | ||
789 | ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1); | ||
790 | track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1); | ||
791 | } else { | ||
792 | ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1); | ||
793 | track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1); | ||
794 | } | ||
795 | } else | ||
796 | track->db_depth_info = radeon_get_ib_value(p, idx); | ||
728 | break; | 797 | break; |
729 | case R_028004_DB_DEPTH_VIEW: | 798 | case R_028004_DB_DEPTH_VIEW: |
730 | track->db_depth_view = radeon_get_ib_value(p, idx); | 799 | track->db_depth_view = radeon_get_ib_value(p, idx); |
@@ -757,8 +826,25 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx | |||
757 | case R_0280B4_CB_COLOR5_INFO: | 826 | case R_0280B4_CB_COLOR5_INFO: |
758 | case R_0280B8_CB_COLOR6_INFO: | 827 | case R_0280B8_CB_COLOR6_INFO: |
759 | case R_0280BC_CB_COLOR7_INFO: | 828 | case R_0280BC_CB_COLOR7_INFO: |
760 | tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4; | 829 | if (r600_cs_packet_next_is_pkt3_nop(p)) { |
761 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); | 830 | r = r600_cs_packet_next_reloc(p, &reloc); |
831 | if (r) { | ||
832 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | ||
833 | return -EINVAL; | ||
834 | } | ||
835 | tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4; | ||
836 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); | ||
837 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | ||
838 | ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1); | ||
839 | track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1); | ||
840 | } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | ||
841 | ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1); | ||
842 | track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1); | ||
843 | } | ||
844 | } else { | ||
845 | tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4; | ||
846 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); | ||
847 | } | ||
762 | break; | 848 | break; |
763 | case R_028060_CB_COLOR0_SIZE: | 849 | case R_028060_CB_COLOR0_SIZE: |
764 | case R_028064_CB_COLOR1_SIZE: | 850 | case R_028064_CB_COLOR1_SIZE: |
@@ -946,8 +1032,9 @@ static inline unsigned minify(unsigned size, unsigned levels) | |||
946 | } | 1032 | } |
947 | 1033 | ||
948 | static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels, | 1034 | static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels, |
949 | unsigned w0, unsigned h0, unsigned d0, unsigned bpe, | 1035 | unsigned w0, unsigned h0, unsigned d0, unsigned bpe, |
950 | unsigned *l0_size, unsigned *mipmap_size) | 1036 | unsigned pitch_align, |
1037 | unsigned *l0_size, unsigned *mipmap_size) | ||
951 | { | 1038 | { |
952 | unsigned offset, i, level, face; | 1039 | unsigned offset, i, level, face; |
953 | unsigned width, height, depth, rowstride, size; | 1040 | unsigned width, height, depth, rowstride, size; |
@@ -960,13 +1047,13 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels | |||
960 | height = minify(h0, i); | 1047 | height = minify(h0, i); |
961 | depth = minify(d0, i); | 1048 | depth = minify(d0, i); |
962 | for(face = 0; face < nfaces; face++) { | 1049 | for(face = 0; face < nfaces; face++) { |
963 | rowstride = ((width * bpe) + 255) & ~255; | 1050 | rowstride = ALIGN((width * bpe), pitch_align); |
964 | size = height * rowstride * depth; | 1051 | size = height * rowstride * depth; |
965 | offset += size; | 1052 | offset += size; |
966 | offset = (offset + 0x1f) & ~0x1f; | 1053 | offset = (offset + 0x1f) & ~0x1f; |
967 | } | 1054 | } |
968 | } | 1055 | } |
969 | *l0_size = (((w0 * bpe) + 255) & ~255) * h0 * d0; | 1056 | *l0_size = ALIGN((w0 * bpe), pitch_align) * h0 * d0; |
970 | *mipmap_size = offset; | 1057 | *mipmap_size = offset; |
971 | if (!blevel) | 1058 | if (!blevel) |
972 | *mipmap_size -= *l0_size; | 1059 | *mipmap_size -= *l0_size; |
@@ -985,16 +1072,23 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels | |||
985 | * the texture and mipmap bo object are big enough to cover this resource. | 1072 | * the texture and mipmap bo object are big enough to cover this resource. |
986 | */ | 1073 | */ |
987 | static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | 1074 | static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, |
988 | struct radeon_bo *texture, | 1075 | struct radeon_bo *texture, |
989 | struct radeon_bo *mipmap) | 1076 | struct radeon_bo *mipmap, |
1077 | u32 tiling_flags) | ||
990 | { | 1078 | { |
1079 | struct r600_cs_track *track = p->track; | ||
991 | u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0; | 1080 | u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0; |
992 | u32 word0, word1, l0_size, mipmap_size; | 1081 | u32 word0, word1, l0_size, mipmap_size, pitch, pitch_align; |
993 | 1082 | ||
994 | /* on legacy kernel we don't perform advanced check */ | 1083 | /* on legacy kernel we don't perform advanced check */ |
995 | if (p->rdev == NULL) | 1084 | if (p->rdev == NULL) |
996 | return 0; | 1085 | return 0; |
1086 | |||
997 | word0 = radeon_get_ib_value(p, idx + 0); | 1087 | word0 = radeon_get_ib_value(p, idx + 0); |
1088 | if (tiling_flags & RADEON_TILING_MACRO) | ||
1089 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); | ||
1090 | else if (tiling_flags & RADEON_TILING_MICRO) | ||
1091 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | ||
998 | word1 = radeon_get_ib_value(p, idx + 1); | 1092 | word1 = radeon_get_ib_value(p, idx + 1); |
999 | w0 = G_038000_TEX_WIDTH(word0) + 1; | 1093 | w0 = G_038000_TEX_WIDTH(word0) + 1; |
1000 | h0 = G_038004_TEX_HEIGHT(word1) + 1; | 1094 | h0 = G_038004_TEX_HEIGHT(word1) + 1; |
@@ -1021,11 +1115,55 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i | |||
1021 | __func__, __LINE__, G_038004_DATA_FORMAT(word1)); | 1115 | __func__, __LINE__, G_038004_DATA_FORMAT(word1)); |
1022 | return -EINVAL; | 1116 | return -EINVAL; |
1023 | } | 1117 | } |
1118 | |||
1119 | pitch = G_038000_PITCH(word0) + 1; | ||
1120 | switch (G_038000_TILE_MODE(word0)) { | ||
1121 | case V_038000_ARRAY_LINEAR_GENERAL: | ||
1122 | pitch_align = 1; | ||
1123 | /* XXX check height align */ | ||
1124 | break; | ||
1125 | case V_038000_ARRAY_LINEAR_ALIGNED: | ||
1126 | pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8; | ||
1127 | if (!IS_ALIGNED(pitch, pitch_align)) { | ||
1128 | dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", | ||
1129 | __func__, __LINE__, pitch); | ||
1130 | return -EINVAL; | ||
1131 | } | ||
1132 | /* XXX check height align */ | ||
1133 | break; | ||
1134 | case V_038000_ARRAY_1D_TILED_THIN1: | ||
1135 | pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8; | ||
1136 | if (!IS_ALIGNED(pitch, pitch_align)) { | ||
1137 | dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", | ||
1138 | __func__, __LINE__, pitch); | ||
1139 | return -EINVAL; | ||
1140 | } | ||
1141 | /* XXX check height align */ | ||
1142 | break; | ||
1143 | case V_038000_ARRAY_2D_TILED_THIN1: | ||
1144 | pitch_align = max((u32)track->nbanks, | ||
1145 | (u32)(((track->group_size / 8) / bpe) * track->nbanks)); | ||
1146 | if (!IS_ALIGNED(pitch, pitch_align)) { | ||
1147 | dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", | ||
1148 | __func__, __LINE__, pitch); | ||
1149 | return -EINVAL; | ||
1150 | } | ||
1151 | /* XXX check height align */ | ||
1152 | break; | ||
1153 | default: | ||
1154 | dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, | ||
1155 | G_038000_TILE_MODE(word0), word0); | ||
1156 | return -EINVAL; | ||
1157 | } | ||
1158 | /* XXX check offset align */ | ||
1159 | |||
1024 | word0 = radeon_get_ib_value(p, idx + 4); | 1160 | word0 = radeon_get_ib_value(p, idx + 4); |
1025 | word1 = radeon_get_ib_value(p, idx + 5); | 1161 | word1 = radeon_get_ib_value(p, idx + 5); |
1026 | blevel = G_038010_BASE_LEVEL(word0); | 1162 | blevel = G_038010_BASE_LEVEL(word0); |
1027 | nlevels = G_038014_LAST_LEVEL(word1); | 1163 | nlevels = G_038014_LAST_LEVEL(word1); |
1028 | r600_texture_size(nfaces, blevel, nlevels, w0, h0, d0, bpe, &l0_size, &mipmap_size); | 1164 | r600_texture_size(nfaces, blevel, nlevels, w0, h0, d0, bpe, |
1165 | (pitch_align * bpe), | ||
1166 | &l0_size, &mipmap_size); | ||
1029 | /* using get ib will give us the offset into the texture bo */ | 1167 | /* using get ib will give us the offset into the texture bo */ |
1030 | word0 = radeon_get_ib_value(p, idx + 2); | 1168 | word0 = radeon_get_ib_value(p, idx + 2); |
1031 | if ((l0_size + word0) > radeon_bo_size(texture)) { | 1169 | if ((l0_size + word0) > radeon_bo_size(texture)) { |
@@ -1239,6 +1377,10 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
1239 | return -EINVAL; | 1377 | return -EINVAL; |
1240 | } | 1378 | } |
1241 | ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | 1379 | ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); |
1380 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | ||
1381 | ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); | ||
1382 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | ||
1383 | ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | ||
1242 | texture = reloc->robj; | 1384 | texture = reloc->robj; |
1243 | /* tex mip base */ | 1385 | /* tex mip base */ |
1244 | r = r600_cs_packet_next_reloc(p, &reloc); | 1386 | r = r600_cs_packet_next_reloc(p, &reloc); |
@@ -1249,7 +1391,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
1249 | ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | 1391 | ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); |
1250 | mipmap = reloc->robj; | 1392 | mipmap = reloc->robj; |
1251 | r = r600_check_texture_resource(p, idx+(i*7)+1, | 1393 | r = r600_check_texture_resource(p, idx+(i*7)+1, |
1252 | texture, mipmap); | 1394 | texture, mipmap, reloc->lobj.tiling_flags); |
1253 | if (r) | 1395 | if (r) |
1254 | return r; | 1396 | return r; |
1255 | break; | 1397 | break; |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 26b4bc9d89a5..e6a58ed48dcf 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -435,7 +435,8 @@ static int r600_hdmi_find_free_block(struct drm_device *dev) | |||
435 | } | 435 | } |
436 | } | 436 | } |
437 | 437 | ||
438 | if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690) { | 438 | if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 || |
439 | rdev->family == CHIP_RS740) { | ||
439 | return free_blocks[0] ? R600_HDMI_BLOCK1 : 0; | 440 | return free_blocks[0] ? R600_HDMI_BLOCK1 : 0; |
440 | } else if (rdev->family >= CHIP_R600) { | 441 | } else if (rdev->family >= CHIP_R600) { |
441 | if (free_blocks[0]) | 442 | if (free_blocks[0]) |
@@ -466,7 +467,8 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder) | |||
466 | if (ASIC_IS_DCE32(rdev)) | 467 | if (ASIC_IS_DCE32(rdev)) |
467 | radeon_encoder->hdmi_config_offset = dig->dig_encoder ? | 468 | radeon_encoder->hdmi_config_offset = dig->dig_encoder ? |
468 | R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1; | 469 | R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1; |
469 | } else if (rdev->family >= CHIP_R600) { | 470 | } else if (rdev->family >= CHIP_R600 || rdev->family == CHIP_RS600 || |
471 | rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { | ||
470 | radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev); | 472 | radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev); |
471 | } | 473 | } |
472 | } | 474 | } |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 59c1f8793e60..858a1920c0d7 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -239,12 +239,18 @@ | |||
239 | #define GRBM_SOFT_RESET 0x8020 | 239 | #define GRBM_SOFT_RESET 0x8020 |
240 | #define SOFT_RESET_CP (1<<0) | 240 | #define SOFT_RESET_CP (1<<0) |
241 | 241 | ||
242 | #define CG_THERMAL_STATUS 0x7F4 | ||
243 | #define ASIC_T(x) ((x) << 0) | ||
244 | #define ASIC_T_MASK 0x1FF | ||
245 | #define ASIC_T_SHIFT 0 | ||
246 | |||
242 | #define HDP_HOST_PATH_CNTL 0x2C00 | 247 | #define HDP_HOST_PATH_CNTL 0x2C00 |
243 | #define HDP_NONSURFACE_BASE 0x2C04 | 248 | #define HDP_NONSURFACE_BASE 0x2C04 |
244 | #define HDP_NONSURFACE_INFO 0x2C08 | 249 | #define HDP_NONSURFACE_INFO 0x2C08 |
245 | #define HDP_NONSURFACE_SIZE 0x2C0C | 250 | #define HDP_NONSURFACE_SIZE 0x2C0C |
246 | #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 | 251 | #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 |
247 | #define HDP_TILING_CONFIG 0x2F3C | 252 | #define HDP_TILING_CONFIG 0x2F3C |
253 | #define HDP_DEBUG1 0x2F34 | ||
248 | 254 | ||
249 | #define MC_VM_AGP_TOP 0x2184 | 255 | #define MC_VM_AGP_TOP 0x2184 |
250 | #define MC_VM_AGP_BOT 0x2188 | 256 | #define MC_VM_AGP_BOT 0x2188 |
@@ -1154,6 +1160,10 @@ | |||
1154 | #define S_038000_TILE_MODE(x) (((x) & 0xF) << 3) | 1160 | #define S_038000_TILE_MODE(x) (((x) & 0xF) << 3) |
1155 | #define G_038000_TILE_MODE(x) (((x) >> 3) & 0xF) | 1161 | #define G_038000_TILE_MODE(x) (((x) >> 3) & 0xF) |
1156 | #define C_038000_TILE_MODE 0xFFFFFF87 | 1162 | #define C_038000_TILE_MODE 0xFFFFFF87 |
1163 | #define V_038000_ARRAY_LINEAR_GENERAL 0x00000000 | ||
1164 | #define V_038000_ARRAY_LINEAR_ALIGNED 0x00000001 | ||
1165 | #define V_038000_ARRAY_1D_TILED_THIN1 0x00000002 | ||
1166 | #define V_038000_ARRAY_2D_TILED_THIN1 0x00000004 | ||
1157 | #define S_038000_TILE_TYPE(x) (((x) & 0x1) << 7) | 1167 | #define S_038000_TILE_TYPE(x) (((x) & 0x1) << 7) |
1158 | #define G_038000_TILE_TYPE(x) (((x) >> 7) & 0x1) | 1168 | #define G_038000_TILE_TYPE(x) (((x) >> 7) & 0x1) |
1159 | #define C_038000_TILE_TYPE 0xFFFFFF7F | 1169 | #define C_038000_TILE_TYPE 0xFFFFFF7F |
@@ -1357,6 +1367,8 @@ | |||
1357 | #define S_028010_ARRAY_MODE(x) (((x) & 0xF) << 15) | 1367 | #define S_028010_ARRAY_MODE(x) (((x) & 0xF) << 15) |
1358 | #define G_028010_ARRAY_MODE(x) (((x) >> 15) & 0xF) | 1368 | #define G_028010_ARRAY_MODE(x) (((x) >> 15) & 0xF) |
1359 | #define C_028010_ARRAY_MODE 0xFFF87FFF | 1369 | #define C_028010_ARRAY_MODE 0xFFF87FFF |
1370 | #define V_028010_ARRAY_1D_TILED_THIN1 0x00000002 | ||
1371 | #define V_028010_ARRAY_2D_TILED_THIN1 0x00000004 | ||
1360 | #define S_028010_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 25) | 1372 | #define S_028010_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 25) |
1361 | #define G_028010_TILE_SURFACE_ENABLE(x) (((x) >> 25) & 0x1) | 1373 | #define G_028010_TILE_SURFACE_ENABLE(x) (((x) >> 25) & 0x1) |
1362 | #define C_028010_TILE_SURFACE_ENABLE 0xFDFFFFFF | 1374 | #define C_028010_TILE_SURFACE_ENABLE 0xFDFFFFFF |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 2f94dc66c183..3cd1c470b777 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -178,6 +178,9 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev); | |||
178 | void radeon_atombios_get_power_modes(struct radeon_device *rdev); | 178 | void radeon_atombios_get_power_modes(struct radeon_device *rdev); |
179 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level); | 179 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level); |
180 | void rs690_pm_info(struct radeon_device *rdev); | 180 | void rs690_pm_info(struct radeon_device *rdev); |
181 | extern u32 rv6xx_get_temp(struct radeon_device *rdev); | ||
182 | extern u32 rv770_get_temp(struct radeon_device *rdev); | ||
183 | extern u32 evergreen_get_temp(struct radeon_device *rdev); | ||
181 | 184 | ||
182 | /* | 185 | /* |
183 | * Fences. | 186 | * Fences. |
@@ -232,7 +235,7 @@ struct radeon_surface_reg { | |||
232 | */ | 235 | */ |
233 | struct radeon_mman { | 236 | struct radeon_mman { |
234 | struct ttm_bo_global_ref bo_global_ref; | 237 | struct ttm_bo_global_ref bo_global_ref; |
235 | struct ttm_global_reference mem_global_ref; | 238 | struct drm_global_reference mem_global_ref; |
236 | struct ttm_bo_device bdev; | 239 | struct ttm_bo_device bdev; |
237 | bool mem_global_referenced; | 240 | bool mem_global_referenced; |
238 | bool initialized; | 241 | bool initialized; |
@@ -671,6 +674,13 @@ struct radeon_pm_profile { | |||
671 | int dpms_on_cm_idx; | 674 | int dpms_on_cm_idx; |
672 | }; | 675 | }; |
673 | 676 | ||
677 | enum radeon_int_thermal_type { | ||
678 | THERMAL_TYPE_NONE, | ||
679 | THERMAL_TYPE_RV6XX, | ||
680 | THERMAL_TYPE_RV770, | ||
681 | THERMAL_TYPE_EVERGREEN, | ||
682 | }; | ||
683 | |||
674 | struct radeon_voltage { | 684 | struct radeon_voltage { |
675 | enum radeon_voltage_type type; | 685 | enum radeon_voltage_type type; |
676 | /* gpio voltage */ | 686 | /* gpio voltage */ |
@@ -766,6 +776,9 @@ struct radeon_pm { | |||
766 | enum radeon_pm_profile_type profile; | 776 | enum radeon_pm_profile_type profile; |
767 | int profile_index; | 777 | int profile_index; |
768 | struct radeon_pm_profile profiles[PM_PROFILE_MAX]; | 778 | struct radeon_pm_profile profiles[PM_PROFILE_MAX]; |
779 | /* internal thermal controller on rv6xx+ */ | ||
780 | enum radeon_int_thermal_type int_thermal_type; | ||
781 | struct device *int_hwmon_dev; | ||
769 | }; | 782 | }; |
770 | 783 | ||
771 | 784 | ||
@@ -902,6 +915,7 @@ struct r600_asic { | |||
902 | unsigned tiling_nbanks; | 915 | unsigned tiling_nbanks; |
903 | unsigned tiling_npipes; | 916 | unsigned tiling_npipes; |
904 | unsigned tiling_group_size; | 917 | unsigned tiling_group_size; |
918 | unsigned tile_config; | ||
905 | struct r100_gpu_lockup lockup; | 919 | struct r100_gpu_lockup lockup; |
906 | }; | 920 | }; |
907 | 921 | ||
@@ -926,6 +940,7 @@ struct rv770_asic { | |||
926 | unsigned tiling_nbanks; | 940 | unsigned tiling_nbanks; |
927 | unsigned tiling_npipes; | 941 | unsigned tiling_npipes; |
928 | unsigned tiling_group_size; | 942 | unsigned tiling_group_size; |
943 | unsigned tile_config; | ||
929 | struct r100_gpu_lockup lockup; | 944 | struct r100_gpu_lockup lockup; |
930 | }; | 945 | }; |
931 | 946 | ||
@@ -951,6 +966,7 @@ struct evergreen_asic { | |||
951 | unsigned tiling_nbanks; | 966 | unsigned tiling_nbanks; |
952 | unsigned tiling_npipes; | 967 | unsigned tiling_npipes; |
953 | unsigned tiling_group_size; | 968 | unsigned tiling_group_size; |
969 | unsigned tile_config; | ||
954 | }; | 970 | }; |
955 | 971 | ||
956 | union radeon_asic_config { | 972 | union radeon_asic_config { |
@@ -1033,6 +1049,9 @@ struct radeon_device { | |||
1033 | uint32_t pcie_reg_mask; | 1049 | uint32_t pcie_reg_mask; |
1034 | radeon_rreg_t pciep_rreg; | 1050 | radeon_rreg_t pciep_rreg; |
1035 | radeon_wreg_t pciep_wreg; | 1051 | radeon_wreg_t pciep_wreg; |
1052 | /* io port */ | ||
1053 | void __iomem *rio_mem; | ||
1054 | resource_size_t rio_mem_size; | ||
1036 | struct radeon_clock clock; | 1055 | struct radeon_clock clock; |
1037 | struct radeon_mc mc; | 1056 | struct radeon_mc mc; |
1038 | struct radeon_gart gart; | 1057 | struct radeon_gart gart; |
@@ -1069,6 +1088,7 @@ struct radeon_device { | |||
1069 | struct mutex vram_mutex; | 1088 | struct mutex vram_mutex; |
1070 | 1089 | ||
1071 | /* audio stuff */ | 1090 | /* audio stuff */ |
1091 | bool audio_enabled; | ||
1072 | struct timer_list audio_timer; | 1092 | struct timer_list audio_timer; |
1073 | int audio_channels; | 1093 | int audio_channels; |
1074 | int audio_rate; | 1094 | int audio_rate; |
@@ -1078,6 +1098,8 @@ struct radeon_device { | |||
1078 | 1098 | ||
1079 | bool powered_down; | 1099 | bool powered_down; |
1080 | struct notifier_block acpi_nb; | 1100 | struct notifier_block acpi_nb; |
1101 | /* only one userspace can use Hyperz features at a time */ | ||
1102 | struct drm_file *hyperz_filp; | ||
1081 | }; | 1103 | }; |
1082 | 1104 | ||
1083 | int radeon_device_init(struct radeon_device *rdev, | 1105 | int radeon_device_init(struct radeon_device *rdev, |
@@ -1114,6 +1136,26 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32 | |||
1114 | } | 1136 | } |
1115 | } | 1137 | } |
1116 | 1138 | ||
1139 | static inline u32 r100_io_rreg(struct radeon_device *rdev, u32 reg) | ||
1140 | { | ||
1141 | if (reg < rdev->rio_mem_size) | ||
1142 | return ioread32(rdev->rio_mem + reg); | ||
1143 | else { | ||
1144 | iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX); | ||
1145 | return ioread32(rdev->rio_mem + RADEON_MM_DATA); | ||
1146 | } | ||
1147 | } | ||
1148 | |||
1149 | static inline void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v) | ||
1150 | { | ||
1151 | if (reg < rdev->rio_mem_size) | ||
1152 | iowrite32(v, rdev->rio_mem + reg); | ||
1153 | else { | ||
1154 | iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX); | ||
1155 | iowrite32(v, rdev->rio_mem + RADEON_MM_DATA); | ||
1156 | } | ||
1157 | } | ||
1158 | |||
1117 | /* | 1159 | /* |
1118 | * Cast helper | 1160 | * Cast helper |
1119 | */ | 1161 | */ |
@@ -1152,6 +1194,8 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32 | |||
1152 | WREG32_PLL(reg, tmp_); \ | 1194 | WREG32_PLL(reg, tmp_); \ |
1153 | } while (0) | 1195 | } while (0) |
1154 | #define DREG32_SYS(sqf, rdev, reg) seq_printf((sqf), #reg " : 0x%08X\n", r100_mm_rreg((rdev), (reg))) | 1196 | #define DREG32_SYS(sqf, rdev, reg) seq_printf((sqf), #reg " : 0x%08X\n", r100_mm_rreg((rdev), (reg))) |
1197 | #define RREG32_IO(reg) r100_io_rreg(rdev, (reg)) | ||
1198 | #define WREG32_IO(reg, v) r100_io_wreg(rdev, (reg), (v)) | ||
1155 | 1199 | ||
1156 | /* | 1200 | /* |
1157 | * Indirect registers accessor | 1201 | * Indirect registers accessor |
@@ -1415,6 +1459,13 @@ extern void r700_cp_fini(struct radeon_device *rdev); | |||
1415 | extern void evergreen_disable_interrupt_state(struct radeon_device *rdev); | 1459 | extern void evergreen_disable_interrupt_state(struct radeon_device *rdev); |
1416 | extern int evergreen_irq_set(struct radeon_device *rdev); | 1460 | extern int evergreen_irq_set(struct radeon_device *rdev); |
1417 | 1461 | ||
1462 | /* radeon_acpi.c */ | ||
1463 | #if defined(CONFIG_ACPI) | ||
1464 | extern int radeon_acpi_init(struct radeon_device *rdev); | ||
1465 | #else | ||
1466 | static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } | ||
1467 | #endif | ||
1468 | |||
1418 | /* evergreen */ | 1469 | /* evergreen */ |
1419 | struct evergreen_mc_save { | 1470 | struct evergreen_mc_save { |
1420 | u32 vga_control[6]; | 1471 | u32 vga_control[6]; |
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c new file mode 100644 index 000000000000..3f6636bb2d7f --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_acpi.c | |||
@@ -0,0 +1,67 @@ | |||
1 | #include <linux/pci.h> | ||
2 | #include <linux/acpi.h> | ||
3 | #include <linux/slab.h> | ||
4 | #include <acpi/acpi_drivers.h> | ||
5 | #include <acpi/acpi_bus.h> | ||
6 | |||
7 | #include "drmP.h" | ||
8 | #include "drm.h" | ||
9 | #include "drm_sarea.h" | ||
10 | #include "drm_crtc_helper.h" | ||
11 | #include "radeon.h" | ||
12 | |||
13 | #include <linux/vga_switcheroo.h> | ||
14 | |||
15 | /* Call the ATIF method | ||
16 | * | ||
17 | * Note: currently we discard the output | ||
18 | */ | ||
19 | static int radeon_atif_call(acpi_handle handle) | ||
20 | { | ||
21 | acpi_status status; | ||
22 | union acpi_object atif_arg_elements[2]; | ||
23 | struct acpi_object_list atif_arg; | ||
24 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; | ||
25 | |||
26 | atif_arg.count = 2; | ||
27 | atif_arg.pointer = &atif_arg_elements[0]; | ||
28 | |||
29 | atif_arg_elements[0].type = ACPI_TYPE_INTEGER; | ||
30 | atif_arg_elements[0].integer.value = 0; | ||
31 | atif_arg_elements[1].type = ACPI_TYPE_INTEGER; | ||
32 | atif_arg_elements[1].integer.value = 0; | ||
33 | |||
34 | status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer); | ||
35 | |||
36 | /* Fail only if calling the method fails and ATIF is supported */ | ||
37 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
38 | printk(KERN_DEBUG "failed to evaluate ATIF got %s\n", acpi_format_exception(status)); | ||
39 | kfree(buffer.pointer); | ||
40 | return 1; | ||
41 | } | ||
42 | |||
43 | kfree(buffer.pointer); | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | /* Call all ACPI methods here */ | ||
48 | int radeon_acpi_init(struct radeon_device *rdev) | ||
49 | { | ||
50 | acpi_handle handle; | ||
51 | int ret; | ||
52 | |||
53 | /* No need to proceed if we're sure that ATIF is not supported */ | ||
54 | if (!ASIC_IS_AVIVO(rdev) || !rdev->bios) | ||
55 | return 0; | ||
56 | |||
57 | /* Get the device handle */ | ||
58 | handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); | ||
59 | |||
60 | /* Call the ATIF method */ | ||
61 | ret = radeon_atif_call(handle); | ||
62 | if (ret) | ||
63 | return ret; | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index c0bbaa64157a..a5aff755f0d2 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -113,6 +113,7 @@ void r100_wb_fini(struct radeon_device *rdev); | |||
113 | int r100_wb_init(struct radeon_device *rdev); | 113 | int r100_wb_init(struct radeon_device *rdev); |
114 | int r100_cp_reset(struct radeon_device *rdev); | 114 | int r100_cp_reset(struct radeon_device *rdev); |
115 | void r100_vga_render_disable(struct radeon_device *rdev); | 115 | void r100_vga_render_disable(struct radeon_device *rdev); |
116 | void r100_restore_sanity(struct radeon_device *rdev); | ||
116 | int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, | 117 | int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, |
117 | struct radeon_cs_packet *pkt, | 118 | struct radeon_cs_packet *pkt, |
118 | struct radeon_bo *robj); | 119 | struct radeon_bo *robj); |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 10673ae59cfa..3bc2bcdf5308 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -723,7 +723,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
723 | } | 723 | } |
724 | 724 | ||
725 | if (i == ATOM_DEVICE_CV_INDEX) { | 725 | if (i == ATOM_DEVICE_CV_INDEX) { |
726 | DRM_DEBUG("Skipping Component Video\n"); | 726 | DRM_DEBUG_KMS("Skipping Component Video\n"); |
727 | continue; | 727 | continue; |
728 | } | 728 | } |
729 | 729 | ||
@@ -1032,21 +1032,18 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev) | |||
1032 | u8 frev, crev; | 1032 | u8 frev, crev; |
1033 | u16 data_offset; | 1033 | u16 data_offset; |
1034 | 1034 | ||
1035 | /* sideport is AMD only */ | ||
1036 | if (rdev->family == CHIP_RS600) | ||
1037 | return false; | ||
1038 | |||
1035 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | 1039 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
1036 | &frev, &crev, &data_offset)) { | 1040 | &frev, &crev, &data_offset)) { |
1037 | igp_info = (union igp_info *)(mode_info->atom_context->bios + | 1041 | igp_info = (union igp_info *)(mode_info->atom_context->bios + |
1038 | data_offset); | 1042 | data_offset); |
1039 | switch (crev) { | 1043 | switch (crev) { |
1040 | case 1: | 1044 | case 1: |
1041 | /* AMD IGPS */ | 1045 | if (igp_info->info.ulBootUpMemoryClock) |
1042 | if ((rdev->family == CHIP_RS690) || | 1046 | return true; |
1043 | (rdev->family == CHIP_RS740)) { | ||
1044 | if (igp_info->info.ulBootUpMemoryClock) | ||
1045 | return true; | ||
1046 | } else { | ||
1047 | if (igp_info->info.ucMemoryType & 0xf0) | ||
1048 | return true; | ||
1049 | } | ||
1050 | break; | 1047 | break; |
1051 | case 2: | 1048 | case 2: |
1052 | if (igp_info->info_2.ucMemoryType & 0x0f) | 1049 | if (igp_info->info_2.ucMemoryType & 0x0f) |
@@ -1095,7 +1092,7 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, | |||
1095 | (tmds_info->asMiscInfo[i]. | 1092 | (tmds_info->asMiscInfo[i]. |
1096 | ucPLL_VoltageSwing & 0xf) << 16; | 1093 | ucPLL_VoltageSwing & 0xf) << 16; |
1097 | 1094 | ||
1098 | DRM_DEBUG("TMDS PLL From ATOMBIOS %u %x\n", | 1095 | DRM_DEBUG_KMS("TMDS PLL From ATOMBIOS %u %x\n", |
1099 | tmds->tmds_pll[i].freq, | 1096 | tmds->tmds_pll[i].freq, |
1100 | tmds->tmds_pll[i].value); | 1097 | tmds->tmds_pll[i].value); |
1101 | 1098 | ||
@@ -1789,14 +1786,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
1789 | } | 1786 | } |
1790 | 1787 | ||
1791 | /* add the i2c bus for thermal/fan chip */ | 1788 | /* add the i2c bus for thermal/fan chip */ |
1792 | /* no support for internal controller yet */ | ||
1793 | if (controller->ucType > 0) { | 1789 | if (controller->ucType > 0) { |
1794 | if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) || | 1790 | if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) { |
1795 | (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) || | 1791 | DRM_INFO("Internal thermal controller %s fan control\n", |
1796 | (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN)) { | 1792 | (controller->ucFanParameters & |
1793 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
1794 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX; | ||
1795 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) { | ||
1796 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
1797 | (controller->ucFanParameters & | ||
1798 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
1799 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV770; | ||
1800 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) { | ||
1797 | DRM_INFO("Internal thermal controller %s fan control\n", | 1801 | DRM_INFO("Internal thermal controller %s fan control\n", |
1798 | (controller->ucFanParameters & | 1802 | (controller->ucFanParameters & |
1799 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | 1803 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); |
1804 | rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN; | ||
1800 | } else if ((controller->ucType == | 1805 | } else if ((controller->ucType == |
1801 | ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || | 1806 | ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || |
1802 | (controller->ucType == | 1807 | (controller->ucType == |
@@ -2179,11 +2184,11 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
2179 | if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) && | 2184 | if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) && |
2180 | (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) { | 2185 | (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) { |
2181 | if (connected) { | 2186 | if (connected) { |
2182 | DRM_DEBUG("TV1 connected\n"); | 2187 | DRM_DEBUG_KMS("TV1 connected\n"); |
2183 | bios_3_scratch |= ATOM_S3_TV1_ACTIVE; | 2188 | bios_3_scratch |= ATOM_S3_TV1_ACTIVE; |
2184 | bios_6_scratch |= ATOM_S6_ACC_REQ_TV1; | 2189 | bios_6_scratch |= ATOM_S6_ACC_REQ_TV1; |
2185 | } else { | 2190 | } else { |
2186 | DRM_DEBUG("TV1 disconnected\n"); | 2191 | DRM_DEBUG_KMS("TV1 disconnected\n"); |
2187 | bios_0_scratch &= ~ATOM_S0_TV1_MASK; | 2192 | bios_0_scratch &= ~ATOM_S0_TV1_MASK; |
2188 | bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE; | 2193 | bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE; |
2189 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_TV1; | 2194 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_TV1; |
@@ -2192,11 +2197,11 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
2192 | if ((radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) && | 2197 | if ((radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) && |
2193 | (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT)) { | 2198 | (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT)) { |
2194 | if (connected) { | 2199 | if (connected) { |
2195 | DRM_DEBUG("CV connected\n"); | 2200 | DRM_DEBUG_KMS("CV connected\n"); |
2196 | bios_3_scratch |= ATOM_S3_CV_ACTIVE; | 2201 | bios_3_scratch |= ATOM_S3_CV_ACTIVE; |
2197 | bios_6_scratch |= ATOM_S6_ACC_REQ_CV; | 2202 | bios_6_scratch |= ATOM_S6_ACC_REQ_CV; |
2198 | } else { | 2203 | } else { |
2199 | DRM_DEBUG("CV disconnected\n"); | 2204 | DRM_DEBUG_KMS("CV disconnected\n"); |
2200 | bios_0_scratch &= ~ATOM_S0_CV_MASK; | 2205 | bios_0_scratch &= ~ATOM_S0_CV_MASK; |
2201 | bios_3_scratch &= ~ATOM_S3_CV_ACTIVE; | 2206 | bios_3_scratch &= ~ATOM_S3_CV_ACTIVE; |
2202 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_CV; | 2207 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_CV; |
@@ -2205,12 +2210,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
2205 | if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) && | 2210 | if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) && |
2206 | (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) { | 2211 | (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) { |
2207 | if (connected) { | 2212 | if (connected) { |
2208 | DRM_DEBUG("LCD1 connected\n"); | 2213 | DRM_DEBUG_KMS("LCD1 connected\n"); |
2209 | bios_0_scratch |= ATOM_S0_LCD1; | 2214 | bios_0_scratch |= ATOM_S0_LCD1; |
2210 | bios_3_scratch |= ATOM_S3_LCD1_ACTIVE; | 2215 | bios_3_scratch |= ATOM_S3_LCD1_ACTIVE; |
2211 | bios_6_scratch |= ATOM_S6_ACC_REQ_LCD1; | 2216 | bios_6_scratch |= ATOM_S6_ACC_REQ_LCD1; |
2212 | } else { | 2217 | } else { |
2213 | DRM_DEBUG("LCD1 disconnected\n"); | 2218 | DRM_DEBUG_KMS("LCD1 disconnected\n"); |
2214 | bios_0_scratch &= ~ATOM_S0_LCD1; | 2219 | bios_0_scratch &= ~ATOM_S0_LCD1; |
2215 | bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE; | 2220 | bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE; |
2216 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_LCD1; | 2221 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_LCD1; |
@@ -2219,12 +2224,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
2219 | if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) && | 2224 | if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) && |
2220 | (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) { | 2225 | (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) { |
2221 | if (connected) { | 2226 | if (connected) { |
2222 | DRM_DEBUG("CRT1 connected\n"); | 2227 | DRM_DEBUG_KMS("CRT1 connected\n"); |
2223 | bios_0_scratch |= ATOM_S0_CRT1_COLOR; | 2228 | bios_0_scratch |= ATOM_S0_CRT1_COLOR; |
2224 | bios_3_scratch |= ATOM_S3_CRT1_ACTIVE; | 2229 | bios_3_scratch |= ATOM_S3_CRT1_ACTIVE; |
2225 | bios_6_scratch |= ATOM_S6_ACC_REQ_CRT1; | 2230 | bios_6_scratch |= ATOM_S6_ACC_REQ_CRT1; |
2226 | } else { | 2231 | } else { |
2227 | DRM_DEBUG("CRT1 disconnected\n"); | 2232 | DRM_DEBUG_KMS("CRT1 disconnected\n"); |
2228 | bios_0_scratch &= ~ATOM_S0_CRT1_MASK; | 2233 | bios_0_scratch &= ~ATOM_S0_CRT1_MASK; |
2229 | bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE; | 2234 | bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE; |
2230 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT1; | 2235 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT1; |
@@ -2233,12 +2238,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
2233 | if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) && | 2238 | if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) && |
2234 | (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) { | 2239 | (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) { |
2235 | if (connected) { | 2240 | if (connected) { |
2236 | DRM_DEBUG("CRT2 connected\n"); | 2241 | DRM_DEBUG_KMS("CRT2 connected\n"); |
2237 | bios_0_scratch |= ATOM_S0_CRT2_COLOR; | 2242 | bios_0_scratch |= ATOM_S0_CRT2_COLOR; |
2238 | bios_3_scratch |= ATOM_S3_CRT2_ACTIVE; | 2243 | bios_3_scratch |= ATOM_S3_CRT2_ACTIVE; |
2239 | bios_6_scratch |= ATOM_S6_ACC_REQ_CRT2; | 2244 | bios_6_scratch |= ATOM_S6_ACC_REQ_CRT2; |
2240 | } else { | 2245 | } else { |
2241 | DRM_DEBUG("CRT2 disconnected\n"); | 2246 | DRM_DEBUG_KMS("CRT2 disconnected\n"); |
2242 | bios_0_scratch &= ~ATOM_S0_CRT2_MASK; | 2247 | bios_0_scratch &= ~ATOM_S0_CRT2_MASK; |
2243 | bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE; | 2248 | bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE; |
2244 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT2; | 2249 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT2; |
@@ -2247,12 +2252,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
2247 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) && | 2252 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) && |
2248 | (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) { | 2253 | (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) { |
2249 | if (connected) { | 2254 | if (connected) { |
2250 | DRM_DEBUG("DFP1 connected\n"); | 2255 | DRM_DEBUG_KMS("DFP1 connected\n"); |
2251 | bios_0_scratch |= ATOM_S0_DFP1; | 2256 | bios_0_scratch |= ATOM_S0_DFP1; |
2252 | bios_3_scratch |= ATOM_S3_DFP1_ACTIVE; | 2257 | bios_3_scratch |= ATOM_S3_DFP1_ACTIVE; |
2253 | bios_6_scratch |= ATOM_S6_ACC_REQ_DFP1; | 2258 | bios_6_scratch |= ATOM_S6_ACC_REQ_DFP1; |
2254 | } else { | 2259 | } else { |
2255 | DRM_DEBUG("DFP1 disconnected\n"); | 2260 | DRM_DEBUG_KMS("DFP1 disconnected\n"); |
2256 | bios_0_scratch &= ~ATOM_S0_DFP1; | 2261 | bios_0_scratch &= ~ATOM_S0_DFP1; |
2257 | bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE; | 2262 | bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE; |
2258 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP1; | 2263 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP1; |
@@ -2261,12 +2266,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
2261 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) && | 2266 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) && |
2262 | (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) { | 2267 | (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) { |
2263 | if (connected) { | 2268 | if (connected) { |
2264 | DRM_DEBUG("DFP2 connected\n"); | 2269 | DRM_DEBUG_KMS("DFP2 connected\n"); |
2265 | bios_0_scratch |= ATOM_S0_DFP2; | 2270 | bios_0_scratch |= ATOM_S0_DFP2; |
2266 | bios_3_scratch |= ATOM_S3_DFP2_ACTIVE; | 2271 | bios_3_scratch |= ATOM_S3_DFP2_ACTIVE; |
2267 | bios_6_scratch |= ATOM_S6_ACC_REQ_DFP2; | 2272 | bios_6_scratch |= ATOM_S6_ACC_REQ_DFP2; |
2268 | } else { | 2273 | } else { |
2269 | DRM_DEBUG("DFP2 disconnected\n"); | 2274 | DRM_DEBUG_KMS("DFP2 disconnected\n"); |
2270 | bios_0_scratch &= ~ATOM_S0_DFP2; | 2275 | bios_0_scratch &= ~ATOM_S0_DFP2; |
2271 | bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE; | 2276 | bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE; |
2272 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP2; | 2277 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP2; |
@@ -2275,12 +2280,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
2275 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) && | 2280 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) && |
2276 | (radeon_connector->devices & ATOM_DEVICE_DFP3_SUPPORT)) { | 2281 | (radeon_connector->devices & ATOM_DEVICE_DFP3_SUPPORT)) { |
2277 | if (connected) { | 2282 | if (connected) { |
2278 | DRM_DEBUG("DFP3 connected\n"); | 2283 | DRM_DEBUG_KMS("DFP3 connected\n"); |
2279 | bios_0_scratch |= ATOM_S0_DFP3; | 2284 | bios_0_scratch |= ATOM_S0_DFP3; |
2280 | bios_3_scratch |= ATOM_S3_DFP3_ACTIVE; | 2285 | bios_3_scratch |= ATOM_S3_DFP3_ACTIVE; |
2281 | bios_6_scratch |= ATOM_S6_ACC_REQ_DFP3; | 2286 | bios_6_scratch |= ATOM_S6_ACC_REQ_DFP3; |
2282 | } else { | 2287 | } else { |
2283 | DRM_DEBUG("DFP3 disconnected\n"); | 2288 | DRM_DEBUG_KMS("DFP3 disconnected\n"); |
2284 | bios_0_scratch &= ~ATOM_S0_DFP3; | 2289 | bios_0_scratch &= ~ATOM_S0_DFP3; |
2285 | bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE; | 2290 | bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE; |
2286 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP3; | 2291 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP3; |
@@ -2289,12 +2294,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
2289 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) && | 2294 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) && |
2290 | (radeon_connector->devices & ATOM_DEVICE_DFP4_SUPPORT)) { | 2295 | (radeon_connector->devices & ATOM_DEVICE_DFP4_SUPPORT)) { |
2291 | if (connected) { | 2296 | if (connected) { |
2292 | DRM_DEBUG("DFP4 connected\n"); | 2297 | DRM_DEBUG_KMS("DFP4 connected\n"); |
2293 | bios_0_scratch |= ATOM_S0_DFP4; | 2298 | bios_0_scratch |= ATOM_S0_DFP4; |
2294 | bios_3_scratch |= ATOM_S3_DFP4_ACTIVE; | 2299 | bios_3_scratch |= ATOM_S3_DFP4_ACTIVE; |
2295 | bios_6_scratch |= ATOM_S6_ACC_REQ_DFP4; | 2300 | bios_6_scratch |= ATOM_S6_ACC_REQ_DFP4; |
2296 | } else { | 2301 | } else { |
2297 | DRM_DEBUG("DFP4 disconnected\n"); | 2302 | DRM_DEBUG_KMS("DFP4 disconnected\n"); |
2298 | bios_0_scratch &= ~ATOM_S0_DFP4; | 2303 | bios_0_scratch &= ~ATOM_S0_DFP4; |
2299 | bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE; | 2304 | bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE; |
2300 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP4; | 2305 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP4; |
@@ -2303,12 +2308,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
2303 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) && | 2308 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) && |
2304 | (radeon_connector->devices & ATOM_DEVICE_DFP5_SUPPORT)) { | 2309 | (radeon_connector->devices & ATOM_DEVICE_DFP5_SUPPORT)) { |
2305 | if (connected) { | 2310 | if (connected) { |
2306 | DRM_DEBUG("DFP5 connected\n"); | 2311 | DRM_DEBUG_KMS("DFP5 connected\n"); |
2307 | bios_0_scratch |= ATOM_S0_DFP5; | 2312 | bios_0_scratch |= ATOM_S0_DFP5; |
2308 | bios_3_scratch |= ATOM_S3_DFP5_ACTIVE; | 2313 | bios_3_scratch |= ATOM_S3_DFP5_ACTIVE; |
2309 | bios_6_scratch |= ATOM_S6_ACC_REQ_DFP5; | 2314 | bios_6_scratch |= ATOM_S6_ACC_REQ_DFP5; |
2310 | } else { | 2315 | } else { |
2311 | DRM_DEBUG("DFP5 disconnected\n"); | 2316 | DRM_DEBUG_KMS("DFP5 disconnected\n"); |
2312 | bios_0_scratch &= ~ATOM_S0_DFP5; | 2317 | bios_0_scratch &= ~ATOM_S0_DFP5; |
2313 | bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE; | 2318 | bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE; |
2314 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5; | 2319 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5; |
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 2c9213739999..654787ec43f4 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
@@ -53,7 +53,7 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev) | |||
53 | return false; | 53 | return false; |
54 | 54 | ||
55 | rdev->bios = NULL; | 55 | rdev->bios = NULL; |
56 | vram_base = drm_get_resource_start(rdev->ddev, 0); | 56 | vram_base = pci_resource_start(rdev->pdev, 0); |
57 | bios = ioremap(vram_base, size); | 57 | bios = ioremap(vram_base, size); |
58 | if (!bios) { | 58 | if (!bios) { |
59 | return false; | 59 | return false; |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 2417d7b06fdb..5e1474cde4b4 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -693,6 +693,10 @@ bool radeon_combios_sideport_present(struct radeon_device *rdev) | |||
693 | struct drm_device *dev = rdev->ddev; | 693 | struct drm_device *dev = rdev->ddev; |
694 | u16 igp_info; | 694 | u16 igp_info; |
695 | 695 | ||
696 | /* sideport is AMD only */ | ||
697 | if (rdev->family == CHIP_RS400) | ||
698 | return false; | ||
699 | |||
696 | igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE); | 700 | igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE); |
697 | 701 | ||
698 | if (igp_info) { | 702 | if (igp_info) { |
@@ -1205,7 +1209,7 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, | |||
1205 | RBIOS32(tmds_info + i * 10 + 0x08); | 1209 | RBIOS32(tmds_info + i * 10 + 0x08); |
1206 | tmds->tmds_pll[i].freq = | 1210 | tmds->tmds_pll[i].freq = |
1207 | RBIOS16(tmds_info + i * 10 + 0x10); | 1211 | RBIOS16(tmds_info + i * 10 + 0x10); |
1208 | DRM_DEBUG("TMDS PLL From COMBIOS %u %x\n", | 1212 | DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n", |
1209 | tmds->tmds_pll[i].freq, | 1213 | tmds->tmds_pll[i].freq, |
1210 | tmds->tmds_pll[i].value); | 1214 | tmds->tmds_pll[i].value); |
1211 | } | 1215 | } |
@@ -1223,7 +1227,7 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, | |||
1223 | stride += 10; | 1227 | stride += 10; |
1224 | else | 1228 | else |
1225 | stride += 6; | 1229 | stride += 6; |
1226 | DRM_DEBUG("TMDS PLL From COMBIOS %u %x\n", | 1230 | DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n", |
1227 | tmds->tmds_pll[i].freq, | 1231 | tmds->tmds_pll[i].freq, |
1228 | tmds->tmds_pll[i].value); | 1232 | tmds->tmds_pll[i].value); |
1229 | } | 1233 | } |
@@ -2208,7 +2212,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2208 | uint16_t tmds_info = | 2212 | uint16_t tmds_info = |
2209 | combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); | 2213 | combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); |
2210 | if (tmds_info) { | 2214 | if (tmds_info) { |
2211 | DRM_DEBUG("Found DFP table, assuming DVI connector\n"); | 2215 | DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n"); |
2212 | 2216 | ||
2213 | radeon_add_legacy_encoder(dev, | 2217 | radeon_add_legacy_encoder(dev, |
2214 | radeon_get_encoder_id(dev, | 2218 | radeon_get_encoder_id(dev, |
@@ -2234,7 +2238,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2234 | } else { | 2238 | } else { |
2235 | uint16_t crt_info = | 2239 | uint16_t crt_info = |
2236 | combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); | 2240 | combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); |
2237 | DRM_DEBUG("Found CRT table, assuming VGA connector\n"); | 2241 | DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n"); |
2238 | if (crt_info) { | 2242 | if (crt_info) { |
2239 | radeon_add_legacy_encoder(dev, | 2243 | radeon_add_legacy_encoder(dev, |
2240 | radeon_get_encoder_id(dev, | 2244 | radeon_get_encoder_id(dev, |
@@ -2251,7 +2255,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2251 | CONNECTOR_OBJECT_ID_VGA, | 2255 | CONNECTOR_OBJECT_ID_VGA, |
2252 | &hpd); | 2256 | &hpd); |
2253 | } else { | 2257 | } else { |
2254 | DRM_DEBUG("No connector info found\n"); | 2258 | DRM_DEBUG_KMS("No connector info found\n"); |
2255 | return false; | 2259 | return false; |
2256 | } | 2260 | } |
2257 | } | 2261 | } |
@@ -2340,7 +2344,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2340 | ddc_i2c.valid = false; | 2344 | ddc_i2c.valid = false; |
2341 | break; | 2345 | break; |
2342 | } | 2346 | } |
2343 | DRM_DEBUG("LCD DDC Info Table found!\n"); | 2347 | DRM_DEBUG_KMS("LCD DDC Info Table found!\n"); |
2344 | } else | 2348 | } else |
2345 | ddc_i2c.valid = false; | 2349 | ddc_i2c.valid = false; |
2346 | 2350 | ||
@@ -2941,9 +2945,8 @@ static void combios_write_ram_size(struct drm_device *dev) | |||
2941 | if (rev < 3) { | 2945 | if (rev < 3) { |
2942 | mem_cntl = RBIOS32(offset + 1); | 2946 | mem_cntl = RBIOS32(offset + 1); |
2943 | mem_size = RBIOS16(offset + 5); | 2947 | mem_size = RBIOS16(offset + 5); |
2944 | if (((rdev->flags & RADEON_FAMILY_MASK) < CHIP_R200) && | 2948 | if ((rdev->family < CHIP_R200) && |
2945 | ((dev->pdev->device != 0x515e) | 2949 | !ASIC_IS_RN50(rdev)) |
2946 | && (dev->pdev->device != 0x5969))) | ||
2947 | WREG32(RADEON_MEM_CNTL, mem_cntl); | 2950 | WREG32(RADEON_MEM_CNTL, mem_cntl); |
2948 | } | 2951 | } |
2949 | } | 2952 | } |
@@ -2954,10 +2957,8 @@ static void combios_write_ram_size(struct drm_device *dev) | |||
2954 | if (offset) { | 2957 | if (offset) { |
2955 | rev = RBIOS8(offset - 1); | 2958 | rev = RBIOS8(offset - 1); |
2956 | if (rev < 1) { | 2959 | if (rev < 1) { |
2957 | if (((rdev->flags & RADEON_FAMILY_MASK) < | 2960 | if ((rdev->family < CHIP_R200) |
2958 | CHIP_R200) | 2961 | && !ASIC_IS_RN50(rdev)) { |
2959 | && ((dev->pdev->device != 0x515e) | ||
2960 | && (dev->pdev->device != 0x5969))) { | ||
2961 | int ram = 0; | 2962 | int ram = 0; |
2962 | int mem_addr_mapping = 0; | 2963 | int mem_addr_mapping = 0; |
2963 | 2964 | ||
@@ -3121,14 +3122,14 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector, | |||
3121 | if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) && | 3122 | if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) && |
3122 | (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) { | 3123 | (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) { |
3123 | if (connected) { | 3124 | if (connected) { |
3124 | DRM_DEBUG("TV1 connected\n"); | 3125 | DRM_DEBUG_KMS("TV1 connected\n"); |
3125 | /* fix me */ | 3126 | /* fix me */ |
3126 | bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO; | 3127 | bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO; |
3127 | /*save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; */ | 3128 | /*save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; */ |
3128 | bios_5_scratch |= RADEON_TV1_ON; | 3129 | bios_5_scratch |= RADEON_TV1_ON; |
3129 | bios_5_scratch |= RADEON_ACC_REQ_TV1; | 3130 | bios_5_scratch |= RADEON_ACC_REQ_TV1; |
3130 | } else { | 3131 | } else { |
3131 | DRM_DEBUG("TV1 disconnected\n"); | 3132 | DRM_DEBUG_KMS("TV1 disconnected\n"); |
3132 | bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK; | 3133 | bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK; |
3133 | bios_5_scratch &= ~RADEON_TV1_ON; | 3134 | bios_5_scratch &= ~RADEON_TV1_ON; |
3134 | bios_5_scratch &= ~RADEON_ACC_REQ_TV1; | 3135 | bios_5_scratch &= ~RADEON_ACC_REQ_TV1; |
@@ -3137,12 +3138,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector, | |||
3137 | if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) && | 3138 | if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) && |
3138 | (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) { | 3139 | (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) { |
3139 | if (connected) { | 3140 | if (connected) { |
3140 | DRM_DEBUG("LCD1 connected\n"); | 3141 | DRM_DEBUG_KMS("LCD1 connected\n"); |
3141 | bios_4_scratch |= RADEON_LCD1_ATTACHED; | 3142 | bios_4_scratch |= RADEON_LCD1_ATTACHED; |
3142 | bios_5_scratch |= RADEON_LCD1_ON; | 3143 | bios_5_scratch |= RADEON_LCD1_ON; |
3143 | bios_5_scratch |= RADEON_ACC_REQ_LCD1; | 3144 | bios_5_scratch |= RADEON_ACC_REQ_LCD1; |
3144 | } else { | 3145 | } else { |
3145 | DRM_DEBUG("LCD1 disconnected\n"); | 3146 | DRM_DEBUG_KMS("LCD1 disconnected\n"); |
3146 | bios_4_scratch &= ~RADEON_LCD1_ATTACHED; | 3147 | bios_4_scratch &= ~RADEON_LCD1_ATTACHED; |
3147 | bios_5_scratch &= ~RADEON_LCD1_ON; | 3148 | bios_5_scratch &= ~RADEON_LCD1_ON; |
3148 | bios_5_scratch &= ~RADEON_ACC_REQ_LCD1; | 3149 | bios_5_scratch &= ~RADEON_ACC_REQ_LCD1; |
@@ -3151,12 +3152,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector, | |||
3151 | if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) && | 3152 | if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) && |
3152 | (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) { | 3153 | (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) { |
3153 | if (connected) { | 3154 | if (connected) { |
3154 | DRM_DEBUG("CRT1 connected\n"); | 3155 | DRM_DEBUG_KMS("CRT1 connected\n"); |
3155 | bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR; | 3156 | bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR; |
3156 | bios_5_scratch |= RADEON_CRT1_ON; | 3157 | bios_5_scratch |= RADEON_CRT1_ON; |
3157 | bios_5_scratch |= RADEON_ACC_REQ_CRT1; | 3158 | bios_5_scratch |= RADEON_ACC_REQ_CRT1; |
3158 | } else { | 3159 | } else { |
3159 | DRM_DEBUG("CRT1 disconnected\n"); | 3160 | DRM_DEBUG_KMS("CRT1 disconnected\n"); |
3160 | bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK; | 3161 | bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK; |
3161 | bios_5_scratch &= ~RADEON_CRT1_ON; | 3162 | bios_5_scratch &= ~RADEON_CRT1_ON; |
3162 | bios_5_scratch &= ~RADEON_ACC_REQ_CRT1; | 3163 | bios_5_scratch &= ~RADEON_ACC_REQ_CRT1; |
@@ -3165,12 +3166,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector, | |||
3165 | if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) && | 3166 | if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) && |
3166 | (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) { | 3167 | (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) { |
3167 | if (connected) { | 3168 | if (connected) { |
3168 | DRM_DEBUG("CRT2 connected\n"); | 3169 | DRM_DEBUG_KMS("CRT2 connected\n"); |
3169 | bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR; | 3170 | bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR; |
3170 | bios_5_scratch |= RADEON_CRT2_ON; | 3171 | bios_5_scratch |= RADEON_CRT2_ON; |
3171 | bios_5_scratch |= RADEON_ACC_REQ_CRT2; | 3172 | bios_5_scratch |= RADEON_ACC_REQ_CRT2; |
3172 | } else { | 3173 | } else { |
3173 | DRM_DEBUG("CRT2 disconnected\n"); | 3174 | DRM_DEBUG_KMS("CRT2 disconnected\n"); |
3174 | bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK; | 3175 | bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK; |
3175 | bios_5_scratch &= ~RADEON_CRT2_ON; | 3176 | bios_5_scratch &= ~RADEON_CRT2_ON; |
3176 | bios_5_scratch &= ~RADEON_ACC_REQ_CRT2; | 3177 | bios_5_scratch &= ~RADEON_ACC_REQ_CRT2; |
@@ -3179,12 +3180,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector, | |||
3179 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) && | 3180 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) && |
3180 | (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) { | 3181 | (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) { |
3181 | if (connected) { | 3182 | if (connected) { |
3182 | DRM_DEBUG("DFP1 connected\n"); | 3183 | DRM_DEBUG_KMS("DFP1 connected\n"); |
3183 | bios_4_scratch |= RADEON_DFP1_ATTACHED; | 3184 | bios_4_scratch |= RADEON_DFP1_ATTACHED; |
3184 | bios_5_scratch |= RADEON_DFP1_ON; | 3185 | bios_5_scratch |= RADEON_DFP1_ON; |
3185 | bios_5_scratch |= RADEON_ACC_REQ_DFP1; | 3186 | bios_5_scratch |= RADEON_ACC_REQ_DFP1; |
3186 | } else { | 3187 | } else { |
3187 | DRM_DEBUG("DFP1 disconnected\n"); | 3188 | DRM_DEBUG_KMS("DFP1 disconnected\n"); |
3188 | bios_4_scratch &= ~RADEON_DFP1_ATTACHED; | 3189 | bios_4_scratch &= ~RADEON_DFP1_ATTACHED; |
3189 | bios_5_scratch &= ~RADEON_DFP1_ON; | 3190 | bios_5_scratch &= ~RADEON_DFP1_ON; |
3190 | bios_5_scratch &= ~RADEON_ACC_REQ_DFP1; | 3191 | bios_5_scratch &= ~RADEON_ACC_REQ_DFP1; |
@@ -3193,12 +3194,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector, | |||
3193 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) && | 3194 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) && |
3194 | (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) { | 3195 | (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) { |
3195 | if (connected) { | 3196 | if (connected) { |
3196 | DRM_DEBUG("DFP2 connected\n"); | 3197 | DRM_DEBUG_KMS("DFP2 connected\n"); |
3197 | bios_4_scratch |= RADEON_DFP2_ATTACHED; | 3198 | bios_4_scratch |= RADEON_DFP2_ATTACHED; |
3198 | bios_5_scratch |= RADEON_DFP2_ON; | 3199 | bios_5_scratch |= RADEON_DFP2_ON; |
3199 | bios_5_scratch |= RADEON_ACC_REQ_DFP2; | 3200 | bios_5_scratch |= RADEON_ACC_REQ_DFP2; |
3200 | } else { | 3201 | } else { |
3201 | DRM_DEBUG("DFP2 disconnected\n"); | 3202 | DRM_DEBUG_KMS("DFP2 disconnected\n"); |
3202 | bios_4_scratch &= ~RADEON_DFP2_ATTACHED; | 3203 | bios_4_scratch &= ~RADEON_DFP2_ATTACHED; |
3203 | bios_5_scratch &= ~RADEON_DFP2_ON; | 3204 | bios_5_scratch &= ~RADEON_DFP2_ON; |
3204 | bios_5_scratch &= ~RADEON_ACC_REQ_DFP2; | 3205 | bios_5_scratch &= ~RADEON_ACC_REQ_DFP2; |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index adccbc2c202c..2395c8600cf4 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -214,7 +214,7 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode | |||
214 | mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; | 214 | mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; |
215 | drm_mode_set_name(mode); | 215 | drm_mode_set_name(mode); |
216 | 216 | ||
217 | DRM_DEBUG("Adding native panel mode %s\n", mode->name); | 217 | DRM_DEBUG_KMS("Adding native panel mode %s\n", mode->name); |
218 | } else if (native_mode->hdisplay != 0 && | 218 | } else if (native_mode->hdisplay != 0 && |
219 | native_mode->vdisplay != 0) { | 219 | native_mode->vdisplay != 0) { |
220 | /* mac laptops without an edid */ | 220 | /* mac laptops without an edid */ |
@@ -226,7 +226,7 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode | |||
226 | */ | 226 | */ |
227 | mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false); | 227 | mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false); |
228 | mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; | 228 | mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; |
229 | DRM_DEBUG("Adding cvt approximation of native panel mode %s\n", mode->name); | 229 | DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name); |
230 | } | 230 | } |
231 | return mode; | 231 | return mode; |
232 | } | 232 | } |
@@ -312,6 +312,20 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr | |||
312 | } | 312 | } |
313 | } | 313 | } |
314 | 314 | ||
315 | if (property == rdev->mode_info.underscan_property) { | ||
316 | /* need to find digital encoder on connector */ | ||
317 | encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); | ||
318 | if (!encoder) | ||
319 | return 0; | ||
320 | |||
321 | radeon_encoder = to_radeon_encoder(encoder); | ||
322 | |||
323 | if (radeon_encoder->underscan_type != val) { | ||
324 | radeon_encoder->underscan_type = val; | ||
325 | radeon_property_change_mode(&radeon_encoder->base); | ||
326 | } | ||
327 | } | ||
328 | |||
315 | if (property == rdev->mode_info.tv_std_property) { | 329 | if (property == rdev->mode_info.tv_std_property) { |
316 | encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TVDAC); | 330 | encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TVDAC); |
317 | if (!encoder) { | 331 | if (!encoder) { |
@@ -522,7 +536,7 @@ static int radeon_lvds_set_property(struct drm_connector *connector, | |||
522 | struct radeon_encoder *radeon_encoder; | 536 | struct radeon_encoder *radeon_encoder; |
523 | enum radeon_rmx_type rmx_type; | 537 | enum radeon_rmx_type rmx_type; |
524 | 538 | ||
525 | DRM_DEBUG("\n"); | 539 | DRM_DEBUG_KMS("\n"); |
526 | if (property != dev->mode_config.scaling_mode_property) | 540 | if (property != dev->mode_config.scaling_mode_property) |
527 | return 0; | 541 | return 0; |
528 | 542 | ||
@@ -1082,6 +1096,8 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1082 | drm_connector_attach_property(&radeon_connector->base, | 1096 | drm_connector_attach_property(&radeon_connector->base, |
1083 | rdev->mode_info.load_detect_property, | 1097 | rdev->mode_info.load_detect_property, |
1084 | 1); | 1098 | 1); |
1099 | /* no HPD on analog connectors */ | ||
1100 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | ||
1085 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 1101 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
1086 | break; | 1102 | break; |
1087 | case DRM_MODE_CONNECTOR_DVIA: | 1103 | case DRM_MODE_CONNECTOR_DVIA: |
@@ -1096,6 +1112,8 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1096 | drm_connector_attach_property(&radeon_connector->base, | 1112 | drm_connector_attach_property(&radeon_connector->base, |
1097 | rdev->mode_info.load_detect_property, | 1113 | rdev->mode_info.load_detect_property, |
1098 | 1); | 1114 | 1); |
1115 | /* no HPD on analog connectors */ | ||
1116 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | ||
1099 | break; | 1117 | break; |
1100 | case DRM_MODE_CONNECTOR_DVII: | 1118 | case DRM_MODE_CONNECTOR_DVII: |
1101 | case DRM_MODE_CONNECTOR_DVID: | 1119 | case DRM_MODE_CONNECTOR_DVID: |
@@ -1116,6 +1134,10 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1116 | drm_connector_attach_property(&radeon_connector->base, | 1134 | drm_connector_attach_property(&radeon_connector->base, |
1117 | rdev->mode_info.coherent_mode_property, | 1135 | rdev->mode_info.coherent_mode_property, |
1118 | 1); | 1136 | 1); |
1137 | if (ASIC_IS_AVIVO(rdev)) | ||
1138 | drm_connector_attach_property(&radeon_connector->base, | ||
1139 | rdev->mode_info.underscan_property, | ||
1140 | UNDERSCAN_AUTO); | ||
1119 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { | 1141 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { |
1120 | radeon_connector->dac_load_detect = true; | 1142 | radeon_connector->dac_load_detect = true; |
1121 | drm_connector_attach_property(&radeon_connector->base, | 1143 | drm_connector_attach_property(&radeon_connector->base, |
@@ -1141,6 +1163,10 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1141 | drm_connector_attach_property(&radeon_connector->base, | 1163 | drm_connector_attach_property(&radeon_connector->base, |
1142 | rdev->mode_info.coherent_mode_property, | 1164 | rdev->mode_info.coherent_mode_property, |
1143 | 1); | 1165 | 1); |
1166 | if (ASIC_IS_AVIVO(rdev)) | ||
1167 | drm_connector_attach_property(&radeon_connector->base, | ||
1168 | rdev->mode_info.underscan_property, | ||
1169 | UNDERSCAN_AUTO); | ||
1144 | subpixel_order = SubPixelHorizontalRGB; | 1170 | subpixel_order = SubPixelHorizontalRGB; |
1145 | break; | 1171 | break; |
1146 | case DRM_MODE_CONNECTOR_DisplayPort: | 1172 | case DRM_MODE_CONNECTOR_DisplayPort: |
@@ -1172,6 +1198,10 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1172 | drm_connector_attach_property(&radeon_connector->base, | 1198 | drm_connector_attach_property(&radeon_connector->base, |
1173 | rdev->mode_info.coherent_mode_property, | 1199 | rdev->mode_info.coherent_mode_property, |
1174 | 1); | 1200 | 1); |
1201 | if (ASIC_IS_AVIVO(rdev)) | ||
1202 | drm_connector_attach_property(&radeon_connector->base, | ||
1203 | rdev->mode_info.underscan_property, | ||
1204 | UNDERSCAN_AUTO); | ||
1175 | break; | 1205 | break; |
1176 | case DRM_MODE_CONNECTOR_SVIDEO: | 1206 | case DRM_MODE_CONNECTOR_SVIDEO: |
1177 | case DRM_MODE_CONNECTOR_Composite: | 1207 | case DRM_MODE_CONNECTOR_Composite: |
@@ -1186,6 +1216,8 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1186 | drm_connector_attach_property(&radeon_connector->base, | 1216 | drm_connector_attach_property(&radeon_connector->base, |
1187 | rdev->mode_info.tv_std_property, | 1217 | rdev->mode_info.tv_std_property, |
1188 | radeon_atombios_get_tv_info(rdev)); | 1218 | radeon_atombios_get_tv_info(rdev)); |
1219 | /* no HPD on analog connectors */ | ||
1220 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | ||
1189 | } | 1221 | } |
1190 | break; | 1222 | break; |
1191 | case DRM_MODE_CONNECTOR_LVDS: | 1223 | case DRM_MODE_CONNECTOR_LVDS: |
@@ -1209,7 +1241,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1209 | break; | 1241 | break; |
1210 | } | 1242 | } |
1211 | 1243 | ||
1212 | if (hpd->hpd == RADEON_HPD_NONE) { | 1244 | if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { |
1213 | if (i2c_bus->valid) | 1245 | if (i2c_bus->valid) |
1214 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 1246 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
1215 | } else | 1247 | } else |
@@ -1276,6 +1308,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1276 | drm_connector_attach_property(&radeon_connector->base, | 1308 | drm_connector_attach_property(&radeon_connector->base, |
1277 | rdev->mode_info.load_detect_property, | 1309 | rdev->mode_info.load_detect_property, |
1278 | 1); | 1310 | 1); |
1311 | /* no HPD on analog connectors */ | ||
1312 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | ||
1279 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 1313 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
1280 | break; | 1314 | break; |
1281 | case DRM_MODE_CONNECTOR_DVIA: | 1315 | case DRM_MODE_CONNECTOR_DVIA: |
@@ -1290,6 +1324,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1290 | drm_connector_attach_property(&radeon_connector->base, | 1324 | drm_connector_attach_property(&radeon_connector->base, |
1291 | rdev->mode_info.load_detect_property, | 1325 | rdev->mode_info.load_detect_property, |
1292 | 1); | 1326 | 1); |
1327 | /* no HPD on analog connectors */ | ||
1328 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | ||
1293 | break; | 1329 | break; |
1294 | case DRM_MODE_CONNECTOR_DVII: | 1330 | case DRM_MODE_CONNECTOR_DVII: |
1295 | case DRM_MODE_CONNECTOR_DVID: | 1331 | case DRM_MODE_CONNECTOR_DVID: |
@@ -1328,6 +1364,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1328 | drm_connector_attach_property(&radeon_connector->base, | 1364 | drm_connector_attach_property(&radeon_connector->base, |
1329 | rdev->mode_info.tv_std_property, | 1365 | rdev->mode_info.tv_std_property, |
1330 | radeon_combios_get_tv_info(rdev)); | 1366 | radeon_combios_get_tv_info(rdev)); |
1367 | /* no HPD on analog connectors */ | ||
1368 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | ||
1331 | } | 1369 | } |
1332 | break; | 1370 | break; |
1333 | case DRM_MODE_CONNECTOR_LVDS: | 1371 | case DRM_MODE_CONNECTOR_LVDS: |
@@ -1345,7 +1383,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1345 | break; | 1383 | break; |
1346 | } | 1384 | } |
1347 | 1385 | ||
1348 | if (hpd->hpd == RADEON_HPD_NONE) { | 1386 | if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { |
1349 | if (i2c_bus->valid) | 1387 | if (i2c_bus->valid) |
1350 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 1388 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
1351 | } else | 1389 | } else |
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 2f042a3c0e62..eb6b9eed7349 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -2120,8 +2120,8 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) | |||
2120 | else | 2120 | else |
2121 | dev_priv->flags |= RADEON_IS_PCI; | 2121 | dev_priv->flags |= RADEON_IS_PCI; |
2122 | 2122 | ||
2123 | ret = drm_addmap(dev, drm_get_resource_start(dev, 2), | 2123 | ret = drm_addmap(dev, pci_resource_start(dev->pdev, 2), |
2124 | drm_get_resource_len(dev, 2), _DRM_REGISTERS, | 2124 | pci_resource_len(dev->pdev, 2), _DRM_REGISTERS, |
2125 | _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio); | 2125 | _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio); |
2126 | if (ret != 0) | 2126 | if (ret != 0) |
2127 | return ret; | 2127 | return ret; |
@@ -2194,9 +2194,9 @@ int radeon_driver_firstopen(struct drm_device *dev) | |||
2194 | 2194 | ||
2195 | dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; | 2195 | dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; |
2196 | 2196 | ||
2197 | dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); | 2197 | dev_priv->fb_aper_offset = pci_resource_start(dev->pdev, 0); |
2198 | ret = drm_addmap(dev, dev_priv->fb_aper_offset, | 2198 | ret = drm_addmap(dev, dev_priv->fb_aper_offset, |
2199 | drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, | 2199 | pci_resource_len(dev->pdev, 0), _DRM_FRAME_BUFFER, |
2200 | _DRM_WRITE_COMBINING, &map); | 2200 | _DRM_WRITE_COMBINING, &map); |
2201 | if (ret != 0) | 2201 | if (ret != 0) |
2202 | return ret; | 2202 | return ret; |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index dd279da90546..a64811a94519 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -415,6 +415,22 @@ static uint32_t cail_reg_read(struct card_info *info, uint32_t reg) | |||
415 | return r; | 415 | return r; |
416 | } | 416 | } |
417 | 417 | ||
418 | static void cail_ioreg_write(struct card_info *info, uint32_t reg, uint32_t val) | ||
419 | { | ||
420 | struct radeon_device *rdev = info->dev->dev_private; | ||
421 | |||
422 | WREG32_IO(reg*4, val); | ||
423 | } | ||
424 | |||
425 | static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) | ||
426 | { | ||
427 | struct radeon_device *rdev = info->dev->dev_private; | ||
428 | uint32_t r; | ||
429 | |||
430 | r = RREG32_IO(reg*4); | ||
431 | return r; | ||
432 | } | ||
433 | |||
418 | int radeon_atombios_init(struct radeon_device *rdev) | 434 | int radeon_atombios_init(struct radeon_device *rdev) |
419 | { | 435 | { |
420 | struct card_info *atom_card_info = | 436 | struct card_info *atom_card_info = |
@@ -427,6 +443,15 @@ int radeon_atombios_init(struct radeon_device *rdev) | |||
427 | atom_card_info->dev = rdev->ddev; | 443 | atom_card_info->dev = rdev->ddev; |
428 | atom_card_info->reg_read = cail_reg_read; | 444 | atom_card_info->reg_read = cail_reg_read; |
429 | atom_card_info->reg_write = cail_reg_write; | 445 | atom_card_info->reg_write = cail_reg_write; |
446 | /* needed for iio ops */ | ||
447 | if (rdev->rio_mem) { | ||
448 | atom_card_info->ioreg_read = cail_ioreg_read; | ||
449 | atom_card_info->ioreg_write = cail_ioreg_write; | ||
450 | } else { | ||
451 | DRM_ERROR("Unable to find PCI I/O BAR; using MMIO for ATOM IIO\n"); | ||
452 | atom_card_info->ioreg_read = cail_reg_read; | ||
453 | atom_card_info->ioreg_write = cail_reg_write; | ||
454 | } | ||
430 | atom_card_info->mc_read = cail_mc_read; | 455 | atom_card_info->mc_read = cail_mc_read; |
431 | atom_card_info->mc_write = cail_mc_write; | 456 | atom_card_info->mc_write = cail_mc_write; |
432 | atom_card_info->pll_read = cail_pll_read; | 457 | atom_card_info->pll_read = cail_pll_read; |
@@ -573,7 +598,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
573 | struct pci_dev *pdev, | 598 | struct pci_dev *pdev, |
574 | uint32_t flags) | 599 | uint32_t flags) |
575 | { | 600 | { |
576 | int r; | 601 | int r, i; |
577 | int dma_bits; | 602 | int dma_bits; |
578 | 603 | ||
579 | rdev->shutdown = false; | 604 | rdev->shutdown = false; |
@@ -650,8 +675,8 @@ int radeon_device_init(struct radeon_device *rdev, | |||
650 | 675 | ||
651 | /* Registers mapping */ | 676 | /* Registers mapping */ |
652 | /* TODO: block userspace mapping of io register */ | 677 | /* TODO: block userspace mapping of io register */ |
653 | rdev->rmmio_base = drm_get_resource_start(rdev->ddev, 2); | 678 | rdev->rmmio_base = pci_resource_start(rdev->pdev, 2); |
654 | rdev->rmmio_size = drm_get_resource_len(rdev->ddev, 2); | 679 | rdev->rmmio_size = pci_resource_len(rdev->pdev, 2); |
655 | rdev->rmmio = ioremap(rdev->rmmio_base, rdev->rmmio_size); | 680 | rdev->rmmio = ioremap(rdev->rmmio_base, rdev->rmmio_size); |
656 | if (rdev->rmmio == NULL) { | 681 | if (rdev->rmmio == NULL) { |
657 | return -ENOMEM; | 682 | return -ENOMEM; |
@@ -659,6 +684,17 @@ int radeon_device_init(struct radeon_device *rdev, | |||
659 | DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); | 684 | DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); |
660 | DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); | 685 | DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); |
661 | 686 | ||
687 | /* io port mapping */ | ||
688 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | ||
689 | if (pci_resource_flags(rdev->pdev, i) & IORESOURCE_IO) { | ||
690 | rdev->rio_mem_size = pci_resource_len(rdev->pdev, i); | ||
691 | rdev->rio_mem = pci_iomap(rdev->pdev, i, rdev->rio_mem_size); | ||
692 | break; | ||
693 | } | ||
694 | } | ||
695 | if (rdev->rio_mem == NULL) | ||
696 | DRM_ERROR("Unable to find PCI I/O BAR\n"); | ||
697 | |||
662 | /* if we have > 1 VGA cards, then disable the radeon VGA resources */ | 698 | /* if we have > 1 VGA cards, then disable the radeon VGA resources */ |
663 | /* this will fail for cards that aren't VGA class devices, just | 699 | /* this will fail for cards that aren't VGA class devices, just |
664 | * ignore it */ | 700 | * ignore it */ |
@@ -701,6 +737,9 @@ void radeon_device_fini(struct radeon_device *rdev) | |||
701 | destroy_workqueue(rdev->wq); | 737 | destroy_workqueue(rdev->wq); |
702 | vga_switcheroo_unregister_client(rdev->pdev); | 738 | vga_switcheroo_unregister_client(rdev->pdev); |
703 | vga_client_register(rdev->pdev, NULL, NULL, NULL); | 739 | vga_client_register(rdev->pdev, NULL, NULL, NULL); |
740 | if (rdev->rio_mem) | ||
741 | pci_iounmap(rdev->pdev, rdev->rio_mem); | ||
742 | rdev->rio_mem = NULL; | ||
704 | iounmap(rdev->rmmio); | 743 | iounmap(rdev->rmmio); |
705 | rdev->rmmio = NULL; | 744 | rdev->rmmio = NULL; |
706 | } | 745 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 8154cdf796e4..74dac9635d70 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -42,7 +42,7 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc) | |||
42 | struct radeon_device *rdev = dev->dev_private; | 42 | struct radeon_device *rdev = dev->dev_private; |
43 | int i; | 43 | int i; |
44 | 44 | ||
45 | DRM_DEBUG("%d\n", radeon_crtc->crtc_id); | 45 | DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); |
46 | WREG32(AVIVO_DC_LUTA_CONTROL + radeon_crtc->crtc_offset, 0); | 46 | WREG32(AVIVO_DC_LUTA_CONTROL + radeon_crtc->crtc_offset, 0); |
47 | 47 | ||
48 | WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); | 48 | WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); |
@@ -75,7 +75,7 @@ static void evergreen_crtc_load_lut(struct drm_crtc *crtc) | |||
75 | struct radeon_device *rdev = dev->dev_private; | 75 | struct radeon_device *rdev = dev->dev_private; |
76 | int i; | 76 | int i; |
77 | 77 | ||
78 | DRM_DEBUG("%d\n", radeon_crtc->crtc_id); | 78 | DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); |
79 | WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0); | 79 | WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0); |
80 | 80 | ||
81 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); | 81 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); |
@@ -469,7 +469,7 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll, | |||
469 | uint32_t post_div; | 469 | uint32_t post_div; |
470 | u32 pll_out_min, pll_out_max; | 470 | u32 pll_out_min, pll_out_max; |
471 | 471 | ||
472 | DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div); | 472 | DRM_DEBUG_KMS("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div); |
473 | freq = freq * 1000; | 473 | freq = freq * 1000; |
474 | 474 | ||
475 | if (pll->flags & RADEON_PLL_IS_LCD) { | 475 | if (pll->flags & RADEON_PLL_IS_LCD) { |
@@ -558,15 +558,17 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll, | |||
558 | current_freq = radeon_div(tmp, ref_div * post_div); | 558 | current_freq = radeon_div(tmp, ref_div * post_div); |
559 | 559 | ||
560 | if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) { | 560 | if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) { |
561 | error = freq - current_freq; | 561 | if (freq < current_freq) |
562 | error = error < 0 ? 0xffffffff : error; | 562 | error = 0xffffffff; |
563 | else | ||
564 | error = freq - current_freq; | ||
563 | } else | 565 | } else |
564 | error = abs(current_freq - freq); | 566 | error = abs(current_freq - freq); |
565 | vco_diff = abs(vco - best_vco); | 567 | vco_diff = abs(vco - best_vco); |
566 | 568 | ||
567 | if ((best_vco == 0 && error < best_error) || | 569 | if ((best_vco == 0 && error < best_error) || |
568 | (best_vco != 0 && | 570 | (best_vco != 0 && |
569 | (error < best_error - 100 || | 571 | ((best_error > 100 && error < best_error - 100) || |
570 | (abs(error - best_error) < 100 && vco_diff < best_vco_diff)))) { | 572 | (abs(error - best_error) < 100 && vco_diff < best_vco_diff)))) { |
571 | best_post_div = post_div; | 573 | best_post_div = post_div; |
572 | best_ref_div = ref_div; | 574 | best_ref_div = ref_div; |
@@ -803,7 +805,7 @@ done: | |||
803 | *ref_div_p = ref_div; | 805 | *ref_div_p = ref_div; |
804 | *post_div_p = post_div; | 806 | *post_div_p = post_div; |
805 | 807 | ||
806 | DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p); | 808 | DRM_DEBUG_KMS("%u %d.%d, %d, %d\n", *dot_clock_p, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p); |
807 | } | 809 | } |
808 | 810 | ||
809 | void radeon_compute_pll(struct radeon_pll *pll, | 811 | void radeon_compute_pll(struct radeon_pll *pll, |
@@ -919,6 +921,12 @@ static struct drm_prop_enum_list radeon_tv_std_enum_list[] = | |||
919 | { TV_STD_SECAM, "secam" }, | 921 | { TV_STD_SECAM, "secam" }, |
920 | }; | 922 | }; |
921 | 923 | ||
924 | static struct drm_prop_enum_list radeon_underscan_enum_list[] = | ||
925 | { { UNDERSCAN_OFF, "off" }, | ||
926 | { UNDERSCAN_ON, "on" }, | ||
927 | { UNDERSCAN_AUTO, "auto" }, | ||
928 | }; | ||
929 | |||
922 | static int radeon_modeset_create_props(struct radeon_device *rdev) | 930 | static int radeon_modeset_create_props(struct radeon_device *rdev) |
923 | { | 931 | { |
924 | int i, sz; | 932 | int i, sz; |
@@ -972,6 +980,18 @@ static int radeon_modeset_create_props(struct radeon_device *rdev) | |||
972 | radeon_tv_std_enum_list[i].name); | 980 | radeon_tv_std_enum_list[i].name); |
973 | } | 981 | } |
974 | 982 | ||
983 | sz = ARRAY_SIZE(radeon_underscan_enum_list); | ||
984 | rdev->mode_info.underscan_property = | ||
985 | drm_property_create(rdev->ddev, | ||
986 | DRM_MODE_PROP_ENUM, | ||
987 | "underscan", sz); | ||
988 | for (i = 0; i < sz; i++) { | ||
989 | drm_property_add_enum(rdev->mode_info.underscan_property, | ||
990 | i, | ||
991 | radeon_underscan_enum_list[i].type, | ||
992 | radeon_underscan_enum_list[i].name); | ||
993 | } | ||
994 | |||
975 | return 0; | 995 | return 0; |
976 | } | 996 | } |
977 | 997 | ||
@@ -1067,15 +1087,26 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
1067 | struct drm_display_mode *adjusted_mode) | 1087 | struct drm_display_mode *adjusted_mode) |
1068 | { | 1088 | { |
1069 | struct drm_device *dev = crtc->dev; | 1089 | struct drm_device *dev = crtc->dev; |
1090 | struct radeon_device *rdev = dev->dev_private; | ||
1070 | struct drm_encoder *encoder; | 1091 | struct drm_encoder *encoder; |
1071 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1092 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1072 | struct radeon_encoder *radeon_encoder; | 1093 | struct radeon_encoder *radeon_encoder; |
1094 | struct drm_connector *connector; | ||
1095 | struct radeon_connector *radeon_connector; | ||
1073 | bool first = true; | 1096 | bool first = true; |
1097 | u32 src_v = 1, dst_v = 1; | ||
1098 | u32 src_h = 1, dst_h = 1; | ||
1099 | |||
1100 | radeon_crtc->h_border = 0; | ||
1101 | radeon_crtc->v_border = 0; | ||
1074 | 1102 | ||
1075 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1103 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1076 | radeon_encoder = to_radeon_encoder(encoder); | ||
1077 | if (encoder->crtc != crtc) | 1104 | if (encoder->crtc != crtc) |
1078 | continue; | 1105 | continue; |
1106 | radeon_encoder = to_radeon_encoder(encoder); | ||
1107 | connector = radeon_get_connector_for_encoder(encoder); | ||
1108 | radeon_connector = to_radeon_connector(connector); | ||
1109 | |||
1079 | if (first) { | 1110 | if (first) { |
1080 | /* set scaling */ | 1111 | /* set scaling */ |
1081 | if (radeon_encoder->rmx_type == RMX_OFF) | 1112 | if (radeon_encoder->rmx_type == RMX_OFF) |
@@ -1085,31 +1116,49 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
1085 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; | 1116 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; |
1086 | else | 1117 | else |
1087 | radeon_crtc->rmx_type = RMX_OFF; | 1118 | radeon_crtc->rmx_type = RMX_OFF; |
1119 | src_v = crtc->mode.vdisplay; | ||
1120 | dst_v = radeon_crtc->native_mode.vdisplay; | ||
1121 | src_h = crtc->mode.hdisplay; | ||
1122 | dst_h = radeon_crtc->native_mode.vdisplay; | ||
1088 | /* copy native mode */ | 1123 | /* copy native mode */ |
1089 | memcpy(&radeon_crtc->native_mode, | 1124 | memcpy(&radeon_crtc->native_mode, |
1090 | &radeon_encoder->native_mode, | 1125 | &radeon_encoder->native_mode, |
1091 | sizeof(struct drm_display_mode)); | 1126 | sizeof(struct drm_display_mode)); |
1127 | |||
1128 | /* fix up for overscan on hdmi */ | ||
1129 | if (ASIC_IS_AVIVO(rdev) && | ||
1130 | ((radeon_encoder->underscan_type == UNDERSCAN_ON) || | ||
1131 | ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && | ||
1132 | drm_detect_hdmi_monitor(radeon_connector->edid)))) { | ||
1133 | radeon_crtc->h_border = (mode->hdisplay >> 5) + 16; | ||
1134 | radeon_crtc->v_border = (mode->vdisplay >> 5) + 16; | ||
1135 | radeon_crtc->rmx_type = RMX_FULL; | ||
1136 | src_v = crtc->mode.vdisplay; | ||
1137 | dst_v = crtc->mode.vdisplay - (radeon_crtc->v_border * 2); | ||
1138 | src_h = crtc->mode.hdisplay; | ||
1139 | dst_h = crtc->mode.hdisplay - (radeon_crtc->h_border * 2); | ||
1140 | } | ||
1092 | first = false; | 1141 | first = false; |
1093 | } else { | 1142 | } else { |
1094 | if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) { | 1143 | if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) { |
1095 | /* WARNING: Right now this can't happen but | 1144 | /* WARNING: Right now this can't happen but |
1096 | * in the future we need to check that scaling | 1145 | * in the future we need to check that scaling |
1097 | * are consistent accross different encoder | 1146 | * are consistent across different encoder |
1098 | * (ie all encoder can work with the same | 1147 | * (ie all encoder can work with the same |
1099 | * scaling). | 1148 | * scaling). |
1100 | */ | 1149 | */ |
1101 | DRM_ERROR("Scaling not consistent accross encoder.\n"); | 1150 | DRM_ERROR("Scaling not consistent across encoder.\n"); |
1102 | return false; | 1151 | return false; |
1103 | } | 1152 | } |
1104 | } | 1153 | } |
1105 | } | 1154 | } |
1106 | if (radeon_crtc->rmx_type != RMX_OFF) { | 1155 | if (radeon_crtc->rmx_type != RMX_OFF) { |
1107 | fixed20_12 a, b; | 1156 | fixed20_12 a, b; |
1108 | a.full = dfixed_const(crtc->mode.vdisplay); | 1157 | a.full = dfixed_const(src_v); |
1109 | b.full = dfixed_const(radeon_crtc->native_mode.hdisplay); | 1158 | b.full = dfixed_const(dst_v); |
1110 | radeon_crtc->vsc.full = dfixed_div(a, b); | 1159 | radeon_crtc->vsc.full = dfixed_div(a, b); |
1111 | a.full = dfixed_const(crtc->mode.hdisplay); | 1160 | a.full = dfixed_const(src_h); |
1112 | b.full = dfixed_const(radeon_crtc->native_mode.vdisplay); | 1161 | b.full = dfixed_const(dst_h); |
1113 | radeon_crtc->hsc.full = dfixed_div(a, b); | 1162 | radeon_crtc->hsc.full = dfixed_div(a, b); |
1114 | } else { | 1163 | } else { |
1115 | radeon_crtc->vsc.full = dfixed_const(1); | 1164 | radeon_crtc->vsc.full = dfixed_const(1); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index e166fe4d7c30..795403b0e2cd 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -46,9 +46,10 @@ | |||
46 | * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs | 46 | * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs |
47 | * - 2.4.0 - add crtc id query | 47 | * - 2.4.0 - add crtc id query |
48 | * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen | 48 | * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen |
49 | * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) | ||
49 | */ | 50 | */ |
50 | #define KMS_DRIVER_MAJOR 2 | 51 | #define KMS_DRIVER_MAJOR 2 |
51 | #define KMS_DRIVER_MINOR 5 | 52 | #define KMS_DRIVER_MINOR 6 |
52 | #define KMS_DRIVER_PATCHLEVEL 0 | 53 | #define KMS_DRIVER_PATCHLEVEL 0 |
53 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 54 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
54 | int radeon_driver_unload_kms(struct drm_device *dev); | 55 | int radeon_driver_unload_kms(struct drm_device *dev); |
@@ -238,7 +239,7 @@ static struct drm_driver kms_driver; | |||
238 | static int __devinit | 239 | static int __devinit |
239 | radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 240 | radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
240 | { | 241 | { |
241 | return drm_get_dev(pdev, ent, &kms_driver); | 242 | return drm_get_pci_dev(pdev, ent, &kms_driver); |
242 | } | 243 | } |
243 | 244 | ||
244 | static void | 245 | static void |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index e0b30b264c28..263c8098d7dd 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -205,14 +205,14 @@ void radeon_encoder_set_active_device(struct drm_encoder *encoder) | |||
205 | if (connector->encoder == encoder) { | 205 | if (connector->encoder == encoder) { |
206 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 206 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
207 | radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices; | 207 | radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices; |
208 | DRM_DEBUG("setting active device to %08x from %08x %08x for encoder %d\n", | 208 | DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n", |
209 | radeon_encoder->active_device, radeon_encoder->devices, | 209 | radeon_encoder->active_device, radeon_encoder->devices, |
210 | radeon_connector->devices, encoder->encoder_type); | 210 | radeon_connector->devices, encoder->encoder_type); |
211 | } | 211 | } |
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
215 | static struct drm_connector * | 215 | struct drm_connector * |
216 | radeon_get_connector_for_encoder(struct drm_encoder *encoder) | 216 | radeon_get_connector_for_encoder(struct drm_encoder *encoder) |
217 | { | 217 | { |
218 | struct drm_device *dev = encoder->dev; | 218 | struct drm_device *dev = encoder->dev; |
@@ -1021,7 +1021,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
1021 | 1021 | ||
1022 | memset(&args, 0, sizeof(args)); | 1022 | memset(&args, 0, sizeof(args)); |
1023 | 1023 | ||
1024 | DRM_DEBUG("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", | 1024 | DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", |
1025 | radeon_encoder->encoder_id, mode, radeon_encoder->devices, | 1025 | radeon_encoder->encoder_id, mode, radeon_encoder->devices, |
1026 | radeon_encoder->active_device); | 1026 | radeon_encoder->active_device); |
1027 | switch (radeon_encoder->encoder_id) { | 1027 | switch (radeon_encoder->encoder_id) { |
@@ -1484,7 +1484,7 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec | |||
1484 | uint32_t bios_0_scratch; | 1484 | uint32_t bios_0_scratch; |
1485 | 1485 | ||
1486 | if (!atombios_dac_load_detect(encoder, connector)) { | 1486 | if (!atombios_dac_load_detect(encoder, connector)) { |
1487 | DRM_DEBUG("detect returned false \n"); | 1487 | DRM_DEBUG_KMS("detect returned false \n"); |
1488 | return connector_status_unknown; | 1488 | return connector_status_unknown; |
1489 | } | 1489 | } |
1490 | 1490 | ||
@@ -1493,7 +1493,7 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec | |||
1493 | else | 1493 | else |
1494 | bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); | 1494 | bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); |
1495 | 1495 | ||
1496 | DRM_DEBUG("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); | 1496 | DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); |
1497 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { | 1497 | if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { |
1498 | if (bios_0_scratch & ATOM_S0_CRT1_MASK) | 1498 | if (bios_0_scratch & ATOM_S0_CRT1_MASK) |
1499 | return connector_status_connected; | 1499 | return connector_status_connected; |
@@ -1694,6 +1694,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1694 | radeon_encoder->encoder_id = encoder_id; | 1694 | radeon_encoder->encoder_id = encoder_id; |
1695 | radeon_encoder->devices = supported_device; | 1695 | radeon_encoder->devices = supported_device; |
1696 | radeon_encoder->rmx_type = RMX_OFF; | 1696 | radeon_encoder->rmx_type = RMX_OFF; |
1697 | radeon_encoder->underscan_type = UNDERSCAN_OFF; | ||
1697 | 1698 | ||
1698 | switch (radeon_encoder->encoder_id) { | 1699 | switch (radeon_encoder->encoder_id) { |
1699 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | 1700 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: |
@@ -1707,6 +1708,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1707 | } else { | 1708 | } else { |
1708 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | 1709 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); |
1709 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | 1710 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); |
1711 | if (ASIC_IS_AVIVO(rdev)) | ||
1712 | radeon_encoder->underscan_type = UNDERSCAN_AUTO; | ||
1710 | } | 1713 | } |
1711 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); | 1714 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); |
1712 | break; | 1715 | break; |
@@ -1736,6 +1739,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1736 | } else { | 1739 | } else { |
1737 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | 1740 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); |
1738 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | 1741 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); |
1742 | if (ASIC_IS_AVIVO(rdev)) | ||
1743 | radeon_encoder->underscan_type = UNDERSCAN_AUTO; | ||
1739 | } | 1744 | } |
1740 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); | 1745 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); |
1741 | break; | 1746 | break; |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index ab389f89fa8d..ddcd3b13f151 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -49,7 +49,7 @@ int radeon_driver_unload_kms(struct drm_device *dev) | |||
49 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | 49 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) |
50 | { | 50 | { |
51 | struct radeon_device *rdev; | 51 | struct radeon_device *rdev; |
52 | int r; | 52 | int r, acpi_status; |
53 | 53 | ||
54 | rdev = kzalloc(sizeof(struct radeon_device), GFP_KERNEL); | 54 | rdev = kzalloc(sizeof(struct radeon_device), GFP_KERNEL); |
55 | if (rdev == NULL) { | 55 | if (rdev == NULL) { |
@@ -77,6 +77,12 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | |||
77 | dev_err(&dev->pdev->dev, "Fatal error during GPU init\n"); | 77 | dev_err(&dev->pdev->dev, "Fatal error during GPU init\n"); |
78 | goto out; | 78 | goto out; |
79 | } | 79 | } |
80 | |||
81 | /* Call ACPI methods */ | ||
82 | acpi_status = radeon_acpi_init(rdev); | ||
83 | if (acpi_status) | ||
84 | dev_dbg(&dev->pdev->dev, "Error during ACPI methods call\n"); | ||
85 | |||
80 | /* Again modeset_init should fail only on fatal error | 86 | /* Again modeset_init should fail only on fatal error |
81 | * otherwise it should provide enough functionalities | 87 | * otherwise it should provide enough functionalities |
82 | * for shadowfb to run | 88 | * for shadowfb to run |
@@ -135,15 +141,36 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
135 | } | 141 | } |
136 | } | 142 | } |
137 | if (!found) { | 143 | if (!found) { |
138 | DRM_DEBUG("unknown crtc id %d\n", value); | 144 | DRM_DEBUG_KMS("unknown crtc id %d\n", value); |
139 | return -EINVAL; | 145 | return -EINVAL; |
140 | } | 146 | } |
141 | break; | 147 | break; |
142 | case RADEON_INFO_ACCEL_WORKING2: | 148 | case RADEON_INFO_ACCEL_WORKING2: |
143 | value = rdev->accel_working; | 149 | value = rdev->accel_working; |
144 | break; | 150 | break; |
151 | case RADEON_INFO_TILING_CONFIG: | ||
152 | if (rdev->family >= CHIP_CEDAR) | ||
153 | value = rdev->config.evergreen.tile_config; | ||
154 | else if (rdev->family >= CHIP_RV770) | ||
155 | value = rdev->config.rv770.tile_config; | ||
156 | else if (rdev->family >= CHIP_R600) | ||
157 | value = rdev->config.r600.tile_config; | ||
158 | else { | ||
159 | DRM_DEBUG_KMS("tiling config is r6xx+ only!\n"); | ||
160 | return -EINVAL; | ||
161 | } | ||
162 | case RADEON_INFO_WANT_HYPERZ: | ||
163 | mutex_lock(&dev->struct_mutex); | ||
164 | if (rdev->hyperz_filp) | ||
165 | value = 0; | ||
166 | else { | ||
167 | rdev->hyperz_filp = filp; | ||
168 | value = 1; | ||
169 | } | ||
170 | mutex_unlock(&dev->struct_mutex); | ||
171 | break; | ||
145 | default: | 172 | default: |
146 | DRM_DEBUG("Invalid request %d\n", info->request); | 173 | DRM_DEBUG_KMS("Invalid request %d\n", info->request); |
147 | return -EINVAL; | 174 | return -EINVAL; |
148 | } | 175 | } |
149 | if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { | 176 | if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { |
@@ -181,9 +208,11 @@ void radeon_driver_postclose_kms(struct drm_device *dev, | |||
181 | void radeon_driver_preclose_kms(struct drm_device *dev, | 208 | void radeon_driver_preclose_kms(struct drm_device *dev, |
182 | struct drm_file *file_priv) | 209 | struct drm_file *file_priv) |
183 | { | 210 | { |
211 | struct radeon_device *rdev = dev->dev_private; | ||
212 | if (rdev->hyperz_filp == file_priv) | ||
213 | rdev->hyperz_filp = NULL; | ||
184 | } | 214 | } |
185 | 215 | ||
186 | |||
187 | /* | 216 | /* |
188 | * VBlank related functions. | 217 | * VBlank related functions. |
189 | */ | 218 | */ |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index e1e5255396ac..989df519a1e4 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -362,10 +362,10 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
362 | uint32_t gen_cntl_reg, gen_cntl_val; | 362 | uint32_t gen_cntl_reg, gen_cntl_val; |
363 | int r; | 363 | int r; |
364 | 364 | ||
365 | DRM_DEBUG("\n"); | 365 | DRM_DEBUG_KMS("\n"); |
366 | /* no fb bound */ | 366 | /* no fb bound */ |
367 | if (!crtc->fb) { | 367 | if (!crtc->fb) { |
368 | DRM_DEBUG("No FB bound\n"); | 368 | DRM_DEBUG_KMS("No FB bound\n"); |
369 | return 0; | 369 | return 0; |
370 | } | 370 | } |
371 | 371 | ||
@@ -528,7 +528,7 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod | |||
528 | uint32_t crtc_v_sync_strt_wid; | 528 | uint32_t crtc_v_sync_strt_wid; |
529 | bool is_tv = false; | 529 | bool is_tv = false; |
530 | 530 | ||
531 | DRM_DEBUG("\n"); | 531 | DRM_DEBUG_KMS("\n"); |
532 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 532 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
533 | if (encoder->crtc == crtc) { | 533 | if (encoder->crtc == crtc) { |
534 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 534 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
@@ -757,7 +757,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
757 | } | 757 | } |
758 | } | 758 | } |
759 | 759 | ||
760 | DRM_DEBUG("\n"); | 760 | DRM_DEBUG_KMS("\n"); |
761 | 761 | ||
762 | if (!use_bios_divs) { | 762 | if (!use_bios_divs) { |
763 | radeon_compute_pll(pll, mode->clock, | 763 | radeon_compute_pll(pll, mode->clock, |
@@ -772,7 +772,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
772 | if (!post_div->divider) | 772 | if (!post_div->divider) |
773 | post_div = &post_divs[0]; | 773 | post_div = &post_divs[0]; |
774 | 774 | ||
775 | DRM_DEBUG("dc=%u, fd=%d, rd=%d, pd=%d\n", | 775 | DRM_DEBUG_KMS("dc=%u, fd=%d, rd=%d, pd=%d\n", |
776 | (unsigned)freq, | 776 | (unsigned)freq, |
777 | feedback_div, | 777 | feedback_div, |
778 | reference_div, | 778 | reference_div, |
@@ -841,12 +841,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
841 | | RADEON_P2PLL_SLEEP | 841 | | RADEON_P2PLL_SLEEP |
842 | | RADEON_P2PLL_ATOMIC_UPDATE_EN)); | 842 | | RADEON_P2PLL_ATOMIC_UPDATE_EN)); |
843 | 843 | ||
844 | DRM_DEBUG("Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n", | 844 | DRM_DEBUG_KMS("Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n", |
845 | (unsigned)pll_ref_div, | 845 | (unsigned)pll_ref_div, |
846 | (unsigned)pll_fb_post_div, | 846 | (unsigned)pll_fb_post_div, |
847 | (unsigned)htotal_cntl, | 847 | (unsigned)htotal_cntl, |
848 | RREG32_PLL(RADEON_P2PLL_CNTL)); | 848 | RREG32_PLL(RADEON_P2PLL_CNTL)); |
849 | DRM_DEBUG("Wrote2: rd=%u, fd=%u, pd=%u\n", | 849 | DRM_DEBUG_KMS("Wrote2: rd=%u, fd=%u, pd=%u\n", |
850 | (unsigned)pll_ref_div & RADEON_P2PLL_REF_DIV_MASK, | 850 | (unsigned)pll_ref_div & RADEON_P2PLL_REF_DIV_MASK, |
851 | (unsigned)pll_fb_post_div & RADEON_P2PLL_FB0_DIV_MASK, | 851 | (unsigned)pll_fb_post_div & RADEON_P2PLL_FB0_DIV_MASK, |
852 | (unsigned)((pll_fb_post_div & | 852 | (unsigned)((pll_fb_post_div & |
@@ -947,12 +947,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
947 | | RADEON_PPLL_ATOMIC_UPDATE_EN | 947 | | RADEON_PPLL_ATOMIC_UPDATE_EN |
948 | | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN)); | 948 | | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN)); |
949 | 949 | ||
950 | DRM_DEBUG("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", | 950 | DRM_DEBUG_KMS("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", |
951 | pll_ref_div, | 951 | pll_ref_div, |
952 | pll_fb_post_div, | 952 | pll_fb_post_div, |
953 | (unsigned)htotal_cntl, | 953 | (unsigned)htotal_cntl, |
954 | RREG32_PLL(RADEON_PPLL_CNTL)); | 954 | RREG32_PLL(RADEON_PPLL_CNTL)); |
955 | DRM_DEBUG("Wrote: rd=%d, fd=%d, pd=%d\n", | 955 | DRM_DEBUG_KMS("Wrote: rd=%d, fd=%d, pd=%d\n", |
956 | pll_ref_div & RADEON_PPLL_REF_DIV_MASK, | 956 | pll_ref_div & RADEON_PPLL_REF_DIV_MASK, |
957 | pll_fb_post_div & RADEON_PPLL_FB3_DIV_MASK, | 957 | pll_fb_post_div & RADEON_PPLL_FB3_DIV_MASK, |
958 | (pll_fb_post_div & RADEON_PPLL_POST3_DIV_MASK) >> 16); | 958 | (pll_fb_post_div & RADEON_PPLL_POST3_DIV_MASK) >> 16); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 5688a0cf6bbe..b8149cbc0c70 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -47,7 +47,7 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
47 | uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man; | 47 | uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man; |
48 | int panel_pwr_delay = 2000; | 48 | int panel_pwr_delay = 2000; |
49 | bool is_mac = false; | 49 | bool is_mac = false; |
50 | DRM_DEBUG("\n"); | 50 | DRM_DEBUG_KMS("\n"); |
51 | 51 | ||
52 | if (radeon_encoder->enc_priv) { | 52 | if (radeon_encoder->enc_priv) { |
53 | if (rdev->is_atom_bios) { | 53 | if (rdev->is_atom_bios) { |
@@ -151,7 +151,7 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, | |||
151 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 151 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
152 | uint32_t lvds_pll_cntl, lvds_gen_cntl, lvds_ss_gen_cntl; | 152 | uint32_t lvds_pll_cntl, lvds_gen_cntl, lvds_ss_gen_cntl; |
153 | 153 | ||
154 | DRM_DEBUG("\n"); | 154 | DRM_DEBUG_KMS("\n"); |
155 | 155 | ||
156 | lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); | 156 | lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); |
157 | lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN; | 157 | lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN; |
@@ -167,7 +167,7 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, | |||
167 | } else { | 167 | } else { |
168 | struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; | 168 | struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; |
169 | if (lvds) { | 169 | if (lvds) { |
170 | DRM_DEBUG("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl); | 170 | DRM_DEBUG_KMS("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl); |
171 | lvds_gen_cntl = lvds->lvds_gen_cntl; | 171 | lvds_gen_cntl = lvds->lvds_gen_cntl; |
172 | lvds_ss_gen_cntl &= ~((0xf << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) | | 172 | lvds_ss_gen_cntl &= ~((0xf << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) | |
173 | (0xf << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT)); | 173 | (0xf << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT)); |
@@ -250,7 +250,7 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode | |||
250 | uint32_t dac_cntl = RREG32(RADEON_DAC_CNTL); | 250 | uint32_t dac_cntl = RREG32(RADEON_DAC_CNTL); |
251 | uint32_t dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL); | 251 | uint32_t dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL); |
252 | 252 | ||
253 | DRM_DEBUG("\n"); | 253 | DRM_DEBUG_KMS("\n"); |
254 | 254 | ||
255 | switch (mode) { | 255 | switch (mode) { |
256 | case DRM_MODE_DPMS_ON: | 256 | case DRM_MODE_DPMS_ON: |
@@ -315,7 +315,7 @@ static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, | |||
315 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 315 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
316 | uint32_t disp_output_cntl, dac_cntl, dac2_cntl, dac_macro_cntl; | 316 | uint32_t disp_output_cntl, dac_cntl, dac2_cntl, dac_macro_cntl; |
317 | 317 | ||
318 | DRM_DEBUG("\n"); | 318 | DRM_DEBUG_KMS("\n"); |
319 | 319 | ||
320 | if (radeon_crtc->crtc_id == 0) { | 320 | if (radeon_crtc->crtc_id == 0) { |
321 | if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)) { | 321 | if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)) { |
@@ -446,7 +446,7 @@ static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode) | |||
446 | struct drm_device *dev = encoder->dev; | 446 | struct drm_device *dev = encoder->dev; |
447 | struct radeon_device *rdev = dev->dev_private; | 447 | struct radeon_device *rdev = dev->dev_private; |
448 | uint32_t fp_gen_cntl = RREG32(RADEON_FP_GEN_CNTL); | 448 | uint32_t fp_gen_cntl = RREG32(RADEON_FP_GEN_CNTL); |
449 | DRM_DEBUG("\n"); | 449 | DRM_DEBUG_KMS("\n"); |
450 | 450 | ||
451 | switch (mode) { | 451 | switch (mode) { |
452 | case DRM_MODE_DPMS_ON: | 452 | case DRM_MODE_DPMS_ON: |
@@ -502,7 +502,7 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, | |||
502 | uint32_t tmp, tmds_pll_cntl, tmds_transmitter_cntl, fp_gen_cntl; | 502 | uint32_t tmp, tmds_pll_cntl, tmds_transmitter_cntl, fp_gen_cntl; |
503 | int i; | 503 | int i; |
504 | 504 | ||
505 | DRM_DEBUG("\n"); | 505 | DRM_DEBUG_KMS("\n"); |
506 | 506 | ||
507 | tmp = tmds_pll_cntl = RREG32(RADEON_TMDS_PLL_CNTL); | 507 | tmp = tmds_pll_cntl = RREG32(RADEON_TMDS_PLL_CNTL); |
508 | tmp &= 0xfffff; | 508 | tmp &= 0xfffff; |
@@ -610,7 +610,7 @@ static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode) | |||
610 | struct drm_device *dev = encoder->dev; | 610 | struct drm_device *dev = encoder->dev; |
611 | struct radeon_device *rdev = dev->dev_private; | 611 | struct radeon_device *rdev = dev->dev_private; |
612 | uint32_t fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); | 612 | uint32_t fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); |
613 | DRM_DEBUG("\n"); | 613 | DRM_DEBUG_KMS("\n"); |
614 | 614 | ||
615 | switch (mode) { | 615 | switch (mode) { |
616 | case DRM_MODE_DPMS_ON: | 616 | case DRM_MODE_DPMS_ON: |
@@ -666,7 +666,7 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, | |||
666 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 666 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
667 | uint32_t fp2_gen_cntl; | 667 | uint32_t fp2_gen_cntl; |
668 | 668 | ||
669 | DRM_DEBUG("\n"); | 669 | DRM_DEBUG_KMS("\n"); |
670 | 670 | ||
671 | if (rdev->is_atom_bios) { | 671 | if (rdev->is_atom_bios) { |
672 | radeon_encoder->pixel_clock = adjusted_mode->clock; | 672 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
@@ -760,7 +760,7 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) | |||
760 | uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0; | 760 | uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0; |
761 | uint32_t tv_master_cntl = 0; | 761 | uint32_t tv_master_cntl = 0; |
762 | bool is_tv; | 762 | bool is_tv; |
763 | DRM_DEBUG("\n"); | 763 | DRM_DEBUG_KMS("\n"); |
764 | 764 | ||
765 | is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; | 765 | is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; |
766 | 766 | ||
@@ -878,7 +878,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, | |||
878 | uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0, disp_tv_out_cntl = 0; | 878 | uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0, disp_tv_out_cntl = 0; |
879 | bool is_tv = false; | 879 | bool is_tv = false; |
880 | 880 | ||
881 | DRM_DEBUG("\n"); | 881 | DRM_DEBUG_KMS("\n"); |
882 | 882 | ||
883 | is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; | 883 | is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; |
884 | 884 | ||
@@ -1075,10 +1075,10 @@ static bool r300_legacy_tv_detect(struct drm_encoder *encoder, | |||
1075 | tmp = RREG32(RADEON_TV_DAC_CNTL); | 1075 | tmp = RREG32(RADEON_TV_DAC_CNTL); |
1076 | if ((tmp & RADEON_TV_DAC_GDACDET) != 0) { | 1076 | if ((tmp & RADEON_TV_DAC_GDACDET) != 0) { |
1077 | found = true; | 1077 | found = true; |
1078 | DRM_DEBUG("S-video TV connection detected\n"); | 1078 | DRM_DEBUG_KMS("S-video TV connection detected\n"); |
1079 | } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { | 1079 | } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { |
1080 | found = true; | 1080 | found = true; |
1081 | DRM_DEBUG("Composite TV connection detected\n"); | 1081 | DRM_DEBUG_KMS("Composite TV connection detected\n"); |
1082 | } | 1082 | } |
1083 | 1083 | ||
1084 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); | 1084 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
@@ -1141,10 +1141,10 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, | |||
1141 | tmp = RREG32(RADEON_TV_DAC_CNTL); | 1141 | tmp = RREG32(RADEON_TV_DAC_CNTL); |
1142 | if (tmp & RADEON_TV_DAC_GDACDET) { | 1142 | if (tmp & RADEON_TV_DAC_GDACDET) { |
1143 | found = true; | 1143 | found = true; |
1144 | DRM_DEBUG("S-video TV connection detected\n"); | 1144 | DRM_DEBUG_KMS("S-video TV connection detected\n"); |
1145 | } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { | 1145 | } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { |
1146 | found = true; | 1146 | found = true; |
1147 | DRM_DEBUG("Composite TV connection detected\n"); | 1147 | DRM_DEBUG_KMS("Composite TV connection detected\n"); |
1148 | } | 1148 | } |
1149 | 1149 | ||
1150 | WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl); | 1150 | WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/drivers/gpu/drm/radeon/radeon_legacy_tv.c index 032040397743..c7b6cb428d09 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_tv.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_tv.c | |||
@@ -496,7 +496,7 @@ static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder) | |||
496 | 496 | ||
497 | restart -= v_offset + h_offset; | 497 | restart -= v_offset + h_offset; |
498 | 498 | ||
499 | DRM_DEBUG("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n", | 499 | DRM_DEBUG_KMS("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n", |
500 | const_ptr->def_restart, tv_dac->h_pos, tv_dac->v_pos, p1, p2, restart); | 500 | const_ptr->def_restart, tv_dac->h_pos, tv_dac->v_pos, p1, p2, restart); |
501 | 501 | ||
502 | tv_dac->tv.hrestart = restart % h_total; | 502 | tv_dac->tv.hrestart = restart % h_total; |
@@ -505,7 +505,7 @@ static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder) | |||
505 | restart /= v_total; | 505 | restart /= v_total; |
506 | tv_dac->tv.frestart = restart % f_total; | 506 | tv_dac->tv.frestart = restart % f_total; |
507 | 507 | ||
508 | DRM_DEBUG("compute_restart: F/H/V=%u,%u,%u\n", | 508 | DRM_DEBUG_KMS("compute_restart: F/H/V=%u,%u,%u\n", |
509 | (unsigned)tv_dac->tv.frestart, | 509 | (unsigned)tv_dac->tv.frestart, |
510 | (unsigned)tv_dac->tv.vrestart, | 510 | (unsigned)tv_dac->tv.vrestart, |
511 | (unsigned)tv_dac->tv.hrestart); | 511 | (unsigned)tv_dac->tv.hrestart); |
@@ -523,7 +523,7 @@ static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder) | |||
523 | tv_dac->tv.timing_cntl = (tv_dac->tv.timing_cntl & ~RADEON_H_INC_MASK) | | 523 | tv_dac->tv.timing_cntl = (tv_dac->tv.timing_cntl & ~RADEON_H_INC_MASK) | |
524 | ((u32)h_inc << RADEON_H_INC_SHIFT); | 524 | ((u32)h_inc << RADEON_H_INC_SHIFT); |
525 | 525 | ||
526 | DRM_DEBUG("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc); | 526 | DRM_DEBUG_KMS("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc); |
527 | 527 | ||
528 | return h_changed; | 528 | return h_changed; |
529 | } | 529 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 95696aa57ac8..71aea4037e90 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -66,6 +66,12 @@ enum radeon_tv_std { | |||
66 | TV_STD_PAL_N, | 66 | TV_STD_PAL_N, |
67 | }; | 67 | }; |
68 | 68 | ||
69 | enum radeon_underscan_type { | ||
70 | UNDERSCAN_OFF, | ||
71 | UNDERSCAN_ON, | ||
72 | UNDERSCAN_AUTO, | ||
73 | }; | ||
74 | |||
69 | enum radeon_hpd_id { | 75 | enum radeon_hpd_id { |
70 | RADEON_HPD_1 = 0, | 76 | RADEON_HPD_1 = 0, |
71 | RADEON_HPD_2, | 77 | RADEON_HPD_2, |
@@ -226,10 +232,12 @@ struct radeon_mode_info { | |||
226 | struct drm_property *coherent_mode_property; | 232 | struct drm_property *coherent_mode_property; |
227 | /* DAC enable load detect */ | 233 | /* DAC enable load detect */ |
228 | struct drm_property *load_detect_property; | 234 | struct drm_property *load_detect_property; |
229 | /* TV standard load detect */ | 235 | /* TV standard */ |
230 | struct drm_property *tv_std_property; | 236 | struct drm_property *tv_std_property; |
231 | /* legacy TMDS PLL detect */ | 237 | /* legacy TMDS PLL detect */ |
232 | struct drm_property *tmds_pll_property; | 238 | struct drm_property *tmds_pll_property; |
239 | /* underscan */ | ||
240 | struct drm_property *underscan_property; | ||
233 | /* hardcoded DFP edid from BIOS */ | 241 | /* hardcoded DFP edid from BIOS */ |
234 | struct edid *bios_hardcoded_edid; | 242 | struct edid *bios_hardcoded_edid; |
235 | 243 | ||
@@ -266,6 +274,8 @@ struct radeon_crtc { | |||
266 | uint32_t legacy_display_base_addr; | 274 | uint32_t legacy_display_base_addr; |
267 | uint32_t legacy_cursor_offset; | 275 | uint32_t legacy_cursor_offset; |
268 | enum radeon_rmx_type rmx_type; | 276 | enum radeon_rmx_type rmx_type; |
277 | u8 h_border; | ||
278 | u8 v_border; | ||
269 | fixed20_12 vsc; | 279 | fixed20_12 vsc; |
270 | fixed20_12 hsc; | 280 | fixed20_12 hsc; |
271 | struct drm_display_mode native_mode; | 281 | struct drm_display_mode native_mode; |
@@ -354,6 +364,7 @@ struct radeon_encoder { | |||
354 | uint32_t flags; | 364 | uint32_t flags; |
355 | uint32_t pixel_clock; | 365 | uint32_t pixel_clock; |
356 | enum radeon_rmx_type rmx_type; | 366 | enum radeon_rmx_type rmx_type; |
367 | enum radeon_underscan_type underscan_type; | ||
357 | struct drm_display_mode native_mode; | 368 | struct drm_display_mode native_mode; |
358 | void *enc_priv; | 369 | void *enc_priv; |
359 | int audio_polling_active; | 370 | int audio_polling_active; |
@@ -392,7 +403,7 @@ struct radeon_connector { | |||
392 | uint32_t connector_id; | 403 | uint32_t connector_id; |
393 | uint32_t devices; | 404 | uint32_t devices; |
394 | struct radeon_i2c_chan *ddc_bus; | 405 | struct radeon_i2c_chan *ddc_bus; |
395 | /* some systems have a an hdmi and vga port with a shared ddc line */ | 406 | /* some systems have an hdmi and vga port with a shared ddc line */ |
396 | bool shared_ddc; | 407 | bool shared_ddc; |
397 | bool use_digital; | 408 | bool use_digital; |
398 | /* we need to mind the EDID between detect | 409 | /* we need to mind the EDID between detect |
@@ -414,6 +425,9 @@ radeon_combios_get_tv_info(struct radeon_device *rdev); | |||
414 | extern enum radeon_tv_std | 425 | extern enum radeon_tv_std |
415 | radeon_atombios_get_tv_info(struct radeon_device *rdev); | 426 | radeon_atombios_get_tv_info(struct radeon_device *rdev); |
416 | 427 | ||
428 | extern struct drm_connector * | ||
429 | radeon_get_connector_for_encoder(struct drm_encoder *encoder); | ||
430 | |||
417 | extern void radeon_connector_hotplug(struct drm_connector *connector); | 431 | extern void radeon_connector_hotplug(struct drm_connector *connector); |
418 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); | 432 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); |
419 | extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector, | 433 | extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector, |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index d5b9373ce06c..0afd1e62347d 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -110,6 +110,7 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, | |||
110 | bo->surface_reg = -1; | 110 | bo->surface_reg = -1; |
111 | INIT_LIST_HEAD(&bo->list); | 111 | INIT_LIST_HEAD(&bo->list); |
112 | 112 | ||
113 | retry: | ||
113 | radeon_ttm_placement_from_domain(bo, domain); | 114 | radeon_ttm_placement_from_domain(bo, domain); |
114 | /* Kernel allocation are uninterruptible */ | 115 | /* Kernel allocation are uninterruptible */ |
115 | mutex_lock(&rdev->vram_mutex); | 116 | mutex_lock(&rdev->vram_mutex); |
@@ -118,10 +119,15 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, | |||
118 | &radeon_ttm_bo_destroy); | 119 | &radeon_ttm_bo_destroy); |
119 | mutex_unlock(&rdev->vram_mutex); | 120 | mutex_unlock(&rdev->vram_mutex); |
120 | if (unlikely(r != 0)) { | 121 | if (unlikely(r != 0)) { |
121 | if (r != -ERESTARTSYS) | 122 | if (r != -ERESTARTSYS) { |
123 | if (domain == RADEON_GEM_DOMAIN_VRAM) { | ||
124 | domain |= RADEON_GEM_DOMAIN_GTT; | ||
125 | goto retry; | ||
126 | } | ||
122 | dev_err(rdev->dev, | 127 | dev_err(rdev->dev, |
123 | "object_init failed for (%lu, 0x%08X)\n", | 128 | "object_init failed for (%lu, 0x%08X)\n", |
124 | size, domain); | 129 | size, domain); |
130 | } | ||
125 | return r; | 131 | return r; |
126 | } | 132 | } |
127 | *bo_ptr = bo; | 133 | *bo_ptr = bo; |
@@ -321,6 +327,7 @@ int radeon_bo_list_validate(struct list_head *head) | |||
321 | { | 327 | { |
322 | struct radeon_bo_list *lobj; | 328 | struct radeon_bo_list *lobj; |
323 | struct radeon_bo *bo; | 329 | struct radeon_bo *bo; |
330 | u32 domain; | ||
324 | int r; | 331 | int r; |
325 | 332 | ||
326 | list_for_each_entry(lobj, head, list) { | 333 | list_for_each_entry(lobj, head, list) { |
@@ -333,17 +340,19 @@ int radeon_bo_list_validate(struct list_head *head) | |||
333 | list_for_each_entry(lobj, head, list) { | 340 | list_for_each_entry(lobj, head, list) { |
334 | bo = lobj->bo; | 341 | bo = lobj->bo; |
335 | if (!bo->pin_count) { | 342 | if (!bo->pin_count) { |
336 | if (lobj->wdomain) { | 343 | domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain; |
337 | radeon_ttm_placement_from_domain(bo, | 344 | |
338 | lobj->wdomain); | 345 | retry: |
339 | } else { | 346 | radeon_ttm_placement_from_domain(bo, domain); |
340 | radeon_ttm_placement_from_domain(bo, | ||
341 | lobj->rdomain); | ||
342 | } | ||
343 | r = ttm_bo_validate(&bo->tbo, &bo->placement, | 347 | r = ttm_bo_validate(&bo->tbo, &bo->placement, |
344 | true, false, false); | 348 | true, false, false); |
345 | if (unlikely(r)) | 349 | if (unlikely(r)) { |
350 | if (r != -ERESTARTSYS && domain == RADEON_GEM_DOMAIN_VRAM) { | ||
351 | domain |= RADEON_GEM_DOMAIN_GTT; | ||
352 | goto retry; | ||
353 | } | ||
346 | return r; | 354 | return r; |
355 | } | ||
347 | } | 356 | } |
348 | lobj->gpu_offset = radeon_bo_gpu_offset(bo); | 357 | lobj->gpu_offset = radeon_bo_gpu_offset(bo); |
349 | lobj->tiling_flags = bo->tiling_flags; | 358 | lobj->tiling_flags = bo->tiling_flags; |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 3fa6984d9896..95f8b3a3c43d 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/acpi.h> | 27 | #include <linux/acpi.h> |
28 | #endif | 28 | #endif |
29 | #include <linux/power_supply.h> | 29 | #include <linux/power_supply.h> |
30 | #include <linux/hwmon.h> | ||
31 | #include <linux/hwmon-sysfs.h> | ||
30 | 32 | ||
31 | #define RADEON_IDLE_LOOP_MS 100 | 33 | #define RADEON_IDLE_LOOP_MS 100 |
32 | #define RADEON_RECLOCK_DELAY_MS 200 | 34 | #define RADEON_RECLOCK_DELAY_MS 200 |
@@ -60,9 +62,9 @@ static int radeon_acpi_event(struct notifier_block *nb, | |||
60 | 62 | ||
61 | if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) { | 63 | if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) { |
62 | if (power_supply_is_system_supplied() > 0) | 64 | if (power_supply_is_system_supplied() > 0) |
63 | DRM_DEBUG("pm: AC\n"); | 65 | DRM_DEBUG_DRIVER("pm: AC\n"); |
64 | else | 66 | else |
65 | DRM_DEBUG("pm: DC\n"); | 67 | DRM_DEBUG_DRIVER("pm: DC\n"); |
66 | 68 | ||
67 | if (rdev->pm.pm_method == PM_METHOD_PROFILE) { | 69 | if (rdev->pm.pm_method == PM_METHOD_PROFILE) { |
68 | if (rdev->pm.profile == PM_PROFILE_AUTO) { | 70 | if (rdev->pm.profile == PM_PROFILE_AUTO) { |
@@ -196,7 +198,7 @@ static void radeon_set_power_state(struct radeon_device *rdev) | |||
196 | radeon_set_engine_clock(rdev, sclk); | 198 | radeon_set_engine_clock(rdev, sclk); |
197 | radeon_pm_debug_check_in_vbl(rdev, true); | 199 | radeon_pm_debug_check_in_vbl(rdev, true); |
198 | rdev->pm.current_sclk = sclk; | 200 | rdev->pm.current_sclk = sclk; |
199 | DRM_DEBUG("Setting: e: %d\n", sclk); | 201 | DRM_DEBUG_DRIVER("Setting: e: %d\n", sclk); |
200 | } | 202 | } |
201 | 203 | ||
202 | /* set memory clock */ | 204 | /* set memory clock */ |
@@ -205,7 +207,7 @@ static void radeon_set_power_state(struct radeon_device *rdev) | |||
205 | radeon_set_memory_clock(rdev, mclk); | 207 | radeon_set_memory_clock(rdev, mclk); |
206 | radeon_pm_debug_check_in_vbl(rdev, true); | 208 | radeon_pm_debug_check_in_vbl(rdev, true); |
207 | rdev->pm.current_mclk = mclk; | 209 | rdev->pm.current_mclk = mclk; |
208 | DRM_DEBUG("Setting: m: %d\n", mclk); | 210 | DRM_DEBUG_DRIVER("Setting: m: %d\n", mclk); |
209 | } | 211 | } |
210 | 212 | ||
211 | if (misc_after) | 213 | if (misc_after) |
@@ -217,7 +219,7 @@ static void radeon_set_power_state(struct radeon_device *rdev) | |||
217 | rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; | 219 | rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; |
218 | rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index; | 220 | rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index; |
219 | } else | 221 | } else |
220 | DRM_DEBUG("pm: GUI not idle!!!\n"); | 222 | DRM_DEBUG_DRIVER("pm: GUI not idle!!!\n"); |
221 | } | 223 | } |
222 | 224 | ||
223 | static void radeon_pm_set_clocks(struct radeon_device *rdev) | 225 | static void radeon_pm_set_clocks(struct radeon_device *rdev) |
@@ -292,27 +294,27 @@ static void radeon_pm_print_states(struct radeon_device *rdev) | |||
292 | struct radeon_power_state *power_state; | 294 | struct radeon_power_state *power_state; |
293 | struct radeon_pm_clock_info *clock_info; | 295 | struct radeon_pm_clock_info *clock_info; |
294 | 296 | ||
295 | DRM_DEBUG("%d Power State(s)\n", rdev->pm.num_power_states); | 297 | DRM_DEBUG_DRIVER("%d Power State(s)\n", rdev->pm.num_power_states); |
296 | for (i = 0; i < rdev->pm.num_power_states; i++) { | 298 | for (i = 0; i < rdev->pm.num_power_states; i++) { |
297 | power_state = &rdev->pm.power_state[i]; | 299 | power_state = &rdev->pm.power_state[i]; |
298 | DRM_DEBUG("State %d: %s\n", i, | 300 | DRM_DEBUG_DRIVER("State %d: %s\n", i, |
299 | radeon_pm_state_type_name[power_state->type]); | 301 | radeon_pm_state_type_name[power_state->type]); |
300 | if (i == rdev->pm.default_power_state_index) | 302 | if (i == rdev->pm.default_power_state_index) |
301 | DRM_DEBUG("\tDefault"); | 303 | DRM_DEBUG_DRIVER("\tDefault"); |
302 | if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP)) | 304 | if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP)) |
303 | DRM_DEBUG("\t%d PCIE Lanes\n", power_state->pcie_lanes); | 305 | DRM_DEBUG_DRIVER("\t%d PCIE Lanes\n", power_state->pcie_lanes); |
304 | if (power_state->flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) | 306 | if (power_state->flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) |
305 | DRM_DEBUG("\tSingle display only\n"); | 307 | DRM_DEBUG_DRIVER("\tSingle display only\n"); |
306 | DRM_DEBUG("\t%d Clock Mode(s)\n", power_state->num_clock_modes); | 308 | DRM_DEBUG_DRIVER("\t%d Clock Mode(s)\n", power_state->num_clock_modes); |
307 | for (j = 0; j < power_state->num_clock_modes; j++) { | 309 | for (j = 0; j < power_state->num_clock_modes; j++) { |
308 | clock_info = &(power_state->clock_info[j]); | 310 | clock_info = &(power_state->clock_info[j]); |
309 | if (rdev->flags & RADEON_IS_IGP) | 311 | if (rdev->flags & RADEON_IS_IGP) |
310 | DRM_DEBUG("\t\t%d e: %d%s\n", | 312 | DRM_DEBUG_DRIVER("\t\t%d e: %d%s\n", |
311 | j, | 313 | j, |
312 | clock_info->sclk * 10, | 314 | clock_info->sclk * 10, |
313 | clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : ""); | 315 | clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : ""); |
314 | else | 316 | else |
315 | DRM_DEBUG("\t\t%d e: %d\tm: %d\tv: %d%s\n", | 317 | DRM_DEBUG_DRIVER("\t\t%d e: %d\tm: %d\tv: %d%s\n", |
316 | j, | 318 | j, |
317 | clock_info->sclk * 10, | 319 | clock_info->sclk * 10, |
318 | clock_info->mclk * 10, | 320 | clock_info->mclk * 10, |
@@ -424,6 +426,82 @@ fail: | |||
424 | static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile); | 426 | static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile); |
425 | static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method); | 427 | static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method); |
426 | 428 | ||
429 | static ssize_t radeon_hwmon_show_temp(struct device *dev, | ||
430 | struct device_attribute *attr, | ||
431 | char *buf) | ||
432 | { | ||
433 | struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); | ||
434 | struct radeon_device *rdev = ddev->dev_private; | ||
435 | u32 temp; | ||
436 | |||
437 | switch (rdev->pm.int_thermal_type) { | ||
438 | case THERMAL_TYPE_RV6XX: | ||
439 | temp = rv6xx_get_temp(rdev); | ||
440 | break; | ||
441 | case THERMAL_TYPE_RV770: | ||
442 | temp = rv770_get_temp(rdev); | ||
443 | break; | ||
444 | case THERMAL_TYPE_EVERGREEN: | ||
445 | temp = evergreen_get_temp(rdev); | ||
446 | break; | ||
447 | default: | ||
448 | temp = 0; | ||
449 | break; | ||
450 | } | ||
451 | |||
452 | return snprintf(buf, PAGE_SIZE, "%d\n", temp); | ||
453 | } | ||
454 | |||
455 | static ssize_t radeon_hwmon_show_name(struct device *dev, | ||
456 | struct device_attribute *attr, | ||
457 | char *buf) | ||
458 | { | ||
459 | return sprintf(buf, "radeon\n"); | ||
460 | } | ||
461 | |||
462 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, radeon_hwmon_show_temp, NULL, 0); | ||
463 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, radeon_hwmon_show_name, NULL, 0); | ||
464 | |||
465 | static struct attribute *hwmon_attributes[] = { | ||
466 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
467 | &sensor_dev_attr_name.dev_attr.attr, | ||
468 | NULL | ||
469 | }; | ||
470 | |||
471 | static const struct attribute_group hwmon_attrgroup = { | ||
472 | .attrs = hwmon_attributes, | ||
473 | }; | ||
474 | |||
475 | static void radeon_hwmon_init(struct radeon_device *rdev) | ||
476 | { | ||
477 | int err; | ||
478 | |||
479 | rdev->pm.int_hwmon_dev = NULL; | ||
480 | |||
481 | switch (rdev->pm.int_thermal_type) { | ||
482 | case THERMAL_TYPE_RV6XX: | ||
483 | case THERMAL_TYPE_RV770: | ||
484 | case THERMAL_TYPE_EVERGREEN: | ||
485 | rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev); | ||
486 | dev_set_drvdata(rdev->pm.int_hwmon_dev, rdev->ddev); | ||
487 | err = sysfs_create_group(&rdev->pm.int_hwmon_dev->kobj, | ||
488 | &hwmon_attrgroup); | ||
489 | if (err) | ||
490 | DRM_ERROR("Unable to create hwmon sysfs file: %d\n", err); | ||
491 | break; | ||
492 | default: | ||
493 | break; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | static void radeon_hwmon_fini(struct radeon_device *rdev) | ||
498 | { | ||
499 | if (rdev->pm.int_hwmon_dev) { | ||
500 | sysfs_remove_group(&rdev->pm.int_hwmon_dev->kobj, &hwmon_attrgroup); | ||
501 | hwmon_device_unregister(rdev->pm.int_hwmon_dev); | ||
502 | } | ||
503 | } | ||
504 | |||
427 | void radeon_pm_suspend(struct radeon_device *rdev) | 505 | void radeon_pm_suspend(struct radeon_device *rdev) |
428 | { | 506 | { |
429 | bool flush_wq = false; | 507 | bool flush_wq = false; |
@@ -471,6 +549,7 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
471 | rdev->pm.dynpm_can_downclock = true; | 549 | rdev->pm.dynpm_can_downclock = true; |
472 | rdev->pm.current_sclk = rdev->clock.default_sclk; | 550 | rdev->pm.current_sclk = rdev->clock.default_sclk; |
473 | rdev->pm.current_mclk = rdev->clock.default_mclk; | 551 | rdev->pm.current_mclk = rdev->clock.default_mclk; |
552 | rdev->pm.int_thermal_type = THERMAL_TYPE_NONE; | ||
474 | 553 | ||
475 | if (rdev->bios) { | 554 | if (rdev->bios) { |
476 | if (rdev->is_atom_bios) | 555 | if (rdev->is_atom_bios) |
@@ -481,6 +560,8 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
481 | radeon_pm_init_profile(rdev); | 560 | radeon_pm_init_profile(rdev); |
482 | } | 561 | } |
483 | 562 | ||
563 | /* set up the internal thermal sensor if applicable */ | ||
564 | radeon_hwmon_init(rdev); | ||
484 | if (rdev->pm.num_power_states > 1) { | 565 | if (rdev->pm.num_power_states > 1) { |
485 | /* where's the best place to put these? */ | 566 | /* where's the best place to put these? */ |
486 | ret = device_create_file(rdev->dev, &dev_attr_power_profile); | 567 | ret = device_create_file(rdev->dev, &dev_attr_power_profile); |
@@ -536,6 +617,7 @@ void radeon_pm_fini(struct radeon_device *rdev) | |||
536 | #endif | 617 | #endif |
537 | } | 618 | } |
538 | 619 | ||
620 | radeon_hwmon_fini(rdev); | ||
539 | if (rdev->pm.i2c_bus) | 621 | if (rdev->pm.i2c_bus) |
540 | radeon_i2c_destroy(rdev->pm.i2c_bus); | 622 | radeon_i2c_destroy(rdev->pm.i2c_bus); |
541 | } | 623 | } |
@@ -576,7 +658,7 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev) | |||
576 | radeon_pm_get_dynpm_state(rdev); | 658 | radeon_pm_get_dynpm_state(rdev); |
577 | radeon_pm_set_clocks(rdev); | 659 | radeon_pm_set_clocks(rdev); |
578 | 660 | ||
579 | DRM_DEBUG("radeon: dynamic power management deactivated\n"); | 661 | DRM_DEBUG_DRIVER("radeon: dynamic power management deactivated\n"); |
580 | } | 662 | } |
581 | } else if (rdev->pm.active_crtc_count == 1) { | 663 | } else if (rdev->pm.active_crtc_count == 1) { |
582 | /* TODO: Increase clocks if needed for current mode */ | 664 | /* TODO: Increase clocks if needed for current mode */ |
@@ -593,7 +675,7 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev) | |||
593 | rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; | 675 | rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; |
594 | queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, | 676 | queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, |
595 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); | 677 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); |
596 | DRM_DEBUG("radeon: dynamic power management activated\n"); | 678 | DRM_DEBUG_DRIVER("radeon: dynamic power management activated\n"); |
597 | } | 679 | } |
598 | } else { /* count == 0 */ | 680 | } else { /* count == 0 */ |
599 | if (rdev->pm.dynpm_state != DYNPM_STATE_MINIMUM) { | 681 | if (rdev->pm.dynpm_state != DYNPM_STATE_MINIMUM) { |
@@ -689,7 +771,7 @@ static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish | |||
689 | bool in_vbl = radeon_pm_in_vbl(rdev); | 771 | bool in_vbl = radeon_pm_in_vbl(rdev); |
690 | 772 | ||
691 | if (in_vbl == false) | 773 | if (in_vbl == false) |
692 | DRM_DEBUG("not in vbl for pm change %08x at %s\n", stat_crtc, | 774 | DRM_DEBUG_DRIVER("not in vbl for pm change %08x at %s\n", stat_crtc, |
693 | finish ? "exit" : "entry"); | 775 | finish ? "exit" : "entry"); |
694 | return in_vbl; | 776 | return in_vbl; |
695 | } | 777 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index e9918d88f5b0..84c53e41a88f 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -59,28 +59,28 @@ static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev) | |||
59 | /* | 59 | /* |
60 | * Global memory. | 60 | * Global memory. |
61 | */ | 61 | */ |
62 | static int radeon_ttm_mem_global_init(struct ttm_global_reference *ref) | 62 | static int radeon_ttm_mem_global_init(struct drm_global_reference *ref) |
63 | { | 63 | { |
64 | return ttm_mem_global_init(ref->object); | 64 | return ttm_mem_global_init(ref->object); |
65 | } | 65 | } |
66 | 66 | ||
67 | static void radeon_ttm_mem_global_release(struct ttm_global_reference *ref) | 67 | static void radeon_ttm_mem_global_release(struct drm_global_reference *ref) |
68 | { | 68 | { |
69 | ttm_mem_global_release(ref->object); | 69 | ttm_mem_global_release(ref->object); |
70 | } | 70 | } |
71 | 71 | ||
72 | static int radeon_ttm_global_init(struct radeon_device *rdev) | 72 | static int radeon_ttm_global_init(struct radeon_device *rdev) |
73 | { | 73 | { |
74 | struct ttm_global_reference *global_ref; | 74 | struct drm_global_reference *global_ref; |
75 | int r; | 75 | int r; |
76 | 76 | ||
77 | rdev->mman.mem_global_referenced = false; | 77 | rdev->mman.mem_global_referenced = false; |
78 | global_ref = &rdev->mman.mem_global_ref; | 78 | global_ref = &rdev->mman.mem_global_ref; |
79 | global_ref->global_type = TTM_GLOBAL_TTM_MEM; | 79 | global_ref->global_type = DRM_GLOBAL_TTM_MEM; |
80 | global_ref->size = sizeof(struct ttm_mem_global); | 80 | global_ref->size = sizeof(struct ttm_mem_global); |
81 | global_ref->init = &radeon_ttm_mem_global_init; | 81 | global_ref->init = &radeon_ttm_mem_global_init; |
82 | global_ref->release = &radeon_ttm_mem_global_release; | 82 | global_ref->release = &radeon_ttm_mem_global_release; |
83 | r = ttm_global_item_ref(global_ref); | 83 | r = drm_global_item_ref(global_ref); |
84 | if (r != 0) { | 84 | if (r != 0) { |
85 | DRM_ERROR("Failed setting up TTM memory accounting " | 85 | DRM_ERROR("Failed setting up TTM memory accounting " |
86 | "subsystem.\n"); | 86 | "subsystem.\n"); |
@@ -90,14 +90,14 @@ static int radeon_ttm_global_init(struct radeon_device *rdev) | |||
90 | rdev->mman.bo_global_ref.mem_glob = | 90 | rdev->mman.bo_global_ref.mem_glob = |
91 | rdev->mman.mem_global_ref.object; | 91 | rdev->mman.mem_global_ref.object; |
92 | global_ref = &rdev->mman.bo_global_ref.ref; | 92 | global_ref = &rdev->mman.bo_global_ref.ref; |
93 | global_ref->global_type = TTM_GLOBAL_TTM_BO; | 93 | global_ref->global_type = DRM_GLOBAL_TTM_BO; |
94 | global_ref->size = sizeof(struct ttm_bo_global); | 94 | global_ref->size = sizeof(struct ttm_bo_global); |
95 | global_ref->init = &ttm_bo_global_init; | 95 | global_ref->init = &ttm_bo_global_init; |
96 | global_ref->release = &ttm_bo_global_release; | 96 | global_ref->release = &ttm_bo_global_release; |
97 | r = ttm_global_item_ref(global_ref); | 97 | r = drm_global_item_ref(global_ref); |
98 | if (r != 0) { | 98 | if (r != 0) { |
99 | DRM_ERROR("Failed setting up TTM BO subsystem.\n"); | 99 | DRM_ERROR("Failed setting up TTM BO subsystem.\n"); |
100 | ttm_global_item_unref(&rdev->mman.mem_global_ref); | 100 | drm_global_item_unref(&rdev->mman.mem_global_ref); |
101 | return r; | 101 | return r; |
102 | } | 102 | } |
103 | 103 | ||
@@ -108,8 +108,8 @@ static int radeon_ttm_global_init(struct radeon_device *rdev) | |||
108 | static void radeon_ttm_global_fini(struct radeon_device *rdev) | 108 | static void radeon_ttm_global_fini(struct radeon_device *rdev) |
109 | { | 109 | { |
110 | if (rdev->mman.mem_global_referenced) { | 110 | if (rdev->mman.mem_global_referenced) { |
111 | ttm_global_item_unref(&rdev->mman.bo_global_ref.ref); | 111 | drm_global_item_unref(&rdev->mman.bo_global_ref.ref); |
112 | ttm_global_item_unref(&rdev->mman.mem_global_ref); | 112 | drm_global_item_unref(&rdev->mman.mem_global_ref); |
113 | rdev->mman.mem_global_referenced = false; | 113 | rdev->mman.mem_global_referenced = false; |
114 | } | 114 | } |
115 | } | 115 | } |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300 index 1e97b2d129fd..b506ec1cab4b 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r300 +++ b/drivers/gpu/drm/radeon/reg_srcs/r300 | |||
@@ -187,7 +187,6 @@ r300 0x4f60 | |||
187 | 0x4364 RS_INST_13 | 187 | 0x4364 RS_INST_13 |
188 | 0x4368 RS_INST_14 | 188 | 0x4368 RS_INST_14 |
189 | 0x436C RS_INST_15 | 189 | 0x436C RS_INST_15 |
190 | 0x43A4 SC_HYPERZ_EN | ||
191 | 0x43A8 SC_EDGERULE | 190 | 0x43A8 SC_EDGERULE |
192 | 0x43B0 SC_CLIP_0_A | 191 | 0x43B0 SC_CLIP_0_A |
193 | 0x43B4 SC_CLIP_0_B | 192 | 0x43B4 SC_CLIP_0_B |
@@ -716,16 +715,4 @@ r300 0x4f60 | |||
716 | 0x4F08 ZB_STENCILREFMASK | 715 | 0x4F08 ZB_STENCILREFMASK |
717 | 0x4F14 ZB_ZTOP | 716 | 0x4F14 ZB_ZTOP |
718 | 0x4F18 ZB_ZCACHE_CTLSTAT | 717 | 0x4F18 ZB_ZCACHE_CTLSTAT |
719 | 0x4F1C ZB_BW_CNTL | ||
720 | 0x4F28 ZB_DEPTHCLEARVALUE | ||
721 | 0x4F30 ZB_ZMASK_OFFSET | ||
722 | 0x4F34 ZB_ZMASK_PITCH | ||
723 | 0x4F38 ZB_ZMASK_WRINDEX | ||
724 | 0x4F3C ZB_ZMASK_DWORD | ||
725 | 0x4F40 ZB_ZMASK_RDINDEX | ||
726 | 0x4F44 ZB_HIZ_OFFSET | ||
727 | 0x4F48 ZB_HIZ_WRINDEX | ||
728 | 0x4F4C ZB_HIZ_DWORD | ||
729 | 0x4F50 ZB_HIZ_RDINDEX | ||
730 | 0x4F54 ZB_HIZ_PITCH | ||
731 | 0x4F58 ZB_ZPASS_DATA | 718 | 0x4F58 ZB_ZPASS_DATA |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r420 b/drivers/gpu/drm/radeon/reg_srcs/r420 index e958980d00f1..8c1214c2390f 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r420 +++ b/drivers/gpu/drm/radeon/reg_srcs/r420 | |||
@@ -130,6 +130,7 @@ r420 0x4f60 | |||
130 | 0x401C GB_SELECT | 130 | 0x401C GB_SELECT |
131 | 0x4020 GB_AA_CONFIG | 131 | 0x4020 GB_AA_CONFIG |
132 | 0x4024 GB_FIFO_SIZE | 132 | 0x4024 GB_FIFO_SIZE |
133 | 0x4028 GB_Z_PEQ_CONFIG | ||
133 | 0x4100 TX_INVALTAGS | 134 | 0x4100 TX_INVALTAGS |
134 | 0x4200 GA_POINT_S0 | 135 | 0x4200 GA_POINT_S0 |
135 | 0x4204 GA_POINT_T0 | 136 | 0x4204 GA_POINT_T0 |
@@ -187,7 +188,6 @@ r420 0x4f60 | |||
187 | 0x4364 RS_INST_13 | 188 | 0x4364 RS_INST_13 |
188 | 0x4368 RS_INST_14 | 189 | 0x4368 RS_INST_14 |
189 | 0x436C RS_INST_15 | 190 | 0x436C RS_INST_15 |
190 | 0x43A4 SC_HYPERZ_EN | ||
191 | 0x43A8 SC_EDGERULE | 191 | 0x43A8 SC_EDGERULE |
192 | 0x43B0 SC_CLIP_0_A | 192 | 0x43B0 SC_CLIP_0_A |
193 | 0x43B4 SC_CLIP_0_B | 193 | 0x43B4 SC_CLIP_0_B |
@@ -782,16 +782,4 @@ r420 0x4f60 | |||
782 | 0x4F08 ZB_STENCILREFMASK | 782 | 0x4F08 ZB_STENCILREFMASK |
783 | 0x4F14 ZB_ZTOP | 783 | 0x4F14 ZB_ZTOP |
784 | 0x4F18 ZB_ZCACHE_CTLSTAT | 784 | 0x4F18 ZB_ZCACHE_CTLSTAT |
785 | 0x4F1C ZB_BW_CNTL | ||
786 | 0x4F28 ZB_DEPTHCLEARVALUE | ||
787 | 0x4F30 ZB_ZMASK_OFFSET | ||
788 | 0x4F34 ZB_ZMASK_PITCH | ||
789 | 0x4F38 ZB_ZMASK_WRINDEX | ||
790 | 0x4F3C ZB_ZMASK_DWORD | ||
791 | 0x4F40 ZB_ZMASK_RDINDEX | ||
792 | 0x4F44 ZB_HIZ_OFFSET | ||
793 | 0x4F48 ZB_HIZ_WRINDEX | ||
794 | 0x4F4C ZB_HIZ_DWORD | ||
795 | 0x4F50 ZB_HIZ_RDINDEX | ||
796 | 0x4F54 ZB_HIZ_PITCH | ||
797 | 0x4F58 ZB_ZPASS_DATA | 785 | 0x4F58 ZB_ZPASS_DATA |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600 index 83e8bc0c2bb2..0828d80396f2 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rs600 +++ b/drivers/gpu/drm/radeon/reg_srcs/rs600 | |||
@@ -187,7 +187,6 @@ rs600 0x6d40 | |||
187 | 0x4364 RS_INST_13 | 187 | 0x4364 RS_INST_13 |
188 | 0x4368 RS_INST_14 | 188 | 0x4368 RS_INST_14 |
189 | 0x436C RS_INST_15 | 189 | 0x436C RS_INST_15 |
190 | 0x43A4 SC_HYPERZ_EN | ||
191 | 0x43A8 SC_EDGERULE | 190 | 0x43A8 SC_EDGERULE |
192 | 0x43B0 SC_CLIP_0_A | 191 | 0x43B0 SC_CLIP_0_A |
193 | 0x43B4 SC_CLIP_0_B | 192 | 0x43B4 SC_CLIP_0_B |
@@ -782,16 +781,4 @@ rs600 0x6d40 | |||
782 | 0x4F08 ZB_STENCILREFMASK | 781 | 0x4F08 ZB_STENCILREFMASK |
783 | 0x4F14 ZB_ZTOP | 782 | 0x4F14 ZB_ZTOP |
784 | 0x4F18 ZB_ZCACHE_CTLSTAT | 783 | 0x4F18 ZB_ZCACHE_CTLSTAT |
785 | 0x4F1C ZB_BW_CNTL | ||
786 | 0x4F28 ZB_DEPTHCLEARVALUE | ||
787 | 0x4F30 ZB_ZMASK_OFFSET | ||
788 | 0x4F34 ZB_ZMASK_PITCH | ||
789 | 0x4F38 ZB_ZMASK_WRINDEX | ||
790 | 0x4F3C ZB_ZMASK_DWORD | ||
791 | 0x4F40 ZB_ZMASK_RDINDEX | ||
792 | 0x4F44 ZB_HIZ_OFFSET | ||
793 | 0x4F48 ZB_HIZ_WRINDEX | ||
794 | 0x4F4C ZB_HIZ_DWORD | ||
795 | 0x4F50 ZB_HIZ_RDINDEX | ||
796 | 0x4F54 ZB_HIZ_PITCH | ||
797 | 0x4F58 ZB_ZPASS_DATA | 784 | 0x4F58 ZB_ZPASS_DATA |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index 1e46233985eb..8293855f5f0d 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 | |||
@@ -235,7 +235,6 @@ rv515 0x6d40 | |||
235 | 0x4354 RS_INST_13 | 235 | 0x4354 RS_INST_13 |
236 | 0x4358 RS_INST_14 | 236 | 0x4358 RS_INST_14 |
237 | 0x435C RS_INST_15 | 237 | 0x435C RS_INST_15 |
238 | 0x43A4 SC_HYPERZ_EN | ||
239 | 0x43A8 SC_EDGERULE | 238 | 0x43A8 SC_EDGERULE |
240 | 0x43B0 SC_CLIP_0_A | 239 | 0x43B0 SC_CLIP_0_A |
241 | 0x43B4 SC_CLIP_0_B | 240 | 0x43B4 SC_CLIP_0_B |
@@ -479,17 +478,5 @@ rv515 0x6d40 | |||
479 | 0x4F08 ZB_STENCILREFMASK | 478 | 0x4F08 ZB_STENCILREFMASK |
480 | 0x4F14 ZB_ZTOP | 479 | 0x4F14 ZB_ZTOP |
481 | 0x4F18 ZB_ZCACHE_CTLSTAT | 480 | 0x4F18 ZB_ZCACHE_CTLSTAT |
482 | 0x4F1C ZB_BW_CNTL | ||
483 | 0x4F28 ZB_DEPTHCLEARVALUE | ||
484 | 0x4F30 ZB_ZMASK_OFFSET | ||
485 | 0x4F34 ZB_ZMASK_PITCH | ||
486 | 0x4F38 ZB_ZMASK_WRINDEX | ||
487 | 0x4F3C ZB_ZMASK_DWORD | ||
488 | 0x4F40 ZB_ZMASK_RDINDEX | ||
489 | 0x4F44 ZB_HIZ_OFFSET | ||
490 | 0x4F48 ZB_HIZ_WRINDEX | ||
491 | 0x4F4C ZB_HIZ_DWORD | ||
492 | 0x4F50 ZB_HIZ_RDINDEX | ||
493 | 0x4F54 ZB_HIZ_PITCH | ||
494 | 0x4F58 ZB_ZPASS_DATA | 481 | 0x4F58 ZB_ZPASS_DATA |
495 | 0x4FD4 ZB_STENCILREFMASK_BF | 482 | 0x4FD4 ZB_STENCILREFMASK_BF |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index f454c9a5e7f2..ae2b76b9a388 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -55,14 +55,6 @@ void rs400_gart_adjust_size(struct radeon_device *rdev) | |||
55 | rdev->mc.gtt_size = 32 * 1024 * 1024; | 55 | rdev->mc.gtt_size = 32 * 1024 * 1024; |
56 | return; | 56 | return; |
57 | } | 57 | } |
58 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) { | ||
59 | /* FIXME: RS400 & RS480 seems to have issue with GART size | ||
60 | * if 4G of system memory (needs more testing) | ||
61 | */ | ||
62 | /* XXX is this still an issue with proper alignment? */ | ||
63 | rdev->mc.gtt_size = 32 * 1024 * 1024; | ||
64 | DRM_ERROR("Forcing to 32M GART size (because of ASIC bug ?)\n"); | ||
65 | } | ||
66 | } | 58 | } |
67 | 59 | ||
68 | void rs400_gart_tlb_flush(struct radeon_device *rdev) | 60 | void rs400_gart_tlb_flush(struct radeon_device *rdev) |
@@ -483,6 +475,8 @@ int rs400_init(struct radeon_device *rdev) | |||
483 | /* Initialize surface registers */ | 475 | /* Initialize surface registers */ |
484 | radeon_surface_init(rdev); | 476 | radeon_surface_init(rdev); |
485 | /* TODO: disable VGA need to use VGA request */ | 477 | /* TODO: disable VGA need to use VGA request */ |
478 | /* restore some register to sane defaults */ | ||
479 | r100_restore_sanity(rdev); | ||
486 | /* BIOS*/ | 480 | /* BIOS*/ |
487 | if (!radeon_get_bios(rdev)) { | 481 | if (!radeon_get_bios(rdev)) { |
488 | if (ASIC_IS_AVIVO(rdev)) | 482 | if (ASIC_IS_AVIVO(rdev)) |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 6dc15ea8ba33..cc05b230d7ef 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -686,8 +686,8 @@ void rs600_mc_init(struct radeon_device *rdev) | |||
686 | { | 686 | { |
687 | u64 base; | 687 | u64 base; |
688 | 688 | ||
689 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 689 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); |
690 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 690 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); |
691 | rdev->mc.vram_is_ddr = true; | 691 | rdev->mc.vram_is_ddr = true; |
692 | rdev->mc.vram_width = 128; | 692 | rdev->mc.vram_width = 128; |
693 | rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); | 693 | rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); |
@@ -696,7 +696,6 @@ void rs600_mc_init(struct radeon_device *rdev) | |||
696 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); | 696 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); |
697 | base = RREG32_MC(R_000004_MC_FB_LOCATION); | 697 | base = RREG32_MC(R_000004_MC_FB_LOCATION); |
698 | base = G_000004_MC_FB_START(base) << 16; | 698 | base = G_000004_MC_FB_START(base) << 16; |
699 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); | ||
700 | radeon_vram_location(rdev, &rdev->mc, base); | 699 | radeon_vram_location(rdev, &rdev->mc, base); |
701 | rdev->mc.gtt_base_align = 0; | 700 | rdev->mc.gtt_base_align = 0; |
702 | radeon_gtt_location(rdev, &rdev->mc); | 701 | radeon_gtt_location(rdev, &rdev->mc); |
@@ -813,6 +812,13 @@ static int rs600_startup(struct radeon_device *rdev) | |||
813 | dev_err(rdev->dev, "failled initializing IB (%d).\n", r); | 812 | dev_err(rdev->dev, "failled initializing IB (%d).\n", r); |
814 | return r; | 813 | return r; |
815 | } | 814 | } |
815 | |||
816 | r = r600_audio_init(rdev); | ||
817 | if (r) { | ||
818 | dev_err(rdev->dev, "failed initializing audio\n"); | ||
819 | return r; | ||
820 | } | ||
821 | |||
816 | return 0; | 822 | return 0; |
817 | } | 823 | } |
818 | 824 | ||
@@ -839,6 +845,7 @@ int rs600_resume(struct radeon_device *rdev) | |||
839 | 845 | ||
840 | int rs600_suspend(struct radeon_device *rdev) | 846 | int rs600_suspend(struct radeon_device *rdev) |
841 | { | 847 | { |
848 | r600_audio_fini(rdev); | ||
842 | r100_cp_disable(rdev); | 849 | r100_cp_disable(rdev); |
843 | r100_wb_disable(rdev); | 850 | r100_wb_disable(rdev); |
844 | rs600_irq_disable(rdev); | 851 | rs600_irq_disable(rdev); |
@@ -848,6 +855,7 @@ int rs600_suspend(struct radeon_device *rdev) | |||
848 | 855 | ||
849 | void rs600_fini(struct radeon_device *rdev) | 856 | void rs600_fini(struct radeon_device *rdev) |
850 | { | 857 | { |
858 | r600_audio_fini(rdev); | ||
851 | r100_cp_fini(rdev); | 859 | r100_cp_fini(rdev); |
852 | r100_wb_fini(rdev); | 860 | r100_wb_fini(rdev); |
853 | r100_ib_fini(rdev); | 861 | r100_ib_fini(rdev); |
@@ -871,6 +879,8 @@ int rs600_init(struct radeon_device *rdev) | |||
871 | radeon_scratch_init(rdev); | 879 | radeon_scratch_init(rdev); |
872 | /* Initialize surface registers */ | 880 | /* Initialize surface registers */ |
873 | radeon_surface_init(rdev); | 881 | radeon_surface_init(rdev); |
882 | /* restore some register to sane defaults */ | ||
883 | r100_restore_sanity(rdev); | ||
874 | /* BIOS */ | 884 | /* BIOS */ |
875 | if (!radeon_get_bios(rdev)) { | 885 | if (!radeon_get_bios(rdev)) { |
876 | if (ASIC_IS_AVIVO(rdev)) | 886 | if (ASIC_IS_AVIVO(rdev)) |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index ce4ecbe10816..3e3f75718be3 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -154,13 +154,13 @@ void rs690_mc_init(struct radeon_device *rdev) | |||
154 | rdev->mc.vram_width = 128; | 154 | rdev->mc.vram_width = 128; |
155 | rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); | 155 | rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); |
156 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; | 156 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; |
157 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 157 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); |
158 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 158 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); |
159 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 159 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
160 | base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); | 160 | base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); |
161 | base = G_000100_MC_FB_START(base) << 16; | 161 | base = G_000100_MC_FB_START(base) << 16; |
162 | rs690_pm_info(rdev); | ||
163 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); | 162 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); |
163 | rs690_pm_info(rdev); | ||
164 | radeon_vram_location(rdev, &rdev->mc, base); | 164 | radeon_vram_location(rdev, &rdev->mc, base); |
165 | rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1; | 165 | rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1; |
166 | radeon_gtt_location(rdev, &rdev->mc); | 166 | radeon_gtt_location(rdev, &rdev->mc); |
@@ -398,7 +398,9 @@ void rs690_bandwidth_update(struct radeon_device *rdev) | |||
398 | struct drm_display_mode *mode1 = NULL; | 398 | struct drm_display_mode *mode1 = NULL; |
399 | struct rs690_watermark wm0; | 399 | struct rs690_watermark wm0; |
400 | struct rs690_watermark wm1; | 400 | struct rs690_watermark wm1; |
401 | u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt; | 401 | u32 tmp; |
402 | u32 d1mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1); | ||
403 | u32 d2mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1); | ||
402 | fixed20_12 priority_mark02, priority_mark12, fill_rate; | 404 | fixed20_12 priority_mark02, priority_mark12, fill_rate; |
403 | fixed20_12 a, b; | 405 | fixed20_12 a, b; |
404 | 406 | ||
@@ -495,10 +497,6 @@ void rs690_bandwidth_update(struct radeon_device *rdev) | |||
495 | d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); | 497 | d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); |
496 | d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); | 498 | d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); |
497 | } | 499 | } |
498 | WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); | ||
499 | WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); | ||
500 | WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); | ||
501 | WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); | ||
502 | } else if (mode0) { | 500 | } else if (mode0) { |
503 | if (dfixed_trunc(wm0.dbpp) > 64) | 501 | if (dfixed_trunc(wm0.dbpp) > 64) |
504 | a.full = dfixed_mul(wm0.dbpp, wm0.num_line_pair); | 502 | a.full = dfixed_mul(wm0.dbpp, wm0.num_line_pair); |
@@ -528,13 +526,7 @@ void rs690_bandwidth_update(struct radeon_device *rdev) | |||
528 | d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); | 526 | d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); |
529 | if (rdev->disp_priority == 2) | 527 | if (rdev->disp_priority == 2) |
530 | d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); | 528 | d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); |
531 | WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); | 529 | } else if (mode1) { |
532 | WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); | ||
533 | WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, | ||
534 | S_006D48_D2MODE_PRIORITY_A_OFF(1)); | ||
535 | WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, | ||
536 | S_006D4C_D2MODE_PRIORITY_B_OFF(1)); | ||
537 | } else { | ||
538 | if (dfixed_trunc(wm1.dbpp) > 64) | 530 | if (dfixed_trunc(wm1.dbpp) > 64) |
539 | a.full = dfixed_mul(wm1.dbpp, wm1.num_line_pair); | 531 | a.full = dfixed_mul(wm1.dbpp, wm1.num_line_pair); |
540 | else | 532 | else |
@@ -563,13 +555,12 @@ void rs690_bandwidth_update(struct radeon_device *rdev) | |||
563 | d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); | 555 | d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); |
564 | if (rdev->disp_priority == 2) | 556 | if (rdev->disp_priority == 2) |
565 | d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); | 557 | d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); |
566 | WREG32(R_006548_D1MODE_PRIORITY_A_CNT, | ||
567 | S_006548_D1MODE_PRIORITY_A_OFF(1)); | ||
568 | WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, | ||
569 | S_00654C_D1MODE_PRIORITY_B_OFF(1)); | ||
570 | WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); | ||
571 | WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); | ||
572 | } | 558 | } |
559 | |||
560 | WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); | ||
561 | WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); | ||
562 | WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); | ||
563 | WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); | ||
573 | } | 564 | } |
574 | 565 | ||
575 | uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg) | 566 | uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg) |
@@ -641,6 +632,13 @@ static int rs690_startup(struct radeon_device *rdev) | |||
641 | dev_err(rdev->dev, "failled initializing IB (%d).\n", r); | 632 | dev_err(rdev->dev, "failled initializing IB (%d).\n", r); |
642 | return r; | 633 | return r; |
643 | } | 634 | } |
635 | |||
636 | r = r600_audio_init(rdev); | ||
637 | if (r) { | ||
638 | dev_err(rdev->dev, "failed initializing audio\n"); | ||
639 | return r; | ||
640 | } | ||
641 | |||
644 | return 0; | 642 | return 0; |
645 | } | 643 | } |
646 | 644 | ||
@@ -667,6 +665,7 @@ int rs690_resume(struct radeon_device *rdev) | |||
667 | 665 | ||
668 | int rs690_suspend(struct radeon_device *rdev) | 666 | int rs690_suspend(struct radeon_device *rdev) |
669 | { | 667 | { |
668 | r600_audio_fini(rdev); | ||
670 | r100_cp_disable(rdev); | 669 | r100_cp_disable(rdev); |
671 | r100_wb_disable(rdev); | 670 | r100_wb_disable(rdev); |
672 | rs600_irq_disable(rdev); | 671 | rs600_irq_disable(rdev); |
@@ -676,6 +675,7 @@ int rs690_suspend(struct radeon_device *rdev) | |||
676 | 675 | ||
677 | void rs690_fini(struct radeon_device *rdev) | 676 | void rs690_fini(struct radeon_device *rdev) |
678 | { | 677 | { |
678 | r600_audio_fini(rdev); | ||
679 | r100_cp_fini(rdev); | 679 | r100_cp_fini(rdev); |
680 | r100_wb_fini(rdev); | 680 | r100_wb_fini(rdev); |
681 | r100_ib_fini(rdev); | 681 | r100_ib_fini(rdev); |
@@ -699,6 +699,8 @@ int rs690_init(struct radeon_device *rdev) | |||
699 | radeon_scratch_init(rdev); | 699 | radeon_scratch_init(rdev); |
700 | /* Initialize surface registers */ | 700 | /* Initialize surface registers */ |
701 | radeon_surface_init(rdev); | 701 | radeon_surface_init(rdev); |
702 | /* restore some register to sane defaults */ | ||
703 | r100_restore_sanity(rdev); | ||
702 | /* TODO: disable VGA need to use VGA request */ | 704 | /* TODO: disable VGA need to use VGA request */ |
703 | /* BIOS*/ | 705 | /* BIOS*/ |
704 | if (!radeon_get_bios(rdev)) { | 706 | if (!radeon_get_bios(rdev)) { |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 0c9c169a6852..4d6e86041a9f 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -469,6 +469,8 @@ int rv515_init(struct radeon_device *rdev) | |||
469 | /* Initialize surface registers */ | 469 | /* Initialize surface registers */ |
470 | radeon_surface_init(rdev); | 470 | radeon_surface_init(rdev); |
471 | /* TODO: disable VGA need to use VGA request */ | 471 | /* TODO: disable VGA need to use VGA request */ |
472 | /* restore some register to sane defaults */ | ||
473 | r100_restore_sanity(rdev); | ||
472 | /* BIOS*/ | 474 | /* BIOS*/ |
473 | if (!radeon_get_bios(rdev)) { | 475 | if (!radeon_get_bios(rdev)) { |
474 | if (ASIC_IS_AVIVO(rdev)) | 476 | if (ASIC_IS_AVIVO(rdev)) |
@@ -925,7 +927,9 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev) | |||
925 | struct drm_display_mode *mode1 = NULL; | 927 | struct drm_display_mode *mode1 = NULL; |
926 | struct rv515_watermark wm0; | 928 | struct rv515_watermark wm0; |
927 | struct rv515_watermark wm1; | 929 | struct rv515_watermark wm1; |
928 | u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt; | 930 | u32 tmp; |
931 | u32 d1mode_priority_a_cnt = MODE_PRIORITY_OFF; | ||
932 | u32 d2mode_priority_a_cnt = MODE_PRIORITY_OFF; | ||
929 | fixed20_12 priority_mark02, priority_mark12, fill_rate; | 933 | fixed20_12 priority_mark02, priority_mark12, fill_rate; |
930 | fixed20_12 a, b; | 934 | fixed20_12 a, b; |
931 | 935 | ||
@@ -999,10 +1003,6 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev) | |||
999 | d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; | 1003 | d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; |
1000 | d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; | 1004 | d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; |
1001 | } | 1005 | } |
1002 | WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); | ||
1003 | WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); | ||
1004 | WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); | ||
1005 | WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); | ||
1006 | } else if (mode0) { | 1006 | } else if (mode0) { |
1007 | if (dfixed_trunc(wm0.dbpp) > 64) | 1007 | if (dfixed_trunc(wm0.dbpp) > 64) |
1008 | a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); | 1008 | a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); |
@@ -1032,11 +1032,7 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev) | |||
1032 | d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); | 1032 | d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); |
1033 | if (rdev->disp_priority == 2) | 1033 | if (rdev->disp_priority == 2) |
1034 | d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; | 1034 | d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; |
1035 | WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); | 1035 | } else if (mode1) { |
1036 | WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); | ||
1037 | WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF); | ||
1038 | WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF); | ||
1039 | } else { | ||
1040 | if (dfixed_trunc(wm1.dbpp) > 64) | 1036 | if (dfixed_trunc(wm1.dbpp) > 64) |
1041 | a.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); | 1037 | a.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); |
1042 | else | 1038 | else |
@@ -1065,11 +1061,12 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev) | |||
1065 | d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); | 1061 | d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); |
1066 | if (rdev->disp_priority == 2) | 1062 | if (rdev->disp_priority == 2) |
1067 | d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; | 1063 | d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; |
1068 | WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF); | ||
1069 | WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF); | ||
1070 | WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); | ||
1071 | WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); | ||
1072 | } | 1064 | } |
1065 | |||
1066 | WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); | ||
1067 | WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); | ||
1068 | WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); | ||
1069 | WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); | ||
1073 | } | 1070 | } |
1074 | 1071 | ||
1075 | void rv515_bandwidth_update(struct radeon_device *rdev) | 1072 | void rv515_bandwidth_update(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index b7fd82064922..f1c796810117 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -42,6 +42,21 @@ | |||
42 | static void rv770_gpu_init(struct radeon_device *rdev); | 42 | static void rv770_gpu_init(struct radeon_device *rdev); |
43 | void rv770_fini(struct radeon_device *rdev); | 43 | void rv770_fini(struct radeon_device *rdev); |
44 | 44 | ||
45 | /* get temperature in millidegrees */ | ||
46 | u32 rv770_get_temp(struct radeon_device *rdev) | ||
47 | { | ||
48 | u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> | ||
49 | ASIC_T_SHIFT; | ||
50 | u32 actual_temp = 0; | ||
51 | |||
52 | if ((temp >> 9) & 1) | ||
53 | actual_temp = 0; | ||
54 | else | ||
55 | actual_temp = (temp >> 1) & 0xff; | ||
56 | |||
57 | return actual_temp * 1000; | ||
58 | } | ||
59 | |||
45 | void rv770_pm_misc(struct radeon_device *rdev) | 60 | void rv770_pm_misc(struct radeon_device *rdev) |
46 | { | 61 | { |
47 | int req_ps_idx = rdev->pm.requested_power_state_index; | 62 | int req_ps_idx = rdev->pm.requested_power_state_index; |
@@ -189,7 +204,10 @@ static void rv770_mc_program(struct radeon_device *rdev) | |||
189 | WREG32((0x2c20 + j), 0x00000000); | 204 | WREG32((0x2c20 + j), 0x00000000); |
190 | WREG32((0x2c24 + j), 0x00000000); | 205 | WREG32((0x2c24 + j), 0x00000000); |
191 | } | 206 | } |
192 | WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); | 207 | /* r7xx hw bug. Read from HDP_DEBUG1 rather |
208 | * than writing to HDP_REG_COHERENCY_FLUSH_CNTL | ||
209 | */ | ||
210 | tmp = RREG32(HDP_DEBUG1); | ||
193 | 211 | ||
194 | rv515_mc_stop(rdev, &save); | 212 | rv515_mc_stop(rdev, &save); |
195 | if (r600_mc_wait_for_idle(rdev)) { | 213 | if (r600_mc_wait_for_idle(rdev)) { |
@@ -659,8 +677,9 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
659 | r600_count_pipe_bits((cc_rb_backend_disable & | 677 | r600_count_pipe_bits((cc_rb_backend_disable & |
660 | R7XX_MAX_BACKENDS_MASK) >> 16)), | 678 | R7XX_MAX_BACKENDS_MASK) >> 16)), |
661 | (cc_rb_backend_disable >> 16)); | 679 | (cc_rb_backend_disable >> 16)); |
662 | gb_tiling_config |= BACKEND_MAP(backend_map); | ||
663 | 680 | ||
681 | rdev->config.rv770.tile_config = gb_tiling_config; | ||
682 | gb_tiling_config |= BACKEND_MAP(backend_map); | ||
664 | 683 | ||
665 | WREG32(GB_TILING_CONFIG, gb_tiling_config); | 684 | WREG32(GB_TILING_CONFIG, gb_tiling_config); |
666 | WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); | 685 | WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); |
@@ -919,8 +938,8 @@ int rv770_mc_init(struct radeon_device *rdev) | |||
919 | } | 938 | } |
920 | rdev->mc.vram_width = numchan * chansize; | 939 | rdev->mc.vram_width = numchan * chansize; |
921 | /* Could aper size report 0 ? */ | 940 | /* Could aper size report 0 ? */ |
922 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 941 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); |
923 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 942 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); |
924 | /* Setup GPU memory space */ | 943 | /* Setup GPU memory space */ |
925 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); | 944 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); |
926 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 945 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index 9506f8cb99e0..b7a5a20e81dc 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h | |||
@@ -122,12 +122,18 @@ | |||
122 | #define GUI_ACTIVE (1<<31) | 122 | #define GUI_ACTIVE (1<<31) |
123 | #define GRBM_STATUS2 0x8014 | 123 | #define GRBM_STATUS2 0x8014 |
124 | 124 | ||
125 | #define CG_MULT_THERMAL_STATUS 0x740 | ||
126 | #define ASIC_T(x) ((x) << 16) | ||
127 | #define ASIC_T_MASK 0x3FF0000 | ||
128 | #define ASIC_T_SHIFT 16 | ||
129 | |||
125 | #define HDP_HOST_PATH_CNTL 0x2C00 | 130 | #define HDP_HOST_PATH_CNTL 0x2C00 |
126 | #define HDP_NONSURFACE_BASE 0x2C04 | 131 | #define HDP_NONSURFACE_BASE 0x2C04 |
127 | #define HDP_NONSURFACE_INFO 0x2C08 | 132 | #define HDP_NONSURFACE_INFO 0x2C08 |
128 | #define HDP_NONSURFACE_SIZE 0x2C0C | 133 | #define HDP_NONSURFACE_SIZE 0x2C0C |
129 | #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 | 134 | #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 |
130 | #define HDP_TILING_CONFIG 0x2F3C | 135 | #define HDP_TILING_CONFIG 0x2F3C |
136 | #define HDP_DEBUG1 0x2F34 | ||
131 | 137 | ||
132 | #define MC_SHARED_CHMAP 0x2004 | 138 | #define MC_SHARED_CHMAP 0x2004 |
133 | #define NOOFCHAN_SHIFT 12 | 139 | #define NOOFCHAN_SHIFT 12 |
diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c index fa05cda8c98f..976dc8d25280 100644 --- a/drivers/gpu/drm/savage/savage_bci.c +++ b/drivers/gpu/drm/savage/savage_bci.c | |||
@@ -573,13 +573,13 @@ int savage_driver_firstopen(struct drm_device *dev) | |||
573 | dev_priv->mtrr[2].handle = -1; | 573 | dev_priv->mtrr[2].handle = -1; |
574 | if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { | 574 | if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { |
575 | fb_rsrc = 0; | 575 | fb_rsrc = 0; |
576 | fb_base = drm_get_resource_start(dev, 0); | 576 | fb_base = pci_resource_start(dev->pdev, 0); |
577 | fb_size = SAVAGE_FB_SIZE_S3; | 577 | fb_size = SAVAGE_FB_SIZE_S3; |
578 | mmio_base = fb_base + SAVAGE_FB_SIZE_S3; | 578 | mmio_base = fb_base + SAVAGE_FB_SIZE_S3; |
579 | aper_rsrc = 0; | 579 | aper_rsrc = 0; |
580 | aperture_base = fb_base + SAVAGE_APERTURE_OFFSET; | 580 | aperture_base = fb_base + SAVAGE_APERTURE_OFFSET; |
581 | /* this should always be true */ | 581 | /* this should always be true */ |
582 | if (drm_get_resource_len(dev, 0) == 0x08000000) { | 582 | if (pci_resource_len(dev->pdev, 0) == 0x08000000) { |
583 | /* Don't make MMIO write-cobining! We need 3 | 583 | /* Don't make MMIO write-cobining! We need 3 |
584 | * MTRRs. */ | 584 | * MTRRs. */ |
585 | dev_priv->mtrr[0].base = fb_base; | 585 | dev_priv->mtrr[0].base = fb_base; |
@@ -599,18 +599,19 @@ int savage_driver_firstopen(struct drm_device *dev) | |||
599 | dev_priv->mtrr[2].size, DRM_MTRR_WC); | 599 | dev_priv->mtrr[2].size, DRM_MTRR_WC); |
600 | } else { | 600 | } else { |
601 | DRM_ERROR("strange pci_resource_len %08llx\n", | 601 | DRM_ERROR("strange pci_resource_len %08llx\n", |
602 | (unsigned long long)drm_get_resource_len(dev, 0)); | 602 | (unsigned long long) |
603 | pci_resource_len(dev->pdev, 0)); | ||
603 | } | 604 | } |
604 | } else if (dev_priv->chipset != S3_SUPERSAVAGE && | 605 | } else if (dev_priv->chipset != S3_SUPERSAVAGE && |
605 | dev_priv->chipset != S3_SAVAGE2000) { | 606 | dev_priv->chipset != S3_SAVAGE2000) { |
606 | mmio_base = drm_get_resource_start(dev, 0); | 607 | mmio_base = pci_resource_start(dev->pdev, 0); |
607 | fb_rsrc = 1; | 608 | fb_rsrc = 1; |
608 | fb_base = drm_get_resource_start(dev, 1); | 609 | fb_base = pci_resource_start(dev->pdev, 1); |
609 | fb_size = SAVAGE_FB_SIZE_S4; | 610 | fb_size = SAVAGE_FB_SIZE_S4; |
610 | aper_rsrc = 1; | 611 | aper_rsrc = 1; |
611 | aperture_base = fb_base + SAVAGE_APERTURE_OFFSET; | 612 | aperture_base = fb_base + SAVAGE_APERTURE_OFFSET; |
612 | /* this should always be true */ | 613 | /* this should always be true */ |
613 | if (drm_get_resource_len(dev, 1) == 0x08000000) { | 614 | if (pci_resource_len(dev->pdev, 1) == 0x08000000) { |
614 | /* Can use one MTRR to cover both fb and | 615 | /* Can use one MTRR to cover both fb and |
615 | * aperture. */ | 616 | * aperture. */ |
616 | dev_priv->mtrr[0].base = fb_base; | 617 | dev_priv->mtrr[0].base = fb_base; |
@@ -620,15 +621,16 @@ int savage_driver_firstopen(struct drm_device *dev) | |||
620 | dev_priv->mtrr[0].size, DRM_MTRR_WC); | 621 | dev_priv->mtrr[0].size, DRM_MTRR_WC); |
621 | } else { | 622 | } else { |
622 | DRM_ERROR("strange pci_resource_len %08llx\n", | 623 | DRM_ERROR("strange pci_resource_len %08llx\n", |
623 | (unsigned long long)drm_get_resource_len(dev, 1)); | 624 | (unsigned long long) |
625 | pci_resource_len(dev->pdev, 1)); | ||
624 | } | 626 | } |
625 | } else { | 627 | } else { |
626 | mmio_base = drm_get_resource_start(dev, 0); | 628 | mmio_base = pci_resource_start(dev->pdev, 0); |
627 | fb_rsrc = 1; | 629 | fb_rsrc = 1; |
628 | fb_base = drm_get_resource_start(dev, 1); | 630 | fb_base = pci_resource_start(dev->pdev, 1); |
629 | fb_size = drm_get_resource_len(dev, 1); | 631 | fb_size = pci_resource_len(dev->pdev, 1); |
630 | aper_rsrc = 2; | 632 | aper_rsrc = 2; |
631 | aperture_base = drm_get_resource_start(dev, 2); | 633 | aperture_base = pci_resource_start(dev->pdev, 2); |
632 | /* Automatic MTRR setup will do the right thing. */ | 634 | /* Automatic MTRR setup will do the right thing. */ |
633 | } | 635 | } |
634 | 636 | ||
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 4fd1f067d380..776bf9e9ea1a 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c | |||
@@ -47,9 +47,8 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) | |||
47 | dev->dev_private = (void *)dev_priv; | 47 | dev->dev_private = (void *)dev_priv; |
48 | dev_priv->chipset = chipset; | 48 | dev_priv->chipset = chipset; |
49 | ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); | 49 | ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); |
50 | if (ret) { | 50 | if (ret) |
51 | kfree(dev_priv); | 51 | kfree(dev_priv); |
52 | } | ||
53 | 52 | ||
54 | return ret; | 53 | return ret; |
55 | } | 54 | } |
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c index af22111397d8..07d0f2979cac 100644 --- a/drivers/gpu/drm/sis/sis_mm.c +++ b/drivers/gpu/drm/sis/sis_mm.c | |||
@@ -78,7 +78,7 @@ static unsigned long sis_sman_mm_offset(void *private, void *ref) | |||
78 | #else /* CONFIG_FB_SIS[_MODULE] */ | 78 | #else /* CONFIG_FB_SIS[_MODULE] */ |
79 | 79 | ||
80 | #define SIS_MM_ALIGN_SHIFT 4 | 80 | #define SIS_MM_ALIGN_SHIFT 4 |
81 | #define SIS_MM_ALIGN_MASK ( (1 << SIS_MM_ALIGN_SHIFT) - 1) | 81 | #define SIS_MM_ALIGN_MASK ((1 << SIS_MM_ALIGN_SHIFT) - 1) |
82 | 82 | ||
83 | #endif /* CONFIG_FB_SIS[_MODULE] */ | 83 | #endif /* CONFIG_FB_SIS[_MODULE] */ |
84 | 84 | ||
@@ -225,9 +225,8 @@ static drm_local_map_t *sis_reg_init(struct drm_device *dev) | |||
225 | map = entry->map; | 225 | map = entry->map; |
226 | if (!map) | 226 | if (!map) |
227 | continue; | 227 | continue; |
228 | if (map->type == _DRM_REGISTERS) { | 228 | if (map->type == _DRM_REGISTERS) |
229 | return map; | 229 | return map; |
230 | } | ||
231 | } | 230 | } |
232 | return NULL; | 231 | return NULL; |
233 | } | 232 | } |
@@ -264,10 +263,10 @@ int sis_idle(struct drm_device *dev) | |||
264 | 263 | ||
265 | end = jiffies + (DRM_HZ * 3); | 264 | end = jiffies + (DRM_HZ * 3); |
266 | 265 | ||
267 | for (i=0; i<4; ++i) { | 266 | for (i = 0; i < 4; ++i) { |
268 | do { | 267 | do { |
269 | idle_reg = SIS_READ(0x85cc); | 268 | idle_reg = SIS_READ(0x85cc); |
270 | } while ( !time_after_eq(jiffies, end) && | 269 | } while (!time_after_eq(jiffies, end) && |
271 | ((idle_reg & 0x80000000) != 0x80000000)); | 270 | ((idle_reg & 0x80000000) != 0x80000000)); |
272 | } | 271 | } |
273 | 272 | ||
@@ -301,7 +300,7 @@ void sis_lastclose(struct drm_device *dev) | |||
301 | mutex_unlock(&dev->struct_mutex); | 300 | mutex_unlock(&dev->struct_mutex); |
302 | } | 301 | } |
303 | 302 | ||
304 | void sis_reclaim_buffers_locked(struct drm_device * dev, | 303 | void sis_reclaim_buffers_locked(struct drm_device *dev, |
305 | struct drm_file *file_priv) | 304 | struct drm_file *file_priv) |
306 | { | 305 | { |
307 | drm_sis_private_t *dev_priv = dev->dev_private; | 306 | drm_sis_private_t *dev_priv = dev->dev_private; |
@@ -312,9 +311,8 @@ void sis_reclaim_buffers_locked(struct drm_device * dev, | |||
312 | return; | 311 | return; |
313 | } | 312 | } |
314 | 313 | ||
315 | if (dev->driver->dma_quiescent) { | 314 | if (dev->driver->dma_quiescent) |
316 | dev->driver->dma_quiescent(dev); | 315 | dev->driver->dma_quiescent(dev); |
317 | } | ||
318 | 316 | ||
319 | drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv); | 317 | drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv); |
320 | mutex_unlock(&dev->struct_mutex); | 318 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/ttm/Makefile b/drivers/gpu/drm/ttm/Makefile index 4256e2006476..b256d4adfafe 100644 --- a/drivers/gpu/drm/ttm/Makefile +++ b/drivers/gpu/drm/ttm/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | ccflags-y := -Iinclude/drm | 4 | ccflags-y := -Iinclude/drm |
5 | ttm-y := ttm_agp_backend.o ttm_memory.o ttm_tt.o ttm_bo.o \ | 5 | ttm-y := ttm_agp_backend.o ttm_memory.o ttm_tt.o ttm_bo.o \ |
6 | ttm_bo_util.o ttm_bo_vm.o ttm_module.o ttm_global.o \ | 6 | ttm_bo_util.o ttm_bo_vm.o ttm_module.o \ |
7 | ttm_object.o ttm_lock.o ttm_execbuf_util.o ttm_page_alloc.o | 7 | ttm_object.o ttm_lock.o ttm_execbuf_util.o ttm_page_alloc.o |
8 | 8 | ||
9 | obj-$(CONFIG_DRM_TTM) += ttm.o | 9 | obj-$(CONFIG_DRM_TTM) += ttm.o |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 555ebb12ace8..cb4cf7ef4d1e 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -476,7 +476,6 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) | |||
476 | ++put_count; | 476 | ++put_count; |
477 | } | 477 | } |
478 | if (bo->mem.mm_node) { | 478 | if (bo->mem.mm_node) { |
479 | bo->mem.mm_node->private = NULL; | ||
480 | drm_mm_put_block(bo->mem.mm_node); | 479 | drm_mm_put_block(bo->mem.mm_node); |
481 | bo->mem.mm_node = NULL; | 480 | bo->mem.mm_node = NULL; |
482 | } | 481 | } |
@@ -670,7 +669,6 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible, | |||
670 | printk(KERN_ERR TTM_PFX "Buffer eviction failed\n"); | 669 | printk(KERN_ERR TTM_PFX "Buffer eviction failed\n"); |
671 | spin_lock(&glob->lru_lock); | 670 | spin_lock(&glob->lru_lock); |
672 | if (evict_mem.mm_node) { | 671 | if (evict_mem.mm_node) { |
673 | evict_mem.mm_node->private = NULL; | ||
674 | drm_mm_put_block(evict_mem.mm_node); | 672 | drm_mm_put_block(evict_mem.mm_node); |
675 | evict_mem.mm_node = NULL; | 673 | evict_mem.mm_node = NULL; |
676 | } | 674 | } |
@@ -929,8 +927,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, | |||
929 | mem->mm_node = node; | 927 | mem->mm_node = node; |
930 | mem->mem_type = mem_type; | 928 | mem->mem_type = mem_type; |
931 | mem->placement = cur_flags; | 929 | mem->placement = cur_flags; |
932 | if (node) | ||
933 | node->private = bo; | ||
934 | return 0; | 930 | return 0; |
935 | } | 931 | } |
936 | 932 | ||
@@ -973,7 +969,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, | |||
973 | interruptible, no_wait_reserve, no_wait_gpu); | 969 | interruptible, no_wait_reserve, no_wait_gpu); |
974 | if (ret == 0 && mem->mm_node) { | 970 | if (ret == 0 && mem->mm_node) { |
975 | mem->placement = cur_flags; | 971 | mem->placement = cur_flags; |
976 | mem->mm_node->private = bo; | ||
977 | return 0; | 972 | return 0; |
978 | } | 973 | } |
979 | if (ret == -ERESTARTSYS) | 974 | if (ret == -ERESTARTSYS) |
@@ -1029,7 +1024,6 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo, | |||
1029 | out_unlock: | 1024 | out_unlock: |
1030 | if (ret && mem.mm_node) { | 1025 | if (ret && mem.mm_node) { |
1031 | spin_lock(&glob->lru_lock); | 1026 | spin_lock(&glob->lru_lock); |
1032 | mem.mm_node->private = NULL; | ||
1033 | drm_mm_put_block(mem.mm_node); | 1027 | drm_mm_put_block(mem.mm_node); |
1034 | spin_unlock(&glob->lru_lock); | 1028 | spin_unlock(&glob->lru_lock); |
1035 | } | 1029 | } |
@@ -1401,7 +1395,7 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj) | |||
1401 | kfree(glob); | 1395 | kfree(glob); |
1402 | } | 1396 | } |
1403 | 1397 | ||
1404 | void ttm_bo_global_release(struct ttm_global_reference *ref) | 1398 | void ttm_bo_global_release(struct drm_global_reference *ref) |
1405 | { | 1399 | { |
1406 | struct ttm_bo_global *glob = ref->object; | 1400 | struct ttm_bo_global *glob = ref->object; |
1407 | 1401 | ||
@@ -1410,7 +1404,7 @@ void ttm_bo_global_release(struct ttm_global_reference *ref) | |||
1410 | } | 1404 | } |
1411 | EXPORT_SYMBOL(ttm_bo_global_release); | 1405 | EXPORT_SYMBOL(ttm_bo_global_release); |
1412 | 1406 | ||
1413 | int ttm_bo_global_init(struct ttm_global_reference *ref) | 1407 | int ttm_bo_global_init(struct drm_global_reference *ref) |
1414 | { | 1408 | { |
1415 | struct ttm_bo_global_ref *bo_ref = | 1409 | struct ttm_bo_global_ref *bo_ref = |
1416 | container_of(ref, struct ttm_bo_global_ref, ref); | 1410 | container_of(ref, struct ttm_bo_global_ref, ref); |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 13012a1f1486..7cffb3e04232 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
@@ -353,8 +353,6 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, | |||
353 | fbo->vm_node = NULL; | 353 | fbo->vm_node = NULL; |
354 | 354 | ||
355 | fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); | 355 | fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); |
356 | if (fbo->mem.mm_node) | ||
357 | fbo->mem.mm_node->private = (void *)fbo; | ||
358 | kref_init(&fbo->list_kref); | 356 | kref_init(&fbo->list_kref); |
359 | kref_init(&fbo->kref); | 357 | kref_init(&fbo->kref); |
360 | fbo->destroy = &ttm_transfered_destroy; | 358 | fbo->destroy = &ttm_transfered_destroy; |
diff --git a/drivers/gpu/drm/ttm/ttm_module.c b/drivers/gpu/drm/ttm/ttm_module.c index 9a6edbfeaa9e..902d7cf9fb4e 100644 --- a/drivers/gpu/drm/ttm/ttm_module.c +++ b/drivers/gpu/drm/ttm/ttm_module.c | |||
@@ -70,8 +70,6 @@ static int __init ttm_init(void) | |||
70 | if (unlikely(ret != 0)) | 70 | if (unlikely(ret != 0)) |
71 | return ret; | 71 | return ret; |
72 | 72 | ||
73 | ttm_global_init(); | ||
74 | |||
75 | atomic_set(&device_released, 0); | 73 | atomic_set(&device_released, 0); |
76 | ret = drm_class_device_register(&ttm_drm_class_device); | 74 | ret = drm_class_device_register(&ttm_drm_class_device); |
77 | if (unlikely(ret != 0)) | 75 | if (unlikely(ret != 0)) |
@@ -81,7 +79,6 @@ static int __init ttm_init(void) | |||
81 | out_no_dev_reg: | 79 | out_no_dev_reg: |
82 | atomic_set(&device_released, 1); | 80 | atomic_set(&device_released, 1); |
83 | wake_up_all(&exit_q); | 81 | wake_up_all(&exit_q); |
84 | ttm_global_release(); | ||
85 | return ret; | 82 | return ret; |
86 | } | 83 | } |
87 | 84 | ||
@@ -95,7 +92,6 @@ static void __exit ttm_exit(void) | |||
95 | */ | 92 | */ |
96 | 93 | ||
97 | wait_event(exit_q, atomic_read(&device_released) == 1); | 94 | wait_event(exit_q, atomic_read(&device_released) == 1); |
98 | ttm_global_release(); | ||
99 | } | 95 | } |
100 | 96 | ||
101 | module_init(ttm_init); | 97 | module_init(ttm_init); |
diff --git a/drivers/gpu/drm/via/via_dma.c b/drivers/gpu/drm/via/via_dma.c index bfb92d283260..68dda74a50ae 100644 --- a/drivers/gpu/drm/via/via_dma.c +++ b/drivers/gpu/drm/via/via_dma.c | |||
@@ -58,28 +58,29 @@ | |||
58 | *((uint32_t *)(vb)) = ((nReg) >> 2) | HALCYON_HEADER1; \ | 58 | *((uint32_t *)(vb)) = ((nReg) >> 2) | HALCYON_HEADER1; \ |
59 | *((uint32_t *)(vb) + 1) = (nData); \ | 59 | *((uint32_t *)(vb) + 1) = (nData); \ |
60 | vb = ((uint32_t *)vb) + 2; \ | 60 | vb = ((uint32_t *)vb) + 2; \ |
61 | dev_priv->dma_low +=8; \ | 61 | dev_priv->dma_low += 8; \ |
62 | } | 62 | } |
63 | 63 | ||
64 | #define via_flush_write_combine() DRM_MEMORYBARRIER() | 64 | #define via_flush_write_combine() DRM_MEMORYBARRIER() |
65 | 65 | ||
66 | #define VIA_OUT_RING_QW(w1,w2) \ | 66 | #define VIA_OUT_RING_QW(w1, w2) do { \ |
67 | *vb++ = (w1); \ | 67 | *vb++ = (w1); \ |
68 | *vb++ = (w2); \ | 68 | *vb++ = (w2); \ |
69 | dev_priv->dma_low += 8; | 69 | dev_priv->dma_low += 8; \ |
70 | } while (0) | ||
70 | 71 | ||
71 | static void via_cmdbuf_start(drm_via_private_t * dev_priv); | 72 | static void via_cmdbuf_start(drm_via_private_t *dev_priv); |
72 | static void via_cmdbuf_pause(drm_via_private_t * dev_priv); | 73 | static void via_cmdbuf_pause(drm_via_private_t *dev_priv); |
73 | static void via_cmdbuf_reset(drm_via_private_t * dev_priv); | 74 | static void via_cmdbuf_reset(drm_via_private_t *dev_priv); |
74 | static void via_cmdbuf_rewind(drm_via_private_t * dev_priv); | 75 | static void via_cmdbuf_rewind(drm_via_private_t *dev_priv); |
75 | static int via_wait_idle(drm_via_private_t * dev_priv); | 76 | static int via_wait_idle(drm_via_private_t *dev_priv); |
76 | static void via_pad_cache(drm_via_private_t * dev_priv, int qwords); | 77 | static void via_pad_cache(drm_via_private_t *dev_priv, int qwords); |
77 | 78 | ||
78 | /* | 79 | /* |
79 | * Free space in command buffer. | 80 | * Free space in command buffer. |
80 | */ | 81 | */ |
81 | 82 | ||
82 | static uint32_t via_cmdbuf_space(drm_via_private_t * dev_priv) | 83 | static uint32_t via_cmdbuf_space(drm_via_private_t *dev_priv) |
83 | { | 84 | { |
84 | uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; | 85 | uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; |
85 | uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base; | 86 | uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base; |
@@ -93,7 +94,7 @@ static uint32_t via_cmdbuf_space(drm_via_private_t * dev_priv) | |||
93 | * How much does the command regulator lag behind? | 94 | * How much does the command regulator lag behind? |
94 | */ | 95 | */ |
95 | 96 | ||
96 | static uint32_t via_cmdbuf_lag(drm_via_private_t * dev_priv) | 97 | static uint32_t via_cmdbuf_lag(drm_via_private_t *dev_priv) |
97 | { | 98 | { |
98 | uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; | 99 | uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; |
99 | uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base; | 100 | uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base; |
@@ -108,7 +109,7 @@ static uint32_t via_cmdbuf_lag(drm_via_private_t * dev_priv) | |||
108 | */ | 109 | */ |
109 | 110 | ||
110 | static inline int | 111 | static inline int |
111 | via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size) | 112 | via_cmdbuf_wait(drm_via_private_t *dev_priv, unsigned int size) |
112 | { | 113 | { |
113 | uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; | 114 | uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; |
114 | uint32_t cur_addr, hw_addr, next_addr; | 115 | uint32_t cur_addr, hw_addr, next_addr; |
@@ -146,14 +147,13 @@ static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv, | |||
146 | dev_priv->dma_high) { | 147 | dev_priv->dma_high) { |
147 | via_cmdbuf_rewind(dev_priv); | 148 | via_cmdbuf_rewind(dev_priv); |
148 | } | 149 | } |
149 | if (via_cmdbuf_wait(dev_priv, size) != 0) { | 150 | if (via_cmdbuf_wait(dev_priv, size) != 0) |
150 | return NULL; | 151 | return NULL; |
151 | } | ||
152 | 152 | ||
153 | return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low); | 153 | return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low); |
154 | } | 154 | } |
155 | 155 | ||
156 | int via_dma_cleanup(struct drm_device * dev) | 156 | int via_dma_cleanup(struct drm_device *dev) |
157 | { | 157 | { |
158 | if (dev->dev_private) { | 158 | if (dev->dev_private) { |
159 | drm_via_private_t *dev_priv = | 159 | drm_via_private_t *dev_priv = |
@@ -171,9 +171,9 @@ int via_dma_cleanup(struct drm_device * dev) | |||
171 | return 0; | 171 | return 0; |
172 | } | 172 | } |
173 | 173 | ||
174 | static int via_initialize(struct drm_device * dev, | 174 | static int via_initialize(struct drm_device *dev, |
175 | drm_via_private_t * dev_priv, | 175 | drm_via_private_t *dev_priv, |
176 | drm_via_dma_init_t * init) | 176 | drm_via_dma_init_t *init) |
177 | { | 177 | { |
178 | if (!dev_priv || !dev_priv->mmio) { | 178 | if (!dev_priv || !dev_priv->mmio) { |
179 | DRM_ERROR("via_dma_init called before via_map_init\n"); | 179 | DRM_ERROR("via_dma_init called before via_map_init\n"); |
@@ -258,7 +258,7 @@ static int via_dma_init(struct drm_device *dev, void *data, struct drm_file *fil | |||
258 | return retcode; | 258 | return retcode; |
259 | } | 259 | } |
260 | 260 | ||
261 | static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * cmd) | 261 | static int via_dispatch_cmdbuffer(struct drm_device *dev, drm_via_cmdbuffer_t *cmd) |
262 | { | 262 | { |
263 | drm_via_private_t *dev_priv; | 263 | drm_via_private_t *dev_priv; |
264 | uint32_t *vb; | 264 | uint32_t *vb; |
@@ -271,9 +271,8 @@ static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * | |||
271 | return -EFAULT; | 271 | return -EFAULT; |
272 | } | 272 | } |
273 | 273 | ||
274 | if (cmd->size > VIA_PCI_BUF_SIZE) { | 274 | if (cmd->size > VIA_PCI_BUF_SIZE) |
275 | return -ENOMEM; | 275 | return -ENOMEM; |
276 | } | ||
277 | 276 | ||
278 | if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size)) | 277 | if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size)) |
279 | return -EFAULT; | 278 | return -EFAULT; |
@@ -291,9 +290,8 @@ static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * | |||
291 | } | 290 | } |
292 | 291 | ||
293 | vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size); | 292 | vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size); |
294 | if (vb == NULL) { | 293 | if (vb == NULL) |
295 | return -EAGAIN; | 294 | return -EAGAIN; |
296 | } | ||
297 | 295 | ||
298 | memcpy(vb, dev_priv->pci_buf, cmd->size); | 296 | memcpy(vb, dev_priv->pci_buf, cmd->size); |
299 | 297 | ||
@@ -311,13 +309,12 @@ static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * | |||
311 | return 0; | 309 | return 0; |
312 | } | 310 | } |
313 | 311 | ||
314 | int via_driver_dma_quiescent(struct drm_device * dev) | 312 | int via_driver_dma_quiescent(struct drm_device *dev) |
315 | { | 313 | { |
316 | drm_via_private_t *dev_priv = dev->dev_private; | 314 | drm_via_private_t *dev_priv = dev->dev_private; |
317 | 315 | ||
318 | if (!via_wait_idle(dev_priv)) { | 316 | if (!via_wait_idle(dev_priv)) |
319 | return -EBUSY; | 317 | return -EBUSY; |
320 | } | ||
321 | return 0; | 318 | return 0; |
322 | } | 319 | } |
323 | 320 | ||
@@ -339,22 +336,17 @@ static int via_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *fi | |||
339 | DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size); | 336 | DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size); |
340 | 337 | ||
341 | ret = via_dispatch_cmdbuffer(dev, cmdbuf); | 338 | ret = via_dispatch_cmdbuffer(dev, cmdbuf); |
342 | if (ret) { | 339 | return ret; |
343 | return ret; | ||
344 | } | ||
345 | |||
346 | return 0; | ||
347 | } | 340 | } |
348 | 341 | ||
349 | static int via_dispatch_pci_cmdbuffer(struct drm_device * dev, | 342 | static int via_dispatch_pci_cmdbuffer(struct drm_device *dev, |
350 | drm_via_cmdbuffer_t * cmd) | 343 | drm_via_cmdbuffer_t *cmd) |
351 | { | 344 | { |
352 | drm_via_private_t *dev_priv = dev->dev_private; | 345 | drm_via_private_t *dev_priv = dev->dev_private; |
353 | int ret; | 346 | int ret; |
354 | 347 | ||
355 | if (cmd->size > VIA_PCI_BUF_SIZE) { | 348 | if (cmd->size > VIA_PCI_BUF_SIZE) |
356 | return -ENOMEM; | 349 | return -ENOMEM; |
357 | } | ||
358 | if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size)) | 350 | if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size)) |
359 | return -EFAULT; | 351 | return -EFAULT; |
360 | 352 | ||
@@ -380,19 +372,14 @@ static int via_pci_cmdbuffer(struct drm_device *dev, void *data, struct drm_file | |||
380 | DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size); | 372 | DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size); |
381 | 373 | ||
382 | ret = via_dispatch_pci_cmdbuffer(dev, cmdbuf); | 374 | ret = via_dispatch_pci_cmdbuffer(dev, cmdbuf); |
383 | if (ret) { | 375 | return ret; |
384 | return ret; | ||
385 | } | ||
386 | |||
387 | return 0; | ||
388 | } | 376 | } |
389 | 377 | ||
390 | static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv, | 378 | static inline uint32_t *via_align_buffer(drm_via_private_t *dev_priv, |
391 | uint32_t * vb, int qw_count) | 379 | uint32_t * vb, int qw_count) |
392 | { | 380 | { |
393 | for (; qw_count > 0; --qw_count) { | 381 | for (; qw_count > 0; --qw_count) |
394 | VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY); | 382 | VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY); |
395 | } | ||
396 | return vb; | 383 | return vb; |
397 | } | 384 | } |
398 | 385 | ||
@@ -401,7 +388,7 @@ static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv, | |||
401 | * | 388 | * |
402 | * Returns virtual pointer to ring buffer. | 389 | * Returns virtual pointer to ring buffer. |
403 | */ | 390 | */ |
404 | static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv) | 391 | static inline uint32_t *via_get_dma(drm_via_private_t *dev_priv) |
405 | { | 392 | { |
406 | return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low); | 393 | return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low); |
407 | } | 394 | } |
@@ -411,18 +398,18 @@ static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv) | |||
411 | * modifying the pause address stored in the buffer itself. If | 398 | * modifying the pause address stored in the buffer itself. If |
412 | * the regulator has already paused, restart it. | 399 | * the regulator has already paused, restart it. |
413 | */ | 400 | */ |
414 | static int via_hook_segment(drm_via_private_t * dev_priv, | 401 | static int via_hook_segment(drm_via_private_t *dev_priv, |
415 | uint32_t pause_addr_hi, uint32_t pause_addr_lo, | 402 | uint32_t pause_addr_hi, uint32_t pause_addr_lo, |
416 | int no_pci_fire) | 403 | int no_pci_fire) |
417 | { | 404 | { |
418 | int paused, count; | 405 | int paused, count; |
419 | volatile uint32_t *paused_at = dev_priv->last_pause_ptr; | 406 | volatile uint32_t *paused_at = dev_priv->last_pause_ptr; |
420 | uint32_t reader,ptr; | 407 | uint32_t reader, ptr; |
421 | uint32_t diff; | 408 | uint32_t diff; |
422 | 409 | ||
423 | paused = 0; | 410 | paused = 0; |
424 | via_flush_write_combine(); | 411 | via_flush_write_combine(); |
425 | (void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1); | 412 | (void) *(volatile uint32_t *)(via_get_dma(dev_priv) - 1); |
426 | 413 | ||
427 | *paused_at = pause_addr_lo; | 414 | *paused_at = pause_addr_lo; |
428 | via_flush_write_combine(); | 415 | via_flush_write_combine(); |
@@ -435,7 +422,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv, | |||
435 | dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1; | 422 | dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1; |
436 | 423 | ||
437 | /* | 424 | /* |
438 | * If there is a possibility that the command reader will | 425 | * If there is a possibility that the command reader will |
439 | * miss the new pause address and pause on the old one, | 426 | * miss the new pause address and pause on the old one, |
440 | * In that case we need to program the new start address | 427 | * In that case we need to program the new start address |
441 | * using PCI. | 428 | * using PCI. |
@@ -443,9 +430,9 @@ static int via_hook_segment(drm_via_private_t * dev_priv, | |||
443 | 430 | ||
444 | diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff; | 431 | diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff; |
445 | count = 10000000; | 432 | count = 10000000; |
446 | while(diff == 0 && count--) { | 433 | while (diff == 0 && count--) { |
447 | paused = (VIA_READ(0x41c) & 0x80000000); | 434 | paused = (VIA_READ(0x41c) & 0x80000000); |
448 | if (paused) | 435 | if (paused) |
449 | break; | 436 | break; |
450 | reader = *(dev_priv->hw_addr_ptr); | 437 | reader = *(dev_priv->hw_addr_ptr); |
451 | diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff; | 438 | diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff; |
@@ -477,7 +464,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv, | |||
477 | return paused; | 464 | return paused; |
478 | } | 465 | } |
479 | 466 | ||
480 | static int via_wait_idle(drm_via_private_t * dev_priv) | 467 | static int via_wait_idle(drm_via_private_t *dev_priv) |
481 | { | 468 | { |
482 | int count = 10000000; | 469 | int count = 10000000; |
483 | 470 | ||
@@ -491,9 +478,9 @@ static int via_wait_idle(drm_via_private_t * dev_priv) | |||
491 | return count; | 478 | return count; |
492 | } | 479 | } |
493 | 480 | ||
494 | static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type, | 481 | static uint32_t *via_align_cmd(drm_via_private_t *dev_priv, uint32_t cmd_type, |
495 | uint32_t addr, uint32_t * cmd_addr_hi, | 482 | uint32_t addr, uint32_t *cmd_addr_hi, |
496 | uint32_t * cmd_addr_lo, int skip_wait) | 483 | uint32_t *cmd_addr_lo, int skip_wait) |
497 | { | 484 | { |
498 | uint32_t agp_base; | 485 | uint32_t agp_base; |
499 | uint32_t cmd_addr, addr_lo, addr_hi; | 486 | uint32_t cmd_addr, addr_lo, addr_hi; |
@@ -521,7 +508,7 @@ static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type, | |||
521 | return vb; | 508 | return vb; |
522 | } | 509 | } |
523 | 510 | ||
524 | static void via_cmdbuf_start(drm_via_private_t * dev_priv) | 511 | static void via_cmdbuf_start(drm_via_private_t *dev_priv) |
525 | { | 512 | { |
526 | uint32_t pause_addr_lo, pause_addr_hi; | 513 | uint32_t pause_addr_lo, pause_addr_hi; |
527 | uint32_t start_addr, start_addr_lo; | 514 | uint32_t start_addr, start_addr_lo; |
@@ -580,7 +567,7 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv) | |||
580 | dev_priv->dma_diff = ptr - reader; | 567 | dev_priv->dma_diff = ptr - reader; |
581 | } | 568 | } |
582 | 569 | ||
583 | static void via_pad_cache(drm_via_private_t * dev_priv, int qwords) | 570 | static void via_pad_cache(drm_via_private_t *dev_priv, int qwords) |
584 | { | 571 | { |
585 | uint32_t *vb; | 572 | uint32_t *vb; |
586 | 573 | ||
@@ -590,7 +577,7 @@ static void via_pad_cache(drm_via_private_t * dev_priv, int qwords) | |||
590 | via_align_buffer(dev_priv, vb, qwords); | 577 | via_align_buffer(dev_priv, vb, qwords); |
591 | } | 578 | } |
592 | 579 | ||
593 | static inline void via_dummy_bitblt(drm_via_private_t * dev_priv) | 580 | static inline void via_dummy_bitblt(drm_via_private_t *dev_priv) |
594 | { | 581 | { |
595 | uint32_t *vb = via_get_dma(dev_priv); | 582 | uint32_t *vb = via_get_dma(dev_priv); |
596 | SetReg2DAGP(0x0C, (0 | (0 << 16))); | 583 | SetReg2DAGP(0x0C, (0 | (0 << 16))); |
@@ -598,7 +585,7 @@ static inline void via_dummy_bitblt(drm_via_private_t * dev_priv) | |||
598 | SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000); | 585 | SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000); |
599 | } | 586 | } |
600 | 587 | ||
601 | static void via_cmdbuf_jump(drm_via_private_t * dev_priv) | 588 | static void via_cmdbuf_jump(drm_via_private_t *dev_priv) |
602 | { | 589 | { |
603 | uint32_t agp_base; | 590 | uint32_t agp_base; |
604 | uint32_t pause_addr_lo, pause_addr_hi; | 591 | uint32_t pause_addr_lo, pause_addr_hi; |
@@ -617,9 +604,8 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) | |||
617 | */ | 604 | */ |
618 | 605 | ||
619 | dev_priv->dma_low = 0; | 606 | dev_priv->dma_low = 0; |
620 | if (via_cmdbuf_wait(dev_priv, CMDBUF_ALIGNMENT_SIZE) != 0) { | 607 | if (via_cmdbuf_wait(dev_priv, CMDBUF_ALIGNMENT_SIZE) != 0) |
621 | DRM_ERROR("via_cmdbuf_jump failed\n"); | 608 | DRM_ERROR("via_cmdbuf_jump failed\n"); |
622 | } | ||
623 | 609 | ||
624 | via_dummy_bitblt(dev_priv); | 610 | via_dummy_bitblt(dev_priv); |
625 | via_dummy_bitblt(dev_priv); | 611 | via_dummy_bitblt(dev_priv); |
@@ -657,12 +643,12 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) | |||
657 | } | 643 | } |
658 | 644 | ||
659 | 645 | ||
660 | static void via_cmdbuf_rewind(drm_via_private_t * dev_priv) | 646 | static void via_cmdbuf_rewind(drm_via_private_t *dev_priv) |
661 | { | 647 | { |
662 | via_cmdbuf_jump(dev_priv); | 648 | via_cmdbuf_jump(dev_priv); |
663 | } | 649 | } |
664 | 650 | ||
665 | static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type) | 651 | static void via_cmdbuf_flush(drm_via_private_t *dev_priv, uint32_t cmd_type) |
666 | { | 652 | { |
667 | uint32_t pause_addr_lo, pause_addr_hi; | 653 | uint32_t pause_addr_lo, pause_addr_hi; |
668 | 654 | ||
@@ -670,12 +656,12 @@ static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type) | |||
670 | via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0); | 656 | via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0); |
671 | } | 657 | } |
672 | 658 | ||
673 | static void via_cmdbuf_pause(drm_via_private_t * dev_priv) | 659 | static void via_cmdbuf_pause(drm_via_private_t *dev_priv) |
674 | { | 660 | { |
675 | via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE); | 661 | via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE); |
676 | } | 662 | } |
677 | 663 | ||
678 | static void via_cmdbuf_reset(drm_via_private_t * dev_priv) | 664 | static void via_cmdbuf_reset(drm_via_private_t *dev_priv) |
679 | { | 665 | { |
680 | via_cmdbuf_flush(dev_priv, HC_HAGPBpID_STOP); | 666 | via_cmdbuf_flush(dev_priv, HC_HAGPBpID_STOP); |
681 | via_wait_idle(dev_priv); | 667 | via_wait_idle(dev_priv); |
@@ -708,9 +694,8 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file * | |||
708 | case VIA_CMDBUF_SPACE: | 694 | case VIA_CMDBUF_SPACE: |
709 | while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size) | 695 | while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size) |
710 | && --count) { | 696 | && --count) { |
711 | if (!d_siz->wait) { | 697 | if (!d_siz->wait) |
712 | break; | 698 | break; |
713 | } | ||
714 | } | 699 | } |
715 | if (!count) { | 700 | if (!count) { |
716 | DRM_ERROR("VIA_CMDBUF_SPACE timed out.\n"); | 701 | DRM_ERROR("VIA_CMDBUF_SPACE timed out.\n"); |
@@ -720,9 +705,8 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file * | |||
720 | case VIA_CMDBUF_LAG: | 705 | case VIA_CMDBUF_LAG: |
721 | while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz->size) | 706 | while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz->size) |
722 | && --count) { | 707 | && --count) { |
723 | if (!d_siz->wait) { | 708 | if (!d_siz->wait) |
724 | break; | 709 | break; |
725 | } | ||
726 | } | 710 | } |
727 | if (!count) { | 711 | if (!count) { |
728 | DRM_ERROR("VIA_CMDBUF_LAG timed out.\n"); | 712 | DRM_ERROR("VIA_CMDBUF_LAG timed out.\n"); |
diff --git a/drivers/gpu/drm/via/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c index 4c54f043068e..9b5b4d9dd62c 100644 --- a/drivers/gpu/drm/via/via_dmablit.c +++ b/drivers/gpu/drm/via/via_dmablit.c | |||
@@ -70,7 +70,7 @@ via_unmap_blit_from_device(struct pci_dev *pdev, drm_via_sg_info_t *vsg) | |||
70 | descriptor_this_page; | 70 | descriptor_this_page; |
71 | dma_addr_t next = vsg->chain_start; | 71 | dma_addr_t next = vsg->chain_start; |
72 | 72 | ||
73 | while(num_desc--) { | 73 | while (num_desc--) { |
74 | if (descriptor_this_page-- == 0) { | 74 | if (descriptor_this_page-- == 0) { |
75 | cur_descriptor_page--; | 75 | cur_descriptor_page--; |
76 | descriptor_this_page = vsg->descriptors_per_page - 1; | 76 | descriptor_this_page = vsg->descriptors_per_page - 1; |
@@ -174,19 +174,19 @@ via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg) | |||
174 | struct page *page; | 174 | struct page *page; |
175 | int i; | 175 | int i; |
176 | 176 | ||
177 | switch(vsg->state) { | 177 | switch (vsg->state) { |
178 | case dr_via_device_mapped: | 178 | case dr_via_device_mapped: |
179 | via_unmap_blit_from_device(pdev, vsg); | 179 | via_unmap_blit_from_device(pdev, vsg); |
180 | case dr_via_desc_pages_alloc: | 180 | case dr_via_desc_pages_alloc: |
181 | for (i=0; i<vsg->num_desc_pages; ++i) { | 181 | for (i = 0; i < vsg->num_desc_pages; ++i) { |
182 | if (vsg->desc_pages[i] != NULL) | 182 | if (vsg->desc_pages[i] != NULL) |
183 | free_page((unsigned long)vsg->desc_pages[i]); | 183 | free_page((unsigned long)vsg->desc_pages[i]); |
184 | } | 184 | } |
185 | kfree(vsg->desc_pages); | 185 | kfree(vsg->desc_pages); |
186 | case dr_via_pages_locked: | 186 | case dr_via_pages_locked: |
187 | for (i=0; i<vsg->num_pages; ++i) { | 187 | for (i = 0; i < vsg->num_pages; ++i) { |
188 | if ( NULL != (page = vsg->pages[i])) { | 188 | if (NULL != (page = vsg->pages[i])) { |
189 | if (! PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction)) | 189 | if (!PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction)) |
190 | SetPageDirty(page); | 190 | SetPageDirty(page); |
191 | page_cache_release(page); | 191 | page_cache_release(page); |
192 | } | 192 | } |
@@ -232,7 +232,7 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) | |||
232 | { | 232 | { |
233 | int ret; | 233 | int ret; |
234 | unsigned long first_pfn = VIA_PFN(xfer->mem_addr); | 234 | unsigned long first_pfn = VIA_PFN(xfer->mem_addr); |
235 | vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride -1)) - | 235 | vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride - 1)) - |
236 | first_pfn + 1; | 236 | first_pfn + 1; |
237 | 237 | ||
238 | if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages))) | 238 | if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages))) |
@@ -268,7 +268,7 @@ via_alloc_desc_pages(drm_via_sg_info_t *vsg) | |||
268 | { | 268 | { |
269 | int i; | 269 | int i; |
270 | 270 | ||
271 | vsg->descriptors_per_page = PAGE_SIZE / sizeof( drm_via_descriptor_t); | 271 | vsg->descriptors_per_page = PAGE_SIZE / sizeof(drm_via_descriptor_t); |
272 | vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) / | 272 | vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) / |
273 | vsg->descriptors_per_page; | 273 | vsg->descriptors_per_page; |
274 | 274 | ||
@@ -276,7 +276,7 @@ via_alloc_desc_pages(drm_via_sg_info_t *vsg) | |||
276 | return -ENOMEM; | 276 | return -ENOMEM; |
277 | 277 | ||
278 | vsg->state = dr_via_desc_pages_alloc; | 278 | vsg->state = dr_via_desc_pages_alloc; |
279 | for (i=0; i<vsg->num_desc_pages; ++i) { | 279 | for (i = 0; i < vsg->num_desc_pages; ++i) { |
280 | if (NULL == (vsg->desc_pages[i] = | 280 | if (NULL == (vsg->desc_pages[i] = |
281 | (drm_via_descriptor_t *) __get_free_page(GFP_KERNEL))) | 281 | (drm_via_descriptor_t *) __get_free_page(GFP_KERNEL))) |
282 | return -ENOMEM; | 282 | return -ENOMEM; |
@@ -318,21 +318,20 @@ via_dmablit_handler(struct drm_device *dev, int engine, int from_irq) | |||
318 | drm_via_blitq_t *blitq = dev_priv->blit_queues + engine; | 318 | drm_via_blitq_t *blitq = dev_priv->blit_queues + engine; |
319 | int cur; | 319 | int cur; |
320 | int done_transfer; | 320 | int done_transfer; |
321 | unsigned long irqsave=0; | 321 | unsigned long irqsave = 0; |
322 | uint32_t status = 0; | 322 | uint32_t status = 0; |
323 | 323 | ||
324 | DRM_DEBUG("DMA blit handler called. engine = %d, from_irq = %d, blitq = 0x%lx\n", | 324 | DRM_DEBUG("DMA blit handler called. engine = %d, from_irq = %d, blitq = 0x%lx\n", |
325 | engine, from_irq, (unsigned long) blitq); | 325 | engine, from_irq, (unsigned long) blitq); |
326 | 326 | ||
327 | if (from_irq) { | 327 | if (from_irq) |
328 | spin_lock(&blitq->blit_lock); | 328 | spin_lock(&blitq->blit_lock); |
329 | } else { | 329 | else |
330 | spin_lock_irqsave(&blitq->blit_lock, irqsave); | 330 | spin_lock_irqsave(&blitq->blit_lock, irqsave); |
331 | } | ||
332 | 331 | ||
333 | done_transfer = blitq->is_active && | 332 | done_transfer = blitq->is_active && |
334 | (( status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & VIA_DMA_CSR_TD); | 333 | ((status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & VIA_DMA_CSR_TD); |
335 | done_transfer = done_transfer || ( blitq->aborting && !(status & VIA_DMA_CSR_DE)); | 334 | done_transfer = done_transfer || (blitq->aborting && !(status & VIA_DMA_CSR_DE)); |
336 | 335 | ||
337 | cur = blitq->cur; | 336 | cur = blitq->cur; |
338 | if (done_transfer) { | 337 | if (done_transfer) { |
@@ -377,18 +376,16 @@ via_dmablit_handler(struct drm_device *dev, int engine, int from_irq) | |||
377 | if (!timer_pending(&blitq->poll_timer)) | 376 | if (!timer_pending(&blitq->poll_timer)) |
378 | mod_timer(&blitq->poll_timer, jiffies + 1); | 377 | mod_timer(&blitq->poll_timer, jiffies + 1); |
379 | } else { | 378 | } else { |
380 | if (timer_pending(&blitq->poll_timer)) { | 379 | if (timer_pending(&blitq->poll_timer)) |
381 | del_timer(&blitq->poll_timer); | 380 | del_timer(&blitq->poll_timer); |
382 | } | ||
383 | via_dmablit_engine_off(dev, engine); | 381 | via_dmablit_engine_off(dev, engine); |
384 | } | 382 | } |
385 | } | 383 | } |
386 | 384 | ||
387 | if (from_irq) { | 385 | if (from_irq) |
388 | spin_unlock(&blitq->blit_lock); | 386 | spin_unlock(&blitq->blit_lock); |
389 | } else { | 387 | else |
390 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); | 388 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); |
391 | } | ||
392 | } | 389 | } |
393 | 390 | ||
394 | 391 | ||
@@ -414,10 +411,9 @@ via_dmablit_active(drm_via_blitq_t *blitq, int engine, uint32_t handle, wait_que | |||
414 | ((blitq->cur_blit_handle - handle) <= (1 << 23)); | 411 | ((blitq->cur_blit_handle - handle) <= (1 << 23)); |
415 | 412 | ||
416 | if (queue && active) { | 413 | if (queue && active) { |
417 | slot = handle - blitq->done_blit_handle + blitq->cur -1; | 414 | slot = handle - blitq->done_blit_handle + blitq->cur - 1; |
418 | if (slot >= VIA_NUM_BLIT_SLOTS) { | 415 | if (slot >= VIA_NUM_BLIT_SLOTS) |
419 | slot -= VIA_NUM_BLIT_SLOTS; | 416 | slot -= VIA_NUM_BLIT_SLOTS; |
420 | } | ||
421 | *queue = blitq->blit_queue + slot; | 417 | *queue = blitq->blit_queue + slot; |
422 | } | 418 | } |
423 | 419 | ||
@@ -506,12 +502,12 @@ via_dmablit_workqueue(struct work_struct *work) | |||
506 | int cur_released; | 502 | int cur_released; |
507 | 503 | ||
508 | 504 | ||
509 | DRM_DEBUG("Workqueue task called for blit engine %ld\n",(unsigned long) | 505 | DRM_DEBUG("Workqueue task called for blit engine %ld\n", (unsigned long) |
510 | (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues)); | 506 | (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues)); |
511 | 507 | ||
512 | spin_lock_irqsave(&blitq->blit_lock, irqsave); | 508 | spin_lock_irqsave(&blitq->blit_lock, irqsave); |
513 | 509 | ||
514 | while(blitq->serviced != blitq->cur) { | 510 | while (blitq->serviced != blitq->cur) { |
515 | 511 | ||
516 | cur_released = blitq->serviced++; | 512 | cur_released = blitq->serviced++; |
517 | 513 | ||
@@ -545,13 +541,13 @@ via_dmablit_workqueue(struct work_struct *work) | |||
545 | void | 541 | void |
546 | via_init_dmablit(struct drm_device *dev) | 542 | via_init_dmablit(struct drm_device *dev) |
547 | { | 543 | { |
548 | int i,j; | 544 | int i, j; |
549 | drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; | 545 | drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; |
550 | drm_via_blitq_t *blitq; | 546 | drm_via_blitq_t *blitq; |
551 | 547 | ||
552 | pci_set_master(dev->pdev); | 548 | pci_set_master(dev->pdev); |
553 | 549 | ||
554 | for (i=0; i< VIA_NUM_BLIT_ENGINES; ++i) { | 550 | for (i = 0; i < VIA_NUM_BLIT_ENGINES; ++i) { |
555 | blitq = dev_priv->blit_queues + i; | 551 | blitq = dev_priv->blit_queues + i; |
556 | blitq->dev = dev; | 552 | blitq->dev = dev; |
557 | blitq->cur_blit_handle = 0; | 553 | blitq->cur_blit_handle = 0; |
@@ -564,9 +560,8 @@ via_init_dmablit(struct drm_device *dev) | |||
564 | blitq->is_active = 0; | 560 | blitq->is_active = 0; |
565 | blitq->aborting = 0; | 561 | blitq->aborting = 0; |
566 | spin_lock_init(&blitq->blit_lock); | 562 | spin_lock_init(&blitq->blit_lock); |
567 | for (j=0; j<VIA_NUM_BLIT_SLOTS; ++j) { | 563 | for (j = 0; j < VIA_NUM_BLIT_SLOTS; ++j) |
568 | DRM_INIT_WAITQUEUE(blitq->blit_queue + j); | 564 | DRM_INIT_WAITQUEUE(blitq->blit_queue + j); |
569 | } | ||
570 | DRM_INIT_WAITQUEUE(&blitq->busy_queue); | 565 | DRM_INIT_WAITQUEUE(&blitq->busy_queue); |
571 | INIT_WORK(&blitq->wq, via_dmablit_workqueue); | 566 | INIT_WORK(&blitq->wq, via_dmablit_workqueue); |
572 | setup_timer(&blitq->poll_timer, via_dmablit_timer, | 567 | setup_timer(&blitq->poll_timer, via_dmablit_timer, |
@@ -685,18 +680,17 @@ via_build_sg_info(struct drm_device *dev, drm_via_sg_info_t *vsg, drm_via_dmabli | |||
685 | static int | 680 | static int |
686 | via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine) | 681 | via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine) |
687 | { | 682 | { |
688 | int ret=0; | 683 | int ret = 0; |
689 | unsigned long irqsave; | 684 | unsigned long irqsave; |
690 | 685 | ||
691 | DRM_DEBUG("Num free is %d\n", blitq->num_free); | 686 | DRM_DEBUG("Num free is %d\n", blitq->num_free); |
692 | spin_lock_irqsave(&blitq->blit_lock, irqsave); | 687 | spin_lock_irqsave(&blitq->blit_lock, irqsave); |
693 | while(blitq->num_free == 0) { | 688 | while (blitq->num_free == 0) { |
694 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); | 689 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); |
695 | 690 | ||
696 | DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, blitq->num_free > 0); | 691 | DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, blitq->num_free > 0); |
697 | if (ret) { | 692 | if (ret) |
698 | return (-EINTR == ret) ? -EAGAIN : ret; | 693 | return (-EINTR == ret) ? -EAGAIN : ret; |
699 | } | ||
700 | 694 | ||
701 | spin_lock_irqsave(&blitq->blit_lock, irqsave); | 695 | spin_lock_irqsave(&blitq->blit_lock, irqsave); |
702 | } | 696 | } |
@@ -719,7 +713,7 @@ via_dmablit_release_slot(drm_via_blitq_t *blitq) | |||
719 | spin_lock_irqsave(&blitq->blit_lock, irqsave); | 713 | spin_lock_irqsave(&blitq->blit_lock, irqsave); |
720 | blitq->num_free++; | 714 | blitq->num_free++; |
721 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); | 715 | spin_unlock_irqrestore(&blitq->blit_lock, irqsave); |
722 | DRM_WAKEUP( &blitq->busy_queue ); | 716 | DRM_WAKEUP(&blitq->busy_queue); |
723 | } | 717 | } |
724 | 718 | ||
725 | /* | 719 | /* |
@@ -744,9 +738,8 @@ via_dmablit(struct drm_device *dev, drm_via_dmablit_t *xfer) | |||
744 | 738 | ||
745 | engine = (xfer->to_fb) ? 0 : 1; | 739 | engine = (xfer->to_fb) ? 0 : 1; |
746 | blitq = dev_priv->blit_queues + engine; | 740 | blitq = dev_priv->blit_queues + engine; |
747 | if (0 != (ret = via_dmablit_grab_slot(blitq, engine))) { | 741 | if (0 != (ret = via_dmablit_grab_slot(blitq, engine))) |
748 | return ret; | 742 | return ret; |
749 | } | ||
750 | if (NULL == (vsg = kmalloc(sizeof(*vsg), GFP_KERNEL))) { | 743 | if (NULL == (vsg = kmalloc(sizeof(*vsg), GFP_KERNEL))) { |
751 | via_dmablit_release_slot(blitq); | 744 | via_dmablit_release_slot(blitq); |
752 | return -ENOMEM; | 745 | return -ENOMEM; |
@@ -780,7 +773,7 @@ via_dmablit(struct drm_device *dev, drm_via_dmablit_t *xfer) | |||
780 | */ | 773 | */ |
781 | 774 | ||
782 | int | 775 | int |
783 | via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv ) | 776 | via_dma_blit_sync(struct drm_device *dev, void *data, struct drm_file *file_priv) |
784 | { | 777 | { |
785 | drm_via_blitsync_t *sync = data; | 778 | drm_via_blitsync_t *sync = data; |
786 | int err; | 779 | int err; |
@@ -804,7 +797,7 @@ via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_pri | |||
804 | */ | 797 | */ |
805 | 798 | ||
806 | int | 799 | int |
807 | via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv ) | 800 | via_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv) |
808 | { | 801 | { |
809 | drm_via_dmablit_t *xfer = data; | 802 | drm_via_dmablit_t *xfer = data; |
810 | int err; | 803 | int err; |
diff --git a/drivers/gpu/drm/via/via_dmablit.h b/drivers/gpu/drm/via/via_dmablit.h index 7408a547a036..9b662a327cef 100644 --- a/drivers/gpu/drm/via/via_dmablit.h +++ b/drivers/gpu/drm/via/via_dmablit.h | |||
@@ -45,12 +45,12 @@ typedef struct _drm_via_sg_info { | |||
45 | int num_desc; | 45 | int num_desc; |
46 | enum dma_data_direction direction; | 46 | enum dma_data_direction direction; |
47 | unsigned char *bounce_buffer; | 47 | unsigned char *bounce_buffer; |
48 | dma_addr_t chain_start; | 48 | dma_addr_t chain_start; |
49 | uint32_t free_on_sequence; | 49 | uint32_t free_on_sequence; |
50 | unsigned int descriptors_per_page; | 50 | unsigned int descriptors_per_page; |
51 | int aborted; | 51 | int aborted; |
52 | enum { | 52 | enum { |
53 | dr_via_device_mapped, | 53 | dr_via_device_mapped, |
54 | dr_via_desc_pages_alloc, | 54 | dr_via_desc_pages_alloc, |
55 | dr_via_pages_locked, | 55 | dr_via_pages_locked, |
56 | dr_via_pages_alloc, | 56 | dr_via_pages_alloc, |
@@ -68,7 +68,7 @@ typedef struct _drm_via_blitq { | |||
68 | unsigned num_free; | 68 | unsigned num_free; |
69 | unsigned num_outstanding; | 69 | unsigned num_outstanding; |
70 | unsigned long end; | 70 | unsigned long end; |
71 | int aborting; | 71 | int aborting; |
72 | int is_active; | 72 | int is_active; |
73 | drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS]; | 73 | drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS]; |
74 | spinlock_t blit_lock; | 74 | spinlock_t blit_lock; |
diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h index cafcb844a223..9cf87d912325 100644 --- a/drivers/gpu/drm/via/via_drv.h +++ b/drivers/gpu/drm/via/via_drv.h | |||
@@ -107,9 +107,9 @@ enum via_family { | |||
107 | #define VIA_BASE ((dev_priv->mmio)) | 107 | #define VIA_BASE ((dev_priv->mmio)) |
108 | 108 | ||
109 | #define VIA_READ(reg) DRM_READ32(VIA_BASE, reg) | 109 | #define VIA_READ(reg) DRM_READ32(VIA_BASE, reg) |
110 | #define VIA_WRITE(reg,val) DRM_WRITE32(VIA_BASE, reg, val) | 110 | #define VIA_WRITE(reg, val) DRM_WRITE32(VIA_BASE, reg, val) |
111 | #define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg) | 111 | #define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg) |
112 | #define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val) | 112 | #define VIA_WRITE8(reg, val) DRM_WRITE8(VIA_BASE, reg, val) |
113 | 113 | ||
114 | extern struct drm_ioctl_desc via_ioctls[]; | 114 | extern struct drm_ioctl_desc via_ioctls[]; |
115 | extern int via_max_ioctl; | 115 | extern int via_max_ioctl; |
@@ -121,28 +121,28 @@ extern int via_agp_init(struct drm_device *dev, void *data, struct drm_file *fil | |||
121 | extern int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv); | 121 | extern int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv); |
122 | extern int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv); | 122 | extern int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv); |
123 | extern int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv); | 123 | extern int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv); |
124 | extern int via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv ); | 124 | extern int via_dma_blit_sync(struct drm_device *dev, void *data, struct drm_file *file_priv); |
125 | extern int via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv ); | 125 | extern int via_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv); |
126 | 126 | ||
127 | extern int via_driver_load(struct drm_device *dev, unsigned long chipset); | 127 | extern int via_driver_load(struct drm_device *dev, unsigned long chipset); |
128 | extern int via_driver_unload(struct drm_device *dev); | 128 | extern int via_driver_unload(struct drm_device *dev); |
129 | 129 | ||
130 | extern int via_init_context(struct drm_device * dev, int context); | 130 | extern int via_init_context(struct drm_device *dev, int context); |
131 | extern int via_final_context(struct drm_device * dev, int context); | 131 | extern int via_final_context(struct drm_device *dev, int context); |
132 | 132 | ||
133 | extern int via_do_cleanup_map(struct drm_device * dev); | 133 | extern int via_do_cleanup_map(struct drm_device *dev); |
134 | extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc); | 134 | extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc); |
135 | extern int via_enable_vblank(struct drm_device *dev, int crtc); | 135 | extern int via_enable_vblank(struct drm_device *dev, int crtc); |
136 | extern void via_disable_vblank(struct drm_device *dev, int crtc); | 136 | extern void via_disable_vblank(struct drm_device *dev, int crtc); |
137 | 137 | ||
138 | extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); | 138 | extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); |
139 | extern void via_driver_irq_preinstall(struct drm_device * dev); | 139 | extern void via_driver_irq_preinstall(struct drm_device *dev); |
140 | extern int via_driver_irq_postinstall(struct drm_device *dev); | 140 | extern int via_driver_irq_postinstall(struct drm_device *dev); |
141 | extern void via_driver_irq_uninstall(struct drm_device * dev); | 141 | extern void via_driver_irq_uninstall(struct drm_device *dev); |
142 | 142 | ||
143 | extern int via_dma_cleanup(struct drm_device * dev); | 143 | extern int via_dma_cleanup(struct drm_device *dev); |
144 | extern void via_init_command_verifier(void); | 144 | extern void via_init_command_verifier(void); |
145 | extern int via_driver_dma_quiescent(struct drm_device * dev); | 145 | extern int via_driver_dma_quiescent(struct drm_device *dev); |
146 | extern void via_init_futex(drm_via_private_t *dev_priv); | 146 | extern void via_init_futex(drm_via_private_t *dev_priv); |
147 | extern void via_cleanup_futex(drm_via_private_t *dev_priv); | 147 | extern void via_cleanup_futex(drm_via_private_t *dev_priv); |
148 | extern void via_release_futex(drm_via_private_t *dev_priv, int context); | 148 | extern void via_release_futex(drm_via_private_t *dev_priv, int context); |
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c index 34079f251cd4..d391f48ef87a 100644 --- a/drivers/gpu/drm/via/via_irq.c +++ b/drivers/gpu/drm/via/via_irq.c | |||
@@ -141,11 +141,10 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | |||
141 | atomic_inc(&cur_irq->irq_received); | 141 | atomic_inc(&cur_irq->irq_received); |
142 | DRM_WAKEUP(&cur_irq->irq_queue); | 142 | DRM_WAKEUP(&cur_irq->irq_queue); |
143 | handled = 1; | 143 | handled = 1; |
144 | if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) { | 144 | if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) |
145 | via_dmablit_handler(dev, 0, 1); | 145 | via_dmablit_handler(dev, 0, 1); |
146 | } else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i) { | 146 | else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i) |
147 | via_dmablit_handler(dev, 1, 1); | 147 | via_dmablit_handler(dev, 1, 1); |
148 | } | ||
149 | } | 148 | } |
150 | cur_irq++; | 149 | cur_irq++; |
151 | } | 150 | } |
@@ -160,7 +159,7 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | |||
160 | return IRQ_NONE; | 159 | return IRQ_NONE; |
161 | } | 160 | } |
162 | 161 | ||
163 | static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv) | 162 | static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t *dev_priv) |
164 | { | 163 | { |
165 | u32 status; | 164 | u32 status; |
166 | 165 | ||
@@ -207,7 +206,7 @@ void via_disable_vblank(struct drm_device *dev, int crtc) | |||
207 | } | 206 | } |
208 | 207 | ||
209 | static int | 208 | static int |
210 | via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequence, | 209 | via_driver_irq_wait(struct drm_device *dev, unsigned int irq, int force_sequence, |
211 | unsigned int *sequence) | 210 | unsigned int *sequence) |
212 | { | 211 | { |
213 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; | 212 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; |
@@ -260,7 +259,7 @@ via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequenc | |||
260 | * drm_dma.h hooks | 259 | * drm_dma.h hooks |
261 | */ | 260 | */ |
262 | 261 | ||
263 | void via_driver_irq_preinstall(struct drm_device * dev) | 262 | void via_driver_irq_preinstall(struct drm_device *dev) |
264 | { | 263 | { |
265 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; | 264 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; |
266 | u32 status; | 265 | u32 status; |
@@ -329,7 +328,7 @@ int via_driver_irq_postinstall(struct drm_device *dev) | |||
329 | return 0; | 328 | return 0; |
330 | } | 329 | } |
331 | 330 | ||
332 | void via_driver_irq_uninstall(struct drm_device * dev) | 331 | void via_driver_irq_uninstall(struct drm_device *dev) |
333 | { | 332 | { |
334 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; | 333 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; |
335 | u32 status; | 334 | u32 status; |
diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c index 6e6f91591639..6cca9a709f7a 100644 --- a/drivers/gpu/drm/via/via_map.c +++ b/drivers/gpu/drm/via/via_map.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include "via_drm.h" | 25 | #include "via_drm.h" |
26 | #include "via_drv.h" | 26 | #include "via_drv.h" |
27 | 27 | ||
28 | static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init) | 28 | static int via_do_init_map(struct drm_device *dev, drm_via_init_t *init) |
29 | { | 29 | { |
30 | drm_via_private_t *dev_priv = dev->dev_private; | 30 | drm_via_private_t *dev_priv = dev->dev_private; |
31 | 31 | ||
@@ -68,7 +68,7 @@ static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init) | |||
68 | return 0; | 68 | return 0; |
69 | } | 69 | } |
70 | 70 | ||
71 | int via_do_cleanup_map(struct drm_device * dev) | 71 | int via_do_cleanup_map(struct drm_device *dev) |
72 | { | 72 | { |
73 | via_dma_cleanup(dev); | 73 | via_dma_cleanup(dev); |
74 | 74 | ||
diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c index f694cb5ededc..6cc2dadae3ef 100644 --- a/drivers/gpu/drm/via/via_mm.c +++ b/drivers/gpu/drm/via/via_mm.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include "drm_sman.h" | 31 | #include "drm_sman.h" |
32 | 32 | ||
33 | #define VIA_MM_ALIGN_SHIFT 4 | 33 | #define VIA_MM_ALIGN_SHIFT 4 |
34 | #define VIA_MM_ALIGN_MASK ( (1 << VIA_MM_ALIGN_SHIFT) - 1) | 34 | #define VIA_MM_ALIGN_MASK ((1 << VIA_MM_ALIGN_SHIFT) - 1) |
35 | 35 | ||
36 | int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) | 36 | int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) |
37 | { | 37 | { |
@@ -172,7 +172,7 @@ int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
172 | } | 172 | } |
173 | 173 | ||
174 | 174 | ||
175 | void via_reclaim_buffers_locked(struct drm_device * dev, | 175 | void via_reclaim_buffers_locked(struct drm_device *dev, |
176 | struct drm_file *file_priv) | 176 | struct drm_file *file_priv) |
177 | { | 177 | { |
178 | drm_via_private_t *dev_priv = dev->dev_private; | 178 | drm_via_private_t *dev_priv = dev->dev_private; |
@@ -183,9 +183,8 @@ void via_reclaim_buffers_locked(struct drm_device * dev, | |||
183 | return; | 183 | return; |
184 | } | 184 | } |
185 | 185 | ||
186 | if (dev->driver->dma_quiescent) { | 186 | if (dev->driver->dma_quiescent) |
187 | dev->driver->dma_quiescent(dev); | 187 | dev->driver->dma_quiescent(dev); |
188 | } | ||
189 | 188 | ||
190 | drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv); | 189 | drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv); |
191 | mutex_unlock(&dev->struct_mutex); | 190 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/via/via_verifier.c b/drivers/gpu/drm/via/via_verifier.c index 46a579198747..48957b856d41 100644 --- a/drivers/gpu/drm/via/via_verifier.c +++ b/drivers/gpu/drm/via/via_verifier.c | |||
@@ -235,7 +235,7 @@ static hazard_t table2[256]; | |||
235 | static hazard_t table3[256]; | 235 | static hazard_t table3[256]; |
236 | 236 | ||
237 | static __inline__ int | 237 | static __inline__ int |
238 | eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) | 238 | eat_words(const uint32_t **buf, const uint32_t *buf_end, unsigned num_words) |
239 | { | 239 | { |
240 | if ((buf_end - *buf) >= num_words) { | 240 | if ((buf_end - *buf) >= num_words) { |
241 | *buf += num_words; | 241 | *buf += num_words; |
@@ -252,7 +252,7 @@ eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) | |||
252 | static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq, | 252 | static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq, |
253 | unsigned long offset, | 253 | unsigned long offset, |
254 | unsigned long size, | 254 | unsigned long size, |
255 | struct drm_device * dev) | 255 | struct drm_device *dev) |
256 | { | 256 | { |
257 | struct drm_map_list *r_list; | 257 | struct drm_map_list *r_list; |
258 | drm_local_map_t *map = seq->map_cache; | 258 | drm_local_map_t *map = seq->map_cache; |
@@ -344,7 +344,7 @@ static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq) | |||
344 | } | 344 | } |
345 | 345 | ||
346 | static __inline__ int | 346 | static __inline__ int |
347 | investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq) | 347 | investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq) |
348 | { | 348 | { |
349 | register uint32_t tmp, *tmp_addr; | 349 | register uint32_t tmp, *tmp_addr; |
350 | 350 | ||
@@ -518,7 +518,7 @@ investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq) | |||
518 | 518 | ||
519 | static __inline__ int | 519 | static __inline__ int |
520 | via_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end, | 520 | via_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end, |
521 | drm_via_state_t * cur_seq) | 521 | drm_via_state_t *cur_seq) |
522 | { | 522 | { |
523 | drm_via_private_t *dev_priv = | 523 | drm_via_private_t *dev_priv = |
524 | (drm_via_private_t *) cur_seq->dev->dev_private; | 524 | (drm_via_private_t *) cur_seq->dev->dev_private; |
@@ -621,8 +621,8 @@ via_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end, | |||
621 | } | 621 | } |
622 | 622 | ||
623 | static __inline__ verifier_state_t | 623 | static __inline__ verifier_state_t |
624 | via_check_header2(uint32_t const **buffer, const uint32_t * buf_end, | 624 | via_check_header2(uint32_t const **buffer, const uint32_t *buf_end, |
625 | drm_via_state_t * hc_state) | 625 | drm_via_state_t *hc_state) |
626 | { | 626 | { |
627 | uint32_t cmd; | 627 | uint32_t cmd; |
628 | int hz_mode; | 628 | int hz_mode; |
@@ -706,16 +706,15 @@ via_check_header2(uint32_t const **buffer, const uint32_t * buf_end, | |||
706 | return state_error; | 706 | return state_error; |
707 | } | 707 | } |
708 | } | 708 | } |
709 | if (hc_state->unfinished && finish_current_sequence(hc_state)) { | 709 | if (hc_state->unfinished && finish_current_sequence(hc_state)) |
710 | return state_error; | 710 | return state_error; |
711 | } | ||
712 | *buffer = buf; | 711 | *buffer = buf; |
713 | return state_command; | 712 | return state_command; |
714 | } | 713 | } |
715 | 714 | ||
716 | static __inline__ verifier_state_t | 715 | static __inline__ verifier_state_t |
717 | via_parse_header2(drm_via_private_t * dev_priv, uint32_t const **buffer, | 716 | via_parse_header2(drm_via_private_t *dev_priv, uint32_t const **buffer, |
718 | const uint32_t * buf_end, int *fire_count) | 717 | const uint32_t *buf_end, int *fire_count) |
719 | { | 718 | { |
720 | uint32_t cmd; | 719 | uint32_t cmd; |
721 | const uint32_t *buf = *buffer; | 720 | const uint32_t *buf = *buffer; |
@@ -833,8 +832,8 @@ via_check_header1(uint32_t const **buffer, const uint32_t * buf_end) | |||
833 | } | 832 | } |
834 | 833 | ||
835 | static __inline__ verifier_state_t | 834 | static __inline__ verifier_state_t |
836 | via_parse_header1(drm_via_private_t * dev_priv, uint32_t const **buffer, | 835 | via_parse_header1(drm_via_private_t *dev_priv, uint32_t const **buffer, |
837 | const uint32_t * buf_end) | 836 | const uint32_t *buf_end) |
838 | { | 837 | { |
839 | register uint32_t cmd; | 838 | register uint32_t cmd; |
840 | const uint32_t *buf = *buffer; | 839 | const uint32_t *buf = *buffer; |
@@ -851,7 +850,7 @@ via_parse_header1(drm_via_private_t * dev_priv, uint32_t const **buffer, | |||
851 | } | 850 | } |
852 | 851 | ||
853 | static __inline__ verifier_state_t | 852 | static __inline__ verifier_state_t |
854 | via_check_vheader5(uint32_t const **buffer, const uint32_t * buf_end) | 853 | via_check_vheader5(uint32_t const **buffer, const uint32_t *buf_end) |
855 | { | 854 | { |
856 | uint32_t data; | 855 | uint32_t data; |
857 | const uint32_t *buf = *buffer; | 856 | const uint32_t *buf = *buffer; |
@@ -884,8 +883,8 @@ via_check_vheader5(uint32_t const **buffer, const uint32_t * buf_end) | |||
884 | } | 883 | } |
885 | 884 | ||
886 | static __inline__ verifier_state_t | 885 | static __inline__ verifier_state_t |
887 | via_parse_vheader5(drm_via_private_t * dev_priv, uint32_t const **buffer, | 886 | via_parse_vheader5(drm_via_private_t *dev_priv, uint32_t const **buffer, |
888 | const uint32_t * buf_end) | 887 | const uint32_t *buf_end) |
889 | { | 888 | { |
890 | uint32_t addr, count, i; | 889 | uint32_t addr, count, i; |
891 | const uint32_t *buf = *buffer; | 890 | const uint32_t *buf = *buffer; |
@@ -893,9 +892,8 @@ via_parse_vheader5(drm_via_private_t * dev_priv, uint32_t const **buffer, | |||
893 | addr = *buf++ & ~VIA_VIDEOMASK; | 892 | addr = *buf++ & ~VIA_VIDEOMASK; |
894 | i = count = *buf; | 893 | i = count = *buf; |
895 | buf += 3; | 894 | buf += 3; |
896 | while (i--) { | 895 | while (i--) |
897 | VIA_WRITE(addr, *buf++); | 896 | VIA_WRITE(addr, *buf++); |
898 | } | ||
899 | if (count & 3) | 897 | if (count & 3) |
900 | buf += 4 - (count & 3); | 898 | buf += 4 - (count & 3); |
901 | *buffer = buf; | 899 | *buffer = buf; |
@@ -940,8 +938,8 @@ via_check_vheader6(uint32_t const **buffer, const uint32_t * buf_end) | |||
940 | } | 938 | } |
941 | 939 | ||
942 | static __inline__ verifier_state_t | 940 | static __inline__ verifier_state_t |
943 | via_parse_vheader6(drm_via_private_t * dev_priv, uint32_t const **buffer, | 941 | via_parse_vheader6(drm_via_private_t *dev_priv, uint32_t const **buffer, |
944 | const uint32_t * buf_end) | 942 | const uint32_t *buf_end) |
945 | { | 943 | { |
946 | 944 | ||
947 | uint32_t addr, count, i; | 945 | uint32_t addr, count, i; |
@@ -1037,7 +1035,7 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, | |||
1037 | } | 1035 | } |
1038 | 1036 | ||
1039 | int | 1037 | int |
1040 | via_parse_command_stream(struct drm_device * dev, const uint32_t * buf, | 1038 | via_parse_command_stream(struct drm_device *dev, const uint32_t *buf, |
1041 | unsigned int size) | 1039 | unsigned int size) |
1042 | { | 1040 | { |
1043 | 1041 | ||
@@ -1085,9 +1083,8 @@ via_parse_command_stream(struct drm_device * dev, const uint32_t * buf, | |||
1085 | return -EINVAL; | 1083 | return -EINVAL; |
1086 | } | 1084 | } |
1087 | } | 1085 | } |
1088 | if (state == state_error) { | 1086 | if (state == state_error) |
1089 | return -EINVAL; | 1087 | return -EINVAL; |
1090 | } | ||
1091 | return 0; | 1088 | return 0; |
1092 | } | 1089 | } |
1093 | 1090 | ||
@@ -1096,13 +1093,11 @@ setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size) | |||
1096 | { | 1093 | { |
1097 | int i; | 1094 | int i; |
1098 | 1095 | ||
1099 | for (i = 0; i < 256; ++i) { | 1096 | for (i = 0; i < 256; ++i) |
1100 | table[i] = forbidden_command; | 1097 | table[i] = forbidden_command; |
1101 | } | ||
1102 | 1098 | ||
1103 | for (i = 0; i < size; ++i) { | 1099 | for (i = 0; i < size; ++i) |
1104 | table[init_table[i].code] = init_table[i].hz; | 1100 | table[init_table[i].code] = init_table[i].hz; |
1105 | } | ||
1106 | } | 1101 | } |
1107 | 1102 | ||
1108 | void via_init_command_verifier(void) | 1103 | void via_init_command_verifier(void) |
diff --git a/drivers/gpu/drm/via/via_verifier.h b/drivers/gpu/drm/via/via_verifier.h index d6f8214b69f5..26b6d361ab95 100644 --- a/drivers/gpu/drm/via/via_verifier.h +++ b/drivers/gpu/drm/via/via_verifier.h | |||
@@ -54,8 +54,8 @@ typedef struct { | |||
54 | const uint32_t *buf_start; | 54 | const uint32_t *buf_start; |
55 | } drm_via_state_t; | 55 | } drm_via_state_t; |
56 | 56 | ||
57 | extern int via_verify_command_stream(const uint32_t * buf, unsigned int size, | 57 | extern int via_verify_command_stream(const uint32_t *buf, unsigned int size, |
58 | struct drm_device * dev, int agp); | 58 | struct drm_device *dev, int agp); |
59 | extern int via_parse_command_stream(struct drm_device *dev, const uint32_t *buf, | 59 | extern int via_parse_command_stream(struct drm_device *dev, const uint32_t *buf, |
60 | unsigned int size); | 60 | unsigned int size); |
61 | 61 | ||
diff --git a/drivers/gpu/drm/via/via_video.c b/drivers/gpu/drm/via/via_video.c index 6efac8117c93..675d311f038f 100644 --- a/drivers/gpu/drm/via/via_video.c +++ b/drivers/gpu/drm/via/via_video.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include "via_drm.h" | 29 | #include "via_drm.h" |
30 | #include "via_drv.h" | 30 | #include "via_drv.h" |
31 | 31 | ||
32 | void via_init_futex(drm_via_private_t * dev_priv) | 32 | void via_init_futex(drm_via_private_t *dev_priv) |
33 | { | 33 | { |
34 | unsigned int i; | 34 | unsigned int i; |
35 | 35 | ||
@@ -41,11 +41,11 @@ void via_init_futex(drm_via_private_t * dev_priv) | |||
41 | } | 41 | } |
42 | } | 42 | } |
43 | 43 | ||
44 | void via_cleanup_futex(drm_via_private_t * dev_priv) | 44 | void via_cleanup_futex(drm_via_private_t *dev_priv) |
45 | { | 45 | { |
46 | } | 46 | } |
47 | 47 | ||
48 | void via_release_futex(drm_via_private_t * dev_priv, int context) | 48 | void via_release_futex(drm_via_private_t *dev_priv, int context) |
49 | { | 49 | { |
50 | unsigned int i; | 50 | unsigned int i; |
51 | volatile int *lock; | 51 | volatile int *lock; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index b793c8c9acb3..9dd395b90216 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -764,7 +764,7 @@ static struct drm_driver driver = { | |||
764 | 764 | ||
765 | static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 765 | static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
766 | { | 766 | { |
767 | return drm_get_dev(pdev, ent, &driver); | 767 | return drm_get_pci_dev(pdev, ent, &driver); |
768 | } | 768 | } |
769 | 769 | ||
770 | static int __init vmwgfx_init(void) | 770 | static int __init vmwgfx_init(void) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index eaad52095339..429f917b60bf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -164,7 +164,7 @@ struct vmw_vga_topology_state { | |||
164 | struct vmw_private { | 164 | struct vmw_private { |
165 | struct ttm_bo_device bdev; | 165 | struct ttm_bo_device bdev; |
166 | struct ttm_bo_global_ref bo_global_ref; | 166 | struct ttm_bo_global_ref bo_global_ref; |
167 | struct ttm_global_reference mem_global_ref; | 167 | struct drm_global_reference mem_global_ref; |
168 | 168 | ||
169 | struct vmw_fifo_state fifo; | 169 | struct vmw_fifo_state fifo; |
170 | 170 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index b0866f04ec76..870967a97c15 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |||
@@ -528,7 +528,7 @@ int vmw_fb_init(struct vmw_private *vmw_priv) | |||
528 | * Dirty & Deferred IO | 528 | * Dirty & Deferred IO |
529 | */ | 529 | */ |
530 | par->dirty.x1 = par->dirty.x2 = 0; | 530 | par->dirty.x1 = par->dirty.x2 = 0; |
531 | par->dirty.y1 = par->dirty.y1 = 0; | 531 | par->dirty.y1 = par->dirty.y2 = 0; |
532 | par->dirty.active = true; | 532 | par->dirty.active = true; |
533 | spin_lock_init(&par->dirty.lock); | 533 | spin_lock_init(&par->dirty.lock); |
534 | info->fbdefio = &vmw_defio; | 534 | info->fbdefio = &vmw_defio; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c index e3df4adfb4d8..83123287c60c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c | |||
@@ -44,29 +44,29 @@ int vmw_mmap(struct file *filp, struct vm_area_struct *vma) | |||
44 | return ttm_bo_mmap(filp, vma, &dev_priv->bdev); | 44 | return ttm_bo_mmap(filp, vma, &dev_priv->bdev); |
45 | } | 45 | } |
46 | 46 | ||
47 | static int vmw_ttm_mem_global_init(struct ttm_global_reference *ref) | 47 | static int vmw_ttm_mem_global_init(struct drm_global_reference *ref) |
48 | { | 48 | { |
49 | DRM_INFO("global init.\n"); | 49 | DRM_INFO("global init.\n"); |
50 | return ttm_mem_global_init(ref->object); | 50 | return ttm_mem_global_init(ref->object); |
51 | } | 51 | } |
52 | 52 | ||
53 | static void vmw_ttm_mem_global_release(struct ttm_global_reference *ref) | 53 | static void vmw_ttm_mem_global_release(struct drm_global_reference *ref) |
54 | { | 54 | { |
55 | ttm_mem_global_release(ref->object); | 55 | ttm_mem_global_release(ref->object); |
56 | } | 56 | } |
57 | 57 | ||
58 | int vmw_ttm_global_init(struct vmw_private *dev_priv) | 58 | int vmw_ttm_global_init(struct vmw_private *dev_priv) |
59 | { | 59 | { |
60 | struct ttm_global_reference *global_ref; | 60 | struct drm_global_reference *global_ref; |
61 | int ret; | 61 | int ret; |
62 | 62 | ||
63 | global_ref = &dev_priv->mem_global_ref; | 63 | global_ref = &dev_priv->mem_global_ref; |
64 | global_ref->global_type = TTM_GLOBAL_TTM_MEM; | 64 | global_ref->global_type = DRM_GLOBAL_TTM_MEM; |
65 | global_ref->size = sizeof(struct ttm_mem_global); | 65 | global_ref->size = sizeof(struct ttm_mem_global); |
66 | global_ref->init = &vmw_ttm_mem_global_init; | 66 | global_ref->init = &vmw_ttm_mem_global_init; |
67 | global_ref->release = &vmw_ttm_mem_global_release; | 67 | global_ref->release = &vmw_ttm_mem_global_release; |
68 | 68 | ||
69 | ret = ttm_global_item_ref(global_ref); | 69 | ret = drm_global_item_ref(global_ref); |
70 | if (unlikely(ret != 0)) { | 70 | if (unlikely(ret != 0)) { |
71 | DRM_ERROR("Failed setting up TTM memory accounting.\n"); | 71 | DRM_ERROR("Failed setting up TTM memory accounting.\n"); |
72 | return ret; | 72 | return ret; |
@@ -75,11 +75,11 @@ int vmw_ttm_global_init(struct vmw_private *dev_priv) | |||
75 | dev_priv->bo_global_ref.mem_glob = | 75 | dev_priv->bo_global_ref.mem_glob = |
76 | dev_priv->mem_global_ref.object; | 76 | dev_priv->mem_global_ref.object; |
77 | global_ref = &dev_priv->bo_global_ref.ref; | 77 | global_ref = &dev_priv->bo_global_ref.ref; |
78 | global_ref->global_type = TTM_GLOBAL_TTM_BO; | 78 | global_ref->global_type = DRM_GLOBAL_TTM_BO; |
79 | global_ref->size = sizeof(struct ttm_bo_global); | 79 | global_ref->size = sizeof(struct ttm_bo_global); |
80 | global_ref->init = &ttm_bo_global_init; | 80 | global_ref->init = &ttm_bo_global_init; |
81 | global_ref->release = &ttm_bo_global_release; | 81 | global_ref->release = &ttm_bo_global_release; |
82 | ret = ttm_global_item_ref(global_ref); | 82 | ret = drm_global_item_ref(global_ref); |
83 | 83 | ||
84 | if (unlikely(ret != 0)) { | 84 | if (unlikely(ret != 0)) { |
85 | DRM_ERROR("Failed setting up TTM buffer objects.\n"); | 85 | DRM_ERROR("Failed setting up TTM buffer objects.\n"); |
@@ -88,12 +88,12 @@ int vmw_ttm_global_init(struct vmw_private *dev_priv) | |||
88 | 88 | ||
89 | return 0; | 89 | return 0; |
90 | out_no_bo: | 90 | out_no_bo: |
91 | ttm_global_item_unref(&dev_priv->mem_global_ref); | 91 | drm_global_item_unref(&dev_priv->mem_global_ref); |
92 | return ret; | 92 | return ret; |
93 | } | 93 | } |
94 | 94 | ||
95 | void vmw_ttm_global_release(struct vmw_private *dev_priv) | 95 | void vmw_ttm_global_release(struct vmw_private *dev_priv) |
96 | { | 96 | { |
97 | ttm_global_item_unref(&dev_priv->bo_global_ref.ref); | 97 | drm_global_item_unref(&dev_priv->bo_global_ref.ref); |
98 | ttm_global_item_unref(&dev_priv->mem_global_ref); | 98 | drm_global_item_unref(&dev_priv->mem_global_ref); |
99 | } | 99 | } |