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
Unified · Split
| @@ -495,6 +495,12 @@ static struct component_match *exynos_drm_match_add(struct device *dev) · 494 unmodified lines | ||
| 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 |
| @@ -585,10 +591,21 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) · 84 unmodified lines | ||
| 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 |
| @@ -619,23 +636,9 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) · 24 unmodified lines | ||
| 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: |
| @@ -658,9 +661,11 @@ err_unregister_g2d_drv: · 16 unmodified lines | ||
| 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: |
| @@ -741,6 +746,18 @@ static int exynos_drm_init(void) · 74 unmodified lines | ||
| 741 | 746 | { |
| 742 | 747 | int ret; |
| 743 | 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; | |
| 760 | + | |
| 744 | 761 | exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, |
| 745 | 762 | NULL, 0); |
| 746 | 763 | if (IS_ERR(exynos_drm_pdev)) |
| @@ -302,9 +302,12 @@ static void g2d_fini_cmdlist(struct g2d_data *g2d) · 301 unmodified lines | ||
| 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) |
| @@ -364,22 +364,9 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, · 363 unmodified lines | ||
| 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 = |
| @@ -26,6 +26,20 @@ struct gk20a_fb_priv { · 25 unmodified lines | ||
| 26 | 26 | struct nouveau_fb base; |
| 27 | 27 | }; |
| 28 | 28 | |
| 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 | + | |
| 29 | 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, |
| @@ -48,7 +62,7 @@ gk20a_fb_oclass = &(struct nouveau_fb_impl) { · 16 unmodified lines | ||
| 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, |
| @@ -790,6 +790,22 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update) · 789 unmodified lines | ||
| 790 | 790 | return 0; |
| 791 | 791 | } |
| 792 | 792 | |
| 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 | + | |
| 793 | 809 | static int |
| 794 | 810 | nv50_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update) |
| 795 | 811 | { |
| @@ -1104,14 +1120,14 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, · 308 unmodified lines | ||
| 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 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, · 23 unmodified lines | ||
| 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; |
| @@ -1217,7 +1217,7 @@ free: · 1216 unmodified lines | ||
| 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 | |
| @@ -1238,6 +1238,15 @@ int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) · 14 unmodified lines | ||
| 1238 | 1238 | return r; |
| 1239 | 1239 | } |
| 1240 | 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); | |
| 1247 | + return r; | |
| 1248 | +} | |
| 1249 | + | |
| 1241 | 1250 | static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; |
| 1242 | 1251 | |
| 1243 | 1252 | static void atom_index_iio(struct atom_context *ctx, int base) |
| @@ -125,6 +125,7 @@ struct card_info { · 124 unmodified lines | ||
| 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 @@ extern int atom_debug; · 14 unmodified lines | ||
| 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, |
| @@ -100,6 +100,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, · 99 unmodified lines | ||
| 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 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, · 7 unmodified lines | ||
| 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 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, · 27 unmodified lines | ||
| 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; |
| @@ -48,6 +48,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, · 47 unmodified lines | ||
| 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 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, · 28 unmodified lines | ||
| 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 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, · 6 unmodified lines | ||
| 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; |
| @@ -952,6 +952,7 @@ int radeon_atombios_init(struct radeon_device *rdev) · 951 unmodified lines | ||
| 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; |
| @@ -736,7 +736,6 @@ static const struct drm_crtc_funcs tegra_crtc_funcs = { · 735 unmodified lines | ||
| 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 @@ static void tegra_crtc_disable(struct drm_crtc *crtc) · 9 unmodified lines | ||
| 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 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc, · 82 unmodified lines | ||
| 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 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc) · 47 unmodified lines | ||
| 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 @@ static void tegra_crtc_commit(struct drm_crtc *crtc) · 41 unmodified lines | ||
| 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) |