Commit e061167151b3caad080349aaa6eed594d0c745c4
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm gixes from Dave Airlie: - exynos: infinite loop regressions fixed - i915: one regression - radeon: one race condition on monitor probing - noveau: two regressions - tegra: one vblank regression fix * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/tegra: dc: Add missing call to drm_vblank_on() drm/nouveau/nv50/disp: Fix modeset on G94 drm/gk20a/fb: fix setting of large page size bit drm/radeon: add locking around atombios scratch space usage drm/i915: Fix obj->map_and_fenceable across tiling changes drm/exynos: fix possible infinite loop issue drm/exynos: g2d: fix null pointer dereference drm/exynos: resolve infinite loop issue on non multi-platform drm/exynos: resolve infinite loop issue on multi-platform
Showing 11 changed files Side-by-side Diff
- drivers/gpu/drm/exynos/exynos_drm_drv.c
- drivers/gpu/drm/exynos/exynos_drm_g2d.c
- drivers/gpu/drm/i915/i915_gem_tiling.c
- drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c
- drivers/gpu/drm/nouveau/nv50_display.c
- drivers/gpu/drm/radeon/atom.c
- drivers/gpu/drm/radeon/atom.h
- drivers/gpu/drm/radeon/atombios_dp.c
- drivers/gpu/drm/radeon/atombios_i2c.c
- drivers/gpu/drm/radeon/radeon_device.c
- drivers/gpu/drm/tegra/dc.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
... | ... | @@ -495,6 +495,12 @@ |
495 | 495 | |
496 | 496 | mutex_lock(&drm_component_lock); |
497 | 497 | |
498 | + /* Do not retry to probe if there is no any kms driver regitered. */ | |
499 | + if (list_empty(&drm_component_list)) { | |
500 | + mutex_unlock(&drm_component_lock); | |
501 | + return ERR_PTR(-ENODEV); | |
502 | + } | |
503 | + | |
498 | 504 | list_for_each_entry(cdev, &drm_component_list, list) { |
499 | 505 | /* |
500 | 506 | * Add components to master only in case that crtc and |
501 | 507 | |
... | ... | @@ -585,10 +591,21 @@ |
585 | 591 | goto err_unregister_mixer_drv; |
586 | 592 | #endif |
587 | 593 | |
594 | + match = exynos_drm_match_add(&pdev->dev); | |
595 | + if (IS_ERR(match)) { | |
596 | + ret = PTR_ERR(match); | |
597 | + goto err_unregister_hdmi_drv; | |
598 | + } | |
599 | + | |
600 | + ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops, | |
601 | + match); | |
602 | + if (ret < 0) | |
603 | + goto err_unregister_hdmi_drv; | |
604 | + | |
588 | 605 | #ifdef CONFIG_DRM_EXYNOS_G2D |
589 | 606 | ret = platform_driver_register(&g2d_driver); |
590 | 607 | if (ret < 0) |
591 | - goto err_unregister_hdmi_drv; | |
608 | + goto err_del_component_master; | |
592 | 609 | #endif |
593 | 610 | |
594 | 611 | #ifdef CONFIG_DRM_EXYNOS_FIMC |
595 | 612 | |
596 | 613 | |
... | ... | @@ -619,23 +636,9 @@ |
619 | 636 | goto err_unregister_ipp_drv; |
620 | 637 | #endif |
621 | 638 | |
622 | - match = exynos_drm_match_add(&pdev->dev); | |
623 | - if (IS_ERR(match)) { | |
624 | - ret = PTR_ERR(match); | |
625 | - goto err_unregister_resources; | |
626 | - } | |
627 | - | |
628 | - ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops, | |
629 | - match); | |
630 | - if (ret < 0) | |
631 | - goto err_unregister_resources; | |
632 | - | |
633 | 639 | return ret; |
634 | 640 | |
635 | -err_unregister_resources: | |
636 | - | |
637 | 641 | #ifdef CONFIG_DRM_EXYNOS_IPP |
638 | - exynos_platform_device_ipp_unregister(); | |
639 | 642 | err_unregister_ipp_drv: |
640 | 643 | platform_driver_unregister(&ipp_driver); |
641 | 644 | err_unregister_gsc_drv: |
642 | 645 | |
643 | 646 | |
... | ... | @@ -658,9 +661,11 @@ |
658 | 661 | |
659 | 662 | #ifdef CONFIG_DRM_EXYNOS_G2D |
660 | 663 | platform_driver_unregister(&g2d_driver); |
661 | -err_unregister_hdmi_drv: | |
664 | +err_del_component_master: | |
662 | 665 | #endif |
666 | + component_master_del(&pdev->dev, &exynos_drm_ops); | |
663 | 667 | |
668 | +err_unregister_hdmi_drv: | |
664 | 669 | #ifdef CONFIG_DRM_EXYNOS_HDMI |
665 | 670 | platform_driver_unregister(&hdmi_driver); |
666 | 671 | err_unregister_mixer_drv: |
... | ... | @@ -740,6 +745,18 @@ |
740 | 745 | static int exynos_drm_init(void) |
741 | 746 | { |
742 | 747 | int ret; |
748 | + | |
749 | + /* | |
750 | + * Register device object only in case of Exynos SoC. | |
751 | + * | |
752 | + * Below codes resolves temporarily infinite loop issue incurred | |
753 | + * by Exynos drm driver when using multi-platform kernel. | |
754 | + * So these codes will be replaced with more generic way later. | |
755 | + */ | |
756 | + if (!of_machine_is_compatible("samsung,exynos3") && | |
757 | + !of_machine_is_compatible("samsung,exynos4") && | |
758 | + !of_machine_is_compatible("samsung,exynos5")) | |
759 | + return -ENODEV; | |
743 | 760 | |
744 | 761 | exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, |
745 | 762 | NULL, 0); |
drivers/gpu/drm/exynos/exynos_drm_g2d.c
... | ... | @@ -302,9 +302,12 @@ |
302 | 302 | struct exynos_drm_subdrv *subdrv = &g2d->subdrv; |
303 | 303 | |
304 | 304 | kfree(g2d->cmdlist_node); |
305 | - dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE, | |
306 | - g2d->cmdlist_pool_virt, | |
307 | - g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs); | |
305 | + | |
306 | + if (g2d->cmdlist_pool_virt && g2d->cmdlist_pool) { | |
307 | + dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE, | |
308 | + g2d->cmdlist_pool_virt, | |
309 | + g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs); | |
310 | + } | |
308 | 311 | } |
309 | 312 | |
310 | 313 | static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d) |
drivers/gpu/drm/i915/i915_gem_tiling.c
... | ... | @@ -364,22 +364,9 @@ |
364 | 364 | * has to also include the unfenced register the GPU uses |
365 | 365 | * whilst executing a fenced command for an untiled object. |
366 | 366 | */ |
367 | - | |
368 | - obj->map_and_fenceable = | |
369 | - !i915_gem_obj_ggtt_bound(obj) || | |
370 | - (i915_gem_obj_ggtt_offset(obj) + | |
371 | - obj->base.size <= dev_priv->gtt.mappable_end && | |
372 | - i915_gem_object_fence_ok(obj, args->tiling_mode)); | |
373 | - | |
374 | - /* Rebind if we need a change of alignment */ | |
375 | - if (!obj->map_and_fenceable) { | |
376 | - u32 unfenced_align = | |
377 | - i915_gem_get_gtt_alignment(dev, obj->base.size, | |
378 | - args->tiling_mode, | |
379 | - false); | |
380 | - if (i915_gem_obj_ggtt_offset(obj) & (unfenced_align - 1)) | |
381 | - ret = i915_gem_object_ggtt_unbind(obj); | |
382 | - } | |
367 | + if (obj->map_and_fenceable && | |
368 | + !i915_gem_object_fence_ok(obj, args->tiling_mode)) | |
369 | + ret = i915_gem_object_ggtt_unbind(obj); | |
383 | 370 | |
384 | 371 | if (ret == 0) { |
385 | 372 | obj->fence_dirty = |
drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c
... | ... | @@ -27,6 +27,20 @@ |
27 | 27 | }; |
28 | 28 | |
29 | 29 | static int |
30 | +gk20a_fb_init(struct nouveau_object *object) | |
31 | +{ | |
32 | + struct gk20a_fb_priv *priv = (void *)object; | |
33 | + int ret; | |
34 | + | |
35 | + ret = nouveau_fb_init(&priv->base); | |
36 | + if (ret) | |
37 | + return ret; | |
38 | + | |
39 | + nv_mask(priv, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */ | |
40 | + return 0; | |
41 | +} | |
42 | + | |
43 | +static int | |
30 | 44 | gk20a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, |
31 | 45 | struct nouveau_oclass *oclass, void *data, u32 size, |
32 | 46 | struct nouveau_object **pobject) |
... | ... | @@ -48,7 +62,7 @@ |
48 | 62 | .base.ofuncs = &(struct nouveau_ofuncs) { |
49 | 63 | .ctor = gk20a_fb_ctor, |
50 | 64 | .dtor = _nouveau_fb_dtor, |
51 | - .init = _nouveau_fb_init, | |
65 | + .init = gk20a_fb_init, | |
52 | 66 | .fini = _nouveau_fb_fini, |
53 | 67 | }, |
54 | 68 | .memtype = nvc0_fb_memtype_valid, |
drivers/gpu/drm/nouveau/nv50_display.c
... | ... | @@ -791,6 +791,22 @@ |
791 | 791 | } |
792 | 792 | |
793 | 793 | static int |
794 | +nv50_crtc_set_raster_vblank_dmi(struct nouveau_crtc *nv_crtc, u32 usec) | |
795 | +{ | |
796 | + struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); | |
797 | + u32 *push; | |
798 | + | |
799 | + push = evo_wait(mast, 8); | |
800 | + if (!push) | |
801 | + return -ENOMEM; | |
802 | + | |
803 | + evo_mthd(push, 0x0828 + (nv_crtc->index * 0x400), 1); | |
804 | + evo_data(push, usec); | |
805 | + evo_kick(push, mast); | |
806 | + return 0; | |
807 | +} | |
808 | + | |
809 | +static int | |
794 | 810 | nv50_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update) |
795 | 811 | { |
796 | 812 | struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); |
797 | 813 | |
... | ... | @@ -1104,14 +1120,14 @@ |
1104 | 1120 | evo_mthd(push, 0x0804 + (nv_crtc->index * 0x400), 2); |
1105 | 1121 | evo_data(push, 0x00800000 | mode->clock); |
1106 | 1122 | evo_data(push, (ilace == 2) ? 2 : 0); |
1107 | - evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 8); | |
1123 | + evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 6); | |
1108 | 1124 | evo_data(push, 0x00000000); |
1109 | 1125 | evo_data(push, (vactive << 16) | hactive); |
1110 | 1126 | evo_data(push, ( vsynce << 16) | hsynce); |
1111 | 1127 | evo_data(push, (vblanke << 16) | hblanke); |
1112 | 1128 | evo_data(push, (vblanks << 16) | hblanks); |
1113 | 1129 | evo_data(push, (vblan2e << 16) | vblan2s); |
1114 | - evo_data(push, vblankus); | |
1130 | + evo_mthd(push, 0x082c + (nv_crtc->index * 0x400), 1); | |
1115 | 1131 | evo_data(push, 0x00000000); |
1116 | 1132 | evo_mthd(push, 0x0900 + (nv_crtc->index * 0x400), 2); |
1117 | 1133 | evo_data(push, 0x00000311); |
... | ... | @@ -1141,6 +1157,11 @@ |
1141 | 1157 | nv_connector = nouveau_crtc_connector_get(nv_crtc); |
1142 | 1158 | nv50_crtc_set_dither(nv_crtc, false); |
1143 | 1159 | nv50_crtc_set_scale(nv_crtc, false); |
1160 | + | |
1161 | + /* G94 only accepts this after setting scale */ | |
1162 | + if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) | |
1163 | + nv50_crtc_set_raster_vblank_dmi(nv_crtc, vblankus); | |
1164 | + | |
1144 | 1165 | nv50_crtc_set_color_vibrance(nv_crtc, false); |
1145 | 1166 | nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, false); |
1146 | 1167 | return 0; |
drivers/gpu/drm/radeon/atom.c
... | ... | @@ -1217,7 +1217,7 @@ |
1217 | 1217 | return ret; |
1218 | 1218 | } |
1219 | 1219 | |
1220 | -int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | |
1220 | +int atom_execute_table_scratch_unlocked(struct atom_context *ctx, int index, uint32_t * params) | |
1221 | 1221 | { |
1222 | 1222 | int r; |
1223 | 1223 | |
... | ... | @@ -1235,6 +1235,15 @@ |
1235 | 1235 | ctx->divmul[1] = 0; |
1236 | 1236 | r = atom_execute_table_locked(ctx, index, params); |
1237 | 1237 | mutex_unlock(&ctx->mutex); |
1238 | + return r; | |
1239 | +} | |
1240 | + | |
1241 | +int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | |
1242 | +{ | |
1243 | + int r; | |
1244 | + mutex_lock(&ctx->scratch_mutex); | |
1245 | + r = atom_execute_table_scratch_unlocked(ctx, index, params); | |
1246 | + mutex_unlock(&ctx->scratch_mutex); | |
1238 | 1247 | return r; |
1239 | 1248 | } |
1240 | 1249 |
drivers/gpu/drm/radeon/atom.h
... | ... | @@ -125,6 +125,7 @@ |
125 | 125 | struct atom_context { |
126 | 126 | struct card_info *card; |
127 | 127 | struct mutex mutex; |
128 | + struct mutex scratch_mutex; | |
128 | 129 | void *bios; |
129 | 130 | uint32_t cmd_table, data_table; |
130 | 131 | uint16_t *iio; |
... | ... | @@ -145,6 +146,7 @@ |
145 | 146 | |
146 | 147 | struct atom_context *atom_parse(struct card_info *, void *); |
147 | 148 | int atom_execute_table(struct atom_context *, int, uint32_t *); |
149 | +int atom_execute_table_scratch_unlocked(struct atom_context *, int, uint32_t *); | |
148 | 150 | int atom_asic_init(struct atom_context *); |
149 | 151 | void atom_destroy(struct atom_context *); |
150 | 152 | bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, |
drivers/gpu/drm/radeon/atombios_dp.c
... | ... | @@ -100,6 +100,7 @@ |
100 | 100 | memset(&args, 0, sizeof(args)); |
101 | 101 | |
102 | 102 | mutex_lock(&chan->mutex); |
103 | + mutex_lock(&rdev->mode_info.atom_context->scratch_mutex); | |
103 | 104 | |
104 | 105 | base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1); |
105 | 106 | |
... | ... | @@ -113,7 +114,7 @@ |
113 | 114 | if (ASIC_IS_DCE4(rdev)) |
114 | 115 | args.v2.ucHPD_ID = chan->rec.hpd; |
115 | 116 | |
116 | - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | |
117 | + atom_execute_table_scratch_unlocked(rdev->mode_info.atom_context, index, (uint32_t *)&args); | |
117 | 118 | |
118 | 119 | *ack = args.v1.ucReplyStatus; |
119 | 120 | |
... | ... | @@ -147,6 +148,7 @@ |
147 | 148 | |
148 | 149 | r = recv_bytes; |
149 | 150 | done: |
151 | + mutex_unlock(&rdev->mode_info.atom_context->scratch_mutex); | |
150 | 152 | mutex_unlock(&chan->mutex); |
151 | 153 | |
152 | 154 | return r; |
drivers/gpu/drm/radeon/atombios_i2c.c
... | ... | @@ -48,6 +48,7 @@ |
48 | 48 | memset(&args, 0, sizeof(args)); |
49 | 49 | |
50 | 50 | mutex_lock(&chan->mutex); |
51 | + mutex_lock(&rdev->mode_info.atom_context->scratch_mutex); | |
51 | 52 | |
52 | 53 | base = (unsigned char *)rdev->mode_info.atom_context->scratch; |
53 | 54 | |
... | ... | @@ -82,7 +83,7 @@ |
82 | 83 | args.ucSlaveAddr = slave_addr << 1; |
83 | 84 | args.ucLineNumber = chan->rec.i2c_id; |
84 | 85 | |
85 | - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | |
86 | + atom_execute_table_scratch_unlocked(rdev->mode_info.atom_context, index, (uint32_t *)&args); | |
86 | 87 | |
87 | 88 | /* error */ |
88 | 89 | if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) { |
... | ... | @@ -95,6 +96,7 @@ |
95 | 96 | radeon_atom_copy_swap(buf, base, num, false); |
96 | 97 | |
97 | 98 | done: |
99 | + mutex_unlock(&rdev->mode_info.atom_context->scratch_mutex); | |
98 | 100 | mutex_unlock(&chan->mutex); |
99 | 101 | |
100 | 102 | return r; |
drivers/gpu/drm/radeon/radeon_device.c
... | ... | @@ -952,6 +952,7 @@ |
952 | 952 | } |
953 | 953 | |
954 | 954 | mutex_init(&rdev->mode_info.atom_context->mutex); |
955 | + mutex_init(&rdev->mode_info.atom_context->scratch_mutex); | |
955 | 956 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); |
956 | 957 | atom_allocate_fb_scratch(rdev->mode_info.atom_context); |
957 | 958 | return 0; |
drivers/gpu/drm/tegra/dc.c
... | ... | @@ -736,7 +736,6 @@ |
736 | 736 | |
737 | 737 | static void tegra_crtc_disable(struct drm_crtc *crtc) |
738 | 738 | { |
739 | - struct tegra_dc *dc = to_tegra_dc(crtc); | |
740 | 739 | struct drm_device *drm = crtc->dev; |
741 | 740 | struct drm_plane *plane; |
742 | 741 | |
... | ... | @@ -752,7 +751,7 @@ |
752 | 751 | } |
753 | 752 | } |
754 | 753 | |
755 | - drm_vblank_off(drm, dc->pipe); | |
754 | + drm_crtc_vblank_off(crtc); | |
756 | 755 | } |
757 | 756 | |
758 | 757 | static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc, |
... | ... | @@ -841,8 +840,6 @@ |
841 | 840 | u32 value; |
842 | 841 | int err; |
843 | 842 | |
844 | - drm_vblank_pre_modeset(crtc->dev, dc->pipe); | |
845 | - | |
846 | 843 | err = tegra_crtc_setup_clk(crtc, mode); |
847 | 844 | if (err) { |
848 | 845 | dev_err(dc->dev, "failed to setup clock for CRTC: %d\n", err); |
... | ... | @@ -896,6 +893,8 @@ |
896 | 893 | unsigned int syncpt; |
897 | 894 | unsigned long value; |
898 | 895 | |
896 | + drm_crtc_vblank_off(crtc); | |
897 | + | |
899 | 898 | /* hardware initialization */ |
900 | 899 | reset_control_deassert(dc->rst); |
901 | 900 | usleep_range(10000, 20000); |
... | ... | @@ -943,7 +942,7 @@ |
943 | 942 | value = GENERAL_ACT_REQ | WIN_A_ACT_REQ; |
944 | 943 | tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); |
945 | 944 | |
946 | - drm_vblank_post_modeset(crtc->dev, dc->pipe); | |
945 | + drm_crtc_vblank_on(crtc); | |
947 | 946 | } |
948 | 947 | |
949 | 948 | static void tegra_crtc_load_lut(struct drm_crtc *crtc) |