diff options
Diffstat (limited to 'drivers/gpu')
68 files changed, 1061 insertions, 581 deletions
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 09e11a5d921a..fd9d0af4d536 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c | |||
@@ -206,7 +206,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, | |||
206 | size_t size; | 206 | size_t size; |
207 | int ret; | 207 | int ret; |
208 | 208 | ||
209 | DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n", | 209 | DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n", |
210 | sizes->surface_width, sizes->surface_height, | 210 | sizes->surface_width, sizes->surface_height, |
211 | sizes->surface_bpp); | 211 | sizes->surface_bpp); |
212 | 212 | ||
@@ -220,7 +220,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, | |||
220 | 220 | ||
221 | size = mode_cmd.pitches[0] * mode_cmd.height; | 221 | size = mode_cmd.pitches[0] * mode_cmd.height; |
222 | obj = drm_gem_cma_create(dev, size); | 222 | obj = drm_gem_cma_create(dev, size); |
223 | if (!obj) | 223 | if (IS_ERR(obj)) |
224 | return -ENOMEM; | 224 | return -ENOMEM; |
225 | 225 | ||
226 | fbi = framebuffer_alloc(0, dev->dev); | 226 | fbi = framebuffer_alloc(0, dev->dev); |
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index cdf8b1e7602d..d4b20ceda3fb 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c | |||
@@ -205,8 +205,6 @@ static int drm_gem_one_name_info(int id, void *ptr, void *data) | |||
205 | struct drm_gem_object *obj = ptr; | 205 | struct drm_gem_object *obj = ptr; |
206 | struct seq_file *m = data; | 206 | struct seq_file *m = data; |
207 | 207 | ||
208 | seq_printf(m, "name %d size %zd\n", obj->name, obj->size); | ||
209 | |||
210 | seq_printf(m, "%6d %8zd %7d %8d\n", | 208 | seq_printf(m, "%6d %8zd %7d %8d\n", |
211 | obj->name, obj->size, | 209 | obj->name, obj->size, |
212 | atomic_read(&obj->handle_count), | 210 | atomic_read(&obj->handle_count), |
@@ -239,7 +237,7 @@ int drm_vma_info(struct seq_file *m, void *data) | |||
239 | mutex_lock(&dev->struct_mutex); | 237 | mutex_lock(&dev->struct_mutex); |
240 | seq_printf(m, "vma use count: %d, high_memory = %pK, 0x%pK\n", | 238 | seq_printf(m, "vma use count: %d, high_memory = %pK, 0x%pK\n", |
241 | atomic_read(&dev->vma_count), | 239 | atomic_read(&dev->vma_count), |
242 | high_memory, (void *)virt_to_phys(high_memory)); | 240 | high_memory, (void *)(unsigned long)virt_to_phys(high_memory)); |
243 | 241 | ||
244 | list_for_each_entry(pt, &dev->vmalist, head) { | 242 | list_for_each_entry(pt, &dev->vmalist, head) { |
245 | vma = pt->vma; | 243 | vma = pt->vma; |
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index aaeb6f8d69ce..b8a282ea8751 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c | |||
@@ -64,7 +64,6 @@ int drm_get_platform_dev(struct platform_device *platdev, | |||
64 | } | 64 | } |
65 | 65 | ||
66 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 66 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
67 | dev_set_drvdata(&platdev->dev, dev); | ||
68 | ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); | 67 | ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); |
69 | if (ret) | 68 | if (ret) |
70 | goto err_g1; | 69 | goto err_g1; |
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 59a26e577b57..fc345d4ebb03 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config DRM_EXYNOS | 1 | config DRM_EXYNOS |
2 | tristate "DRM Support for Samsung SoC EXYNOS Series" | 2 | tristate "DRM Support for Samsung SoC EXYNOS Series" |
3 | depends on DRM && PLAT_SAMSUNG | 3 | depends on DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM) |
4 | select DRM_KMS_HELPER | 4 | select DRM_KMS_HELPER |
5 | select FB_CFB_FILLRECT | 5 | select FB_CFB_FILLRECT |
6 | select FB_CFB_COPYAREA | 6 | select FB_CFB_COPYAREA |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c index 18c271862ca8..0f68a2872673 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c | |||
@@ -374,6 +374,7 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, | |||
374 | exynos_connector->encoder_id = encoder->base.id; | 374 | exynos_connector->encoder_id = encoder->base.id; |
375 | exynos_connector->manager = manager; | 375 | exynos_connector->manager = manager; |
376 | exynos_connector->dpms = DRM_MODE_DPMS_OFF; | 376 | exynos_connector->dpms = DRM_MODE_DPMS_OFF; |
377 | connector->dpms = DRM_MODE_DPMS_OFF; | ||
377 | connector->encoder = encoder; | 378 | connector->encoder = encoder; |
378 | 379 | ||
379 | err = drm_mode_connector_attach_encoder(connector, encoder); | 380 | err = drm_mode_connector_attach_encoder(connector, encoder); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index e51503fbaf2b..241ad1eeec64 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c | |||
@@ -43,12 +43,14 @@ | |||
43 | * @manager: specific encoder has its own manager to control a hardware | 43 | * @manager: specific encoder has its own manager to control a hardware |
44 | * appropriately and we can access a hardware drawing on this manager. | 44 | * appropriately and we can access a hardware drawing on this manager. |
45 | * @dpms: store the encoder dpms value. | 45 | * @dpms: store the encoder dpms value. |
46 | * @updated: indicate whether overlay data updating is needed or not. | ||
46 | */ | 47 | */ |
47 | struct exynos_drm_encoder { | 48 | struct exynos_drm_encoder { |
48 | struct drm_crtc *old_crtc; | 49 | struct drm_crtc *old_crtc; |
49 | struct drm_encoder drm_encoder; | 50 | struct drm_encoder drm_encoder; |
50 | struct exynos_drm_manager *manager; | 51 | struct exynos_drm_manager *manager; |
51 | int dpms; | 52 | int dpms; |
53 | bool updated; | ||
52 | }; | 54 | }; |
53 | 55 | ||
54 | static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode) | 56 | static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode) |
@@ -85,7 +87,9 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
85 | switch (mode) { | 87 | switch (mode) { |
86 | case DRM_MODE_DPMS_ON: | 88 | case DRM_MODE_DPMS_ON: |
87 | if (manager_ops && manager_ops->apply) | 89 | if (manager_ops && manager_ops->apply) |
88 | manager_ops->apply(manager->dev); | 90 | if (!exynos_encoder->updated) |
91 | manager_ops->apply(manager->dev); | ||
92 | |||
89 | exynos_drm_connector_power(encoder, mode); | 93 | exynos_drm_connector_power(encoder, mode); |
90 | exynos_encoder->dpms = mode; | 94 | exynos_encoder->dpms = mode; |
91 | break; | 95 | break; |
@@ -94,6 +98,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
94 | case DRM_MODE_DPMS_OFF: | 98 | case DRM_MODE_DPMS_OFF: |
95 | exynos_drm_connector_power(encoder, mode); | 99 | exynos_drm_connector_power(encoder, mode); |
96 | exynos_encoder->dpms = mode; | 100 | exynos_encoder->dpms = mode; |
101 | exynos_encoder->updated = false; | ||
97 | break; | 102 | break; |
98 | default: | 103 | default: |
99 | DRM_ERROR("unspecified mode %d\n", mode); | 104 | DRM_ERROR("unspecified mode %d\n", mode); |
@@ -205,13 +210,22 @@ static void exynos_drm_encoder_prepare(struct drm_encoder *encoder) | |||
205 | 210 | ||
206 | static void exynos_drm_encoder_commit(struct drm_encoder *encoder) | 211 | static void exynos_drm_encoder_commit(struct drm_encoder *encoder) |
207 | { | 212 | { |
208 | struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); | 213 | struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); |
214 | struct exynos_drm_manager *manager = exynos_encoder->manager; | ||
209 | struct exynos_drm_manager_ops *manager_ops = manager->ops; | 215 | struct exynos_drm_manager_ops *manager_ops = manager->ops; |
210 | 216 | ||
211 | DRM_DEBUG_KMS("%s\n", __FILE__); | 217 | DRM_DEBUG_KMS("%s\n", __FILE__); |
212 | 218 | ||
213 | if (manager_ops && manager_ops->commit) | 219 | if (manager_ops && manager_ops->commit) |
214 | manager_ops->commit(manager->dev); | 220 | manager_ops->commit(manager->dev); |
221 | |||
222 | /* | ||
223 | * this will avoid one issue that overlay data is updated to | ||
224 | * real hardware two times. | ||
225 | * And this variable will be used to check if the data was | ||
226 | * already updated or not by exynos_drm_encoder_dpms function. | ||
227 | */ | ||
228 | exynos_encoder->updated = true; | ||
215 | } | 229 | } |
216 | 230 | ||
217 | static void exynos_drm_encoder_disable(struct drm_encoder *encoder) | 231 | static void exynos_drm_encoder_disable(struct drm_encoder *encoder) |
@@ -401,19 +415,6 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data) | |||
401 | manager_ops->dpms(manager->dev, mode); | 415 | manager_ops->dpms(manager->dev, mode); |
402 | 416 | ||
403 | /* | 417 | /* |
404 | * set current mode to new one so that data aren't updated into | ||
405 | * registers by drm_helper_connector_dpms two times. | ||
406 | * | ||
407 | * in case that drm_crtc_helper_set_mode() is called, | ||
408 | * overlay_ops->commit() and manager_ops->commit() callbacks | ||
409 | * can be called two times, first at drm_crtc_helper_set_mode() | ||
410 | * and second at drm_helper_connector_dpms(). | ||
411 | * so with this setting, when drm_helper_connector_dpms() is called | ||
412 | * encoder->funcs->dpms() will be ignored. | ||
413 | */ | ||
414 | exynos_encoder->dpms = mode; | ||
415 | |||
416 | /* | ||
417 | * if this condition is ok then it means that the crtc is already | 418 | * if this condition is ok then it means that the crtc is already |
418 | * detached from encoder and last function for detaching is properly | 419 | * detached from encoder and last function for detaching is properly |
419 | * done, so clear pipe from manager to prevent repeated call. | 420 | * done, so clear pipe from manager to prevent repeated call. |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 614b2e9ac462..e7fbb823fd8e 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
@@ -1142,7 +1142,7 @@ static int __devinit mixer_probe(struct platform_device *pdev) | |||
1142 | const struct of_device_id *match; | 1142 | const struct of_device_id *match; |
1143 | match = of_match_node(of_match_ptr(mixer_match_types), | 1143 | match = of_match_node(of_match_ptr(mixer_match_types), |
1144 | pdev->dev.of_node); | 1144 | pdev->dev.of_node); |
1145 | drv = match->data; | 1145 | drv = (struct mixer_drv_data *)match->data; |
1146 | } else { | 1146 | } else { |
1147 | drv = (struct mixer_drv_data *) | 1147 | drv = (struct mixer_drv_data *) |
1148 | platform_get_device_id(pdev)->driver_data; | 1148 | platform_get_device_id(pdev)->driver_data; |
diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c index 38f3a6cb8c7d..3edd981e0770 100644 --- a/drivers/gpu/drm/i915/dvo_ch7xxx.c +++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c | |||
@@ -303,10 +303,10 @@ static bool ch7xxx_get_hw_state(struct intel_dvo_device *dvo) | |||
303 | 303 | ||
304 | ch7xxx_readb(dvo, CH7xxx_PM, &val); | 304 | ch7xxx_readb(dvo, CH7xxx_PM, &val); |
305 | 305 | ||
306 | if (val & CH7xxx_PM_FPD) | 306 | if (val & (CH7xxx_PM_DVIL | CH7xxx_PM_DVIP)) |
307 | return false; | ||
308 | else | ||
309 | return true; | 307 | return true; |
308 | else | ||
309 | return false; | ||
310 | } | 310 | } |
311 | 311 | ||
312 | static void ch7xxx_dump_regs(struct intel_dvo_device *dvo) | 312 | static void ch7xxx_dump_regs(struct intel_dvo_device *dvo) |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index c9bfd83dde64..61ae104dca8c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1505,7 +1505,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1505 | goto put_gmch; | 1505 | goto put_gmch; |
1506 | } | 1506 | } |
1507 | 1507 | ||
1508 | i915_kick_out_firmware_fb(dev_priv); | 1508 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
1509 | i915_kick_out_firmware_fb(dev_priv); | ||
1509 | 1510 | ||
1510 | pci_set_master(dev->pdev); | 1511 | pci_set_master(dev->pdev); |
1511 | 1512 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index aac4e5e1a5b9..6770ee6084b4 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -118,6 +118,13 @@ module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0600); | |||
118 | MODULE_PARM_DESC(i915_enable_ppgtt, | 118 | MODULE_PARM_DESC(i915_enable_ppgtt, |
119 | "Enable PPGTT (default: true)"); | 119 | "Enable PPGTT (default: true)"); |
120 | 120 | ||
121 | unsigned int i915_preliminary_hw_support __read_mostly = 0; | ||
122 | module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600); | ||
123 | MODULE_PARM_DESC(preliminary_hw_support, | ||
124 | "Enable preliminary hardware support. " | ||
125 | "Enable Haswell and ValleyView Support. " | ||
126 | "(default: false)"); | ||
127 | |||
121 | static struct drm_driver driver; | 128 | static struct drm_driver driver; |
122 | extern int intel_agp_enabled; | 129 | extern int intel_agp_enabled; |
123 | 130 | ||
@@ -826,6 +833,12 @@ i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
826 | struct intel_device_info *intel_info = | 833 | struct intel_device_info *intel_info = |
827 | (struct intel_device_info *) ent->driver_data; | 834 | (struct intel_device_info *) ent->driver_data; |
828 | 835 | ||
836 | if (intel_info->is_haswell || intel_info->is_valleyview) | ||
837 | if(!i915_preliminary_hw_support) { | ||
838 | DRM_ERROR("Preliminary hardware support disabled\n"); | ||
839 | return -ENODEV; | ||
840 | } | ||
841 | |||
829 | /* Only bind to function 0 of the device. Early generations | 842 | /* Only bind to function 0 of the device. Early generations |
830 | * used function 1 as a placeholder for multi-head. This causes | 843 | * used function 1 as a placeholder for multi-head. This causes |
831 | * us confusion instead, especially on the systems where both | 844 | * us confusion instead, especially on the systems where both |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4f2831aa5fed..f511fa2f4168 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1217,6 +1217,7 @@ extern int i915_enable_rc6 __read_mostly; | |||
1217 | extern int i915_enable_fbc __read_mostly; | 1217 | extern int i915_enable_fbc __read_mostly; |
1218 | extern bool i915_enable_hangcheck __read_mostly; | 1218 | extern bool i915_enable_hangcheck __read_mostly; |
1219 | extern int i915_enable_ppgtt __read_mostly; | 1219 | extern int i915_enable_ppgtt __read_mostly; |
1220 | extern unsigned int i915_preliminary_hw_support __read_mostly; | ||
1220 | 1221 | ||
1221 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); | 1222 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); |
1222 | extern int i915_resume(struct drm_device *dev); | 1223 | extern int i915_resume(struct drm_device *dev); |
@@ -1341,9 +1342,14 @@ int __must_check i915_gem_object_get_pages(struct drm_i915_gem_object *obj); | |||
1341 | static inline struct page *i915_gem_object_get_page(struct drm_i915_gem_object *obj, int n) | 1342 | static inline struct page *i915_gem_object_get_page(struct drm_i915_gem_object *obj, int n) |
1342 | { | 1343 | { |
1343 | struct scatterlist *sg = obj->pages->sgl; | 1344 | struct scatterlist *sg = obj->pages->sgl; |
1344 | while (n >= SG_MAX_SINGLE_ALLOC) { | 1345 | int nents = obj->pages->nents; |
1346 | while (nents > SG_MAX_SINGLE_ALLOC) { | ||
1347 | if (n < SG_MAX_SINGLE_ALLOC - 1) | ||
1348 | break; | ||
1349 | |||
1345 | sg = sg_chain_ptr(sg + SG_MAX_SINGLE_ALLOC - 1); | 1350 | sg = sg_chain_ptr(sg + SG_MAX_SINGLE_ALLOC - 1); |
1346 | n -= SG_MAX_SINGLE_ALLOC - 1; | 1351 | n -= SG_MAX_SINGLE_ALLOC - 1; |
1352 | nents -= SG_MAX_SINGLE_ALLOC - 1; | ||
1347 | } | 1353 | } |
1348 | return sg_page(sg+n); | 1354 | return sg_page(sg+n); |
1349 | } | 1355 | } |
@@ -1427,7 +1433,7 @@ int __must_check i915_gpu_idle(struct drm_device *dev); | |||
1427 | int __must_check i915_gem_idle(struct drm_device *dev); | 1433 | int __must_check i915_gem_idle(struct drm_device *dev); |
1428 | int i915_add_request(struct intel_ring_buffer *ring, | 1434 | int i915_add_request(struct intel_ring_buffer *ring, |
1429 | struct drm_file *file, | 1435 | struct drm_file *file, |
1430 | struct drm_i915_gem_request *request); | 1436 | u32 *seqno); |
1431 | int __must_check i915_wait_seqno(struct intel_ring_buffer *ring, | 1437 | int __must_check i915_wait_seqno(struct intel_ring_buffer *ring, |
1432 | uint32_t seqno); | 1438 | uint32_t seqno); |
1433 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); | 1439 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 19dbdd7dd564..107f09befe92 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1407,8 +1407,10 @@ out: | |||
1407 | return VM_FAULT_NOPAGE; | 1407 | return VM_FAULT_NOPAGE; |
1408 | case -ENOMEM: | 1408 | case -ENOMEM: |
1409 | return VM_FAULT_OOM; | 1409 | return VM_FAULT_OOM; |
1410 | case -ENOSPC: | ||
1411 | return VM_FAULT_SIGBUS; | ||
1410 | default: | 1412 | default: |
1411 | WARN_ON_ONCE(ret); | 1413 | WARN_ONCE(ret, "unhandled error in i915_gem_fault: %i\n", ret); |
1412 | return VM_FAULT_SIGBUS; | 1414 | return VM_FAULT_SIGBUS; |
1413 | } | 1415 | } |
1414 | } | 1416 | } |
@@ -1822,10 +1824,11 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
1822 | sg_set_page(sg, page, PAGE_SIZE, 0); | 1824 | sg_set_page(sg, page, PAGE_SIZE, 0); |
1823 | } | 1825 | } |
1824 | 1826 | ||
1827 | obj->pages = st; | ||
1828 | |||
1825 | if (i915_gem_object_needs_bit17_swizzle(obj)) | 1829 | if (i915_gem_object_needs_bit17_swizzle(obj)) |
1826 | i915_gem_object_do_bit_17_swizzle(obj); | 1830 | i915_gem_object_do_bit_17_swizzle(obj); |
1827 | 1831 | ||
1828 | obj->pages = st; | ||
1829 | return 0; | 1832 | return 0; |
1830 | 1833 | ||
1831 | err_pages: | 1834 | err_pages: |
@@ -1955,11 +1958,12 @@ i915_gem_next_request_seqno(struct intel_ring_buffer *ring) | |||
1955 | int | 1958 | int |
1956 | i915_add_request(struct intel_ring_buffer *ring, | 1959 | i915_add_request(struct intel_ring_buffer *ring, |
1957 | struct drm_file *file, | 1960 | struct drm_file *file, |
1958 | struct drm_i915_gem_request *request) | 1961 | u32 *out_seqno) |
1959 | { | 1962 | { |
1960 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 1963 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
1961 | uint32_t seqno; | 1964 | struct drm_i915_gem_request *request; |
1962 | u32 request_ring_position; | 1965 | u32 request_ring_position; |
1966 | u32 seqno; | ||
1963 | int was_empty; | 1967 | int was_empty; |
1964 | int ret; | 1968 | int ret; |
1965 | 1969 | ||
@@ -1974,11 +1978,9 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
1974 | if (ret) | 1978 | if (ret) |
1975 | return ret; | 1979 | return ret; |
1976 | 1980 | ||
1977 | if (request == NULL) { | 1981 | request = kmalloc(sizeof(*request), GFP_KERNEL); |
1978 | request = kmalloc(sizeof(*request), GFP_KERNEL); | 1982 | if (request == NULL) |
1979 | if (request == NULL) | 1983 | return -ENOMEM; |
1980 | return -ENOMEM; | ||
1981 | } | ||
1982 | 1984 | ||
1983 | seqno = i915_gem_next_request_seqno(ring); | 1985 | seqno = i915_gem_next_request_seqno(ring); |
1984 | 1986 | ||
@@ -2030,6 +2032,8 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
2030 | } | 2032 | } |
2031 | } | 2033 | } |
2032 | 2034 | ||
2035 | if (out_seqno) | ||
2036 | *out_seqno = seqno; | ||
2033 | return 0; | 2037 | return 0; |
2034 | } | 2038 | } |
2035 | 2039 | ||
@@ -3959,6 +3963,9 @@ i915_gem_init_hw(struct drm_device *dev) | |||
3959 | if (!intel_enable_gtt()) | 3963 | if (!intel_enable_gtt()) |
3960 | return -EIO; | 3964 | return -EIO; |
3961 | 3965 | ||
3966 | if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1)) | ||
3967 | I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000); | ||
3968 | |||
3962 | i915_gem_l3_remap(dev); | 3969 | i915_gem_l3_remap(dev); |
3963 | 3970 | ||
3964 | i915_gem_init_swizzling(dev); | 3971 | i915_gem_init_swizzling(dev); |
@@ -4098,7 +4105,6 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, | |||
4098 | } | 4105 | } |
4099 | 4106 | ||
4100 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); | 4107 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); |
4101 | BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); | ||
4102 | mutex_unlock(&dev->struct_mutex); | 4108 | mutex_unlock(&dev->struct_mutex); |
4103 | 4109 | ||
4104 | ret = drm_irq_install(dev); | 4110 | ret = drm_irq_install(dev); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 64c1be0a9cfd..a4162ddff6c5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -521,7 +521,7 @@ | |||
521 | */ | 521 | */ |
522 | # define _3D_CHICKEN2_WM_READ_PIPELINED (1 << 14) | 522 | # define _3D_CHICKEN2_WM_READ_PIPELINED (1 << 14) |
523 | #define _3D_CHICKEN3 0x02090 | 523 | #define _3D_CHICKEN3 0x02090 |
524 | #define _3D_CHICKEN_SF_DISABLE_FASTCLIP_CULL (1 << 5) | 524 | #define _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL (1 << 5) |
525 | 525 | ||
526 | #define MI_MODE 0x0209c | 526 | #define MI_MODE 0x0209c |
527 | # define VS_TIMER_DISPATCH (1 << 6) | 527 | # define VS_TIMER_DISPATCH (1 << 6) |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 893f30164b7e..b726b478a4f5 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -219,20 +219,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, | |||
219 | intel_encoder_to_crt(to_intel_encoder(encoder)); | 219 | intel_encoder_to_crt(to_intel_encoder(encoder)); |
220 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 220 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
221 | struct drm_i915_private *dev_priv = dev->dev_private; | 221 | struct drm_i915_private *dev_priv = dev->dev_private; |
222 | int dpll_md_reg; | 222 | u32 adpa; |
223 | u32 adpa, dpll_md; | ||
224 | |||
225 | dpll_md_reg = DPLL_MD(intel_crtc->pipe); | ||
226 | |||
227 | /* | ||
228 | * Disable separate mode multiplier used when cloning SDVO to CRT | ||
229 | * XXX this needs to be adjusted when we really are cloning | ||
230 | */ | ||
231 | if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { | ||
232 | dpll_md = I915_READ(dpll_md_reg); | ||
233 | I915_WRITE(dpll_md_reg, | ||
234 | dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); | ||
235 | } | ||
236 | 223 | ||
237 | adpa = ADPA_HOTPLUG_BITS; | 224 | adpa = ADPA_HOTPLUG_BITS; |
238 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 225 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
@@ -742,7 +729,7 @@ void intel_crt_init(struct drm_device *dev) | |||
742 | 729 | ||
743 | crt->base.type = INTEL_OUTPUT_ANALOG; | 730 | crt->base.type = INTEL_OUTPUT_ANALOG; |
744 | crt->base.cloneable = true; | 731 | crt->base.cloneable = true; |
745 | if (IS_HASWELL(dev)) | 732 | if (IS_HASWELL(dev) || IS_I830(dev)) |
746 | crt->base.crtc_mask = (1 << 0); | 733 | crt->base.crtc_mask = (1 << 0); |
747 | else | 734 | else |
748 | crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); | 735 | crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2b6ce9b2674a..461a637f1ef7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3253,6 +3253,16 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
3253 | 3253 | ||
3254 | if (HAS_PCH_CPT(dev)) | 3254 | if (HAS_PCH_CPT(dev)) |
3255 | intel_cpt_verify_modeset(dev, intel_crtc->pipe); | 3255 | intel_cpt_verify_modeset(dev, intel_crtc->pipe); |
3256 | |||
3257 | /* | ||
3258 | * There seems to be a race in PCH platform hw (at least on some | ||
3259 | * outputs) where an enabled pipe still completes any pageflip right | ||
3260 | * away (as if the pipe is off) instead of waiting for vblank. As soon | ||
3261 | * as the first vblank happend, everything works as expected. Hence just | ||
3262 | * wait for one vblank before returning to avoid strange things | ||
3263 | * happening. | ||
3264 | */ | ||
3265 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
3256 | } | 3266 | } |
3257 | 3267 | ||
3258 | static void ironlake_crtc_disable(struct drm_crtc *crtc) | 3268 | static void ironlake_crtc_disable(struct drm_crtc *crtc) |
@@ -7882,6 +7892,34 @@ struct intel_quirk { | |||
7882 | void (*hook)(struct drm_device *dev); | 7892 | void (*hook)(struct drm_device *dev); |
7883 | }; | 7893 | }; |
7884 | 7894 | ||
7895 | /* For systems that don't have a meaningful PCI subdevice/subvendor ID */ | ||
7896 | struct intel_dmi_quirk { | ||
7897 | void (*hook)(struct drm_device *dev); | ||
7898 | const struct dmi_system_id (*dmi_id_list)[]; | ||
7899 | }; | ||
7900 | |||
7901 | static int intel_dmi_reverse_brightness(const struct dmi_system_id *id) | ||
7902 | { | ||
7903 | DRM_INFO("Backlight polarity reversed on %s\n", id->ident); | ||
7904 | return 1; | ||
7905 | } | ||
7906 | |||
7907 | static const struct intel_dmi_quirk intel_dmi_quirks[] = { | ||
7908 | { | ||
7909 | .dmi_id_list = &(const struct dmi_system_id[]) { | ||
7910 | { | ||
7911 | .callback = intel_dmi_reverse_brightness, | ||
7912 | .ident = "NCR Corporation", | ||
7913 | .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"), | ||
7914 | DMI_MATCH(DMI_PRODUCT_NAME, ""), | ||
7915 | }, | ||
7916 | }, | ||
7917 | { } /* terminating entry */ | ||
7918 | }, | ||
7919 | .hook = quirk_invert_brightness, | ||
7920 | }, | ||
7921 | }; | ||
7922 | |||
7885 | static struct intel_quirk intel_quirks[] = { | 7923 | static struct intel_quirk intel_quirks[] = { |
7886 | /* HP Mini needs pipe A force quirk (LP: #322104) */ | 7924 | /* HP Mini needs pipe A force quirk (LP: #322104) */ |
7887 | { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, | 7925 | { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, |
@@ -7892,8 +7930,7 @@ static struct intel_quirk intel_quirks[] = { | |||
7892 | /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ | 7930 | /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ |
7893 | { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, | 7931 | { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, |
7894 | 7932 | ||
7895 | /* 855 & before need to leave pipe A & dpll A up */ | 7933 | /* 830/845 need to leave pipe A & dpll A up */ |
7896 | { 0x3582, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, | ||
7897 | { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, | 7934 | { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
7898 | { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, | 7935 | { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
7899 | 7936 | ||
@@ -7922,6 +7959,10 @@ static void intel_init_quirks(struct drm_device *dev) | |||
7922 | q->subsystem_device == PCI_ANY_ID)) | 7959 | q->subsystem_device == PCI_ANY_ID)) |
7923 | q->hook(dev); | 7960 | q->hook(dev); |
7924 | } | 7961 | } |
7962 | for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) { | ||
7963 | if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0) | ||
7964 | intel_dmi_quirks[i].hook(dev); | ||
7965 | } | ||
7925 | } | 7966 | } |
7926 | 7967 | ||
7927 | /* Disable the VGA plane that we never use */ | 7968 | /* Disable the VGA plane that we never use */ |
@@ -8049,29 +8090,42 @@ static void intel_enable_pipe_a(struct drm_device *dev) | |||
8049 | 8090 | ||
8050 | } | 8091 | } |
8051 | 8092 | ||
8093 | static bool | ||
8094 | intel_check_plane_mapping(struct intel_crtc *crtc) | ||
8095 | { | ||
8096 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; | ||
8097 | u32 reg, val; | ||
8098 | |||
8099 | if (dev_priv->num_pipe == 1) | ||
8100 | return true; | ||
8101 | |||
8102 | reg = DSPCNTR(!crtc->plane); | ||
8103 | val = I915_READ(reg); | ||
8104 | |||
8105 | if ((val & DISPLAY_PLANE_ENABLE) && | ||
8106 | (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe)) | ||
8107 | return false; | ||
8108 | |||
8109 | return true; | ||
8110 | } | ||
8111 | |||
8052 | static void intel_sanitize_crtc(struct intel_crtc *crtc) | 8112 | static void intel_sanitize_crtc(struct intel_crtc *crtc) |
8053 | { | 8113 | { |
8054 | struct drm_device *dev = crtc->base.dev; | 8114 | struct drm_device *dev = crtc->base.dev; |
8055 | struct drm_i915_private *dev_priv = dev->dev_private; | 8115 | struct drm_i915_private *dev_priv = dev->dev_private; |
8056 | u32 reg, val; | 8116 | u32 reg; |
8057 | 8117 | ||
8058 | /* Clear any frame start delays used for debugging left by the BIOS */ | 8118 | /* Clear any frame start delays used for debugging left by the BIOS */ |
8059 | reg = PIPECONF(crtc->pipe); | 8119 | reg = PIPECONF(crtc->pipe); |
8060 | I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); | 8120 | I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); |
8061 | 8121 | ||
8062 | /* We need to sanitize the plane -> pipe mapping first because this will | 8122 | /* We need to sanitize the plane -> pipe mapping first because this will |
8063 | * disable the crtc (and hence change the state) if it is wrong. */ | 8123 | * disable the crtc (and hence change the state) if it is wrong. Note |
8064 | if (!HAS_PCH_SPLIT(dev)) { | 8124 | * that gen4+ has a fixed plane -> pipe mapping. */ |
8125 | if (INTEL_INFO(dev)->gen < 4 && !intel_check_plane_mapping(crtc)) { | ||
8065 | struct intel_connector *connector; | 8126 | struct intel_connector *connector; |
8066 | bool plane; | 8127 | bool plane; |
8067 | 8128 | ||
8068 | reg = DSPCNTR(crtc->plane); | ||
8069 | val = I915_READ(reg); | ||
8070 | |||
8071 | if ((val & DISPLAY_PLANE_ENABLE) == 0 && | ||
8072 | (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe)) | ||
8073 | goto ok; | ||
8074 | |||
8075 | DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n", | 8129 | DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n", |
8076 | crtc->base.base.id); | 8130 | crtc->base.base.id); |
8077 | 8131 | ||
@@ -8095,7 +8149,6 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) | |||
8095 | WARN_ON(crtc->active); | 8149 | WARN_ON(crtc->active); |
8096 | crtc->base.enabled = false; | 8150 | crtc->base.enabled = false; |
8097 | } | 8151 | } |
8098 | ok: | ||
8099 | 8152 | ||
8100 | if (dev_priv->quirks & QUIRK_PIPEA_FORCE && | 8153 | if (dev_priv->quirks & QUIRK_PIPEA_FORCE && |
8101 | crtc->pipe == PIPE_A && !crtc->active) { | 8154 | crtc->pipe == PIPE_A && !crtc->active) { |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d1e8ddb2d6c0..368ed8ef1600 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1797,7 +1797,8 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1797 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1797 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
1798 | break; | 1798 | break; |
1799 | if (i == intel_dp->lane_count && voltage_tries == 5) { | 1799 | if (i == intel_dp->lane_count && voltage_tries == 5) { |
1800 | if (++loop_tries == 5) { | 1800 | ++loop_tries; |
1801 | if (loop_tries == 5) { | ||
1801 | DRM_DEBUG_KMS("too many full retries, give up\n"); | 1802 | DRM_DEBUG_KMS("too many full retries, give up\n"); |
1802 | break; | 1803 | break; |
1803 | } | 1804 | } |
@@ -1807,11 +1808,15 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1807 | } | 1808 | } |
1808 | 1809 | ||
1809 | /* Check to see if we've tried the same voltage 5 times */ | 1810 | /* Check to see if we've tried the same voltage 5 times */ |
1810 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) { | 1811 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { |
1811 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
1812 | voltage_tries = 0; | ||
1813 | } else | ||
1814 | ++voltage_tries; | 1812 | ++voltage_tries; |
1813 | if (voltage_tries == 5) { | ||
1814 | DRM_DEBUG_KMS("too many voltage retries, give up\n"); | ||
1815 | break; | ||
1816 | } | ||
1817 | } else | ||
1818 | voltage_tries = 0; | ||
1819 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
1815 | 1820 | ||
1816 | /* Compute new intel_dp->train_set as requested by target */ | 1821 | /* Compute new intel_dp->train_set as requested by target */ |
1817 | intel_get_adjust_train(intel_dp, link_status); | 1822 | intel_get_adjust_train(intel_dp, link_status); |
@@ -2369,8 +2374,9 @@ static void | |||
2369 | intel_dp_destroy(struct drm_connector *connector) | 2374 | intel_dp_destroy(struct drm_connector *connector) |
2370 | { | 2375 | { |
2371 | struct drm_device *dev = connector->dev; | 2376 | struct drm_device *dev = connector->dev; |
2377 | struct intel_dp *intel_dp = intel_attached_dp(connector); | ||
2372 | 2378 | ||
2373 | if (intel_dpd_is_edp(dev)) | 2379 | if (is_edp(intel_dp)) |
2374 | intel_panel_destroy_backlight(dev); | 2380 | intel_panel_destroy_backlight(dev); |
2375 | 2381 | ||
2376 | drm_sysfs_connector_remove(connector); | 2382 | drm_sysfs_connector_remove(connector); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index e3166df55daa..edba93b3474b 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -777,6 +777,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
777 | DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), | 777 | DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), |
778 | }, | 778 | }, |
779 | }, | 779 | }, |
780 | { | ||
781 | .callback = intel_no_lvds_dmi_callback, | ||
782 | .ident = "Supermicro X7SPA-H", | ||
783 | .matches = { | ||
784 | DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"), | ||
785 | DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"), | ||
786 | }, | ||
787 | }, | ||
780 | 788 | ||
781 | { } /* terminating entry */ | 789 | { } /* terminating entry */ |
782 | }; | 790 | }; |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index ebff850a9ab6..d7bc817f51a0 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -209,7 +209,6 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay, | |||
209 | } | 209 | } |
210 | 210 | ||
211 | static int intel_overlay_do_wait_request(struct intel_overlay *overlay, | 211 | static int intel_overlay_do_wait_request(struct intel_overlay *overlay, |
212 | struct drm_i915_gem_request *request, | ||
213 | void (*tail)(struct intel_overlay *)) | 212 | void (*tail)(struct intel_overlay *)) |
214 | { | 213 | { |
215 | struct drm_device *dev = overlay->dev; | 214 | struct drm_device *dev = overlay->dev; |
@@ -218,12 +217,10 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, | |||
218 | int ret; | 217 | int ret; |
219 | 218 | ||
220 | BUG_ON(overlay->last_flip_req); | 219 | BUG_ON(overlay->last_flip_req); |
221 | ret = i915_add_request(ring, NULL, request); | 220 | ret = i915_add_request(ring, NULL, &overlay->last_flip_req); |
222 | if (ret) { | 221 | if (ret) |
223 | kfree(request); | 222 | return ret; |
224 | return ret; | 223 | |
225 | } | ||
226 | overlay->last_flip_req = request->seqno; | ||
227 | overlay->flip_tail = tail; | 224 | overlay->flip_tail = tail; |
228 | ret = i915_wait_seqno(ring, overlay->last_flip_req); | 225 | ret = i915_wait_seqno(ring, overlay->last_flip_req); |
229 | if (ret) | 226 | if (ret) |
@@ -240,7 +237,6 @@ static int intel_overlay_on(struct intel_overlay *overlay) | |||
240 | struct drm_device *dev = overlay->dev; | 237 | struct drm_device *dev = overlay->dev; |
241 | struct drm_i915_private *dev_priv = dev->dev_private; | 238 | struct drm_i915_private *dev_priv = dev->dev_private; |
242 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | 239 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
243 | struct drm_i915_gem_request *request; | ||
244 | int ret; | 240 | int ret; |
245 | 241 | ||
246 | BUG_ON(overlay->active); | 242 | BUG_ON(overlay->active); |
@@ -248,17 +244,9 @@ static int intel_overlay_on(struct intel_overlay *overlay) | |||
248 | 244 | ||
249 | WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE)); | 245 | WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE)); |
250 | 246 | ||
251 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
252 | if (request == NULL) { | ||
253 | ret = -ENOMEM; | ||
254 | goto out; | ||
255 | } | ||
256 | |||
257 | ret = intel_ring_begin(ring, 4); | 247 | ret = intel_ring_begin(ring, 4); |
258 | if (ret) { | 248 | if (ret) |
259 | kfree(request); | 249 | return ret; |
260 | goto out; | ||
261 | } | ||
262 | 250 | ||
263 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON); | 251 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON); |
264 | intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE); | 252 | intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE); |
@@ -266,9 +254,7 @@ static int intel_overlay_on(struct intel_overlay *overlay) | |||
266 | intel_ring_emit(ring, MI_NOOP); | 254 | intel_ring_emit(ring, MI_NOOP); |
267 | intel_ring_advance(ring); | 255 | intel_ring_advance(ring); |
268 | 256 | ||
269 | ret = intel_overlay_do_wait_request(overlay, request, NULL); | 257 | return intel_overlay_do_wait_request(overlay, NULL); |
270 | out: | ||
271 | return ret; | ||
272 | } | 258 | } |
273 | 259 | ||
274 | /* overlay needs to be enabled in OCMD reg */ | 260 | /* overlay needs to be enabled in OCMD reg */ |
@@ -278,17 +264,12 @@ static int intel_overlay_continue(struct intel_overlay *overlay, | |||
278 | struct drm_device *dev = overlay->dev; | 264 | struct drm_device *dev = overlay->dev; |
279 | drm_i915_private_t *dev_priv = dev->dev_private; | 265 | drm_i915_private_t *dev_priv = dev->dev_private; |
280 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | 266 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
281 | struct drm_i915_gem_request *request; | ||
282 | u32 flip_addr = overlay->flip_addr; | 267 | u32 flip_addr = overlay->flip_addr; |
283 | u32 tmp; | 268 | u32 tmp; |
284 | int ret; | 269 | int ret; |
285 | 270 | ||
286 | BUG_ON(!overlay->active); | 271 | BUG_ON(!overlay->active); |
287 | 272 | ||
288 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
289 | if (request == NULL) | ||
290 | return -ENOMEM; | ||
291 | |||
292 | if (load_polyphase_filter) | 273 | if (load_polyphase_filter) |
293 | flip_addr |= OFC_UPDATE; | 274 | flip_addr |= OFC_UPDATE; |
294 | 275 | ||
@@ -298,22 +279,14 @@ static int intel_overlay_continue(struct intel_overlay *overlay, | |||
298 | DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); | 279 | DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); |
299 | 280 | ||
300 | ret = intel_ring_begin(ring, 2); | 281 | ret = intel_ring_begin(ring, 2); |
301 | if (ret) { | 282 | if (ret) |
302 | kfree(request); | ||
303 | return ret; | 283 | return ret; |
304 | } | 284 | |
305 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); | 285 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); |
306 | intel_ring_emit(ring, flip_addr); | 286 | intel_ring_emit(ring, flip_addr); |
307 | intel_ring_advance(ring); | 287 | intel_ring_advance(ring); |
308 | 288 | ||
309 | ret = i915_add_request(ring, NULL, request); | 289 | return i915_add_request(ring, NULL, &overlay->last_flip_req); |
310 | if (ret) { | ||
311 | kfree(request); | ||
312 | return ret; | ||
313 | } | ||
314 | |||
315 | overlay->last_flip_req = request->seqno; | ||
316 | return 0; | ||
317 | } | 290 | } |
318 | 291 | ||
319 | static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay) | 292 | static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay) |
@@ -349,15 +322,10 @@ static int intel_overlay_off(struct intel_overlay *overlay) | |||
349 | struct drm_i915_private *dev_priv = dev->dev_private; | 322 | struct drm_i915_private *dev_priv = dev->dev_private; |
350 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | 323 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
351 | u32 flip_addr = overlay->flip_addr; | 324 | u32 flip_addr = overlay->flip_addr; |
352 | struct drm_i915_gem_request *request; | ||
353 | int ret; | 325 | int ret; |
354 | 326 | ||
355 | BUG_ON(!overlay->active); | 327 | BUG_ON(!overlay->active); |
356 | 328 | ||
357 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
358 | if (request == NULL) | ||
359 | return -ENOMEM; | ||
360 | |||
361 | /* According to intel docs the overlay hw may hang (when switching | 329 | /* According to intel docs the overlay hw may hang (when switching |
362 | * off) without loading the filter coeffs. It is however unclear whether | 330 | * off) without loading the filter coeffs. It is however unclear whether |
363 | * this applies to the disabling of the overlay or to the switching off | 331 | * this applies to the disabling of the overlay or to the switching off |
@@ -365,22 +333,28 @@ static int intel_overlay_off(struct intel_overlay *overlay) | |||
365 | flip_addr |= OFC_UPDATE; | 333 | flip_addr |= OFC_UPDATE; |
366 | 334 | ||
367 | ret = intel_ring_begin(ring, 6); | 335 | ret = intel_ring_begin(ring, 6); |
368 | if (ret) { | 336 | if (ret) |
369 | kfree(request); | ||
370 | return ret; | 337 | return ret; |
371 | } | 338 | |
372 | /* wait for overlay to go idle */ | 339 | /* wait for overlay to go idle */ |
373 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); | 340 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); |
374 | intel_ring_emit(ring, flip_addr); | 341 | intel_ring_emit(ring, flip_addr); |
375 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 342 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); |
376 | /* turn overlay off */ | 343 | /* turn overlay off */ |
377 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); | 344 | if (IS_I830(dev)) { |
378 | intel_ring_emit(ring, flip_addr); | 345 | /* Workaround: Don't disable the overlay fully, since otherwise |
379 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 346 | * it dies on the next OVERLAY_ON cmd. */ |
347 | intel_ring_emit(ring, MI_NOOP); | ||
348 | intel_ring_emit(ring, MI_NOOP); | ||
349 | intel_ring_emit(ring, MI_NOOP); | ||
350 | } else { | ||
351 | intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); | ||
352 | intel_ring_emit(ring, flip_addr); | ||
353 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | ||
354 | } | ||
380 | intel_ring_advance(ring); | 355 | intel_ring_advance(ring); |
381 | 356 | ||
382 | return intel_overlay_do_wait_request(overlay, request, | 357 | return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail); |
383 | intel_overlay_off_tail); | ||
384 | } | 358 | } |
385 | 359 | ||
386 | /* recover from an interruption due to a signal | 360 | /* recover from an interruption due to a signal |
@@ -425,24 +399,16 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) | |||
425 | return 0; | 399 | return 0; |
426 | 400 | ||
427 | if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) { | 401 | if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) { |
428 | struct drm_i915_gem_request *request; | ||
429 | |||
430 | /* synchronous slowpath */ | 402 | /* synchronous slowpath */ |
431 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
432 | if (request == NULL) | ||
433 | return -ENOMEM; | ||
434 | |||
435 | ret = intel_ring_begin(ring, 2); | 403 | ret = intel_ring_begin(ring, 2); |
436 | if (ret) { | 404 | if (ret) |
437 | kfree(request); | ||
438 | return ret; | 405 | return ret; |
439 | } | ||
440 | 406 | ||
441 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 407 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); |
442 | intel_ring_emit(ring, MI_NOOP); | 408 | intel_ring_emit(ring, MI_NOOP); |
443 | intel_ring_advance(ring); | 409 | intel_ring_advance(ring); |
444 | 410 | ||
445 | ret = intel_overlay_do_wait_request(overlay, request, | 411 | ret = intel_overlay_do_wait_request(overlay, |
446 | intel_overlay_release_old_vid_tail); | 412 | intel_overlay_release_old_vid_tail); |
447 | if (ret) | 413 | if (ret) |
448 | return ret; | 414 | return ret; |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index e019b2369861..e2aacd329545 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -435,7 +435,7 @@ int intel_panel_setup_backlight(struct drm_device *dev) | |||
435 | props.type = BACKLIGHT_RAW; | 435 | props.type = BACKLIGHT_RAW; |
436 | props.max_brightness = _intel_panel_get_max_backlight(dev); | 436 | props.max_brightness = _intel_panel_get_max_backlight(dev); |
437 | if (props.max_brightness == 0) { | 437 | if (props.max_brightness == 0) { |
438 | DRM_ERROR("Failed to get maximum backlight value\n"); | 438 | DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n"); |
439 | return -ENODEV; | 439 | return -ENODEV; |
440 | } | 440 | } |
441 | dev_priv->backlight = | 441 | dev_priv->backlight = |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b3b4b6cea8b0..72f41aaa71ff 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -3442,8 +3442,8 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
3442 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); | 3442 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); |
3443 | 3443 | ||
3444 | /* Bspec says we need to always set all mask bits. */ | 3444 | /* Bspec says we need to always set all mask bits. */ |
3445 | I915_WRITE(_3D_CHICKEN, (0xFFFF << 16) | | 3445 | I915_WRITE(_3D_CHICKEN3, (0xFFFF << 16) | |
3446 | _3D_CHICKEN_SF_DISABLE_FASTCLIP_CULL); | 3446 | _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL); |
3447 | 3447 | ||
3448 | /* | 3448 | /* |
3449 | * According to the spec the following bits should be | 3449 | * According to the spec the following bits should be |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 0007a4d9bf6e..79d308da29ff 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -139,6 +139,11 @@ struct intel_sdvo { | |||
139 | 139 | ||
140 | /* DDC bus used by this SDVO encoder */ | 140 | /* DDC bus used by this SDVO encoder */ |
141 | uint8_t ddc_bus; | 141 | uint8_t ddc_bus; |
142 | |||
143 | /* | ||
144 | * the sdvo flag gets lost in round trip: dtd->adjusted_mode->dtd | ||
145 | */ | ||
146 | uint8_t dtd_sdvo_flags; | ||
142 | }; | 147 | }; |
143 | 148 | ||
144 | struct intel_sdvo_connector { | 149 | struct intel_sdvo_connector { |
@@ -889,6 +894,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) | |||
889 | } | 894 | } |
890 | #endif | 895 | #endif |
891 | 896 | ||
897 | static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, | ||
898 | unsigned if_index, uint8_t tx_rate, | ||
899 | uint8_t *data, unsigned length) | ||
900 | { | ||
901 | uint8_t set_buf_index[2] = { if_index, 0 }; | ||
902 | uint8_t hbuf_size, tmp[8]; | ||
903 | int i; | ||
904 | |||
905 | if (!intel_sdvo_set_value(intel_sdvo, | ||
906 | SDVO_CMD_SET_HBUF_INDEX, | ||
907 | set_buf_index, 2)) | ||
908 | return false; | ||
909 | |||
910 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO, | ||
911 | &hbuf_size, 1)) | ||
912 | return false; | ||
913 | |||
914 | /* Buffer size is 0 based, hooray! */ | ||
915 | hbuf_size++; | ||
916 | |||
917 | DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n", | ||
918 | if_index, length, hbuf_size); | ||
919 | |||
920 | for (i = 0; i < hbuf_size; i += 8) { | ||
921 | memset(tmp, 0, 8); | ||
922 | if (i < length) | ||
923 | memcpy(tmp, data + i, min_t(unsigned, 8, length - i)); | ||
924 | |||
925 | if (!intel_sdvo_set_value(intel_sdvo, | ||
926 | SDVO_CMD_SET_HBUF_DATA, | ||
927 | tmp, 8)) | ||
928 | return false; | ||
929 | } | ||
930 | |||
931 | return intel_sdvo_set_value(intel_sdvo, | ||
932 | SDVO_CMD_SET_HBUF_TXRATE, | ||
933 | &tx_rate, 1); | ||
934 | } | ||
935 | |||
892 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) | 936 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) |
893 | { | 937 | { |
894 | struct dip_infoframe avi_if = { | 938 | struct dip_infoframe avi_if = { |
@@ -896,11 +940,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) | |||
896 | .ver = DIP_VERSION_AVI, | 940 | .ver = DIP_VERSION_AVI, |
897 | .len = DIP_LEN_AVI, | 941 | .len = DIP_LEN_AVI, |
898 | }; | 942 | }; |
899 | uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; | ||
900 | uint8_t set_buf_index[2] = { 1, 0 }; | ||
901 | uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; | 943 | uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; |
902 | uint64_t *data = (uint64_t *)sdvo_data; | ||
903 | unsigned i; | ||
904 | 944 | ||
905 | intel_dip_infoframe_csum(&avi_if); | 945 | intel_dip_infoframe_csum(&avi_if); |
906 | 946 | ||
@@ -910,22 +950,9 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) | |||
910 | sdvo_data[3] = avi_if.checksum; | 950 | sdvo_data[3] = avi_if.checksum; |
911 | memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); | 951 | memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); |
912 | 952 | ||
913 | if (!intel_sdvo_set_value(intel_sdvo, | 953 | return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, |
914 | SDVO_CMD_SET_HBUF_INDEX, | 954 | SDVO_HBUF_TX_VSYNC, |
915 | set_buf_index, 2)) | 955 | sdvo_data, sizeof(sdvo_data)); |
916 | return false; | ||
917 | |||
918 | for (i = 0; i < sizeof(sdvo_data); i += 8) { | ||
919 | if (!intel_sdvo_set_value(intel_sdvo, | ||
920 | SDVO_CMD_SET_HBUF_DATA, | ||
921 | data, 8)) | ||
922 | return false; | ||
923 | data++; | ||
924 | } | ||
925 | |||
926 | return intel_sdvo_set_value(intel_sdvo, | ||
927 | SDVO_CMD_SET_HBUF_TXRATE, | ||
928 | &tx_rate, 1); | ||
929 | } | 956 | } |
930 | 957 | ||
931 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) | 958 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) |
@@ -984,6 +1011,7 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, | |||
984 | return false; | 1011 | return false; |
985 | 1012 | ||
986 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | 1013 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
1014 | intel_sdvo->dtd_sdvo_flags = input_dtd.part2.sdvo_flags; | ||
987 | 1015 | ||
988 | return true; | 1016 | return true; |
989 | } | 1017 | } |
@@ -1092,6 +1120,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1092 | * adjusted_mode. | 1120 | * adjusted_mode. |
1093 | */ | 1121 | */ |
1094 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1122 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1123 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) | ||
1124 | input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags; | ||
1095 | if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) | 1125 | if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) |
1096 | DRM_INFO("Setting input timings on %s failed\n", | 1126 | DRM_INFO("Setting input timings on %s failed\n", |
1097 | SDVO_NAME(intel_sdvo)); | 1127 | SDVO_NAME(intel_sdvo)); |
@@ -2277,10 +2307,8 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) | |||
2277 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; | 2307 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; |
2278 | } | 2308 | } |
2279 | 2309 | ||
2280 | /* SDVO LVDS is cloneable because the SDVO encoder does the upscaling, | 2310 | /* SDVO LVDS is not cloneable because the input mode gets adjusted by the encoder */ |
2281 | * as opposed to native LVDS, where we upscale with the panel-fitter | 2311 | intel_sdvo->base.cloneable = false; |
2282 | * (and hence only the native LVDS resolution could be cloned). */ | ||
2283 | intel_sdvo->base.cloneable = true; | ||
2284 | 2312 | ||
2285 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); | 2313 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2286 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) | 2314 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index 9d030142ee43..770bdd6ecd9f 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h | |||
@@ -708,6 +708,8 @@ struct intel_sdvo_enhancements_arg { | |||
708 | #define SDVO_CMD_SET_AUDIO_STAT 0x91 | 708 | #define SDVO_CMD_SET_AUDIO_STAT 0x91 |
709 | #define SDVO_CMD_GET_AUDIO_STAT 0x92 | 709 | #define SDVO_CMD_GET_AUDIO_STAT 0x92 |
710 | #define SDVO_CMD_SET_HBUF_INDEX 0x93 | 710 | #define SDVO_CMD_SET_HBUF_INDEX 0x93 |
711 | #define SDVO_HBUF_INDEX_ELD 0 | ||
712 | #define SDVO_HBUF_INDEX_AVI_IF 1 | ||
711 | #define SDVO_CMD_GET_HBUF_INDEX 0x94 | 713 | #define SDVO_CMD_GET_HBUF_INDEX 0x94 |
712 | #define SDVO_CMD_GET_HBUF_INFO 0x95 | 714 | #define SDVO_CMD_GET_HBUF_INFO 0x95 |
713 | #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 | 715 | #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 |
diff --git a/drivers/gpu/drm/nouveau/core/core/gpuobj.c b/drivers/gpu/drm/nouveau/core/core/gpuobj.c index 1f34549aff18..70586fde69cf 100644 --- a/drivers/gpu/drm/nouveau/core/core/gpuobj.c +++ b/drivers/gpu/drm/nouveau/core/core/gpuobj.c | |||
@@ -39,6 +39,11 @@ nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj) | |||
39 | nv_wo32(gpuobj, i, 0x00000000); | 39 | nv_wo32(gpuobj, i, 0x00000000); |
40 | } | 40 | } |
41 | 41 | ||
42 | if (gpuobj->node) { | ||
43 | nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap, | ||
44 | &gpuobj->node); | ||
45 | } | ||
46 | |||
42 | if (gpuobj->heap.block_size) | 47 | if (gpuobj->heap.block_size) |
43 | nouveau_mm_fini(&gpuobj->heap); | 48 | nouveau_mm_fini(&gpuobj->heap); |
44 | 49 | ||
diff --git a/drivers/gpu/drm/nouveau/core/core/mm.c b/drivers/gpu/drm/nouveau/core/core/mm.c index bfddf87926dd..a6d3cd6490f7 100644 --- a/drivers/gpu/drm/nouveau/core/core/mm.c +++ b/drivers/gpu/drm/nouveau/core/core/mm.c | |||
@@ -218,13 +218,16 @@ nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block) | |||
218 | node = kzalloc(sizeof(*node), GFP_KERNEL); | 218 | node = kzalloc(sizeof(*node), GFP_KERNEL); |
219 | if (!node) | 219 | if (!node) |
220 | return -ENOMEM; | 220 | return -ENOMEM; |
221 | node->offset = roundup(offset, mm->block_size); | 221 | |
222 | node->length = rounddown(offset + length, mm->block_size) - node->offset; | 222 | if (length) { |
223 | node->offset = roundup(offset, mm->block_size); | ||
224 | node->length = rounddown(offset + length, mm->block_size); | ||
225 | node->length -= node->offset; | ||
226 | } | ||
223 | 227 | ||
224 | list_add_tail(&node->nl_entry, &mm->nodes); | 228 | list_add_tail(&node->nl_entry, &mm->nodes); |
225 | list_add_tail(&node->fl_entry, &mm->free); | 229 | list_add_tail(&node->fl_entry, &mm->free); |
226 | mm->heap_nodes++; | 230 | mm->heap_nodes++; |
227 | mm->heap_size += length; | ||
228 | return 0; | 231 | return 0; |
229 | } | 232 | } |
230 | 233 | ||
@@ -236,7 +239,7 @@ nouveau_mm_fini(struct nouveau_mm *mm) | |||
236 | int nodes = 0; | 239 | int nodes = 0; |
237 | 240 | ||
238 | list_for_each_entry(node, &mm->nodes, nl_entry) { | 241 | list_for_each_entry(node, &mm->nodes, nl_entry) { |
239 | if (nodes++ == mm->heap_nodes) | 242 | if (WARN_ON(nodes++ == mm->heap_nodes)) |
240 | return -EBUSY; | 243 | return -EBUSY; |
241 | } | 244 | } |
242 | 245 | ||
diff --git a/drivers/gpu/drm/nouveau/core/include/core/mm.h b/drivers/gpu/drm/nouveau/core/include/core/mm.h index 9ee9bf4028ca..975137ba34a6 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/mm.h +++ b/drivers/gpu/drm/nouveau/core/include/core/mm.h | |||
@@ -19,7 +19,6 @@ struct nouveau_mm { | |||
19 | 19 | ||
20 | u32 block_size; | 20 | u32 block_size; |
21 | int heap_nodes; | 21 | int heap_nodes; |
22 | u32 heap_size; | ||
23 | }; | 22 | }; |
24 | 23 | ||
25 | int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block); | 24 | int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block); |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c index dcb5c2befc92..70ca7d5a1aa1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c | |||
@@ -72,7 +72,7 @@ nouveau_bios_shadow_of(struct nouveau_bios *bios) | |||
72 | } | 72 | } |
73 | 73 | ||
74 | data = of_get_property(dn, "NVDA,BMP", &size); | 74 | data = of_get_property(dn, "NVDA,BMP", &size); |
75 | if (data) { | 75 | if (data && size) { |
76 | bios->size = size; | 76 | bios->size = size; |
77 | bios->data = kmalloc(bios->size, GFP_KERNEL); | 77 | bios->data = kmalloc(bios->size, GFP_KERNEL); |
78 | if (bios->data) | 78 | if (bios->data) |
@@ -104,6 +104,9 @@ nouveau_bios_shadow_pramin(struct nouveau_bios *bios) | |||
104 | goto out; | 104 | goto out; |
105 | 105 | ||
106 | bios->size = nv_rd08(bios, 0x700002) * 512; | 106 | bios->size = nv_rd08(bios, 0x700002) * 512; |
107 | if (!bios->size) | ||
108 | goto out; | ||
109 | |||
107 | bios->data = kmalloc(bios->size, GFP_KERNEL); | 110 | bios->data = kmalloc(bios->size, GFP_KERNEL); |
108 | if (bios->data) { | 111 | if (bios->data) { |
109 | for (i = 0; i < bios->size; i++) | 112 | for (i = 0; i < bios->size; i++) |
@@ -155,6 +158,9 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) | |||
155 | 158 | ||
156 | /* read entire bios image to system memory */ | 159 | /* read entire bios image to system memory */ |
157 | bios->size = nv_rd08(bios, 0x300002) * 512; | 160 | bios->size = nv_rd08(bios, 0x300002) * 512; |
161 | if (!bios->size) | ||
162 | goto out; | ||
163 | |||
158 | bios->data = kmalloc(bios->size, GFP_KERNEL); | 164 | bios->data = kmalloc(bios->size, GFP_KERNEL); |
159 | if (bios->data) { | 165 | if (bios->data) { |
160 | for (i = 0; i < bios->size; i++) | 166 | for (i = 0; i < bios->size; i++) |
@@ -186,14 +192,22 @@ nouveau_bios_shadow_acpi(struct nouveau_bios *bios) | |||
186 | { | 192 | { |
187 | struct pci_dev *pdev = nv_device(bios)->pdev; | 193 | struct pci_dev *pdev = nv_device(bios)->pdev; |
188 | int ret, cnt, i; | 194 | int ret, cnt, i; |
189 | u8 data[3]; | ||
190 | 195 | ||
191 | if (!nouveau_acpi_rom_supported(pdev)) | 196 | if (!nouveau_acpi_rom_supported(pdev)) { |
197 | bios->data = NULL; | ||
192 | return; | 198 | return; |
199 | } | ||
193 | 200 | ||
194 | bios->size = 0; | 201 | bios->size = 0; |
195 | if (nouveau_acpi_get_bios_chunk(data, 0, 3) == 3) | 202 | bios->data = kmalloc(4096, GFP_KERNEL); |
196 | bios->size = data[2] * 512; | 203 | if (bios->data) { |
204 | if (nouveau_acpi_get_bios_chunk(bios->data, 0, 4096) == 4096) | ||
205 | bios->size = bios->data[2] * 512; | ||
206 | kfree(bios->data); | ||
207 | } | ||
208 | |||
209 | if (!bios->size) | ||
210 | return; | ||
197 | 211 | ||
198 | bios->data = kmalloc(bios->size, GFP_KERNEL); | 212 | bios->data = kmalloc(bios->size, GFP_KERNEL); |
199 | for (i = 0; bios->data && i < bios->size; i += cnt) { | 213 | for (i = 0; bios->data && i < bios->size; i += cnt) { |
@@ -229,12 +243,14 @@ nouveau_bios_shadow_pci(struct nouveau_bios *bios) | |||
229 | static int | 243 | static int |
230 | nouveau_bios_score(struct nouveau_bios *bios, const bool writeable) | 244 | nouveau_bios_score(struct nouveau_bios *bios, const bool writeable) |
231 | { | 245 | { |
232 | if (!bios->data || bios->data[0] != 0x55 || bios->data[1] != 0xAA) { | 246 | if (bios->size < 3 || !bios->data || bios->data[0] != 0x55 || |
247 | bios->data[1] != 0xAA) { | ||
233 | nv_info(bios, "... signature not found\n"); | 248 | nv_info(bios, "... signature not found\n"); |
234 | return 0; | 249 | return 0; |
235 | } | 250 | } |
236 | 251 | ||
237 | if (nvbios_checksum(bios->data, bios->data[2] * 512)) { | 252 | if (nvbios_checksum(bios->data, |
253 | min_t(u32, bios->data[2] * 512, bios->size))) { | ||
238 | nv_info(bios, "... checksum invalid\n"); | 254 | nv_info(bios, "... checksum invalid\n"); |
239 | /* if a ro image is somewhat bad, it's probably all rubbish */ | 255 | /* if a ro image is somewhat bad, it's probably all rubbish */ |
240 | return writeable ? 2 : 1; | 256 | return writeable ? 2 : 1; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c index 9ed6e728a94c..7d750382a833 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c | |||
@@ -43,7 +43,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) | |||
43 | *ver = nv_ro08(bios, dcb); | 43 | *ver = nv_ro08(bios, dcb); |
44 | 44 | ||
45 | if (*ver >= 0x41) { | 45 | if (*ver >= 0x41) { |
46 | nv_warn(bios, "DCB *ver 0x%02x unknown\n", *ver); | 46 | nv_warn(bios, "DCB version 0x%02x unknown\n", *ver); |
47 | return 0x0000; | 47 | return 0x0000; |
48 | } else | 48 | } else |
49 | if (*ver >= 0x30) { | 49 | if (*ver >= 0x30) { |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c index 5e5f4cddae3c..f835501203e5 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c | |||
@@ -157,11 +157,10 @@ pll_map_reg(struct nouveau_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len) | |||
157 | while (map->reg) { | 157 | while (map->reg) { |
158 | if (map->reg == reg && *ver >= 0x20) { | 158 | if (map->reg == reg && *ver >= 0x20) { |
159 | u16 addr = (data += hdr); | 159 | u16 addr = (data += hdr); |
160 | *type = map->type; | ||
160 | while (cnt--) { | 161 | while (cnt--) { |
161 | if (nv_ro32(bios, data) == map->reg) { | 162 | if (nv_ro32(bios, data) == map->reg) |
162 | *type = map->type; | ||
163 | return data; | 163 | return data; |
164 | } | ||
165 | data += *len; | 164 | data += *len; |
166 | } | 165 | } |
167 | return addr; | 166 | return addr; |
@@ -200,11 +199,10 @@ pll_map_type(struct nouveau_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len) | |||
200 | while (map->reg) { | 199 | while (map->reg) { |
201 | if (map->type == type && *ver >= 0x20) { | 200 | if (map->type == type && *ver >= 0x20) { |
202 | u16 addr = (data += hdr); | 201 | u16 addr = (data += hdr); |
202 | *reg = map->reg; | ||
203 | while (cnt--) { | 203 | while (cnt--) { |
204 | if (nv_ro32(bios, data) == map->reg) { | 204 | if (nv_ro32(bios, data) == map->reg) |
205 | *reg = map->reg; | ||
206 | return data; | 205 | return data; |
207 | } | ||
208 | data += *len; | 206 | data += *len; |
209 | } | 207 | } |
210 | return addr; | 208 | return addr; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c index 436e9efe7ef5..5f570806143a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c | |||
@@ -219,13 +219,11 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
219 | ((priv->base.ram.size & 0x000000ff) << 32); | 219 | ((priv->base.ram.size & 0x000000ff) << 32); |
220 | 220 | ||
221 | tags = nv_rd32(priv, 0x100320); | 221 | tags = nv_rd32(priv, 0x100320); |
222 | if (tags) { | 222 | ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1); |
223 | ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1); | 223 | if (ret) |
224 | if (ret) | 224 | return ret; |
225 | return ret; | ||
226 | 225 | ||
227 | nv_debug(priv, "%d compression tags\n", tags); | 226 | nv_debug(priv, "%d compression tags\n", tags); |
228 | } | ||
229 | 227 | ||
230 | size = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail; | 228 | size = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail; |
231 | switch (device->chipset) { | 229 | switch (device->chipset) { |
@@ -237,6 +235,7 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
237 | return ret; | 235 | return ret; |
238 | 236 | ||
239 | priv->base.ram.stolen = (u64)nv_rd32(priv, 0x100e10) << 12; | 237 | priv->base.ram.stolen = (u64)nv_rd32(priv, 0x100e10) << 12; |
238 | priv->base.ram.type = NV_MEM_TYPE_STOLEN; | ||
240 | break; | 239 | break; |
241 | default: | 240 | default: |
242 | ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size, | 241 | ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size, |
@@ -277,7 +276,6 @@ nv50_fb_dtor(struct nouveau_object *object) | |||
277 | __free_page(priv->r100c08_page); | 276 | __free_page(priv->r100c08_page); |
278 | } | 277 | } |
279 | 278 | ||
280 | nouveau_mm_fini(&priv->base.vram); | ||
281 | nouveau_fb_destroy(&priv->base); | 279 | nouveau_fb_destroy(&priv->base); |
282 | } | 280 | } |
283 | 281 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c index 3d2c88310f98..dbfc2abf0cfe 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c | |||
@@ -292,7 +292,7 @@ nouveau_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
292 | case DCB_I2C_NVIO_BIT: | 292 | case DCB_I2C_NVIO_BIT: |
293 | port->drive = info.drive & 0x0f; | 293 | port->drive = info.drive & 0x0f; |
294 | if (device->card_type < NV_D0) { | 294 | if (device->card_type < NV_D0) { |
295 | if (info.drive >= ARRAY_SIZE(nv50_i2c_port)) | 295 | if (port->drive >= ARRAY_SIZE(nv50_i2c_port)) |
296 | break; | 296 | break; |
297 | port->drive = nv50_i2c_port[port->drive]; | 297 | port->drive = nv50_i2c_port[port->drive]; |
298 | port->sense = port->drive; | 298 | port->sense = port->drive; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c index b29237970fa0..523178685180 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c | |||
@@ -134,7 +134,7 @@ nouveau_therm_fan_sense(struct nouveau_therm *therm) | |||
134 | end = ptimer->read(ptimer); | 134 | end = ptimer->read(ptimer); |
135 | 135 | ||
136 | if (cycles == 5) { | 136 | if (cycles == 5) { |
137 | tach = (u64)60000000000; | 137 | tach = (u64)60000000000ULL; |
138 | do_div(tach, (end - start)); | 138 | do_div(tach, (end - start)); |
139 | return tach; | 139 | return tach; |
140 | } else | 140 | } else |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c index 0203e1e12caa..49050d991e75 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c | |||
@@ -92,7 +92,8 @@ nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
92 | struct nv04_vmmgr_priv *priv; | 92 | struct nv04_vmmgr_priv *priv; |
93 | int ret; | 93 | int ret; |
94 | 94 | ||
95 | if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { | 95 | if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) || |
96 | !nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { | ||
96 | return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass, | 97 | return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass, |
97 | data, size, pobject); | 98 | data, size, pobject); |
98 | } | 99 | } |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c index 0ac18d05a146..aa8131436e3d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c | |||
@@ -163,7 +163,8 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
163 | struct nv04_vmmgr_priv *priv; | 163 | struct nv04_vmmgr_priv *priv; |
164 | int ret; | 164 | int ret; |
165 | 165 | ||
166 | if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { | 166 | if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) || |
167 | !nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { | ||
167 | return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass, | 168 | return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass, |
168 | data, size, pobject); | 169 | data, size, pobject); |
169 | } | 170 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 259e5f1adf47..35ac57f0aab6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -456,6 +456,7 @@ static struct ttm_tt * | |||
456 | nouveau_ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size, | 456 | nouveau_ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size, |
457 | uint32_t page_flags, struct page *dummy_read) | 457 | uint32_t page_flags, struct page *dummy_read) |
458 | { | 458 | { |
459 | #if __OS_HAS_AGP | ||
459 | struct nouveau_drm *drm = nouveau_bdev(bdev); | 460 | struct nouveau_drm *drm = nouveau_bdev(bdev); |
460 | struct drm_device *dev = drm->dev; | 461 | struct drm_device *dev = drm->dev; |
461 | 462 | ||
@@ -463,6 +464,7 @@ nouveau_ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size, | |||
463 | return ttm_agp_tt_create(bdev, dev->agp->bridge, size, | 464 | return ttm_agp_tt_create(bdev, dev->agp->bridge, size, |
464 | page_flags, dummy_read); | 465 | page_flags, dummy_read); |
465 | } | 466 | } |
467 | #endif | ||
466 | 468 | ||
467 | return nouveau_sgdma_create_ttm(bdev, size, page_flags, dummy_read); | 469 | return nouveau_sgdma_create_ttm(bdev, size, page_flags, dummy_read); |
468 | } | 470 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 8f98e5a8c488..86124b131f4f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -290,6 +290,7 @@ nouveau_display_create(struct drm_device *dev) | |||
290 | struct nouveau_drm *drm = nouveau_drm(dev); | 290 | struct nouveau_drm *drm = nouveau_drm(dev); |
291 | struct nouveau_disp *pdisp = nouveau_disp(drm->device); | 291 | struct nouveau_disp *pdisp = nouveau_disp(drm->device); |
292 | struct nouveau_display *disp; | 292 | struct nouveau_display *disp; |
293 | u32 pclass = dev->pdev->class >> 8; | ||
293 | int ret, gen; | 294 | int ret, gen; |
294 | 295 | ||
295 | disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL); | 296 | disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL); |
@@ -360,23 +361,27 @@ nouveau_display_create(struct drm_device *dev) | |||
360 | drm_kms_helper_poll_init(dev); | 361 | drm_kms_helper_poll_init(dev); |
361 | drm_kms_helper_poll_disable(dev); | 362 | drm_kms_helper_poll_disable(dev); |
362 | 363 | ||
363 | if (nv_device(drm->device)->card_type < NV_50) | 364 | if (nouveau_modeset == 1 || |
364 | ret = nv04_display_create(dev); | 365 | (nouveau_modeset < 0 && pclass == PCI_CLASS_DISPLAY_VGA)) { |
365 | else | 366 | if (nv_device(drm->device)->card_type < NV_50) |
366 | if (nv_device(drm->device)->card_type < NV_D0) | 367 | ret = nv04_display_create(dev); |
367 | ret = nv50_display_create(dev); | 368 | else |
368 | else | 369 | if (nv_device(drm->device)->card_type < NV_D0) |
369 | ret = nvd0_display_create(dev); | 370 | ret = nv50_display_create(dev); |
370 | if (ret) | 371 | else |
371 | goto disp_create_err; | 372 | ret = nvd0_display_create(dev); |
372 | |||
373 | if (dev->mode_config.num_crtc) { | ||
374 | ret = drm_vblank_init(dev, dev->mode_config.num_crtc); | ||
375 | if (ret) | 373 | if (ret) |
376 | goto vblank_err; | 374 | goto disp_create_err; |
375 | |||
376 | if (dev->mode_config.num_crtc) { | ||
377 | ret = drm_vblank_init(dev, dev->mode_config.num_crtc); | ||
378 | if (ret) | ||
379 | goto vblank_err; | ||
380 | } | ||
381 | |||
382 | nouveau_backlight_init(dev); | ||
377 | } | 383 | } |
378 | 384 | ||
379 | nouveau_backlight_init(dev); | ||
380 | return 0; | 385 | return 0; |
381 | 386 | ||
382 | vblank_err: | 387 | vblank_err: |
@@ -395,7 +400,8 @@ nouveau_display_destroy(struct drm_device *dev) | |||
395 | nouveau_backlight_exit(dev); | 400 | nouveau_backlight_exit(dev); |
396 | drm_vblank_cleanup(dev); | 401 | drm_vblank_cleanup(dev); |
397 | 402 | ||
398 | disp->dtor(dev); | 403 | if (disp->dtor) |
404 | disp->dtor(dev); | ||
399 | 405 | ||
400 | drm_kms_helper_poll_fini(dev); | 406 | drm_kms_helper_poll_fini(dev); |
401 | drm_mode_config_cleanup(dev); | 407 | drm_mode_config_cleanup(dev); |
@@ -530,9 +536,11 @@ nouveau_page_flip_reserve(struct nouveau_bo *old_bo, | |||
530 | if (ret) | 536 | if (ret) |
531 | goto fail; | 537 | goto fail; |
532 | 538 | ||
533 | ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0); | 539 | if (likely(old_bo != new_bo)) { |
534 | if (ret) | 540 | ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0); |
535 | goto fail_unreserve; | 541 | if (ret) |
542 | goto fail_unreserve; | ||
543 | } | ||
536 | 544 | ||
537 | return 0; | 545 | return 0; |
538 | 546 | ||
@@ -551,8 +559,10 @@ nouveau_page_flip_unreserve(struct nouveau_bo *old_bo, | |||
551 | nouveau_bo_fence(new_bo, fence); | 559 | nouveau_bo_fence(new_bo, fence); |
552 | ttm_bo_unreserve(&new_bo->bo); | 560 | ttm_bo_unreserve(&new_bo->bo); |
553 | 561 | ||
554 | nouveau_bo_fence(old_bo, fence); | 562 | if (likely(old_bo != new_bo)) { |
555 | ttm_bo_unreserve(&old_bo->bo); | 563 | nouveau_bo_fence(old_bo, fence); |
564 | ttm_bo_unreserve(&old_bo->bo); | ||
565 | } | ||
556 | 566 | ||
557 | nouveau_bo_unpin(old_bo); | 567 | nouveau_bo_unpin(old_bo); |
558 | } | 568 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index ccae8c26ae2b..0910125cbbc3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -63,8 +63,9 @@ MODULE_PARM_DESC(noaccel, "disable kernel/abi16 acceleration"); | |||
63 | static int nouveau_noaccel = 0; | 63 | static int nouveau_noaccel = 0; |
64 | module_param_named(noaccel, nouveau_noaccel, int, 0400); | 64 | module_param_named(noaccel, nouveau_noaccel, int, 0400); |
65 | 65 | ||
66 | MODULE_PARM_DESC(modeset, "enable driver"); | 66 | MODULE_PARM_DESC(modeset, "enable driver (default: auto, " |
67 | static int nouveau_modeset = -1; | 67 | "0 = disabled, 1 = enabled, 2 = headless)"); |
68 | int nouveau_modeset = -1; | ||
68 | module_param_named(modeset, nouveau_modeset, int, 0400); | 69 | module_param_named(modeset, nouveau_modeset, int, 0400); |
69 | 70 | ||
70 | static struct drm_driver driver; | 71 | static struct drm_driver driver; |
@@ -363,7 +364,8 @@ nouveau_drm_unload(struct drm_device *dev) | |||
363 | 364 | ||
364 | nouveau_pm_fini(dev); | 365 | nouveau_pm_fini(dev); |
365 | 366 | ||
366 | nouveau_display_fini(dev); | 367 | if (dev->mode_config.num_crtc) |
368 | nouveau_display_fini(dev); | ||
367 | nouveau_display_destroy(dev); | 369 | nouveau_display_destroy(dev); |
368 | 370 | ||
369 | nouveau_irq_fini(dev); | 371 | nouveau_irq_fini(dev); |
@@ -403,13 +405,15 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state) | |||
403 | pm_state.event == PM_EVENT_PRETHAW) | 405 | pm_state.event == PM_EVENT_PRETHAW) |
404 | return 0; | 406 | return 0; |
405 | 407 | ||
406 | NV_INFO(drm, "suspending fbcon...\n"); | 408 | if (dev->mode_config.num_crtc) { |
407 | nouveau_fbcon_set_suspend(dev, 1); | 409 | NV_INFO(drm, "suspending fbcon...\n"); |
410 | nouveau_fbcon_set_suspend(dev, 1); | ||
408 | 411 | ||
409 | NV_INFO(drm, "suspending display...\n"); | 412 | NV_INFO(drm, "suspending display...\n"); |
410 | ret = nouveau_display_suspend(dev); | 413 | ret = nouveau_display_suspend(dev); |
411 | if (ret) | 414 | if (ret) |
412 | return ret; | 415 | return ret; |
416 | } | ||
413 | 417 | ||
414 | NV_INFO(drm, "evicting buffers...\n"); | 418 | NV_INFO(drm, "evicting buffers...\n"); |
415 | ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM); | 419 | ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM); |
@@ -445,8 +449,10 @@ fail_client: | |||
445 | nouveau_client_init(&cli->base); | 449 | nouveau_client_init(&cli->base); |
446 | } | 450 | } |
447 | 451 | ||
448 | NV_INFO(drm, "resuming display...\n"); | 452 | if (dev->mode_config.num_crtc) { |
449 | nouveau_display_resume(dev); | 453 | NV_INFO(drm, "resuming display...\n"); |
454 | nouveau_display_resume(dev); | ||
455 | } | ||
450 | return ret; | 456 | return ret; |
451 | } | 457 | } |
452 | 458 | ||
@@ -486,8 +492,10 @@ nouveau_drm_resume(struct pci_dev *pdev) | |||
486 | nouveau_irq_postinstall(dev); | 492 | nouveau_irq_postinstall(dev); |
487 | nouveau_pm_resume(dev); | 493 | nouveau_pm_resume(dev); |
488 | 494 | ||
489 | NV_INFO(drm, "resuming display...\n"); | 495 | if (dev->mode_config.num_crtc) { |
490 | nouveau_display_resume(dev); | 496 | NV_INFO(drm, "resuming display...\n"); |
497 | nouveau_display_resume(dev); | ||
498 | } | ||
491 | return 0; | 499 | return 0; |
492 | } | 500 | } |
493 | 501 | ||
@@ -662,9 +670,7 @@ nouveau_drm_init(void) | |||
662 | #ifdef CONFIG_VGA_CONSOLE | 670 | #ifdef CONFIG_VGA_CONSOLE |
663 | if (vgacon_text_force()) | 671 | if (vgacon_text_force()) |
664 | nouveau_modeset = 0; | 672 | nouveau_modeset = 0; |
665 | else | ||
666 | #endif | 673 | #endif |
667 | nouveau_modeset = 1; | ||
668 | } | 674 | } |
669 | 675 | ||
670 | if (!nouveau_modeset) | 676 | if (!nouveau_modeset) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h index 819471217546..a10169927086 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/drivers/gpu/drm/nouveau/nouveau_drm.h | |||
@@ -141,4 +141,6 @@ int nouveau_drm_resume(struct pci_dev *); | |||
141 | nv_info((cli), fmt, ##args); \ | 141 | nv_info((cli), fmt, ##args); \ |
142 | } while (0) | 142 | } while (0) |
143 | 143 | ||
144 | extern int nouveau_modeset; | ||
145 | |||
144 | #endif | 146 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 9ca8afdb5549..1d8cb506a28a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
@@ -61,13 +61,15 @@ nouveau_irq_handler(DRM_IRQ_ARGS) | |||
61 | 61 | ||
62 | nv_subdev(pmc)->intr(nv_subdev(pmc)); | 62 | nv_subdev(pmc)->intr(nv_subdev(pmc)); |
63 | 63 | ||
64 | if (device->card_type >= NV_D0) { | 64 | if (dev->mode_config.num_crtc) { |
65 | if (nv_rd32(device, 0x000100) & 0x04000000) | 65 | if (device->card_type >= NV_D0) { |
66 | nvd0_display_intr(dev); | 66 | if (nv_rd32(device, 0x000100) & 0x04000000) |
67 | } else | 67 | nvd0_display_intr(dev); |
68 | if (device->card_type >= NV_50) { | 68 | } else |
69 | if (nv_rd32(device, 0x000100) & 0x04000000) | 69 | if (device->card_type >= NV_50) { |
70 | nv50_display_intr(dev); | 70 | if (nv_rd32(device, 0x000100) & 0x04000000) |
71 | nv50_display_intr(dev); | ||
72 | } | ||
71 | } | 73 | } |
72 | 74 | ||
73 | return IRQ_HANDLED; | 75 | return IRQ_HANDLED; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index 0bf64c90aa20..5566172774df 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c | |||
@@ -52,7 +52,7 @@ nouveau_pm_perflvl_aux(struct drm_device *dev, struct nouveau_pm_level *perflvl, | |||
52 | { | 52 | { |
53 | struct nouveau_drm *drm = nouveau_drm(dev); | 53 | struct nouveau_drm *drm = nouveau_drm(dev); |
54 | struct nouveau_pm *pm = nouveau_pm(dev); | 54 | struct nouveau_pm *pm = nouveau_pm(dev); |
55 | struct nouveau_therm *therm = nouveau_therm(drm); | 55 | struct nouveau_therm *therm = nouveau_therm(drm->device); |
56 | int ret; | 56 | int ret; |
57 | 57 | ||
58 | /*XXX: not on all boards, we should control based on temperature | 58 | /*XXX: not on all boards, we should control based on temperature |
@@ -64,7 +64,6 @@ nouveau_pm_perflvl_aux(struct drm_device *dev, struct nouveau_pm_level *perflvl, | |||
64 | ret = therm->fan_set(therm, perflvl->fanspeed); | 64 | ret = therm->fan_set(therm, perflvl->fanspeed); |
65 | if (ret && ret != -ENODEV) { | 65 | if (ret && ret != -ENODEV) { |
66 | NV_ERROR(drm, "fanspeed set failed: %d\n", ret); | 66 | NV_ERROR(drm, "fanspeed set failed: %d\n", ret); |
67 | return ret; | ||
68 | } | 67 | } |
69 | } | 68 | } |
70 | 69 | ||
@@ -706,8 +705,7 @@ nouveau_hwmon_init(struct drm_device *dev) | |||
706 | struct device *hwmon_dev; | 705 | struct device *hwmon_dev; |
707 | int ret = 0; | 706 | int ret = 0; |
708 | 707 | ||
709 | if (!therm || !therm->temp_get || !therm->attr_get || | 708 | if (!therm || !therm->temp_get || !therm->attr_get || !therm->attr_set) |
710 | !therm->attr_set || therm->temp_get(therm) < 0) | ||
711 | return -ENODEV; | 709 | return -ENODEV; |
712 | 710 | ||
713 | hwmon_dev = hwmon_device_register(&dev->pdev->dev); | 711 | hwmon_dev = hwmon_device_register(&dev->pdev->dev); |
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index 347a3bd78d04..64f7020fb605 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c | |||
@@ -220,7 +220,7 @@ out: | |||
220 | NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); | 220 | NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); |
221 | 221 | ||
222 | if (blue == 0x18) { | 222 | if (blue == 0x18) { |
223 | NV_INFO(drm, "Load detected on head A\n"); | 223 | NV_DEBUG(drm, "Load detected on head A\n"); |
224 | return connector_status_connected; | 224 | return connector_status_connected; |
225 | } | 225 | } |
226 | 226 | ||
@@ -338,8 +338,8 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | |||
338 | 338 | ||
339 | if (nv17_dac_sample_load(encoder) & | 339 | if (nv17_dac_sample_load(encoder) & |
340 | NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { | 340 | NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { |
341 | NV_INFO(drm, "Load detected on output %c\n", | 341 | NV_DEBUG(drm, "Load detected on output %c\n", |
342 | '@' + ffs(dcb->or)); | 342 | '@' + ffs(dcb->or)); |
343 | return connector_status_connected; | 343 | return connector_status_connected; |
344 | } else { | 344 | } else { |
345 | return connector_status_disconnected; | 345 | return connector_status_disconnected; |
@@ -413,9 +413,9 @@ static void nv04_dac_commit(struct drm_encoder *encoder) | |||
413 | 413 | ||
414 | helper->dpms(encoder, DRM_MODE_DPMS_ON); | 414 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
415 | 415 | ||
416 | NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", | 416 | NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", |
417 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), | 417 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), |
418 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | 418 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); |
419 | } | 419 | } |
420 | 420 | ||
421 | void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable) | 421 | void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable) |
@@ -461,8 +461,8 @@ static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) | |||
461 | return; | 461 | return; |
462 | nv_encoder->last_dpms = mode; | 462 | nv_encoder->last_dpms = mode; |
463 | 463 | ||
464 | NV_INFO(drm, "Setting dpms mode %d on vga encoder (output %d)\n", | 464 | NV_DEBUG(drm, "Setting dpms mode %d on vga encoder (output %d)\n", |
465 | mode, nv_encoder->dcb->index); | 465 | mode, nv_encoder->dcb->index); |
466 | 466 | ||
467 | nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); | 467 | nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); |
468 | } | 468 | } |
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index da55d7642c8c..184cdf806761 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
@@ -476,9 +476,9 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
476 | 476 | ||
477 | helper->dpms(encoder, DRM_MODE_DPMS_ON); | 477 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
478 | 478 | ||
479 | NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", | 479 | NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", |
480 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), | 480 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), |
481 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | 481 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); |
482 | } | 482 | } |
483 | 483 | ||
484 | static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) | 484 | static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) |
@@ -520,8 +520,8 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
520 | return; | 520 | return; |
521 | nv_encoder->last_dpms = mode; | 521 | nv_encoder->last_dpms = mode; |
522 | 522 | ||
523 | NV_INFO(drm, "Setting dpms mode %d on lvds encoder (output %d)\n", | 523 | NV_DEBUG(drm, "Setting dpms mode %d on lvds encoder (output %d)\n", |
524 | mode, nv_encoder->dcb->index); | 524 | mode, nv_encoder->dcb->index); |
525 | 525 | ||
526 | if (was_powersaving && is_powersaving_dpms(mode)) | 526 | if (was_powersaving && is_powersaving_dpms(mode)) |
527 | return; | 527 | return; |
@@ -565,8 +565,8 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) | |||
565 | return; | 565 | return; |
566 | nv_encoder->last_dpms = mode; | 566 | nv_encoder->last_dpms = mode; |
567 | 567 | ||
568 | NV_INFO(drm, "Setting dpms mode %d on tmds encoder (output %d)\n", | 568 | NV_DEBUG(drm, "Setting dpms mode %d on tmds encoder (output %d)\n", |
569 | mode, nv_encoder->dcb->index); | 569 | mode, nv_encoder->dcb->index); |
570 | 570 | ||
571 | nv04_dfp_update_backlight(encoder, mode); | 571 | nv04_dfp_update_backlight(encoder, mode); |
572 | nv04_dfp_update_fp_control(encoder, mode); | 572 | nv04_dfp_update_fp_control(encoder, mode); |
diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c index 099fbeda6e2e..62e826a139b3 100644 --- a/drivers/gpu/drm/nouveau/nv04_tv.c +++ b/drivers/gpu/drm/nouveau/nv04_tv.c | |||
@@ -75,8 +75,8 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int mode) | |||
75 | struct nv04_mode_state *state = &nv04_display(dev)->mode_reg; | 75 | struct nv04_mode_state *state = &nv04_display(dev)->mode_reg; |
76 | uint8_t crtc1A; | 76 | uint8_t crtc1A; |
77 | 77 | ||
78 | NV_INFO(drm, "Setting dpms mode %d on TV encoder (output %d)\n", | 78 | NV_DEBUG(drm, "Setting dpms mode %d on TV encoder (output %d)\n", |
79 | mode, nv_encoder->dcb->index); | 79 | mode, nv_encoder->dcb->index); |
80 | 80 | ||
81 | state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK); | 81 | state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK); |
82 | 82 | ||
@@ -167,9 +167,8 @@ static void nv04_tv_commit(struct drm_encoder *encoder) | |||
167 | 167 | ||
168 | helper->dpms(encoder, DRM_MODE_DPMS_ON); | 168 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
169 | 169 | ||
170 | NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", | 170 | NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", |
171 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, | 171 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); |
172 | '@' + ffs(nv_encoder->dcb->or)); | ||
173 | } | 172 | } |
174 | 173 | ||
175 | static void nv04_tv_destroy(struct drm_encoder *encoder) | 174 | static void nv04_tv_destroy(struct drm_encoder *encoder) |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 96184d02c8d9..2e566e123e9e 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -1690,10 +1690,10 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1690 | } | 1690 | } |
1691 | /* all other cases */ | 1691 | /* all other cases */ |
1692 | pll_in_use = radeon_get_pll_use_mask(crtc); | 1692 | pll_in_use = radeon_get_pll_use_mask(crtc); |
1693 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | ||
1694 | return ATOM_PPLL2; | ||
1695 | if (!(pll_in_use & (1 << ATOM_PPLL1))) | 1693 | if (!(pll_in_use & (1 << ATOM_PPLL1))) |
1696 | return ATOM_PPLL1; | 1694 | return ATOM_PPLL1; |
1695 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | ||
1696 | return ATOM_PPLL2; | ||
1697 | DRM_ERROR("unable to allocate a PPLL\n"); | 1697 | DRM_ERROR("unable to allocate a PPLL\n"); |
1698 | return ATOM_PPLL_INVALID; | 1698 | return ATOM_PPLL_INVALID; |
1699 | } else { | 1699 | } else { |
@@ -1715,10 +1715,10 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1715 | } | 1715 | } |
1716 | /* all other cases */ | 1716 | /* all other cases */ |
1717 | pll_in_use = radeon_get_pll_use_mask(crtc); | 1717 | pll_in_use = radeon_get_pll_use_mask(crtc); |
1718 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | ||
1719 | return ATOM_PPLL2; | ||
1720 | if (!(pll_in_use & (1 << ATOM_PPLL1))) | 1718 | if (!(pll_in_use & (1 << ATOM_PPLL1))) |
1721 | return ATOM_PPLL1; | 1719 | return ATOM_PPLL1; |
1720 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | ||
1721 | return ATOM_PPLL2; | ||
1722 | DRM_ERROR("unable to allocate a PPLL\n"); | 1722 | DRM_ERROR("unable to allocate a PPLL\n"); |
1723 | return ATOM_PPLL_INVALID; | 1723 | return ATOM_PPLL_INVALID; |
1724 | } else { | 1724 | } else { |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 49cbb3795a10..ba498f8e47a2 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -184,6 +184,7 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder, | |||
184 | struct radeon_backlight_privdata *pdata; | 184 | struct radeon_backlight_privdata *pdata; |
185 | struct radeon_encoder_atom_dig *dig; | 185 | struct radeon_encoder_atom_dig *dig; |
186 | u8 backlight_level; | 186 | u8 backlight_level; |
187 | char bl_name[16]; | ||
187 | 188 | ||
188 | if (!radeon_encoder->enc_priv) | 189 | if (!radeon_encoder->enc_priv) |
189 | return; | 190 | return; |
@@ -203,7 +204,9 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder, | |||
203 | memset(&props, 0, sizeof(props)); | 204 | memset(&props, 0, sizeof(props)); |
204 | props.max_brightness = RADEON_MAX_BL_LEVEL; | 205 | props.max_brightness = RADEON_MAX_BL_LEVEL; |
205 | props.type = BACKLIGHT_RAW; | 206 | props.type = BACKLIGHT_RAW; |
206 | bd = backlight_device_register("radeon_bl", &drm_connector->kdev, | 207 | snprintf(bl_name, sizeof(bl_name), |
208 | "radeon_bl%d", dev->primary->index); | ||
209 | bd = backlight_device_register(bl_name, &drm_connector->kdev, | ||
207 | pdata, &radeon_atom_backlight_ops, &props); | 210 | pdata, &radeon_atom_backlight_ops, &props); |
208 | if (IS_ERR(bd)) { | 211 | if (IS_ERR(bd)) { |
209 | DRM_ERROR("Backlight registration failed\n"); | 212 | DRM_ERROR("Backlight registration failed\n"); |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index a1f49c5fd74b..14313ad43b76 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -3431,9 +3431,14 @@ void evergreen_pcie_gen2_enable(struct radeon_device *rdev) | |||
3431 | if (!(mask & DRM_PCIE_SPEED_50)) | 3431 | if (!(mask & DRM_PCIE_SPEED_50)) |
3432 | return; | 3432 | return; |
3433 | 3433 | ||
3434 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3435 | if (speed_cntl & LC_CURRENT_DATA_RATE) { | ||
3436 | DRM_INFO("PCIE gen 2 link speeds already enabled\n"); | ||
3437 | return; | ||
3438 | } | ||
3439 | |||
3434 | DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); | 3440 | DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); |
3435 | 3441 | ||
3436 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3437 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) || | 3442 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) || |
3438 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | 3443 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { |
3439 | 3444 | ||
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 573ed1bc6cf7..95e6318b6268 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -264,7 +264,7 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, | |||
264 | /* macro tile width & height */ | 264 | /* macro tile width & height */ |
265 | palign = (8 * surf->bankw * track->npipes) * surf->mtilea; | 265 | palign = (8 * surf->bankw * track->npipes) * surf->mtilea; |
266 | halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; | 266 | halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; |
267 | mtileb = (palign / 8) * (halign / 8) * tileb;; | 267 | mtileb = (palign / 8) * (halign / 8) * tileb; |
268 | mtile_pr = surf->nbx / palign; | 268 | mtile_pr = surf->nbx / palign; |
269 | mtile_ps = (mtile_pr * surf->nby) / halign; | 269 | mtile_ps = (mtile_pr * surf->nby) / halign; |
270 | surf->layer_size = mtile_ps * mtileb * slice_pt; | 270 | surf->layer_size = mtile_ps * mtileb * slice_pt; |
@@ -2829,6 +2829,7 @@ static bool evergreen_vm_reg_valid(u32 reg) | |||
2829 | case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS: | 2829 | case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS: |
2830 | return true; | 2830 | return true; |
2831 | default: | 2831 | default: |
2832 | DRM_ERROR("Invalid register 0x%x in CS\n", reg); | ||
2832 | return false; | 2833 | return false; |
2833 | } | 2834 | } |
2834 | } | 2835 | } |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 8bcb554ea0c5..81e6a568c29d 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -770,9 +770,13 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev) | |||
770 | WREG32(0x15DC, 0); | 770 | WREG32(0x15DC, 0); |
771 | 771 | ||
772 | /* empty context1-7 */ | 772 | /* empty context1-7 */ |
773 | /* Assign the pt base to something valid for now; the pts used for | ||
774 | * the VMs are determined by the application and setup and assigned | ||
775 | * on the fly in the vm part of radeon_gart.c | ||
776 | */ | ||
773 | for (i = 1; i < 8; i++) { | 777 | for (i = 1; i < 8; i++) { |
774 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0); | 778 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0); |
775 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), 0); | 779 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn); |
776 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), | 780 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), |
777 | rdev->gart.table_addr >> 12); | 781 | rdev->gart.table_addr >> 12); |
778 | } | 782 | } |
@@ -1534,26 +1538,31 @@ void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe, | |||
1534 | { | 1538 | { |
1535 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; | 1539 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; |
1536 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); | 1540 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); |
1537 | int i; | ||
1538 | 1541 | ||
1539 | radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, 1 + count * 2)); | 1542 | while (count) { |
1540 | radeon_ring_write(ring, pe); | 1543 | unsigned ndw = 1 + count * 2; |
1541 | radeon_ring_write(ring, upper_32_bits(pe) & 0xff); | 1544 | if (ndw > 0x3FFF) |
1542 | for (i = 0; i < count; ++i) { | 1545 | ndw = 0x3FFF; |
1543 | uint64_t value = 0; | 1546 | |
1544 | if (flags & RADEON_VM_PAGE_SYSTEM) { | 1547 | radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, ndw)); |
1545 | value = radeon_vm_map_gart(rdev, addr); | 1548 | radeon_ring_write(ring, pe); |
1546 | value &= 0xFFFFFFFFFFFFF000ULL; | 1549 | radeon_ring_write(ring, upper_32_bits(pe) & 0xff); |
1547 | addr += incr; | 1550 | for (; ndw > 1; ndw -= 2, --count, pe += 8) { |
1548 | 1551 | uint64_t value = 0; | |
1549 | } else if (flags & RADEON_VM_PAGE_VALID) { | 1552 | if (flags & RADEON_VM_PAGE_SYSTEM) { |
1550 | value = addr; | 1553 | value = radeon_vm_map_gart(rdev, addr); |
1551 | addr += incr; | 1554 | value &= 0xFFFFFFFFFFFFF000ULL; |
1552 | } | 1555 | addr += incr; |
1556 | |||
1557 | } else if (flags & RADEON_VM_PAGE_VALID) { | ||
1558 | value = addr; | ||
1559 | addr += incr; | ||
1560 | } | ||
1553 | 1561 | ||
1554 | value |= r600_flags; | 1562 | value |= r600_flags; |
1555 | radeon_ring_write(ring, value); | 1563 | radeon_ring_write(ring, value); |
1556 | radeon_ring_write(ring, upper_32_bits(value)); | 1564 | radeon_ring_write(ring, upper_32_bits(value)); |
1565 | } | ||
1557 | } | 1566 | } |
1558 | } | 1567 | } |
1559 | 1568 | ||
@@ -1572,12 +1581,6 @@ void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
1572 | if (vm == NULL) | 1581 | if (vm == NULL) |
1573 | return; | 1582 | return; |
1574 | 1583 | ||
1575 | radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (vm->id << 2), 0)); | ||
1576 | radeon_ring_write(ring, 0); | ||
1577 | |||
1578 | radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (vm->id << 2), 0)); | ||
1579 | radeon_ring_write(ring, vm->last_pfn); | ||
1580 | |||
1581 | radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0)); | 1584 | radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0)); |
1582 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); | 1585 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); |
1583 | 1586 | ||
@@ -1588,4 +1591,8 @@ void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
1588 | /* bits 0-7 are the VM contexts0-7 */ | 1591 | /* bits 0-7 are the VM contexts0-7 */ |
1589 | radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); | 1592 | radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); |
1590 | radeon_ring_write(ring, 1 << vm->id); | 1593 | radeon_ring_write(ring, 1 << vm->id); |
1594 | |||
1595 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ | ||
1596 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | ||
1597 | radeon_ring_write(ring, 0x0); | ||
1591 | } | 1598 | } |
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index 2423d1b5d385..cbef6815907a 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h | |||
@@ -502,6 +502,7 @@ | |||
502 | #define PACKET3_MPEG_INDEX 0x3A | 502 | #define PACKET3_MPEG_INDEX 0x3A |
503 | #define PACKET3_WAIT_REG_MEM 0x3C | 503 | #define PACKET3_WAIT_REG_MEM 0x3C |
504 | #define PACKET3_MEM_WRITE 0x3D | 504 | #define PACKET3_MEM_WRITE 0x3D |
505 | #define PACKET3_PFP_SYNC_ME 0x42 | ||
505 | #define PACKET3_SURFACE_SYNC 0x43 | 506 | #define PACKET3_SURFACE_SYNC 0x43 |
506 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) | 507 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) |
507 | # define PACKET3_CB1_DEST_BASE_ENA (1 << 7) | 508 | # define PACKET3_CB1_DEST_BASE_ENA (1 << 7) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 70c800ff6190..cda280d157da 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -3703,6 +3703,12 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) | |||
3703 | if (!(mask & DRM_PCIE_SPEED_50)) | 3703 | if (!(mask & DRM_PCIE_SPEED_50)) |
3704 | return; | 3704 | return; |
3705 | 3705 | ||
3706 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3707 | if (speed_cntl & LC_CURRENT_DATA_RATE) { | ||
3708 | DRM_INFO("PCIE gen 2 link speeds already enabled\n"); | ||
3709 | return; | ||
3710 | } | ||
3711 | |||
3706 | DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); | 3712 | DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); |
3707 | 3713 | ||
3708 | /* 55 nm r6xx asics */ | 3714 | /* 55 nm r6xx asics */ |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b04c06444d8b..8c42d54c2e26 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -663,9 +663,14 @@ struct radeon_vm { | |||
663 | struct list_head list; | 663 | struct list_head list; |
664 | struct list_head va; | 664 | struct list_head va; |
665 | unsigned id; | 665 | unsigned id; |
666 | unsigned last_pfn; | 666 | |
667 | u64 pd_gpu_addr; | 667 | /* contains the page directory */ |
668 | struct radeon_sa_bo *sa_bo; | 668 | struct radeon_sa_bo *page_directory; |
669 | uint64_t pd_gpu_addr; | ||
670 | |||
671 | /* array of page tables, one for each page directory entry */ | ||
672 | struct radeon_sa_bo **page_tables; | ||
673 | |||
669 | struct mutex mutex; | 674 | struct mutex mutex; |
670 | /* last fence for cs using this vm */ | 675 | /* last fence for cs using this vm */ |
671 | struct radeon_fence *fence; | 676 | struct radeon_fence *fence; |
@@ -1843,9 +1848,10 @@ extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size | |||
1843 | */ | 1848 | */ |
1844 | int radeon_vm_manager_init(struct radeon_device *rdev); | 1849 | int radeon_vm_manager_init(struct radeon_device *rdev); |
1845 | void radeon_vm_manager_fini(struct radeon_device *rdev); | 1850 | void radeon_vm_manager_fini(struct radeon_device *rdev); |
1846 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); | 1851 | void radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); |
1847 | void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); | 1852 | void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); |
1848 | int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm); | 1853 | int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm); |
1854 | void radeon_vm_add_to_lru(struct radeon_device *rdev, struct radeon_vm *vm); | ||
1849 | struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, | 1855 | struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, |
1850 | struct radeon_vm *vm, int ring); | 1856 | struct radeon_vm *vm, int ring); |
1851 | void radeon_vm_fence(struct radeon_device *rdev, | 1857 | void radeon_vm_fence(struct radeon_device *rdev, |
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c index b0a5688c67f8..196d28d99570 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.c +++ b/drivers/gpu/drm/radeon/radeon_acpi.c | |||
@@ -201,7 +201,7 @@ static int radeon_atif_verify_interface(acpi_handle handle, | |||
201 | 201 | ||
202 | size = *(u16 *) info->buffer.pointer; | 202 | size = *(u16 *) info->buffer.pointer; |
203 | if (size < 12) { | 203 | if (size < 12) { |
204 | DRM_INFO("ATIF buffer is too small: %lu\n", size); | 204 | DRM_INFO("ATIF buffer is too small: %zu\n", size); |
205 | err = -EINVAL; | 205 | err = -EINVAL; |
206 | goto out; | 206 | goto out; |
207 | } | 207 | } |
@@ -370,6 +370,7 @@ int radeon_atif_handler(struct radeon_device *rdev, | |||
370 | 370 | ||
371 | radeon_set_backlight_level(rdev, enc, req.backlight_level); | 371 | radeon_set_backlight_level(rdev, enc, req.backlight_level); |
372 | 372 | ||
373 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) | ||
373 | if (rdev->is_atom_bios) { | 374 | if (rdev->is_atom_bios) { |
374 | struct radeon_encoder_atom_dig *dig = enc->enc_priv; | 375 | struct radeon_encoder_atom_dig *dig = enc->enc_priv; |
375 | backlight_force_update(dig->bl_dev, | 376 | backlight_force_update(dig->bl_dev, |
@@ -379,6 +380,7 @@ int radeon_atif_handler(struct radeon_device *rdev, | |||
379 | backlight_force_update(dig->bl_dev, | 380 | backlight_force_update(dig->bl_dev, |
380 | BACKLIGHT_UPDATE_HOTKEY); | 381 | BACKLIGHT_UPDATE_HOTKEY); |
381 | } | 382 | } |
383 | #endif | ||
382 | } | 384 | } |
383 | } | 385 | } |
384 | /* TODO: check other events */ | 386 | /* TODO: check other events */ |
@@ -485,7 +487,7 @@ static int radeon_atcs_verify_interface(acpi_handle handle, | |||
485 | 487 | ||
486 | size = *(u16 *) info->buffer.pointer; | 488 | size = *(u16 *) info->buffer.pointer; |
487 | if (size < 8) { | 489 | if (size < 8) { |
488 | DRM_INFO("ATCS buffer is too small: %lu\n", size); | 490 | DRM_INFO("ATCS buffer is too small: %zu\n", size); |
489 | err = -EINVAL; | 491 | err = -EINVAL; |
490 | goto out; | 492 | goto out; |
491 | } | 493 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 582e99449c12..15f5ded65e0c 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -87,7 +87,7 @@ static union acpi_object *radeon_atpx_call(acpi_handle handle, int function, | |||
87 | atpx_arg_elements[1].integer.value = 0; | 87 | atpx_arg_elements[1].integer.value = 0; |
88 | } | 88 | } |
89 | 89 | ||
90 | status = acpi_evaluate_object(handle, "ATPX", &atpx_arg, &buffer); | 90 | status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer); |
91 | 91 | ||
92 | /* Fail only if calling the method fails and ATPX is supported */ | 92 | /* Fail only if calling the method fails and ATPX is supported */ |
93 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 93 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
@@ -148,7 +148,7 @@ static int radeon_atpx_verify_interface(struct radeon_atpx *atpx) | |||
148 | 148 | ||
149 | size = *(u16 *) info->buffer.pointer; | 149 | size = *(u16 *) info->buffer.pointer; |
150 | if (size < 8) { | 150 | if (size < 8) { |
151 | printk("ATPX buffer is too small: %lu\n", size); | 151 | printk("ATPX buffer is too small: %zu\n", size); |
152 | err = -EINVAL; | 152 | err = -EINVAL; |
153 | goto out; | 153 | goto out; |
154 | } | 154 | } |
@@ -352,9 +352,9 @@ static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) | |||
352 | } | 352 | } |
353 | 353 | ||
354 | /** | 354 | /** |
355 | * radeon_atpx_switchto - switch to the requested GPU | 355 | * radeon_atpx_power_state - power down/up the requested GPU |
356 | * | 356 | * |
357 | * @id: GPU to switch to | 357 | * @id: GPU to power down/up |
358 | * @state: requested power state (0 = off, 1 = on) | 358 | * @state: requested power state (0 = off, 1 = on) |
359 | * | 359 | * |
360 | * Execute the necessary ATPX function to power down/up the discrete GPU | 360 | * Execute the necessary ATPX function to power down/up the discrete GPU |
@@ -373,11 +373,11 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, | |||
373 | } | 373 | } |
374 | 374 | ||
375 | /** | 375 | /** |
376 | * radeon_atpx_pci_probe_handle - look up the ATRM and ATPX handles | 376 | * radeon_atpx_pci_probe_handle - look up the ATPX handle |
377 | * | 377 | * |
378 | * @pdev: pci device | 378 | * @pdev: pci device |
379 | * | 379 | * |
380 | * Look up the ATPX and ATRM handles (all asics). | 380 | * Look up the ATPX handles (all asics). |
381 | * Returns true if the handles are found, false if not. | 381 | * Returns true if the handles are found, false if not. |
382 | */ | 382 | */ |
383 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | 383 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 67cfc1795ecd..b884c362a8c2 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -941,7 +941,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
941 | struct drm_mode_object *obj; | 941 | struct drm_mode_object *obj; |
942 | int i; | 942 | int i; |
943 | enum drm_connector_status ret = connector_status_disconnected; | 943 | enum drm_connector_status ret = connector_status_disconnected; |
944 | bool dret = false; | 944 | bool dret = false, broken_edid = false; |
945 | 945 | ||
946 | if (!force && radeon_check_hpd_status_unchanged(connector)) | 946 | if (!force && radeon_check_hpd_status_unchanged(connector)) |
947 | return connector->status; | 947 | return connector->status; |
@@ -965,6 +965,9 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
965 | ret = connector_status_disconnected; | 965 | ret = connector_status_disconnected; |
966 | DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); | 966 | DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); |
967 | radeon_connector->ddc_bus = NULL; | 967 | radeon_connector->ddc_bus = NULL; |
968 | } else { | ||
969 | ret = connector_status_connected; | ||
970 | broken_edid = true; /* defer use_digital to later */ | ||
968 | } | 971 | } |
969 | } else { | 972 | } else { |
970 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); | 973 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
@@ -1047,13 +1050,24 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
1047 | 1050 | ||
1048 | encoder_funcs = encoder->helper_private; | 1051 | encoder_funcs = encoder->helper_private; |
1049 | if (encoder_funcs->detect) { | 1052 | if (encoder_funcs->detect) { |
1050 | if (ret != connector_status_connected) { | 1053 | if (!broken_edid) { |
1051 | ret = encoder_funcs->detect(encoder, connector); | 1054 | if (ret != connector_status_connected) { |
1052 | if (ret == connector_status_connected) { | 1055 | /* deal with analog monitors without DDC */ |
1053 | radeon_connector->use_digital = false; | 1056 | ret = encoder_funcs->detect(encoder, connector); |
1057 | if (ret == connector_status_connected) { | ||
1058 | radeon_connector->use_digital = false; | ||
1059 | } | ||
1060 | if (ret != connector_status_disconnected) | ||
1061 | radeon_connector->detected_by_load = true; | ||
1054 | } | 1062 | } |
1055 | if (ret != connector_status_disconnected) | 1063 | } else { |
1056 | radeon_connector->detected_by_load = true; | 1064 | enum drm_connector_status lret; |
1065 | /* assume digital unless load detected otherwise */ | ||
1066 | radeon_connector->use_digital = true; | ||
1067 | lret = encoder_funcs->detect(encoder, connector); | ||
1068 | DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret); | ||
1069 | if (lret == connector_status_connected) | ||
1070 | radeon_connector->use_digital = false; | ||
1057 | } | 1071 | } |
1058 | break; | 1072 | break; |
1059 | } | 1073 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index cb7b7c062fef..41672cc563fb 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -478,6 +478,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
478 | } | 478 | } |
479 | 479 | ||
480 | out: | 480 | out: |
481 | radeon_vm_add_to_lru(rdev, vm); | ||
481 | mutex_unlock(&vm->mutex); | 482 | mutex_unlock(&vm->mutex); |
482 | mutex_unlock(&rdev->vm_manager.lock); | 483 | mutex_unlock(&rdev->vm_manager.lock); |
483 | return r; | 484 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 64a42647f08a..e2f5f888c374 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -355,6 +355,8 @@ int radeon_wb_init(struct radeon_device *rdev) | |||
355 | */ | 355 | */ |
356 | void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base) | 356 | void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base) |
357 | { | 357 | { |
358 | uint64_t limit = (uint64_t)radeon_vram_limit << 20; | ||
359 | |||
358 | mc->vram_start = base; | 360 | mc->vram_start = base; |
359 | if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) { | 361 | if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) { |
360 | dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); | 362 | dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); |
@@ -368,8 +370,8 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 | |||
368 | mc->mc_vram_size = mc->aper_size; | 370 | mc->mc_vram_size = mc->aper_size; |
369 | } | 371 | } |
370 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | 372 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
371 | if (radeon_vram_limit && radeon_vram_limit < mc->real_vram_size) | 373 | if (limit && limit < mc->real_vram_size) |
372 | mc->real_vram_size = radeon_vram_limit; | 374 | mc->real_vram_size = limit; |
373 | dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", | 375 | dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", |
374 | mc->mc_vram_size >> 20, mc->vram_start, | 376 | mc->mc_vram_size >> 20, mc->vram_start, |
375 | mc->vram_end, mc->real_vram_size >> 20); | 377 | mc->vram_end, mc->real_vram_size >> 20); |
@@ -835,6 +837,19 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state) | |||
835 | } | 837 | } |
836 | 838 | ||
837 | /** | 839 | /** |
840 | * radeon_check_pot_argument - check that argument is a power of two | ||
841 | * | ||
842 | * @arg: value to check | ||
843 | * | ||
844 | * Validates that a certain argument is a power of two (all asics). | ||
845 | * Returns true if argument is valid. | ||
846 | */ | ||
847 | static bool radeon_check_pot_argument(int arg) | ||
848 | { | ||
849 | return (arg & (arg - 1)) == 0; | ||
850 | } | ||
851 | |||
852 | /** | ||
838 | * radeon_check_arguments - validate module params | 853 | * radeon_check_arguments - validate module params |
839 | * | 854 | * |
840 | * @rdev: radeon_device pointer | 855 | * @rdev: radeon_device pointer |
@@ -845,52 +860,25 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state) | |||
845 | static void radeon_check_arguments(struct radeon_device *rdev) | 860 | static void radeon_check_arguments(struct radeon_device *rdev) |
846 | { | 861 | { |
847 | /* vramlimit must be a power of two */ | 862 | /* vramlimit must be a power of two */ |
848 | switch (radeon_vram_limit) { | 863 | if (!radeon_check_pot_argument(radeon_vram_limit)) { |
849 | case 0: | ||
850 | case 4: | ||
851 | case 8: | ||
852 | case 16: | ||
853 | case 32: | ||
854 | case 64: | ||
855 | case 128: | ||
856 | case 256: | ||
857 | case 512: | ||
858 | case 1024: | ||
859 | case 2048: | ||
860 | case 4096: | ||
861 | break; | ||
862 | default: | ||
863 | dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n", | 864 | dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n", |
864 | radeon_vram_limit); | 865 | radeon_vram_limit); |
865 | radeon_vram_limit = 0; | 866 | radeon_vram_limit = 0; |
866 | break; | ||
867 | } | 867 | } |
868 | radeon_vram_limit = radeon_vram_limit << 20; | 868 | |
869 | /* gtt size must be power of two and greater or equal to 32M */ | 869 | /* gtt size must be power of two and greater or equal to 32M */ |
870 | switch (radeon_gart_size) { | 870 | if (radeon_gart_size < 32) { |
871 | case 4: | ||
872 | case 8: | ||
873 | case 16: | ||
874 | dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n", | 871 | dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n", |
875 | radeon_gart_size); | 872 | radeon_gart_size); |
876 | radeon_gart_size = 512; | 873 | radeon_gart_size = 512; |
877 | break; | 874 | |
878 | case 32: | 875 | } else if (!radeon_check_pot_argument(radeon_gart_size)) { |
879 | case 64: | ||
880 | case 128: | ||
881 | case 256: | ||
882 | case 512: | ||
883 | case 1024: | ||
884 | case 2048: | ||
885 | case 4096: | ||
886 | break; | ||
887 | default: | ||
888 | dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n", | 876 | dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n", |
889 | radeon_gart_size); | 877 | radeon_gart_size); |
890 | radeon_gart_size = 512; | 878 | radeon_gart_size = 512; |
891 | break; | ||
892 | } | 879 | } |
893 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | 880 | rdev->mc.gtt_size = (uint64_t)radeon_gart_size << 20; |
881 | |||
894 | /* AGP mode can only be -1, 1, 2, 4, 8 */ | 882 | /* AGP mode can only be -1, 1, 2, 4, 8 */ |
895 | switch (radeon_agpmode) { | 883 | switch (radeon_agpmode) { |
896 | case -1: | 884 | case -1: |
@@ -1018,6 +1006,10 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1018 | return r; | 1006 | return r; |
1019 | /* initialize vm here */ | 1007 | /* initialize vm here */ |
1020 | mutex_init(&rdev->vm_manager.lock); | 1008 | mutex_init(&rdev->vm_manager.lock); |
1009 | /* Adjust VM size here. | ||
1010 | * Currently set to 4GB ((1 << 20) 4k pages). | ||
1011 | * Max GPUVM size for cayman and SI is 40 bits. | ||
1012 | */ | ||
1021 | rdev->vm_manager.max_pfn = 1 << 20; | 1013 | rdev->vm_manager.max_pfn = 1 << 20; |
1022 | INIT_LIST_HEAD(&rdev->vm_manager.lru_vm); | 1014 | INIT_LIST_HEAD(&rdev->vm_manager.lru_vm); |
1023 | 1015 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index f0c06d196b75..4debd60e5aa6 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -355,14 +355,13 @@ int radeon_gart_init(struct radeon_device *rdev) | |||
355 | DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", | 355 | DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", |
356 | rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); | 356 | rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); |
357 | /* Allocate pages table */ | 357 | /* Allocate pages table */ |
358 | rdev->gart.pages = kzalloc(sizeof(void *) * rdev->gart.num_cpu_pages, | 358 | rdev->gart.pages = vzalloc(sizeof(void *) * rdev->gart.num_cpu_pages); |
359 | GFP_KERNEL); | ||
360 | if (rdev->gart.pages == NULL) { | 359 | if (rdev->gart.pages == NULL) { |
361 | radeon_gart_fini(rdev); | 360 | radeon_gart_fini(rdev); |
362 | return -ENOMEM; | 361 | return -ENOMEM; |
363 | } | 362 | } |
364 | rdev->gart.pages_addr = kzalloc(sizeof(dma_addr_t) * | 363 | rdev->gart.pages_addr = vzalloc(sizeof(dma_addr_t) * |
365 | rdev->gart.num_cpu_pages, GFP_KERNEL); | 364 | rdev->gart.num_cpu_pages); |
366 | if (rdev->gart.pages_addr == NULL) { | 365 | if (rdev->gart.pages_addr == NULL) { |
367 | radeon_gart_fini(rdev); | 366 | radeon_gart_fini(rdev); |
368 | return -ENOMEM; | 367 | return -ENOMEM; |
@@ -388,8 +387,8 @@ void radeon_gart_fini(struct radeon_device *rdev) | |||
388 | radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); | 387 | radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); |
389 | } | 388 | } |
390 | rdev->gart.ready = false; | 389 | rdev->gart.ready = false; |
391 | kfree(rdev->gart.pages); | 390 | vfree(rdev->gart.pages); |
392 | kfree(rdev->gart.pages_addr); | 391 | vfree(rdev->gart.pages_addr); |
393 | rdev->gart.pages = NULL; | 392 | rdev->gart.pages = NULL; |
394 | rdev->gart.pages_addr = NULL; | 393 | rdev->gart.pages_addr = NULL; |
395 | 394 | ||
@@ -423,6 +422,18 @@ void radeon_gart_fini(struct radeon_device *rdev) | |||
423 | */ | 422 | */ |
424 | 423 | ||
425 | /** | 424 | /** |
425 | * radeon_vm_num_pde - return the number of page directory entries | ||
426 | * | ||
427 | * @rdev: radeon_device pointer | ||
428 | * | ||
429 | * Calculate the number of page directory entries (cayman+). | ||
430 | */ | ||
431 | static unsigned radeon_vm_num_pdes(struct radeon_device *rdev) | ||
432 | { | ||
433 | return rdev->vm_manager.max_pfn >> RADEON_VM_BLOCK_SIZE; | ||
434 | } | ||
435 | |||
436 | /** | ||
426 | * radeon_vm_directory_size - returns the size of the page directory in bytes | 437 | * radeon_vm_directory_size - returns the size of the page directory in bytes |
427 | * | 438 | * |
428 | * @rdev: radeon_device pointer | 439 | * @rdev: radeon_device pointer |
@@ -431,7 +442,7 @@ void radeon_gart_fini(struct radeon_device *rdev) | |||
431 | */ | 442 | */ |
432 | static unsigned radeon_vm_directory_size(struct radeon_device *rdev) | 443 | static unsigned radeon_vm_directory_size(struct radeon_device *rdev) |
433 | { | 444 | { |
434 | return (rdev->vm_manager.max_pfn >> RADEON_VM_BLOCK_SIZE) * 8; | 445 | return RADEON_GPU_PAGE_ALIGN(radeon_vm_num_pdes(rdev) * 8); |
435 | } | 446 | } |
436 | 447 | ||
437 | /** | 448 | /** |
@@ -451,11 +462,11 @@ int radeon_vm_manager_init(struct radeon_device *rdev) | |||
451 | 462 | ||
452 | if (!rdev->vm_manager.enabled) { | 463 | if (!rdev->vm_manager.enabled) { |
453 | /* allocate enough for 2 full VM pts */ | 464 | /* allocate enough for 2 full VM pts */ |
454 | size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev)); | 465 | size = radeon_vm_directory_size(rdev); |
455 | size += RADEON_GPU_PAGE_ALIGN(rdev->vm_manager.max_pfn * 8); | 466 | size += rdev->vm_manager.max_pfn * 8; |
456 | size *= 2; | 467 | size *= 2; |
457 | r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, | 468 | r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, |
458 | size, | 469 | RADEON_GPU_PAGE_ALIGN(size), |
459 | RADEON_GEM_DOMAIN_VRAM); | 470 | RADEON_GEM_DOMAIN_VRAM); |
460 | if (r) { | 471 | if (r) { |
461 | dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", | 472 | dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", |
@@ -476,7 +487,7 @@ int radeon_vm_manager_init(struct radeon_device *rdev) | |||
476 | 487 | ||
477 | /* restore page table */ | 488 | /* restore page table */ |
478 | list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) { | 489 | list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) { |
479 | if (vm->sa_bo == NULL) | 490 | if (vm->page_directory == NULL) |
480 | continue; | 491 | continue; |
481 | 492 | ||
482 | list_for_each_entry(bo_va, &vm->va, vm_list) { | 493 | list_for_each_entry(bo_va, &vm->va, vm_list) { |
@@ -500,16 +511,25 @@ static void radeon_vm_free_pt(struct radeon_device *rdev, | |||
500 | struct radeon_vm *vm) | 511 | struct radeon_vm *vm) |
501 | { | 512 | { |
502 | struct radeon_bo_va *bo_va; | 513 | struct radeon_bo_va *bo_va; |
514 | int i; | ||
503 | 515 | ||
504 | if (!vm->sa_bo) | 516 | if (!vm->page_directory) |
505 | return; | 517 | return; |
506 | 518 | ||
507 | list_del_init(&vm->list); | 519 | list_del_init(&vm->list); |
508 | radeon_sa_bo_free(rdev, &vm->sa_bo, vm->fence); | 520 | radeon_sa_bo_free(rdev, &vm->page_directory, vm->fence); |
509 | 521 | ||
510 | list_for_each_entry(bo_va, &vm->va, vm_list) { | 522 | list_for_each_entry(bo_va, &vm->va, vm_list) { |
511 | bo_va->valid = false; | 523 | bo_va->valid = false; |
512 | } | 524 | } |
525 | |||
526 | if (vm->page_tables == NULL) | ||
527 | return; | ||
528 | |||
529 | for (i = 0; i < radeon_vm_num_pdes(rdev); i++) | ||
530 | radeon_sa_bo_free(rdev, &vm->page_tables[i], vm->fence); | ||
531 | |||
532 | kfree(vm->page_tables); | ||
513 | } | 533 | } |
514 | 534 | ||
515 | /** | 535 | /** |
@@ -546,63 +566,106 @@ void radeon_vm_manager_fini(struct radeon_device *rdev) | |||
546 | } | 566 | } |
547 | 567 | ||
548 | /** | 568 | /** |
569 | * radeon_vm_evict - evict page table to make room for new one | ||
570 | * | ||
571 | * @rdev: radeon_device pointer | ||
572 | * @vm: VM we want to allocate something for | ||
573 | * | ||
574 | * Evict a VM from the lru, making sure that it isn't @vm. (cayman+). | ||
575 | * Returns 0 for success, -ENOMEM for failure. | ||
576 | * | ||
577 | * Global and local mutex must be locked! | ||
578 | */ | ||
579 | static int radeon_vm_evict(struct radeon_device *rdev, struct radeon_vm *vm) | ||
580 | { | ||
581 | struct radeon_vm *vm_evict; | ||
582 | |||
583 | if (list_empty(&rdev->vm_manager.lru_vm)) | ||
584 | return -ENOMEM; | ||
585 | |||
586 | vm_evict = list_first_entry(&rdev->vm_manager.lru_vm, | ||
587 | struct radeon_vm, list); | ||
588 | if (vm_evict == vm) | ||
589 | return -ENOMEM; | ||
590 | |||
591 | mutex_lock(&vm_evict->mutex); | ||
592 | radeon_vm_free_pt(rdev, vm_evict); | ||
593 | mutex_unlock(&vm_evict->mutex); | ||
594 | return 0; | ||
595 | } | ||
596 | |||
597 | /** | ||
549 | * radeon_vm_alloc_pt - allocates a page table for a VM | 598 | * radeon_vm_alloc_pt - allocates a page table for a VM |
550 | * | 599 | * |
551 | * @rdev: radeon_device pointer | 600 | * @rdev: radeon_device pointer |
552 | * @vm: vm to bind | 601 | * @vm: vm to bind |
553 | * | 602 | * |
554 | * Allocate a page table for the requested vm (cayman+). | 603 | * Allocate a page table for the requested vm (cayman+). |
555 | * Also starts to populate the page table. | ||
556 | * Returns 0 for success, error for failure. | 604 | * Returns 0 for success, error for failure. |
557 | * | 605 | * |
558 | * Global and local mutex must be locked! | 606 | * Global and local mutex must be locked! |
559 | */ | 607 | */ |
560 | int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm) | 608 | int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm) |
561 | { | 609 | { |
562 | struct radeon_vm *vm_evict; | 610 | unsigned pd_size, pts_size; |
563 | int r; | ||
564 | u64 *pd_addr; | 611 | u64 *pd_addr; |
565 | int tables_size; | 612 | int r; |
566 | 613 | ||
567 | if (vm == NULL) { | 614 | if (vm == NULL) { |
568 | return -EINVAL; | 615 | return -EINVAL; |
569 | } | 616 | } |
570 | 617 | ||
571 | /* allocate enough to cover the current VM size */ | 618 | if (vm->page_directory != NULL) { |
572 | tables_size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev)); | ||
573 | tables_size += RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8); | ||
574 | |||
575 | if (vm->sa_bo != NULL) { | ||
576 | /* update lru */ | ||
577 | list_del_init(&vm->list); | ||
578 | list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); | ||
579 | return 0; | 619 | return 0; |
580 | } | 620 | } |
581 | 621 | ||
582 | retry: | 622 | retry: |
583 | r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, &vm->sa_bo, | 623 | pd_size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev)); |
584 | tables_size, RADEON_GPU_PAGE_SIZE, false); | 624 | r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, |
625 | &vm->page_directory, pd_size, | ||
626 | RADEON_GPU_PAGE_SIZE, false); | ||
585 | if (r == -ENOMEM) { | 627 | if (r == -ENOMEM) { |
586 | if (list_empty(&rdev->vm_manager.lru_vm)) { | 628 | r = radeon_vm_evict(rdev, vm); |
629 | if (r) | ||
587 | return r; | 630 | return r; |
588 | } | ||
589 | vm_evict = list_first_entry(&rdev->vm_manager.lru_vm, struct radeon_vm, list); | ||
590 | mutex_lock(&vm_evict->mutex); | ||
591 | radeon_vm_free_pt(rdev, vm_evict); | ||
592 | mutex_unlock(&vm_evict->mutex); | ||
593 | goto retry; | 631 | goto retry; |
594 | 632 | ||
595 | } else if (r) { | 633 | } else if (r) { |
596 | return r; | 634 | return r; |
597 | } | 635 | } |
598 | 636 | ||
599 | pd_addr = radeon_sa_bo_cpu_addr(vm->sa_bo); | 637 | vm->pd_gpu_addr = radeon_sa_bo_gpu_addr(vm->page_directory); |
600 | vm->pd_gpu_addr = radeon_sa_bo_gpu_addr(vm->sa_bo); | 638 | |
601 | memset(pd_addr, 0, tables_size); | 639 | /* Initially clear the page directory */ |
640 | pd_addr = radeon_sa_bo_cpu_addr(vm->page_directory); | ||
641 | memset(pd_addr, 0, pd_size); | ||
642 | |||
643 | pts_size = radeon_vm_num_pdes(rdev) * sizeof(struct radeon_sa_bo *); | ||
644 | vm->page_tables = kzalloc(pts_size, GFP_KERNEL); | ||
645 | |||
646 | if (vm->page_tables == NULL) { | ||
647 | DRM_ERROR("Cannot allocate memory for page table array\n"); | ||
648 | radeon_sa_bo_free(rdev, &vm->page_directory, vm->fence); | ||
649 | return -ENOMEM; | ||
650 | } | ||
651 | |||
652 | return 0; | ||
653 | } | ||
602 | 654 | ||
655 | /** | ||
656 | * radeon_vm_add_to_lru - add VMs page table to LRU list | ||
657 | * | ||
658 | * @rdev: radeon_device pointer | ||
659 | * @vm: vm to add to LRU | ||
660 | * | ||
661 | * Add the allocated page table to the LRU list (cayman+). | ||
662 | * | ||
663 | * Global mutex must be locked! | ||
664 | */ | ||
665 | void radeon_vm_add_to_lru(struct radeon_device *rdev, struct radeon_vm *vm) | ||
666 | { | ||
667 | list_del_init(&vm->list); | ||
603 | list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); | 668 | list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); |
604 | return radeon_vm_bo_update_pte(rdev, vm, rdev->ring_tmp_bo.bo, | ||
605 | &rdev->ring_tmp_bo.bo->tbo.mem); | ||
606 | } | 669 | } |
607 | 670 | ||
608 | /** | 671 | /** |
@@ -793,20 +856,6 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
793 | } | 856 | } |
794 | 857 | ||
795 | mutex_lock(&vm->mutex); | 858 | mutex_lock(&vm->mutex); |
796 | if (last_pfn > vm->last_pfn) { | ||
797 | /* release mutex and lock in right order */ | ||
798 | mutex_unlock(&vm->mutex); | ||
799 | mutex_lock(&rdev->vm_manager.lock); | ||
800 | mutex_lock(&vm->mutex); | ||
801 | /* and check again */ | ||
802 | if (last_pfn > vm->last_pfn) { | ||
803 | /* grow va space 32M by 32M */ | ||
804 | unsigned align = ((32 << 20) >> 12) - 1; | ||
805 | radeon_vm_free_pt(rdev, vm); | ||
806 | vm->last_pfn = (last_pfn + align) & ~align; | ||
807 | } | ||
808 | mutex_unlock(&rdev->vm_manager.lock); | ||
809 | } | ||
810 | head = &vm->va; | 859 | head = &vm->va; |
811 | last_offset = 0; | 860 | last_offset = 0; |
812 | list_for_each_entry(tmp, &vm->va, vm_list) { | 861 | list_for_each_entry(tmp, &vm->va, vm_list) { |
@@ -865,6 +914,154 @@ uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr) | |||
865 | } | 914 | } |
866 | 915 | ||
867 | /** | 916 | /** |
917 | * radeon_vm_update_pdes - make sure that page directory is valid | ||
918 | * | ||
919 | * @rdev: radeon_device pointer | ||
920 | * @vm: requested vm | ||
921 | * @start: start of GPU address range | ||
922 | * @end: end of GPU address range | ||
923 | * | ||
924 | * Allocates new page tables if necessary | ||
925 | * and updates the page directory (cayman+). | ||
926 | * Returns 0 for success, error for failure. | ||
927 | * | ||
928 | * Global and local mutex must be locked! | ||
929 | */ | ||
930 | static int radeon_vm_update_pdes(struct radeon_device *rdev, | ||
931 | struct radeon_vm *vm, | ||
932 | uint64_t start, uint64_t end) | ||
933 | { | ||
934 | static const uint32_t incr = RADEON_VM_PTE_COUNT * 8; | ||
935 | |||
936 | uint64_t last_pde = ~0, last_pt = ~0; | ||
937 | unsigned count = 0; | ||
938 | uint64_t pt_idx; | ||
939 | int r; | ||
940 | |||
941 | start = (start / RADEON_GPU_PAGE_SIZE) >> RADEON_VM_BLOCK_SIZE; | ||
942 | end = (end / RADEON_GPU_PAGE_SIZE) >> RADEON_VM_BLOCK_SIZE; | ||
943 | |||
944 | /* walk over the address space and update the page directory */ | ||
945 | for (pt_idx = start; pt_idx <= end; ++pt_idx) { | ||
946 | uint64_t pde, pt; | ||
947 | |||
948 | if (vm->page_tables[pt_idx]) | ||
949 | continue; | ||
950 | |||
951 | retry: | ||
952 | r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, | ||
953 | &vm->page_tables[pt_idx], | ||
954 | RADEON_VM_PTE_COUNT * 8, | ||
955 | RADEON_GPU_PAGE_SIZE, false); | ||
956 | |||
957 | if (r == -ENOMEM) { | ||
958 | r = radeon_vm_evict(rdev, vm); | ||
959 | if (r) | ||
960 | return r; | ||
961 | goto retry; | ||
962 | } else if (r) { | ||
963 | return r; | ||
964 | } | ||
965 | |||
966 | pde = vm->pd_gpu_addr + pt_idx * 8; | ||
967 | |||
968 | pt = radeon_sa_bo_gpu_addr(vm->page_tables[pt_idx]); | ||
969 | |||
970 | if (((last_pde + 8 * count) != pde) || | ||
971 | ((last_pt + incr * count) != pt)) { | ||
972 | |||
973 | if (count) { | ||
974 | radeon_asic_vm_set_page(rdev, last_pde, | ||
975 | last_pt, count, incr, | ||
976 | RADEON_VM_PAGE_VALID); | ||
977 | } | ||
978 | |||
979 | count = 1; | ||
980 | last_pde = pde; | ||
981 | last_pt = pt; | ||
982 | } else { | ||
983 | ++count; | ||
984 | } | ||
985 | } | ||
986 | |||
987 | if (count) { | ||
988 | radeon_asic_vm_set_page(rdev, last_pde, last_pt, count, | ||
989 | incr, RADEON_VM_PAGE_VALID); | ||
990 | |||
991 | } | ||
992 | |||
993 | return 0; | ||
994 | } | ||
995 | |||
996 | /** | ||
997 | * radeon_vm_update_ptes - make sure that page tables are valid | ||
998 | * | ||
999 | * @rdev: radeon_device pointer | ||
1000 | * @vm: requested vm | ||
1001 | * @start: start of GPU address range | ||
1002 | * @end: end of GPU address range | ||
1003 | * @dst: destination address to map to | ||
1004 | * @flags: mapping flags | ||
1005 | * | ||
1006 | * Update the page tables in the range @start - @end (cayman+). | ||
1007 | * | ||
1008 | * Global and local mutex must be locked! | ||
1009 | */ | ||
1010 | static void radeon_vm_update_ptes(struct radeon_device *rdev, | ||
1011 | struct radeon_vm *vm, | ||
1012 | uint64_t start, uint64_t end, | ||
1013 | uint64_t dst, uint32_t flags) | ||
1014 | { | ||
1015 | static const uint64_t mask = RADEON_VM_PTE_COUNT - 1; | ||
1016 | |||
1017 | uint64_t last_pte = ~0, last_dst = ~0; | ||
1018 | unsigned count = 0; | ||
1019 | uint64_t addr; | ||
1020 | |||
1021 | start = start / RADEON_GPU_PAGE_SIZE; | ||
1022 | end = end / RADEON_GPU_PAGE_SIZE; | ||
1023 | |||
1024 | /* walk over the address space and update the page tables */ | ||
1025 | for (addr = start; addr < end; ) { | ||
1026 | uint64_t pt_idx = addr >> RADEON_VM_BLOCK_SIZE; | ||
1027 | unsigned nptes; | ||
1028 | uint64_t pte; | ||
1029 | |||
1030 | if ((addr & ~mask) == (end & ~mask)) | ||
1031 | nptes = end - addr; | ||
1032 | else | ||
1033 | nptes = RADEON_VM_PTE_COUNT - (addr & mask); | ||
1034 | |||
1035 | pte = radeon_sa_bo_gpu_addr(vm->page_tables[pt_idx]); | ||
1036 | pte += (addr & mask) * 8; | ||
1037 | |||
1038 | if ((last_pte + 8 * count) != pte) { | ||
1039 | |||
1040 | if (count) { | ||
1041 | radeon_asic_vm_set_page(rdev, last_pte, | ||
1042 | last_dst, count, | ||
1043 | RADEON_GPU_PAGE_SIZE, | ||
1044 | flags); | ||
1045 | } | ||
1046 | |||
1047 | count = nptes; | ||
1048 | last_pte = pte; | ||
1049 | last_dst = dst; | ||
1050 | } else { | ||
1051 | count += nptes; | ||
1052 | } | ||
1053 | |||
1054 | addr += nptes; | ||
1055 | dst += nptes * RADEON_GPU_PAGE_SIZE; | ||
1056 | } | ||
1057 | |||
1058 | if (count) { | ||
1059 | radeon_asic_vm_set_page(rdev, last_pte, last_dst, count, | ||
1060 | RADEON_GPU_PAGE_SIZE, flags); | ||
1061 | } | ||
1062 | } | ||
1063 | |||
1064 | /** | ||
868 | * radeon_vm_bo_update_pte - map a bo into the vm page table | 1065 | * radeon_vm_bo_update_pte - map a bo into the vm page table |
869 | * | 1066 | * |
870 | * @rdev: radeon_device pointer | 1067 | * @rdev: radeon_device pointer |
@@ -887,12 +1084,11 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
887 | struct radeon_semaphore *sem = NULL; | 1084 | struct radeon_semaphore *sem = NULL; |
888 | struct radeon_bo_va *bo_va; | 1085 | struct radeon_bo_va *bo_va; |
889 | unsigned nptes, npdes, ndw; | 1086 | unsigned nptes, npdes, ndw; |
890 | uint64_t pe, addr; | 1087 | uint64_t addr; |
891 | uint64_t pfn; | ||
892 | int r; | 1088 | int r; |
893 | 1089 | ||
894 | /* nothing to do if vm isn't bound */ | 1090 | /* nothing to do if vm isn't bound */ |
895 | if (vm->sa_bo == NULL) | 1091 | if (vm->page_directory == NULL) |
896 | return 0; | 1092 | return 0; |
897 | 1093 | ||
898 | bo_va = radeon_vm_bo_find(vm, bo); | 1094 | bo_va = radeon_vm_bo_find(vm, bo); |
@@ -939,25 +1135,29 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
939 | } | 1135 | } |
940 | } | 1136 | } |
941 | 1137 | ||
942 | /* estimate number of dw needed */ | ||
943 | /* reserve space for 32-bit padding */ | ||
944 | ndw = 32; | ||
945 | |||
946 | nptes = radeon_bo_ngpu_pages(bo); | 1138 | nptes = radeon_bo_ngpu_pages(bo); |
947 | 1139 | ||
948 | pfn = (bo_va->soffset / RADEON_GPU_PAGE_SIZE); | 1140 | /* assume two extra pdes in case the mapping overlaps the borders */ |
1141 | npdes = (nptes >> RADEON_VM_BLOCK_SIZE) + 2; | ||
949 | 1142 | ||
950 | /* handle cases where a bo spans several pdes */ | 1143 | /* estimate number of dw needed */ |
951 | npdes = (ALIGN(pfn + nptes, RADEON_VM_PTE_COUNT) - | 1144 | /* semaphore, fence and padding */ |
952 | (pfn & ~(RADEON_VM_PTE_COUNT - 1))) >> RADEON_VM_BLOCK_SIZE; | 1145 | ndw = 32; |
1146 | |||
1147 | if (RADEON_VM_BLOCK_SIZE > 11) | ||
1148 | /* reserve space for one header for every 2k dwords */ | ||
1149 | ndw += (nptes >> 11) * 4; | ||
1150 | else | ||
1151 | /* reserve space for one header for | ||
1152 | every (1 << BLOCK_SIZE) entries */ | ||
1153 | ndw += (nptes >> RADEON_VM_BLOCK_SIZE) * 4; | ||
953 | 1154 | ||
954 | /* reserve space for one header for every 2k dwords */ | ||
955 | ndw += (nptes >> 11) * 3; | ||
956 | /* reserve space for pte addresses */ | 1155 | /* reserve space for pte addresses */ |
957 | ndw += nptes * 2; | 1156 | ndw += nptes * 2; |
958 | 1157 | ||
959 | /* reserve space for one header for every 2k dwords */ | 1158 | /* reserve space for one header for every 2k dwords */ |
960 | ndw += (npdes >> 11) * 3; | 1159 | ndw += (npdes >> 11) * 4; |
1160 | |||
961 | /* reserve space for pde addresses */ | 1161 | /* reserve space for pde addresses */ |
962 | ndw += npdes * 2; | 1162 | ndw += npdes * 2; |
963 | 1163 | ||
@@ -971,22 +1171,14 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
971 | radeon_fence_note_sync(vm->fence, ridx); | 1171 | radeon_fence_note_sync(vm->fence, ridx); |
972 | } | 1172 | } |
973 | 1173 | ||
974 | /* update page table entries */ | 1174 | r = radeon_vm_update_pdes(rdev, vm, bo_va->soffset, bo_va->eoffset); |
975 | pe = vm->pd_gpu_addr; | 1175 | if (r) { |
976 | pe += radeon_vm_directory_size(rdev); | 1176 | radeon_ring_unlock_undo(rdev, ring); |
977 | pe += (bo_va->soffset / RADEON_GPU_PAGE_SIZE) * 8; | 1177 | return r; |
978 | 1178 | } | |
979 | radeon_asic_vm_set_page(rdev, pe, addr, nptes, | ||
980 | RADEON_GPU_PAGE_SIZE, bo_va->flags); | ||
981 | |||
982 | /* update page directory entries */ | ||
983 | addr = pe; | ||
984 | |||
985 | pe = vm->pd_gpu_addr; | ||
986 | pe += ((bo_va->soffset / RADEON_GPU_PAGE_SIZE) >> RADEON_VM_BLOCK_SIZE) * 8; | ||
987 | 1179 | ||
988 | radeon_asic_vm_set_page(rdev, pe, addr, npdes, | 1180 | radeon_vm_update_ptes(rdev, vm, bo_va->soffset, bo_va->eoffset, |
989 | RADEON_VM_PTE_COUNT * 8, RADEON_VM_PAGE_VALID); | 1181 | addr, bo_va->flags); |
990 | 1182 | ||
991 | radeon_fence_unref(&vm->fence); | 1183 | radeon_fence_unref(&vm->fence); |
992 | r = radeon_fence_emit(rdev, &vm->fence, ridx); | 1184 | r = radeon_fence_emit(rdev, &vm->fence, ridx); |
@@ -997,6 +1189,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
997 | radeon_ring_unlock_commit(rdev, ring); | 1189 | radeon_ring_unlock_commit(rdev, ring); |
998 | radeon_semaphore_free(rdev, &sem, vm->fence); | 1190 | radeon_semaphore_free(rdev, &sem, vm->fence); |
999 | radeon_fence_unref(&vm->last_flush); | 1191 | radeon_fence_unref(&vm->last_flush); |
1192 | |||
1000 | return 0; | 1193 | return 0; |
1001 | } | 1194 | } |
1002 | 1195 | ||
@@ -1056,31 +1249,15 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev, | |||
1056 | * @rdev: radeon_device pointer | 1249 | * @rdev: radeon_device pointer |
1057 | * @vm: requested vm | 1250 | * @vm: requested vm |
1058 | * | 1251 | * |
1059 | * Init @vm (cayman+). | 1252 | * Init @vm fields (cayman+). |
1060 | * Map the IB pool and any other shared objects into the VM | ||
1061 | * by default as it's used by all VMs. | ||
1062 | * Returns 0 for success, error for failure. | ||
1063 | */ | 1253 | */ |
1064 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | 1254 | void radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) |
1065 | { | 1255 | { |
1066 | struct radeon_bo_va *bo_va; | ||
1067 | int r; | ||
1068 | |||
1069 | vm->id = 0; | 1256 | vm->id = 0; |
1070 | vm->fence = NULL; | 1257 | vm->fence = NULL; |
1071 | vm->last_pfn = 0; | ||
1072 | mutex_init(&vm->mutex); | 1258 | mutex_init(&vm->mutex); |
1073 | INIT_LIST_HEAD(&vm->list); | 1259 | INIT_LIST_HEAD(&vm->list); |
1074 | INIT_LIST_HEAD(&vm->va); | 1260 | INIT_LIST_HEAD(&vm->va); |
1075 | |||
1076 | /* map the ib pool buffer at 0 in virtual address space, set | ||
1077 | * read only | ||
1078 | */ | ||
1079 | bo_va = radeon_vm_bo_add(rdev, vm, rdev->ring_tmp_bo.bo); | ||
1080 | r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET, | ||
1081 | RADEON_VM_PAGE_READABLE | | ||
1082 | RADEON_VM_PAGE_SNOOPED); | ||
1083 | return r; | ||
1084 | } | 1261 | } |
1085 | 1262 | ||
1086 | /** | 1263 | /** |
@@ -1102,17 +1279,6 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
1102 | radeon_vm_free_pt(rdev, vm); | 1279 | radeon_vm_free_pt(rdev, vm); |
1103 | mutex_unlock(&rdev->vm_manager.lock); | 1280 | mutex_unlock(&rdev->vm_manager.lock); |
1104 | 1281 | ||
1105 | /* remove all bo at this point non are busy any more because unbind | ||
1106 | * waited for the last vm fence to signal | ||
1107 | */ | ||
1108 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | ||
1109 | if (!r) { | ||
1110 | bo_va = radeon_vm_bo_find(vm, rdev->ring_tmp_bo.bo); | ||
1111 | list_del_init(&bo_va->bo_list); | ||
1112 | list_del_init(&bo_va->vm_list); | ||
1113 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | ||
1114 | kfree(bo_va); | ||
1115 | } | ||
1116 | if (!list_empty(&vm->va)) { | 1282 | if (!list_empty(&vm->va)) { |
1117 | dev_err(rdev->dev, "still active bo inside vm\n"); | 1283 | dev_err(rdev->dev, "still active bo inside vm\n"); |
1118 | } | 1284 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index f38fbcc46935..fe5c1f6b7957 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -53,6 +53,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, | |||
53 | struct drm_gem_object **obj) | 53 | struct drm_gem_object **obj) |
54 | { | 54 | { |
55 | struct radeon_bo *robj; | 55 | struct radeon_bo *robj; |
56 | unsigned long max_size; | ||
56 | int r; | 57 | int r; |
57 | 58 | ||
58 | *obj = NULL; | 59 | *obj = NULL; |
@@ -60,11 +61,26 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, | |||
60 | if (alignment < PAGE_SIZE) { | 61 | if (alignment < PAGE_SIZE) { |
61 | alignment = PAGE_SIZE; | 62 | alignment = PAGE_SIZE; |
62 | } | 63 | } |
64 | |||
65 | /* maximun bo size is the minimun btw visible vram and gtt size */ | ||
66 | max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); | ||
67 | if (size > max_size) { | ||
68 | printk(KERN_WARNING "%s:%d alloc size %dMb bigger than %ldMb limit\n", | ||
69 | __func__, __LINE__, size >> 20, max_size >> 20); | ||
70 | return -ENOMEM; | ||
71 | } | ||
72 | |||
73 | retry: | ||
63 | r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, NULL, &robj); | 74 | r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, NULL, &robj); |
64 | if (r) { | 75 | if (r) { |
65 | if (r != -ERESTARTSYS) | 76 | if (r != -ERESTARTSYS) { |
77 | if (initial_domain == RADEON_GEM_DOMAIN_VRAM) { | ||
78 | initial_domain |= RADEON_GEM_DOMAIN_GTT; | ||
79 | goto retry; | ||
80 | } | ||
66 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", | 81 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", |
67 | size, initial_domain, alignment, r); | 82 | size, initial_domain, alignment, r); |
83 | } | ||
68 | return r; | 84 | return r; |
69 | } | 85 | } |
70 | *obj = &robj->gem_base; | 86 | *obj = &robj->gem_base; |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 83b8d8aa71c0..dc781c49b96b 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -419,6 +419,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
419 | /* new gpu have virtual address space support */ | 419 | /* new gpu have virtual address space support */ |
420 | if (rdev->family >= CHIP_CAYMAN) { | 420 | if (rdev->family >= CHIP_CAYMAN) { |
421 | struct radeon_fpriv *fpriv; | 421 | struct radeon_fpriv *fpriv; |
422 | struct radeon_bo_va *bo_va; | ||
422 | int r; | 423 | int r; |
423 | 424 | ||
424 | fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); | 425 | fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); |
@@ -426,7 +427,15 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
426 | return -ENOMEM; | 427 | return -ENOMEM; |
427 | } | 428 | } |
428 | 429 | ||
429 | r = radeon_vm_init(rdev, &fpriv->vm); | 430 | radeon_vm_init(rdev, &fpriv->vm); |
431 | |||
432 | /* map the ib pool buffer read only into | ||
433 | * virtual address space */ | ||
434 | bo_va = radeon_vm_bo_add(rdev, &fpriv->vm, | ||
435 | rdev->ring_tmp_bo.bo); | ||
436 | r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET, | ||
437 | RADEON_VM_PAGE_READABLE | | ||
438 | RADEON_VM_PAGE_SNOOPED); | ||
430 | if (r) { | 439 | if (r) { |
431 | radeon_vm_fini(rdev, &fpriv->vm); | 440 | radeon_vm_fini(rdev, &fpriv->vm); |
432 | kfree(fpriv); | 441 | kfree(fpriv); |
@@ -454,6 +463,17 @@ void radeon_driver_postclose_kms(struct drm_device *dev, | |||
454 | /* new gpu have virtual address space support */ | 463 | /* new gpu have virtual address space support */ |
455 | if (rdev->family >= CHIP_CAYMAN && file_priv->driver_priv) { | 464 | if (rdev->family >= CHIP_CAYMAN && file_priv->driver_priv) { |
456 | struct radeon_fpriv *fpriv = file_priv->driver_priv; | 465 | struct radeon_fpriv *fpriv = file_priv->driver_priv; |
466 | struct radeon_bo_va *bo_va; | ||
467 | int r; | ||
468 | |||
469 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | ||
470 | if (!r) { | ||
471 | bo_va = radeon_vm_bo_find(&fpriv->vm, | ||
472 | rdev->ring_tmp_bo.bo); | ||
473 | if (bo_va) | ||
474 | radeon_vm_bo_rmv(rdev, bo_va); | ||
475 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | ||
476 | } | ||
457 | 477 | ||
458 | radeon_vm_fini(rdev, &fpriv->vm); | 478 | radeon_vm_fini(rdev, &fpriv->vm); |
459 | kfree(fpriv); | 479 | kfree(fpriv); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 5677a424b585..6857cb4efb76 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -295,6 +295,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
295 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 295 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
296 | struct drm_device *dev = crtc->dev; | 296 | struct drm_device *dev = crtc->dev; |
297 | struct radeon_device *rdev = dev->dev_private; | 297 | struct radeon_device *rdev = dev->dev_private; |
298 | uint32_t crtc_ext_cntl = 0; | ||
298 | uint32_t mask; | 299 | uint32_t mask; |
299 | 300 | ||
300 | if (radeon_crtc->crtc_id) | 301 | if (radeon_crtc->crtc_id) |
@@ -307,6 +308,16 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
307 | RADEON_CRTC_VSYNC_DIS | | 308 | RADEON_CRTC_VSYNC_DIS | |
308 | RADEON_CRTC_HSYNC_DIS); | 309 | RADEON_CRTC_HSYNC_DIS); |
309 | 310 | ||
311 | /* | ||
312 | * On all dual CRTC GPUs this bit controls the CRTC of the primary DAC. | ||
313 | * Therefore it is set in the DAC DMPS function. | ||
314 | * This is different for GPU's with a single CRTC but a primary and a | ||
315 | * TV DAC: here it controls the single CRTC no matter where it is | ||
316 | * routed. Therefore we set it here. | ||
317 | */ | ||
318 | if (rdev->flags & RADEON_SINGLE_CRTC) | ||
319 | crtc_ext_cntl = RADEON_CRTC_CRT_ON; | ||
320 | |||
310 | switch (mode) { | 321 | switch (mode) { |
311 | case DRM_MODE_DPMS_ON: | 322 | case DRM_MODE_DPMS_ON: |
312 | radeon_crtc->enabled = true; | 323 | radeon_crtc->enabled = true; |
@@ -317,7 +328,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
317 | else { | 328 | else { |
318 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | | 329 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | |
319 | RADEON_CRTC_DISP_REQ_EN_B)); | 330 | RADEON_CRTC_DISP_REQ_EN_B)); |
320 | WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); | 331 | WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl)); |
321 | } | 332 | } |
322 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); | 333 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); |
323 | radeon_crtc_load_lut(crtc); | 334 | radeon_crtc_load_lut(crtc); |
@@ -331,7 +342,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
331 | else { | 342 | else { |
332 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | | 343 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | |
333 | RADEON_CRTC_DISP_REQ_EN_B)); | 344 | RADEON_CRTC_DISP_REQ_EN_B)); |
334 | WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask); | 345 | WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~(mask | crtc_ext_cntl)); |
335 | } | 346 | } |
336 | radeon_crtc->enabled = false; | 347 | radeon_crtc->enabled = false; |
337 | /* adjust pm to dpms changes AFTER disabling crtcs */ | 348 | /* adjust pm to dpms changes AFTER disabling crtcs */ |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 92487e614778..f5ba2241dacc 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -269,27 +269,6 @@ static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = { | |||
269 | .disable = radeon_legacy_encoder_disable, | 269 | .disable = radeon_legacy_encoder_disable, |
270 | }; | 270 | }; |
271 | 271 | ||
272 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) | ||
273 | |||
274 | static uint8_t radeon_legacy_lvds_level(struct backlight_device *bd) | ||
275 | { | ||
276 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); | ||
277 | uint8_t level; | ||
278 | |||
279 | /* Convert brightness to hardware level */ | ||
280 | if (bd->props.brightness < 0) | ||
281 | level = 0; | ||
282 | else if (bd->props.brightness > RADEON_MAX_BL_LEVEL) | ||
283 | level = RADEON_MAX_BL_LEVEL; | ||
284 | else | ||
285 | level = bd->props.brightness; | ||
286 | |||
287 | if (pdata->negative) | ||
288 | level = RADEON_MAX_BL_LEVEL - level; | ||
289 | |||
290 | return level; | ||
291 | } | ||
292 | |||
293 | u8 | 272 | u8 |
294 | radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder) | 273 | radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder) |
295 | { | 274 | { |
@@ -331,6 +310,27 @@ radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 leve | |||
331 | radeon_legacy_lvds_update(&radeon_encoder->base, dpms_mode); | 310 | radeon_legacy_lvds_update(&radeon_encoder->base, dpms_mode); |
332 | } | 311 | } |
333 | 312 | ||
313 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) | ||
314 | |||
315 | static uint8_t radeon_legacy_lvds_level(struct backlight_device *bd) | ||
316 | { | ||
317 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); | ||
318 | uint8_t level; | ||
319 | |||
320 | /* Convert brightness to hardware level */ | ||
321 | if (bd->props.brightness < 0) | ||
322 | level = 0; | ||
323 | else if (bd->props.brightness > RADEON_MAX_BL_LEVEL) | ||
324 | level = RADEON_MAX_BL_LEVEL; | ||
325 | else | ||
326 | level = bd->props.brightness; | ||
327 | |||
328 | if (pdata->negative) | ||
329 | level = RADEON_MAX_BL_LEVEL - level; | ||
330 | |||
331 | return level; | ||
332 | } | ||
333 | |||
334 | static int radeon_legacy_backlight_update_status(struct backlight_device *bd) | 334 | static int radeon_legacy_backlight_update_status(struct backlight_device *bd) |
335 | { | 335 | { |
336 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); | 336 | struct radeon_backlight_privdata *pdata = bl_get_data(bd); |
@@ -370,6 +370,7 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, | |||
370 | struct backlight_properties props; | 370 | struct backlight_properties props; |
371 | struct radeon_backlight_privdata *pdata; | 371 | struct radeon_backlight_privdata *pdata; |
372 | uint8_t backlight_level; | 372 | uint8_t backlight_level; |
373 | char bl_name[16]; | ||
373 | 374 | ||
374 | if (!radeon_encoder->enc_priv) | 375 | if (!radeon_encoder->enc_priv) |
375 | return; | 376 | return; |
@@ -389,7 +390,9 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, | |||
389 | memset(&props, 0, sizeof(props)); | 390 | memset(&props, 0, sizeof(props)); |
390 | props.max_brightness = RADEON_MAX_BL_LEVEL; | 391 | props.max_brightness = RADEON_MAX_BL_LEVEL; |
391 | props.type = BACKLIGHT_RAW; | 392 | props.type = BACKLIGHT_RAW; |
392 | bd = backlight_device_register("radeon_bl", &drm_connector->kdev, | 393 | snprintf(bl_name, sizeof(bl_name), |
394 | "radeon_bl%d", dev->primary->index); | ||
395 | bd = backlight_device_register(bl_name, &drm_connector->kdev, | ||
393 | pdata, &radeon_backlight_ops, &props); | 396 | pdata, &radeon_backlight_ops, &props); |
394 | if (IS_ERR(bd)) { | 397 | if (IS_ERR(bd)) { |
395 | DRM_ERROR("Backlight registration failed\n"); | 398 | DRM_ERROR("Backlight registration failed\n"); |
@@ -534,7 +537,9 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode | |||
534 | break; | 537 | break; |
535 | } | 538 | } |
536 | 539 | ||
537 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); | 540 | /* handled in radeon_crtc_dpms() */ |
541 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) | ||
542 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); | ||
538 | WREG32(RADEON_DAC_CNTL, dac_cntl); | 543 | WREG32(RADEON_DAC_CNTL, dac_cntl); |
539 | WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); | 544 | WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); |
540 | 545 | ||
@@ -659,6 +664,8 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc | |||
659 | 664 | ||
660 | if (ASIC_IS_R300(rdev)) | 665 | if (ASIC_IS_R300(rdev)) |
661 | tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); | 666 | tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); |
667 | else if (ASIC_IS_RV100(rdev)) | ||
668 | tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT); | ||
662 | else | 669 | else |
663 | tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); | 670 | tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); |
664 | 671 | ||
@@ -668,6 +675,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc | |||
668 | tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; | 675 | tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; |
669 | WREG32(RADEON_DAC_CNTL, tmp); | 676 | WREG32(RADEON_DAC_CNTL, tmp); |
670 | 677 | ||
678 | tmp = dac_macro_cntl; | ||
671 | tmp &= ~(RADEON_DAC_PDWN_R | | 679 | tmp &= ~(RADEON_DAC_PDWN_R | |
672 | RADEON_DAC_PDWN_G | | 680 | RADEON_DAC_PDWN_G | |
673 | RADEON_DAC_PDWN_B); | 681 | RADEON_DAC_PDWN_B); |
@@ -991,11 +999,7 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, | |||
991 | static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder) | 999 | static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder) |
992 | { | 1000 | { |
993 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1001 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
994 | struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv; | 1002 | /* don't destroy the i2c bus record here, this will be done in radeon_i2c_fini */ |
995 | if (tmds) { | ||
996 | if (tmds->i2c_bus) | ||
997 | radeon_i2c_destroy(tmds->i2c_bus); | ||
998 | } | ||
999 | kfree(radeon_encoder->enc_priv); | 1003 | kfree(radeon_encoder->enc_priv); |
1000 | drm_encoder_cleanup(encoder); | 1004 | drm_encoder_cleanup(encoder); |
1001 | kfree(radeon_encoder); | 1005 | kfree(radeon_encoder); |
@@ -1093,7 +1097,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) | |||
1093 | } else { | 1097 | } else { |
1094 | if (is_tv) | 1098 | if (is_tv) |
1095 | WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); | 1099 | WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); |
1096 | else | 1100 | /* handled in radeon_crtc_dpms() */ |
1101 | else if (!(rdev->flags & RADEON_SINGLE_CRTC)) | ||
1097 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | 1102 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); |
1098 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); | 1103 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
1099 | } | 1104 | } |
@@ -1417,13 +1422,104 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, | |||
1417 | return found; | 1422 | return found; |
1418 | } | 1423 | } |
1419 | 1424 | ||
1425 | static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder, | ||
1426 | struct drm_connector *connector) | ||
1427 | { | ||
1428 | struct drm_device *dev = encoder->dev; | ||
1429 | struct radeon_device *rdev = dev->dev_private; | ||
1430 | uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl; | ||
1431 | uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c; | ||
1432 | uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f; | ||
1433 | uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp; | ||
1434 | uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid; | ||
1435 | bool found = false; | ||
1436 | int i; | ||
1437 | |||
1438 | /* save the regs we need */ | ||
1439 | gpio_monid = RREG32(RADEON_GPIO_MONID); | ||
1440 | fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); | ||
1441 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); | ||
1442 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | ||
1443 | disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A); | ||
1444 | disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B); | ||
1445 | disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C); | ||
1446 | disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D); | ||
1447 | disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E); | ||
1448 | disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F); | ||
1449 | crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP); | ||
1450 | crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP); | ||
1451 | crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID); | ||
1452 | crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID); | ||
1453 | |||
1454 | tmp = RREG32(RADEON_GPIO_MONID); | ||
1455 | tmp &= ~RADEON_GPIO_A_0; | ||
1456 | WREG32(RADEON_GPIO_MONID, tmp); | ||
1457 | |||
1458 | WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON | | ||
1459 | RADEON_FP2_PANEL_FORMAT | | ||
1460 | R200_FP2_SOURCE_SEL_TRANS_UNIT | | ||
1461 | RADEON_FP2_DVO_EN | | ||
1462 | R200_FP2_DVO_RATE_SEL_SDR)); | ||
1463 | |||
1464 | WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX | | ||
1465 | RADEON_DISP_TRANS_MATRIX_GRAPHICS)); | ||
1466 | |||
1467 | WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN | | ||
1468 | RADEON_CRTC2_DISP_REQ_EN_B)); | ||
1469 | |||
1470 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000); | ||
1471 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0); | ||
1472 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000); | ||
1473 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0); | ||
1474 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000); | ||
1475 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0); | ||
1476 | |||
1477 | WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008); | ||
1478 | WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800); | ||
1479 | WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001); | ||
1480 | WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080); | ||
1481 | |||
1482 | for (i = 0; i < 200; i++) { | ||
1483 | tmp = RREG32(RADEON_GPIO_MONID); | ||
1484 | if (tmp & RADEON_GPIO_Y_0) | ||
1485 | found = true; | ||
1486 | |||
1487 | if (found) | ||
1488 | break; | ||
1489 | |||
1490 | if (!drm_can_sleep()) | ||
1491 | mdelay(1); | ||
1492 | else | ||
1493 | msleep(1); | ||
1494 | } | ||
1495 | |||
1496 | /* restore the regs we used */ | ||
1497 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a); | ||
1498 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b); | ||
1499 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c); | ||
1500 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d); | ||
1501 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e); | ||
1502 | WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f); | ||
1503 | WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp); | ||
1504 | WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp); | ||
1505 | WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid); | ||
1506 | WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid); | ||
1507 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | ||
1508 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | ||
1509 | WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); | ||
1510 | WREG32(RADEON_GPIO_MONID, gpio_monid); | ||
1511 | |||
1512 | return found; | ||
1513 | } | ||
1514 | |||
1420 | static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, | 1515 | static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, |
1421 | struct drm_connector *connector) | 1516 | struct drm_connector *connector) |
1422 | { | 1517 | { |
1423 | struct drm_device *dev = encoder->dev; | 1518 | struct drm_device *dev = encoder->dev; |
1424 | struct radeon_device *rdev = dev->dev_private; | 1519 | struct radeon_device *rdev = dev->dev_private; |
1425 | uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; | 1520 | uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl; |
1426 | uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; | 1521 | uint32_t gpiopad_a = 0, pixclks_cntl, tmp; |
1522 | uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0; | ||
1427 | enum drm_connector_status found = connector_status_disconnected; | 1523 | enum drm_connector_status found = connector_status_disconnected; |
1428 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1524 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1429 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | 1525 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; |
@@ -1460,12 +1556,27 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
1460 | return connector_status_disconnected; | 1556 | return connector_status_disconnected; |
1461 | } | 1557 | } |
1462 | 1558 | ||
1559 | /* R200 uses an external DAC for secondary DAC */ | ||
1560 | if (rdev->family == CHIP_R200) { | ||
1561 | if (radeon_legacy_ext_dac_detect(encoder, connector)) | ||
1562 | found = connector_status_connected; | ||
1563 | return found; | ||
1564 | } | ||
1565 | |||
1463 | /* save the regs we need */ | 1566 | /* save the regs we need */ |
1464 | pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); | 1567 | pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); |
1465 | gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0; | 1568 | |
1466 | disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0; | 1569 | if (rdev->flags & RADEON_SINGLE_CRTC) { |
1467 | disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG); | 1570 | crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); |
1468 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | 1571 | } else { |
1572 | if (ASIC_IS_R300(rdev)) { | ||
1573 | gpiopad_a = RREG32(RADEON_GPIOPAD_A); | ||
1574 | disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); | ||
1575 | } else { | ||
1576 | disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); | ||
1577 | } | ||
1578 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | ||
1579 | } | ||
1469 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); | 1580 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); |
1470 | dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); | 1581 | dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); |
1471 | dac_cntl2 = RREG32(RADEON_DAC_CNTL2); | 1582 | dac_cntl2 = RREG32(RADEON_DAC_CNTL2); |
@@ -1474,22 +1585,24 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
1474 | | RADEON_PIX2CLK_DAC_ALWAYS_ONb); | 1585 | | RADEON_PIX2CLK_DAC_ALWAYS_ONb); |
1475 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); | 1586 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); |
1476 | 1587 | ||
1477 | if (ASIC_IS_R300(rdev)) | 1588 | if (rdev->flags & RADEON_SINGLE_CRTC) { |
1478 | WREG32_P(RADEON_GPIOPAD_A, 1, ~1); | 1589 | tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON; |
1479 | 1590 | WREG32(RADEON_CRTC_EXT_CNTL, tmp); | |
1480 | tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; | ||
1481 | tmp |= RADEON_CRTC2_CRT2_ON | | ||
1482 | (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); | ||
1483 | |||
1484 | WREG32(RADEON_CRTC2_GEN_CNTL, tmp); | ||
1485 | |||
1486 | if (ASIC_IS_R300(rdev)) { | ||
1487 | tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; | ||
1488 | tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; | ||
1489 | WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); | ||
1490 | } else { | 1591 | } else { |
1491 | tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; | 1592 | tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; |
1492 | WREG32(RADEON_DISP_HW_DEBUG, tmp); | 1593 | tmp |= RADEON_CRTC2_CRT2_ON | |
1594 | (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); | ||
1595 | WREG32(RADEON_CRTC2_GEN_CNTL, tmp); | ||
1596 | |||
1597 | if (ASIC_IS_R300(rdev)) { | ||
1598 | WREG32_P(RADEON_GPIOPAD_A, 1, ~1); | ||
1599 | tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; | ||
1600 | tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; | ||
1601 | WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); | ||
1602 | } else { | ||
1603 | tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; | ||
1604 | WREG32(RADEON_DISP_HW_DEBUG, tmp); | ||
1605 | } | ||
1493 | } | 1606 | } |
1494 | 1607 | ||
1495 | tmp = RADEON_TV_DAC_NBLANK | | 1608 | tmp = RADEON_TV_DAC_NBLANK | |
@@ -1531,14 +1644,19 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | |||
1531 | WREG32(RADEON_DAC_CNTL2, dac_cntl2); | 1644 | WREG32(RADEON_DAC_CNTL2, dac_cntl2); |
1532 | WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); | 1645 | WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); |
1533 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); | 1646 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
1534 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | ||
1535 | 1647 | ||
1536 | if (ASIC_IS_R300(rdev)) { | 1648 | if (rdev->flags & RADEON_SINGLE_CRTC) { |
1537 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | 1649 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); |
1538 | WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); | ||
1539 | } else { | 1650 | } else { |
1540 | WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); | 1651 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); |
1652 | if (ASIC_IS_R300(rdev)) { | ||
1653 | WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | ||
1654 | WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); | ||
1655 | } else { | ||
1656 | WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); | ||
1657 | } | ||
1541 | } | 1658 | } |
1659 | |||
1542 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); | 1660 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); |
1543 | 1661 | ||
1544 | return found; | 1662 | return found; |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 8b27dd6e3144..b91118ccef86 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -105,7 +105,6 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
105 | struct radeon_bo *bo; | 105 | struct radeon_bo *bo; |
106 | enum ttm_bo_type type; | 106 | enum ttm_bo_type type; |
107 | unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; | 107 | unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; |
108 | unsigned long max_size = 0; | ||
109 | size_t acc_size; | 108 | size_t acc_size; |
110 | int r; | 109 | int r; |
111 | 110 | ||
@@ -121,18 +120,9 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
121 | } | 120 | } |
122 | *bo_ptr = NULL; | 121 | *bo_ptr = NULL; |
123 | 122 | ||
124 | /* maximun bo size is the minimun btw visible vram and gtt size */ | ||
125 | max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); | ||
126 | if ((page_align << PAGE_SHIFT) >= max_size) { | ||
127 | printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", | ||
128 | __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); | ||
129 | return -ENOMEM; | ||
130 | } | ||
131 | |||
132 | acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, | 123 | acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, |
133 | sizeof(struct radeon_bo)); | 124 | sizeof(struct radeon_bo)); |
134 | 125 | ||
135 | retry: | ||
136 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); | 126 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); |
137 | if (bo == NULL) | 127 | if (bo == NULL) |
138 | return -ENOMEM; | 128 | return -ENOMEM; |
@@ -154,15 +144,6 @@ retry: | |||
154 | acc_size, sg, &radeon_ttm_bo_destroy); | 144 | acc_size, sg, &radeon_ttm_bo_destroy); |
155 | up_read(&rdev->pm.mclk_lock); | 145 | up_read(&rdev->pm.mclk_lock); |
156 | if (unlikely(r != 0)) { | 146 | if (unlikely(r != 0)) { |
157 | if (r != -ERESTARTSYS) { | ||
158 | if (domain == RADEON_GEM_DOMAIN_VRAM) { | ||
159 | domain |= RADEON_GEM_DOMAIN_GTT; | ||
160 | goto retry; | ||
161 | } | ||
162 | dev_err(rdev->dev, | ||
163 | "object_init failed for (%lu, 0x%08X)\n", | ||
164 | size, domain); | ||
165 | } | ||
166 | return r; | 147 | return r; |
167 | } | 148 | } |
168 | *bo_ptr = bo; | 149 | *bo_ptr = bo; |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index bba66902c83b..47634f27f2e5 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -305,7 +305,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v) | |||
305 | { | 305 | { |
306 | #if DRM_DEBUG_CODE | 306 | #if DRM_DEBUG_CODE |
307 | if (ring->count_dw <= 0) { | 307 | if (ring->count_dw <= 0) { |
308 | DRM_ERROR("radeon: writting more dword to ring than expected !\n"); | 308 | DRM_ERROR("radeon: writing more dwords to the ring than expected!\n"); |
309 | } | 309 | } |
310 | #endif | 310 | #endif |
311 | ring->ring[ring->wptr++] = v; | 311 | ring->ring[ring->wptr++] = v; |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index f79633a036c3..b0db712060fb 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -2407,12 +2407,13 @@ static int si_pcie_gart_enable(struct radeon_device *rdev) | |||
2407 | WREG32(0x15DC, 0); | 2407 | WREG32(0x15DC, 0); |
2408 | 2408 | ||
2409 | /* empty context1-15 */ | 2409 | /* empty context1-15 */ |
2410 | /* FIXME start with 4G, once using 2 level pt switch to full | ||
2411 | * vm size space | ||
2412 | */ | ||
2413 | /* set vm size, must be a multiple of 4 */ | 2410 | /* set vm size, must be a multiple of 4 */ |
2414 | WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); | 2411 | WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); |
2415 | WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); | 2412 | WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); |
2413 | /* Assign the pt base to something valid for now; the pts used for | ||
2414 | * the VMs are determined by the application and setup and assigned | ||
2415 | * on the fly in the vm part of radeon_gart.c | ||
2416 | */ | ||
2416 | for (i = 1; i < 16; i++) { | 2417 | for (i = 1; i < 16; i++) { |
2417 | if (i < 8) | 2418 | if (i < 8) |
2418 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), | 2419 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), |
@@ -2807,26 +2808,31 @@ void si_vm_set_page(struct radeon_device *rdev, uint64_t pe, | |||
2807 | { | 2808 | { |
2808 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; | 2809 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; |
2809 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); | 2810 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); |
2810 | int i; | ||
2811 | uint64_t value; | ||
2812 | 2811 | ||
2813 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 2 + count * 2)); | 2812 | while (count) { |
2814 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | | 2813 | unsigned ndw = 2 + count * 2; |
2815 | WRITE_DATA_DST_SEL(1))); | 2814 | if (ndw > 0x3FFE) |
2816 | radeon_ring_write(ring, pe); | 2815 | ndw = 0x3FFE; |
2817 | radeon_ring_write(ring, upper_32_bits(pe)); | 2816 | |
2818 | for (i = 0; i < count; ++i) { | 2817 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, ndw)); |
2819 | if (flags & RADEON_VM_PAGE_SYSTEM) { | 2818 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | |
2820 | value = radeon_vm_map_gart(rdev, addr); | 2819 | WRITE_DATA_DST_SEL(1))); |
2821 | value &= 0xFFFFFFFFFFFFF000ULL; | 2820 | radeon_ring_write(ring, pe); |
2822 | } else if (flags & RADEON_VM_PAGE_VALID) | 2821 | radeon_ring_write(ring, upper_32_bits(pe)); |
2823 | value = addr; | 2822 | for (; ndw > 2; ndw -= 2, --count, pe += 8) { |
2824 | else | 2823 | uint64_t value; |
2825 | value = 0; | 2824 | if (flags & RADEON_VM_PAGE_SYSTEM) { |
2826 | addr += incr; | 2825 | value = radeon_vm_map_gart(rdev, addr); |
2827 | value |= r600_flags; | 2826 | value &= 0xFFFFFFFFFFFFF000ULL; |
2828 | radeon_ring_write(ring, value); | 2827 | } else if (flags & RADEON_VM_PAGE_VALID) |
2829 | radeon_ring_write(ring, upper_32_bits(value)); | 2828 | value = addr; |
2829 | else | ||
2830 | value = 0; | ||
2831 | addr += incr; | ||
2832 | value |= r600_flags; | ||
2833 | radeon_ring_write(ring, value); | ||
2834 | radeon_ring_write(ring, upper_32_bits(value)); | ||
2835 | } | ||
2830 | } | 2836 | } |
2831 | } | 2837 | } |
2832 | 2838 | ||
@@ -2867,6 +2873,10 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
2867 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | 2873 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); |
2868 | radeon_ring_write(ring, 0); | 2874 | radeon_ring_write(ring, 0); |
2869 | radeon_ring_write(ring, 1 << vm->id); | 2875 | radeon_ring_write(ring, 1 << vm->id); |
2876 | |||
2877 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ | ||
2878 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | ||
2879 | radeon_ring_write(ring, 0x0); | ||
2870 | } | 2880 | } |
2871 | 2881 | ||
2872 | /* | 2882 | /* |
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c index c71d493fd0c5..1c350fc4e449 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c | |||
@@ -201,6 +201,8 @@ static int shmob_drm_load(struct drm_device *dev, unsigned long flags) | |||
201 | goto done; | 201 | goto done; |
202 | } | 202 | } |
203 | 203 | ||
204 | platform_set_drvdata(pdev, sdev); | ||
205 | |||
204 | done: | 206 | done: |
205 | if (ret) | 207 | if (ret) |
206 | shmob_drm_unload(dev); | 208 | shmob_drm_unload(dev); |
@@ -299,11 +301,9 @@ static struct drm_driver shmob_drm_driver = { | |||
299 | #if CONFIG_PM_SLEEP | 301 | #if CONFIG_PM_SLEEP |
300 | static int shmob_drm_pm_suspend(struct device *dev) | 302 | static int shmob_drm_pm_suspend(struct device *dev) |
301 | { | 303 | { |
302 | struct platform_device *pdev = to_platform_device(dev); | 304 | struct shmob_drm_device *sdev = dev_get_drvdata(dev); |
303 | struct drm_device *ddev = platform_get_drvdata(pdev); | ||
304 | struct shmob_drm_device *sdev = ddev->dev_private; | ||
305 | 305 | ||
306 | drm_kms_helper_poll_disable(ddev); | 306 | drm_kms_helper_poll_disable(sdev->ddev); |
307 | shmob_drm_crtc_suspend(&sdev->crtc); | 307 | shmob_drm_crtc_suspend(&sdev->crtc); |
308 | 308 | ||
309 | return 0; | 309 | return 0; |
@@ -311,9 +311,7 @@ static int shmob_drm_pm_suspend(struct device *dev) | |||
311 | 311 | ||
312 | static int shmob_drm_pm_resume(struct device *dev) | 312 | static int shmob_drm_pm_resume(struct device *dev) |
313 | { | 313 | { |
314 | struct platform_device *pdev = to_platform_device(dev); | 314 | struct shmob_drm_device *sdev = dev_get_drvdata(dev); |
315 | struct drm_device *ddev = platform_get_drvdata(pdev); | ||
316 | struct shmob_drm_device *sdev = ddev->dev_private; | ||
317 | 315 | ||
318 | mutex_lock(&sdev->ddev->mode_config.mutex); | 316 | mutex_lock(&sdev->ddev->mode_config.mutex); |
319 | shmob_drm_crtc_resume(&sdev->crtc); | 317 | shmob_drm_crtc_resume(&sdev->crtc); |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 402ab69f9f99..bf6e4b5a73b5 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -580,6 +580,7 @@ retry: | |||
580 | if (unlikely(ret != 0)) | 580 | if (unlikely(ret != 0)) |
581 | return ret; | 581 | return ret; |
582 | 582 | ||
583 | retry_reserve: | ||
583 | spin_lock(&glob->lru_lock); | 584 | spin_lock(&glob->lru_lock); |
584 | 585 | ||
585 | if (unlikely(list_empty(&bo->ddestroy))) { | 586 | if (unlikely(list_empty(&bo->ddestroy))) { |
@@ -587,14 +588,20 @@ retry: | |||
587 | return 0; | 588 | return 0; |
588 | } | 589 | } |
589 | 590 | ||
590 | ret = ttm_bo_reserve_locked(bo, interruptible, | 591 | ret = ttm_bo_reserve_locked(bo, false, true, false, 0); |
591 | no_wait_reserve, false, 0); | ||
592 | 592 | ||
593 | if (unlikely(ret != 0)) { | 593 | if (unlikely(ret == -EBUSY)) { |
594 | spin_unlock(&glob->lru_lock); | 594 | spin_unlock(&glob->lru_lock); |
595 | return ret; | 595 | if (likely(!no_wait_reserve)) |
596 | ret = ttm_bo_wait_unreserved(bo, interruptible); | ||
597 | if (unlikely(ret != 0)) | ||
598 | return ret; | ||
599 | |||
600 | goto retry_reserve; | ||
596 | } | 601 | } |
597 | 602 | ||
603 | BUG_ON(ret != 0); | ||
604 | |||
598 | /** | 605 | /** |
599 | * We can re-check for sync object without taking | 606 | * We can re-check for sync object without taking |
600 | * the bo::lock since setting the sync object requires | 607 | * the bo::lock since setting the sync object requires |
@@ -811,17 +818,14 @@ retry: | |||
811 | no_wait_reserve, no_wait_gpu); | 818 | no_wait_reserve, no_wait_gpu); |
812 | kref_put(&bo->list_kref, ttm_bo_release_list); | 819 | kref_put(&bo->list_kref, ttm_bo_release_list); |
813 | 820 | ||
814 | if (likely(ret == 0 || ret == -ERESTARTSYS)) | 821 | return ret; |
815 | return ret; | ||
816 | |||
817 | goto retry; | ||
818 | } | 822 | } |
819 | 823 | ||
820 | ret = ttm_bo_reserve_locked(bo, false, no_wait_reserve, false, 0); | 824 | ret = ttm_bo_reserve_locked(bo, false, true, false, 0); |
821 | 825 | ||
822 | if (unlikely(ret == -EBUSY)) { | 826 | if (unlikely(ret == -EBUSY)) { |
823 | spin_unlock(&glob->lru_lock); | 827 | spin_unlock(&glob->lru_lock); |
824 | if (likely(!no_wait_gpu)) | 828 | if (likely(!no_wait_reserve)) |
825 | ret = ttm_bo_wait_unreserved(bo, interruptible); | 829 | ret = ttm_bo_wait_unreserved(bo, interruptible); |
826 | 830 | ||
827 | kref_put(&bo->list_kref, ttm_bo_release_list); | 831 | kref_put(&bo->list_kref, ttm_bo_release_list); |
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index fccd361f7b50..87aa5f5d3c88 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h | |||
@@ -104,7 +104,7 @@ udl_fb_user_fb_create(struct drm_device *dev, | |||
104 | 104 | ||
105 | int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, | 105 | int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, |
106 | const char *front, char **urb_buf_ptr, | 106 | const char *front, char **urb_buf_ptr, |
107 | u32 byte_offset, u32 byte_width, | 107 | u32 byte_offset, u32 device_byte_offset, u32 byte_width, |
108 | int *ident_ptr, int *sent_ptr); | 108 | int *ident_ptr, int *sent_ptr); |
109 | 109 | ||
110 | int udl_dumb_create(struct drm_file *file_priv, | 110 | int udl_dumb_create(struct drm_file *file_priv, |
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 69a2b16f42a6..d4ab3beaada0 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c | |||
@@ -114,9 +114,10 @@ static void udlfb_dpy_deferred_io(struct fb_info *info, | |||
114 | list_for_each_entry(cur, &fbdefio->pagelist, lru) { | 114 | list_for_each_entry(cur, &fbdefio->pagelist, lru) { |
115 | 115 | ||
116 | if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8), | 116 | if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8), |
117 | &urb, (char *) info->fix.smem_start, | 117 | &urb, (char *) info->fix.smem_start, |
118 | &cmd, cur->index << PAGE_SHIFT, | 118 | &cmd, cur->index << PAGE_SHIFT, |
119 | PAGE_SIZE, &bytes_identical, &bytes_sent)) | 119 | cur->index << PAGE_SHIFT, |
120 | PAGE_SIZE, &bytes_identical, &bytes_sent)) | ||
120 | goto error; | 121 | goto error; |
121 | bytes_rendered += PAGE_SIZE; | 122 | bytes_rendered += PAGE_SIZE; |
122 | } | 123 | } |
@@ -187,10 +188,11 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, | |||
187 | for (i = y; i < y + height ; i++) { | 188 | for (i = y; i < y + height ; i++) { |
188 | const int line_offset = fb->base.pitches[0] * i; | 189 | const int line_offset = fb->base.pitches[0] * i; |
189 | const int byte_offset = line_offset + (x * bpp); | 190 | const int byte_offset = line_offset + (x * bpp); |
190 | 191 | const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp); | |
191 | if (udl_render_hline(dev, bpp, &urb, | 192 | if (udl_render_hline(dev, bpp, &urb, |
192 | (char *) fb->obj->vmapping, | 193 | (char *) fb->obj->vmapping, |
193 | &cmd, byte_offset, width * bpp, | 194 | &cmd, byte_offset, dev_byte_offset, |
195 | width * bpp, | ||
194 | &bytes_identical, &bytes_sent)) | 196 | &bytes_identical, &bytes_sent)) |
195 | goto error; | 197 | goto error; |
196 | } | 198 | } |
diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c index dc095526ffb7..142fee5f983f 100644 --- a/drivers/gpu/drm/udl/udl_transfer.c +++ b/drivers/gpu/drm/udl/udl_transfer.c | |||
@@ -213,11 +213,12 @@ static void udl_compress_hline16( | |||
213 | */ | 213 | */ |
214 | int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, | 214 | int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, |
215 | const char *front, char **urb_buf_ptr, | 215 | const char *front, char **urb_buf_ptr, |
216 | u32 byte_offset, u32 byte_width, | 216 | u32 byte_offset, u32 device_byte_offset, |
217 | u32 byte_width, | ||
217 | int *ident_ptr, int *sent_ptr) | 218 | int *ident_ptr, int *sent_ptr) |
218 | { | 219 | { |
219 | const u8 *line_start, *line_end, *next_pixel; | 220 | const u8 *line_start, *line_end, *next_pixel; |
220 | u32 base16 = 0 + (byte_offset / bpp) * 2; | 221 | u32 base16 = 0 + (device_byte_offset / bpp) * 2; |
221 | struct urb *urb = *urb_ptr; | 222 | struct urb *urb = *urb_ptr; |
222 | u8 *cmd = *urb_buf_ptr; | 223 | u8 *cmd = *urb_buf_ptr; |
223 | u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length; | 224 | u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length; |