diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-27 20:05:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-27 20:05:39 -0400 |
commit | c163b524d2ab37eb102ea0d20f339fad7bb080c9 (patch) | |
tree | f521e5e65fb479f30a43e4a62f4b6a73ee473c8c | |
parent | 3493860c76eb4e5b222f1016d1458615afac9fc4 (diff) | |
parent | 0fcb70c30131aac40f62ba13f89963d5c13b48a7 (diff) |
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie:
"Exynos, i915 and msm fixes and one core fix.
exynos:
hdmi power off and mixer issues
msm:
iommu, build fixes,
i915:
regression races and warning fixes"
* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (22 commits)
drm/i915: vlv_prepare_pll is only needed in case of non DSI interfaces
drm: fix NULL pointer access by wrong ioctl
drm/exynos: enable vsync interrupt while waiting for vblank
drm/exynos: soft reset mixer before reconfigure after power-on
drm/exynos: allow multiple layer updates per vsync for mixer
drm/i915: Hold the table lock whilst walking the file's idr and counting the objects in debugfs
drm/i915: BDW: Adding Reserved PCI IDs.
drm/i915: Only mark the ctx as initialised after a SET_CONTEXT operation
drm/exynos: stop mixer before gating clocks during poweroff
drm/exynos: set power state variable after enabling clocks and power
drm/exynos: disable unused windows on apply
drm/exynos: Fix de-registration ordering
drm/exynos: change zero to NULL for sparse
drm/exynos: dpi: Fix NULL pointer dereference with legacy bindings
drm/exynos: hdmi: fix power order issue
drm/i915: default to having backlight if VBT not available
drm/i915: cache hw power well enabled state
drm/msm: fix IOMMU cleanup for -EPROBE_DEFER
drm/msm: use PAGE_ALIGNED instead of IS_ALIGNED(PAGE_SIZE)
drm/msm/hdmi: set hdp clock rate before prepare_enable
...
26 files changed, 169 insertions, 70 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 03711d00aaae..8218078b6133 100644..100755 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -419,8 +419,9 @@ long drm_ioctl(struct file *filp, | |||
419 | retcode = -EFAULT; | 419 | retcode = -EFAULT; |
420 | goto err_i1; | 420 | goto err_i1; |
421 | } | 421 | } |
422 | } else | 422 | } else if (cmd & IOC_OUT) { |
423 | memset(kdata, 0, usize); | 423 | memset(kdata, 0, usize); |
424 | } | ||
424 | 425 | ||
425 | if (ioctl->flags & DRM_UNLOCKED) | 426 | if (ioctl->flags & DRM_UNLOCKED) |
426 | retcode = func(dev, kdata, file_priv); | 427 | retcode = func(dev, kdata, file_priv); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c index 482127f633c5..9e530f205ad2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c | |||
@@ -40,7 +40,7 @@ exynos_dpi_detect(struct drm_connector *connector, bool force) | |||
40 | { | 40 | { |
41 | struct exynos_dpi *ctx = connector_to_dpi(connector); | 41 | struct exynos_dpi *ctx = connector_to_dpi(connector); |
42 | 42 | ||
43 | if (!ctx->panel->connector) | 43 | if (ctx->panel && !ctx->panel->connector) |
44 | drm_panel_attach(ctx->panel, &ctx->connector); | 44 | drm_panel_attach(ctx->panel, &ctx->connector); |
45 | 45 | ||
46 | return connector_status_connected; | 46 | return connector_status_connected; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index d91f27777537..ab7d182063c3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
@@ -765,24 +765,24 @@ static int exynos_drm_init(void) | |||
765 | 765 | ||
766 | return 0; | 766 | return 0; |
767 | 767 | ||
768 | err_unregister_pd: | ||
769 | platform_device_unregister(exynos_drm_pdev); | ||
770 | |||
771 | err_remove_vidi: | 768 | err_remove_vidi: |
772 | #ifdef CONFIG_DRM_EXYNOS_VIDI | 769 | #ifdef CONFIG_DRM_EXYNOS_VIDI |
773 | exynos_drm_remove_vidi(); | 770 | exynos_drm_remove_vidi(); |
771 | |||
772 | err_unregister_pd: | ||
774 | #endif | 773 | #endif |
774 | platform_device_unregister(exynos_drm_pdev); | ||
775 | 775 | ||
776 | return ret; | 776 | return ret; |
777 | } | 777 | } |
778 | 778 | ||
779 | static void exynos_drm_exit(void) | 779 | static void exynos_drm_exit(void) |
780 | { | 780 | { |
781 | platform_driver_unregister(&exynos_drm_platform_driver); | ||
781 | #ifdef CONFIG_DRM_EXYNOS_VIDI | 782 | #ifdef CONFIG_DRM_EXYNOS_VIDI |
782 | exynos_drm_remove_vidi(); | 783 | exynos_drm_remove_vidi(); |
783 | #endif | 784 | #endif |
784 | platform_device_unregister(exynos_drm_pdev); | 785 | platform_device_unregister(exynos_drm_pdev); |
785 | platform_driver_unregister(&exynos_drm_platform_driver); | ||
786 | } | 786 | } |
787 | 787 | ||
788 | module_init(exynos_drm_init); | 788 | module_init(exynos_drm_init); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 36535f398848..06cde4506278 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -343,7 +343,7 @@ struct exynos_drm_display * exynos_dpi_probe(struct device *dev); | |||
343 | int exynos_dpi_remove(struct device *dev); | 343 | int exynos_dpi_remove(struct device *dev); |
344 | #else | 344 | #else |
345 | static inline struct exynos_drm_display * | 345 | static inline struct exynos_drm_display * |
346 | exynos_dpi_probe(struct device *dev) { return 0; } | 346 | exynos_dpi_probe(struct device *dev) { return NULL; } |
347 | static inline int exynos_dpi_remove(struct device *dev) { return 0; } | 347 | static inline int exynos_dpi_remove(struct device *dev) { return 0; } |
348 | #endif | 348 | #endif |
349 | 349 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index bb45ab2e7384..33161ad38201 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -741,6 +741,8 @@ static void fimd_apply(struct exynos_drm_manager *mgr) | |||
741 | win_data = &ctx->win_data[i]; | 741 | win_data = &ctx->win_data[i]; |
742 | if (win_data->enabled) | 742 | if (win_data->enabled) |
743 | fimd_win_commit(mgr, i); | 743 | fimd_win_commit(mgr, i); |
744 | else | ||
745 | fimd_win_disable(mgr, i); | ||
744 | } | 746 | } |
745 | 747 | ||
746 | fimd_commit(mgr); | 748 | fimd_commit(mgr); |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index c104d0c9b385..aa259b0a873a 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -2090,6 +2090,11 @@ out: | |||
2090 | 2090 | ||
2091 | static void hdmi_dpms(struct exynos_drm_display *display, int mode) | 2091 | static void hdmi_dpms(struct exynos_drm_display *display, int mode) |
2092 | { | 2092 | { |
2093 | struct hdmi_context *hdata = display->ctx; | ||
2094 | struct drm_encoder *encoder = hdata->encoder; | ||
2095 | struct drm_crtc *crtc = encoder->crtc; | ||
2096 | struct drm_crtc_helper_funcs *funcs = NULL; | ||
2097 | |||
2093 | DRM_DEBUG_KMS("mode %d\n", mode); | 2098 | DRM_DEBUG_KMS("mode %d\n", mode); |
2094 | 2099 | ||
2095 | switch (mode) { | 2100 | switch (mode) { |
@@ -2099,6 +2104,20 @@ static void hdmi_dpms(struct exynos_drm_display *display, int mode) | |||
2099 | case DRM_MODE_DPMS_STANDBY: | 2104 | case DRM_MODE_DPMS_STANDBY: |
2100 | case DRM_MODE_DPMS_SUSPEND: | 2105 | case DRM_MODE_DPMS_SUSPEND: |
2101 | case DRM_MODE_DPMS_OFF: | 2106 | case DRM_MODE_DPMS_OFF: |
2107 | /* | ||
2108 | * The SFRs of VP and Mixer are updated by Vertical Sync of | ||
2109 | * Timing generator which is a part of HDMI so the sequence | ||
2110 | * to disable TV Subsystem should be as following, | ||
2111 | * VP -> Mixer -> HDMI | ||
2112 | * | ||
2113 | * Below codes will try to disable Mixer and VP(if used) | ||
2114 | * prior to disabling HDMI. | ||
2115 | */ | ||
2116 | if (crtc) | ||
2117 | funcs = crtc->helper_private; | ||
2118 | if (funcs && funcs->dpms) | ||
2119 | (*funcs->dpms)(crtc, mode); | ||
2120 | |||
2102 | hdmi_poweroff(display); | 2121 | hdmi_poweroff(display); |
2103 | break; | 2122 | break; |
2104 | default: | 2123 | default: |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 4c5aed7e54c8..7529946d0a74 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
@@ -377,6 +377,20 @@ static void mixer_run(struct mixer_context *ctx) | |||
377 | mixer_regs_dump(ctx); | 377 | mixer_regs_dump(ctx); |
378 | } | 378 | } |
379 | 379 | ||
380 | static void mixer_stop(struct mixer_context *ctx) | ||
381 | { | ||
382 | struct mixer_resources *res = &ctx->mixer_res; | ||
383 | int timeout = 20; | ||
384 | |||
385 | mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN); | ||
386 | |||
387 | while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) && | ||
388 | --timeout) | ||
389 | usleep_range(10000, 12000); | ||
390 | |||
391 | mixer_regs_dump(ctx); | ||
392 | } | ||
393 | |||
380 | static void vp_video_buffer(struct mixer_context *ctx, int win) | 394 | static void vp_video_buffer(struct mixer_context *ctx, int win) |
381 | { | 395 | { |
382 | struct mixer_resources *res = &ctx->mixer_res; | 396 | struct mixer_resources *res = &ctx->mixer_res; |
@@ -497,13 +511,8 @@ static void vp_video_buffer(struct mixer_context *ctx, int win) | |||
497 | static void mixer_layer_update(struct mixer_context *ctx) | 511 | static void mixer_layer_update(struct mixer_context *ctx) |
498 | { | 512 | { |
499 | struct mixer_resources *res = &ctx->mixer_res; | 513 | struct mixer_resources *res = &ctx->mixer_res; |
500 | u32 val; | ||
501 | |||
502 | val = mixer_reg_read(res, MXR_CFG); | ||
503 | 514 | ||
504 | /* allow one update per vsync only */ | 515 | mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE); |
505 | if (!(val & MXR_CFG_LAYER_UPDATE_COUNT_MASK)) | ||
506 | mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE); | ||
507 | } | 516 | } |
508 | 517 | ||
509 | static void mixer_graph_buffer(struct mixer_context *ctx, int win) | 518 | static void mixer_graph_buffer(struct mixer_context *ctx, int win) |
@@ -1010,6 +1019,8 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) | |||
1010 | } | 1019 | } |
1011 | mutex_unlock(&mixer_ctx->mixer_mutex); | 1020 | mutex_unlock(&mixer_ctx->mixer_mutex); |
1012 | 1021 | ||
1022 | drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe); | ||
1023 | |||
1013 | atomic_set(&mixer_ctx->wait_vsync_event, 1); | 1024 | atomic_set(&mixer_ctx->wait_vsync_event, 1); |
1014 | 1025 | ||
1015 | /* | 1026 | /* |
@@ -1020,6 +1031,8 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) | |||
1020 | !atomic_read(&mixer_ctx->wait_vsync_event), | 1031 | !atomic_read(&mixer_ctx->wait_vsync_event), |
1021 | HZ/20)) | 1032 | HZ/20)) |
1022 | DRM_DEBUG_KMS("vblank wait timed out.\n"); | 1033 | DRM_DEBUG_KMS("vblank wait timed out.\n"); |
1034 | |||
1035 | drm_vblank_put(mgr->crtc->dev, mixer_ctx->pipe); | ||
1023 | } | 1036 | } |
1024 | 1037 | ||
1025 | static void mixer_window_suspend(struct exynos_drm_manager *mgr) | 1038 | static void mixer_window_suspend(struct exynos_drm_manager *mgr) |
@@ -1061,7 +1074,7 @@ static void mixer_poweron(struct exynos_drm_manager *mgr) | |||
1061 | mutex_unlock(&ctx->mixer_mutex); | 1074 | mutex_unlock(&ctx->mixer_mutex); |
1062 | return; | 1075 | return; |
1063 | } | 1076 | } |
1064 | ctx->powered = true; | 1077 | |
1065 | mutex_unlock(&ctx->mixer_mutex); | 1078 | mutex_unlock(&ctx->mixer_mutex); |
1066 | 1079 | ||
1067 | pm_runtime_get_sync(ctx->dev); | 1080 | pm_runtime_get_sync(ctx->dev); |
@@ -1072,6 +1085,12 @@ static void mixer_poweron(struct exynos_drm_manager *mgr) | |||
1072 | clk_prepare_enable(res->sclk_mixer); | 1085 | clk_prepare_enable(res->sclk_mixer); |
1073 | } | 1086 | } |
1074 | 1087 | ||
1088 | mutex_lock(&ctx->mixer_mutex); | ||
1089 | ctx->powered = true; | ||
1090 | mutex_unlock(&ctx->mixer_mutex); | ||
1091 | |||
1092 | mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET); | ||
1093 | |||
1075 | mixer_reg_write(res, MXR_INT_EN, ctx->int_en); | 1094 | mixer_reg_write(res, MXR_INT_EN, ctx->int_en); |
1076 | mixer_win_reset(ctx); | 1095 | mixer_win_reset(ctx); |
1077 | 1096 | ||
@@ -1084,14 +1103,21 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr) | |||
1084 | struct mixer_resources *res = &ctx->mixer_res; | 1103 | struct mixer_resources *res = &ctx->mixer_res; |
1085 | 1104 | ||
1086 | mutex_lock(&ctx->mixer_mutex); | 1105 | mutex_lock(&ctx->mixer_mutex); |
1087 | if (!ctx->powered) | 1106 | if (!ctx->powered) { |
1088 | goto out; | 1107 | mutex_unlock(&ctx->mixer_mutex); |
1108 | return; | ||
1109 | } | ||
1089 | mutex_unlock(&ctx->mixer_mutex); | 1110 | mutex_unlock(&ctx->mixer_mutex); |
1090 | 1111 | ||
1112 | mixer_stop(ctx); | ||
1091 | mixer_window_suspend(mgr); | 1113 | mixer_window_suspend(mgr); |
1092 | 1114 | ||
1093 | ctx->int_en = mixer_reg_read(res, MXR_INT_EN); | 1115 | ctx->int_en = mixer_reg_read(res, MXR_INT_EN); |
1094 | 1116 | ||
1117 | mutex_lock(&ctx->mixer_mutex); | ||
1118 | ctx->powered = false; | ||
1119 | mutex_unlock(&ctx->mixer_mutex); | ||
1120 | |||
1095 | clk_disable_unprepare(res->mixer); | 1121 | clk_disable_unprepare(res->mixer); |
1096 | if (ctx->vp_enabled) { | 1122 | if (ctx->vp_enabled) { |
1097 | clk_disable_unprepare(res->vp); | 1123 | clk_disable_unprepare(res->vp); |
@@ -1099,12 +1125,6 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr) | |||
1099 | } | 1125 | } |
1100 | 1126 | ||
1101 | pm_runtime_put_sync(ctx->dev); | 1127 | pm_runtime_put_sync(ctx->dev); |
1102 | |||
1103 | mutex_lock(&ctx->mixer_mutex); | ||
1104 | ctx->powered = false; | ||
1105 | |||
1106 | out: | ||
1107 | mutex_unlock(&ctx->mixer_mutex); | ||
1108 | } | 1128 | } |
1109 | 1129 | ||
1110 | static void mixer_dpms(struct exynos_drm_manager *mgr, int mode) | 1130 | static void mixer_dpms(struct exynos_drm_manager *mgr, int mode) |
diff --git a/drivers/gpu/drm/exynos/regs-mixer.h b/drivers/gpu/drm/exynos/regs-mixer.h index 4537026bc385..5f32e1a29411 100644 --- a/drivers/gpu/drm/exynos/regs-mixer.h +++ b/drivers/gpu/drm/exynos/regs-mixer.h | |||
@@ -78,6 +78,7 @@ | |||
78 | #define MXR_STATUS_BIG_ENDIAN (1 << 3) | 78 | #define MXR_STATUS_BIG_ENDIAN (1 << 3) |
79 | #define MXR_STATUS_ENDIAN_MASK (1 << 3) | 79 | #define MXR_STATUS_ENDIAN_MASK (1 << 3) |
80 | #define MXR_STATUS_SYNC_ENABLE (1 << 2) | 80 | #define MXR_STATUS_SYNC_ENABLE (1 << 2) |
81 | #define MXR_STATUS_REG_IDLE (1 << 1) | ||
81 | #define MXR_STATUS_REG_RUN (1 << 0) | 82 | #define MXR_STATUS_REG_RUN (1 << 0) |
82 | 83 | ||
83 | /* bits for MXR_CFG */ | 84 | /* bits for MXR_CFG */ |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 601caa88c092..b8c689202c40 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -446,7 +446,9 @@ static int i915_gem_object_info(struct seq_file *m, void* data) | |||
446 | 446 | ||
447 | memset(&stats, 0, sizeof(stats)); | 447 | memset(&stats, 0, sizeof(stats)); |
448 | stats.file_priv = file->driver_priv; | 448 | stats.file_priv = file->driver_priv; |
449 | spin_lock(&file->table_lock); | ||
449 | idr_for_each(&file->object_idr, per_file_stats, &stats); | 450 | idr_for_each(&file->object_idr, per_file_stats, &stats); |
451 | spin_unlock(&file->table_lock); | ||
450 | /* | 452 | /* |
451 | * Although we have a valid reference on file->pid, that does | 453 | * Although we have a valid reference on file->pid, that does |
452 | * not guarantee that the task_struct who called get_pid() is | 454 | * not guarantee that the task_struct who called get_pid() is |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 49414d30e8d4..a47fbf60b781 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -977,6 +977,8 @@ struct i915_power_well { | |||
977 | bool always_on; | 977 | bool always_on; |
978 | /* power well enable/disable usage count */ | 978 | /* power well enable/disable usage count */ |
979 | int count; | 979 | int count; |
980 | /* cached hw enabled state */ | ||
981 | bool hw_enabled; | ||
980 | unsigned long domains; | 982 | unsigned long domains; |
981 | unsigned long data; | 983 | unsigned long data; |
982 | const struct i915_power_well_ops *ops; | 984 | const struct i915_power_well_ops *ops; |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 3ffe308d5893..a5ddf3bce9c3 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
@@ -598,6 +598,7 @@ static int do_switch(struct intel_engine_cs *ring, | |||
598 | struct intel_context *from = ring->last_context; | 598 | struct intel_context *from = ring->last_context; |
599 | struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(to); | 599 | struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(to); |
600 | u32 hw_flags = 0; | 600 | u32 hw_flags = 0; |
601 | bool uninitialized = false; | ||
601 | int ret, i; | 602 | int ret, i; |
602 | 603 | ||
603 | if (from != NULL && ring == &dev_priv->ring[RCS]) { | 604 | if (from != NULL && ring == &dev_priv->ring[RCS]) { |
@@ -696,19 +697,20 @@ static int do_switch(struct intel_engine_cs *ring, | |||
696 | i915_gem_context_unreference(from); | 697 | i915_gem_context_unreference(from); |
697 | } | 698 | } |
698 | 699 | ||
700 | uninitialized = !to->is_initialized && from == NULL; | ||
701 | to->is_initialized = true; | ||
702 | |||
699 | done: | 703 | done: |
700 | i915_gem_context_reference(to); | 704 | i915_gem_context_reference(to); |
701 | ring->last_context = to; | 705 | ring->last_context = to; |
702 | to->last_ring = ring; | 706 | to->last_ring = ring; |
703 | 707 | ||
704 | if (ring->id == RCS && !to->is_initialized && from == NULL) { | 708 | if (uninitialized) { |
705 | ret = i915_gem_render_state_init(ring); | 709 | ret = i915_gem_render_state_init(ring); |
706 | if (ret) | 710 | if (ret) |
707 | DRM_ERROR("init render state: %d\n", ret); | 711 | DRM_ERROR("init render state: %d\n", ret); |
708 | } | 712 | } |
709 | 713 | ||
710 | to->is_initialized = true; | ||
711 | |||
712 | return 0; | 714 | return 0; |
713 | 715 | ||
714 | unpin_out: | 716 | unpin_out: |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 1ee98f121a00..827498e081df 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -315,9 +315,6 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb) | |||
315 | const struct bdb_lfp_backlight_data *backlight_data; | 315 | const struct bdb_lfp_backlight_data *backlight_data; |
316 | const struct bdb_lfp_backlight_data_entry *entry; | 316 | const struct bdb_lfp_backlight_data_entry *entry; |
317 | 317 | ||
318 | /* Err to enabling backlight if no backlight block. */ | ||
319 | dev_priv->vbt.backlight.present = true; | ||
320 | |||
321 | backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT); | 318 | backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT); |
322 | if (!backlight_data) | 319 | if (!backlight_data) |
323 | return; | 320 | return; |
@@ -1088,6 +1085,9 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) | |||
1088 | 1085 | ||
1089 | dev_priv->vbt.crt_ddc_pin = GMBUS_PORT_VGADDC; | 1086 | dev_priv->vbt.crt_ddc_pin = GMBUS_PORT_VGADDC; |
1090 | 1087 | ||
1088 | /* Default to having backlight */ | ||
1089 | dev_priv->vbt.backlight.present = true; | ||
1090 | |||
1091 | /* LFP panel data */ | 1091 | /* LFP panel data */ |
1092 | dev_priv->vbt.lvds_dither = 1; | 1092 | dev_priv->vbt.lvds_dither = 1; |
1093 | dev_priv->vbt.lvds_vbt = 0; | 1093 | dev_priv->vbt.lvds_vbt = 0; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index efd3cf50cb0f..5f285fba4e41 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -4564,7 +4564,10 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) | |||
4564 | if (intel_crtc->active) | 4564 | if (intel_crtc->active) |
4565 | return; | 4565 | return; |
4566 | 4566 | ||
4567 | vlv_prepare_pll(intel_crtc); | 4567 | is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI); |
4568 | |||
4569 | if (!is_dsi && !IS_CHERRYVIEW(dev)) | ||
4570 | vlv_prepare_pll(intel_crtc); | ||
4568 | 4571 | ||
4569 | /* Set up the display plane register */ | 4572 | /* Set up the display plane register */ |
4570 | dspcntr = DISPPLANE_GAMMA_ENABLE; | 4573 | dspcntr = DISPPLANE_GAMMA_ENABLE; |
@@ -4598,8 +4601,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) | |||
4598 | if (encoder->pre_pll_enable) | 4601 | if (encoder->pre_pll_enable) |
4599 | encoder->pre_pll_enable(encoder); | 4602 | encoder->pre_pll_enable(encoder); |
4600 | 4603 | ||
4601 | is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI); | ||
4602 | |||
4603 | if (!is_dsi) { | 4604 | if (!is_dsi) { |
4604 | if (IS_CHERRYVIEW(dev)) | 4605 | if (IS_CHERRYVIEW(dev)) |
4605 | chv_enable_pll(intel_crtc); | 4606 | chv_enable_pll(intel_crtc); |
@@ -12411,8 +12412,8 @@ intel_display_capture_error_state(struct drm_device *dev) | |||
12411 | 12412 | ||
12412 | for_each_pipe(i) { | 12413 | for_each_pipe(i) { |
12413 | error->pipe[i].power_domain_on = | 12414 | error->pipe[i].power_domain_on = |
12414 | intel_display_power_enabled_sw(dev_priv, | 12415 | intel_display_power_enabled_unlocked(dev_priv, |
12415 | POWER_DOMAIN_PIPE(i)); | 12416 | POWER_DOMAIN_PIPE(i)); |
12416 | if (!error->pipe[i].power_domain_on) | 12417 | if (!error->pipe[i].power_domain_on) |
12417 | continue; | 12418 | continue; |
12418 | 12419 | ||
@@ -12447,7 +12448,7 @@ intel_display_capture_error_state(struct drm_device *dev) | |||
12447 | enum transcoder cpu_transcoder = transcoders[i]; | 12448 | enum transcoder cpu_transcoder = transcoders[i]; |
12448 | 12449 | ||
12449 | error->transcoder[i].power_domain_on = | 12450 | error->transcoder[i].power_domain_on = |
12450 | intel_display_power_enabled_sw(dev_priv, | 12451 | intel_display_power_enabled_unlocked(dev_priv, |
12451 | POWER_DOMAIN_TRANSCODER(cpu_transcoder)); | 12452 | POWER_DOMAIN_TRANSCODER(cpu_transcoder)); |
12452 | if (!error->transcoder[i].power_domain_on) | 12453 | if (!error->transcoder[i].power_domain_on) |
12453 | continue; | 12454 | continue; |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index bda0ae3d80cc..eaa27ee9e367 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -950,8 +950,8 @@ int intel_power_domains_init(struct drm_i915_private *); | |||
950 | void intel_power_domains_remove(struct drm_i915_private *); | 950 | void intel_power_domains_remove(struct drm_i915_private *); |
951 | bool intel_display_power_enabled(struct drm_i915_private *dev_priv, | 951 | bool intel_display_power_enabled(struct drm_i915_private *dev_priv, |
952 | enum intel_display_power_domain domain); | 952 | enum intel_display_power_domain domain); |
953 | bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, | 953 | bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, |
954 | enum intel_display_power_domain domain); | 954 | enum intel_display_power_domain domain); |
955 | void intel_display_power_get(struct drm_i915_private *dev_priv, | 955 | void intel_display_power_get(struct drm_i915_private *dev_priv, |
956 | enum intel_display_power_domain domain); | 956 | enum intel_display_power_domain domain); |
957 | void intel_display_power_put(struct drm_i915_private *dev_priv, | 957 | void intel_display_power_put(struct drm_i915_private *dev_priv, |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 54242e4f6f4c..9ad0c6afc487 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -5603,8 +5603,8 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, | |||
5603 | (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); | 5603 | (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); |
5604 | } | 5604 | } |
5605 | 5605 | ||
5606 | bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, | 5606 | bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, |
5607 | enum intel_display_power_domain domain) | 5607 | enum intel_display_power_domain domain) |
5608 | { | 5608 | { |
5609 | struct i915_power_domains *power_domains; | 5609 | struct i915_power_domains *power_domains; |
5610 | struct i915_power_well *power_well; | 5610 | struct i915_power_well *power_well; |
@@ -5615,16 +5615,19 @@ bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, | |||
5615 | return false; | 5615 | return false; |
5616 | 5616 | ||
5617 | power_domains = &dev_priv->power_domains; | 5617 | power_domains = &dev_priv->power_domains; |
5618 | |||
5618 | is_enabled = true; | 5619 | is_enabled = true; |
5620 | |||
5619 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { | 5621 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { |
5620 | if (power_well->always_on) | 5622 | if (power_well->always_on) |
5621 | continue; | 5623 | continue; |
5622 | 5624 | ||
5623 | if (!power_well->count) { | 5625 | if (!power_well->hw_enabled) { |
5624 | is_enabled = false; | 5626 | is_enabled = false; |
5625 | break; | 5627 | break; |
5626 | } | 5628 | } |
5627 | } | 5629 | } |
5630 | |||
5628 | return is_enabled; | 5631 | return is_enabled; |
5629 | } | 5632 | } |
5630 | 5633 | ||
@@ -5632,30 +5635,15 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv, | |||
5632 | enum intel_display_power_domain domain) | 5635 | enum intel_display_power_domain domain) |
5633 | { | 5636 | { |
5634 | struct i915_power_domains *power_domains; | 5637 | struct i915_power_domains *power_domains; |
5635 | struct i915_power_well *power_well; | 5638 | bool ret; |
5636 | bool is_enabled; | ||
5637 | int i; | ||
5638 | |||
5639 | if (dev_priv->pm.suspended) | ||
5640 | return false; | ||
5641 | 5639 | ||
5642 | power_domains = &dev_priv->power_domains; | 5640 | power_domains = &dev_priv->power_domains; |
5643 | 5641 | ||
5644 | is_enabled = true; | ||
5645 | |||
5646 | mutex_lock(&power_domains->lock); | 5642 | mutex_lock(&power_domains->lock); |
5647 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { | 5643 | ret = intel_display_power_enabled_unlocked(dev_priv, domain); |
5648 | if (power_well->always_on) | ||
5649 | continue; | ||
5650 | |||
5651 | if (!power_well->ops->is_enabled(dev_priv, power_well)) { | ||
5652 | is_enabled = false; | ||
5653 | break; | ||
5654 | } | ||
5655 | } | ||
5656 | mutex_unlock(&power_domains->lock); | 5644 | mutex_unlock(&power_domains->lock); |
5657 | 5645 | ||
5658 | return is_enabled; | 5646 | return ret; |
5659 | } | 5647 | } |
5660 | 5648 | ||
5661 | /* | 5649 | /* |
@@ -5976,6 +5964,7 @@ void intel_display_power_get(struct drm_i915_private *dev_priv, | |||
5976 | if (!power_well->count++) { | 5964 | if (!power_well->count++) { |
5977 | DRM_DEBUG_KMS("enabling %s\n", power_well->name); | 5965 | DRM_DEBUG_KMS("enabling %s\n", power_well->name); |
5978 | power_well->ops->enable(dev_priv, power_well); | 5966 | power_well->ops->enable(dev_priv, power_well); |
5967 | power_well->hw_enabled = true; | ||
5979 | } | 5968 | } |
5980 | 5969 | ||
5981 | check_power_well_state(dev_priv, power_well); | 5970 | check_power_well_state(dev_priv, power_well); |
@@ -6005,6 +5994,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, | |||
6005 | 5994 | ||
6006 | if (!--power_well->count && i915.disable_power_well) { | 5995 | if (!--power_well->count && i915.disable_power_well) { |
6007 | DRM_DEBUG_KMS("disabling %s\n", power_well->name); | 5996 | DRM_DEBUG_KMS("disabling %s\n", power_well->name); |
5997 | power_well->hw_enabled = false; | ||
6008 | power_well->ops->disable(dev_priv, power_well); | 5998 | power_well->ops->disable(dev_priv, power_well); |
6009 | } | 5999 | } |
6010 | 6000 | ||
@@ -6267,8 +6257,11 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv) | |||
6267 | int i; | 6257 | int i; |
6268 | 6258 | ||
6269 | mutex_lock(&power_domains->lock); | 6259 | mutex_lock(&power_domains->lock); |
6270 | for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) | 6260 | for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) { |
6271 | power_well->ops->sync_hw(dev_priv, power_well); | 6261 | power_well->ops->sync_hw(dev_priv, power_well); |
6262 | power_well->hw_enabled = power_well->ops->is_enabled(dev_priv, | ||
6263 | power_well); | ||
6264 | } | ||
6272 | mutex_unlock(&power_domains->lock); | 6265 | mutex_unlock(&power_domains->lock); |
6273 | } | 6266 | } |
6274 | 6267 | ||
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index ae750f6928c1..7f7aadef8a82 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c | |||
@@ -277,6 +277,7 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) | |||
277 | static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"}; | 277 | static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"}; |
278 | static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"}; | 278 | static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"}; |
279 | static const char *hpd_clk_names[] = {"iface_clk", "core_clk", "mdp_core_clk"}; | 279 | static const char *hpd_clk_names[] = {"iface_clk", "core_clk", "mdp_core_clk"}; |
280 | static unsigned long hpd_clk_freq[] = {0, 19200000, 0}; | ||
280 | static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"}; | 281 | static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"}; |
281 | 282 | ||
282 | config.phy_init = hdmi_phy_8x74_init; | 283 | config.phy_init = hdmi_phy_8x74_init; |
@@ -286,6 +287,7 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) | |||
286 | config.pwr_reg_names = pwr_reg_names; | 287 | config.pwr_reg_names = pwr_reg_names; |
287 | config.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names); | 288 | config.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names); |
288 | config.hpd_clk_names = hpd_clk_names; | 289 | config.hpd_clk_names = hpd_clk_names; |
290 | config.hpd_freq = hpd_clk_freq; | ||
289 | config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); | 291 | config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); |
290 | config.pwr_clk_names = pwr_clk_names; | 292 | config.pwr_clk_names = pwr_clk_names; |
291 | config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names); | 293 | config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names); |
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index 9fafee6a3e43..9d7723c6528a 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h | |||
@@ -87,6 +87,7 @@ struct hdmi_platform_config { | |||
87 | 87 | ||
88 | /* clks that need to be on for hpd: */ | 88 | /* clks that need to be on for hpd: */ |
89 | const char **hpd_clk_names; | 89 | const char **hpd_clk_names; |
90 | const long unsigned *hpd_freq; | ||
90 | int hpd_clk_cnt; | 91 | int hpd_clk_cnt; |
91 | 92 | ||
92 | /* clks that need to be on for screen pwr (ie pixel clk): */ | 93 | /* clks that need to be on for screen pwr (ie pixel clk): */ |
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c index e56a6196867c..28f7e3ec6c28 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c | |||
@@ -127,6 +127,14 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector) | |||
127 | } | 127 | } |
128 | 128 | ||
129 | for (i = 0; i < config->hpd_clk_cnt; i++) { | 129 | for (i = 0; i < config->hpd_clk_cnt; i++) { |
130 | if (config->hpd_freq && config->hpd_freq[i]) { | ||
131 | ret = clk_set_rate(hdmi->hpd_clks[i], | ||
132 | config->hpd_freq[i]); | ||
133 | if (ret) | ||
134 | dev_warn(dev->dev, "failed to set clk %s (%d)\n", | ||
135 | config->hpd_clk_names[i], ret); | ||
136 | } | ||
137 | |||
130 | ret = clk_prepare_enable(hdmi->hpd_clks[i]); | 138 | ret = clk_prepare_enable(hdmi->hpd_clks[i]); |
131 | if (ret) { | 139 | if (ret) { |
132 | dev_err(dev->dev, "failed to enable hpd clk: %s (%d)\n", | 140 | dev_err(dev->dev, "failed to enable hpd clk: %s (%d)\n", |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 42caf7fcb0b9..71510ee26e96 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | |||
@@ -20,6 +20,10 @@ | |||
20 | #include "msm_mmu.h" | 20 | #include "msm_mmu.h" |
21 | #include "mdp5_kms.h" | 21 | #include "mdp5_kms.h" |
22 | 22 | ||
23 | static const char *iommu_ports[] = { | ||
24 | "mdp_0", | ||
25 | }; | ||
26 | |||
23 | static struct mdp5_platform_config *mdp5_get_config(struct platform_device *dev); | 27 | static struct mdp5_platform_config *mdp5_get_config(struct platform_device *dev); |
24 | 28 | ||
25 | static int mdp5_hw_init(struct msm_kms *kms) | 29 | static int mdp5_hw_init(struct msm_kms *kms) |
@@ -104,6 +108,12 @@ static void mdp5_preclose(struct msm_kms *kms, struct drm_file *file) | |||
104 | static void mdp5_destroy(struct msm_kms *kms) | 108 | static void mdp5_destroy(struct msm_kms *kms) |
105 | { | 109 | { |
106 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); | 110 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); |
111 | struct msm_mmu *mmu = mdp5_kms->mmu; | ||
112 | |||
113 | if (mmu) { | ||
114 | mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); | ||
115 | mmu->funcs->destroy(mmu); | ||
116 | } | ||
107 | kfree(mdp5_kms); | 117 | kfree(mdp5_kms); |
108 | } | 118 | } |
109 | 119 | ||
@@ -216,10 +226,6 @@ fail: | |||
216 | return ret; | 226 | return ret; |
217 | } | 227 | } |
218 | 228 | ||
219 | static const char *iommu_ports[] = { | ||
220 | "mdp_0", | ||
221 | }; | ||
222 | |||
223 | static int get_clk(struct platform_device *pdev, struct clk **clkp, | 229 | static int get_clk(struct platform_device *pdev, struct clk **clkp, |
224 | const char *name) | 230 | const char *name) |
225 | { | 231 | { |
@@ -317,17 +323,23 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) | |||
317 | mmu = msm_iommu_new(dev, config->iommu); | 323 | mmu = msm_iommu_new(dev, config->iommu); |
318 | if (IS_ERR(mmu)) { | 324 | if (IS_ERR(mmu)) { |
319 | ret = PTR_ERR(mmu); | 325 | ret = PTR_ERR(mmu); |
326 | dev_err(dev->dev, "failed to init iommu: %d\n", ret); | ||
320 | goto fail; | 327 | goto fail; |
321 | } | 328 | } |
329 | |||
322 | ret = mmu->funcs->attach(mmu, iommu_ports, | 330 | ret = mmu->funcs->attach(mmu, iommu_ports, |
323 | ARRAY_SIZE(iommu_ports)); | 331 | ARRAY_SIZE(iommu_ports)); |
324 | if (ret) | 332 | if (ret) { |
333 | dev_err(dev->dev, "failed to attach iommu: %d\n", ret); | ||
334 | mmu->funcs->destroy(mmu); | ||
325 | goto fail; | 335 | goto fail; |
336 | } | ||
326 | } else { | 337 | } else { |
327 | dev_info(dev->dev, "no iommu, fallback to phys " | 338 | dev_info(dev->dev, "no iommu, fallback to phys " |
328 | "contig buffers for scanout\n"); | 339 | "contig buffers for scanout\n"); |
329 | mmu = NULL; | 340 | mmu = NULL; |
330 | } | 341 | } |
342 | mdp5_kms->mmu = mmu; | ||
331 | 343 | ||
332 | mdp5_kms->id = msm_register_mmu(dev, mmu); | 344 | mdp5_kms->id = msm_register_mmu(dev, mmu); |
333 | if (mdp5_kms->id < 0) { | 345 | if (mdp5_kms->id < 0) { |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index c8b1a2522c25..6e981b692d1d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | |||
@@ -33,6 +33,7 @@ struct mdp5_kms { | |||
33 | 33 | ||
34 | /* mapper-id used to request GEM buffer mapped for scanout: */ | 34 | /* mapper-id used to request GEM buffer mapped for scanout: */ |
35 | int id; | 35 | int id; |
36 | struct msm_mmu *mmu; | ||
36 | 37 | ||
37 | /* for tracking smp allocation amongst pipes: */ | 38 | /* for tracking smp allocation amongst pipes: */ |
38 | mdp5_smp_state_t smp_state; | 39 | mdp5_smp_state_t smp_state; |
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 0d2562fb681e..9a5d87db5c23 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c | |||
@@ -159,7 +159,7 @@ static int msm_unload(struct drm_device *dev) | |||
159 | static int get_mdp_ver(struct platform_device *pdev) | 159 | static int get_mdp_ver(struct platform_device *pdev) |
160 | { | 160 | { |
161 | #ifdef CONFIG_OF | 161 | #ifdef CONFIG_OF |
162 | const static struct of_device_id match_types[] = { { | 162 | static const struct of_device_id match_types[] = { { |
163 | .compatible = "qcom,mdss_mdp", | 163 | .compatible = "qcom,mdss_mdp", |
164 | .data = (void *)5, | 164 | .data = (void *)5, |
165 | }, { | 165 | }, { |
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index a752ab83b810..5107fc4826bc 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c | |||
@@ -59,7 +59,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, | |||
59 | struct drm_framebuffer *fb = NULL; | 59 | struct drm_framebuffer *fb = NULL; |
60 | struct fb_info *fbi = NULL; | 60 | struct fb_info *fbi = NULL; |
61 | struct drm_mode_fb_cmd2 mode_cmd = {0}; | 61 | struct drm_mode_fb_cmd2 mode_cmd = {0}; |
62 | dma_addr_t paddr; | 62 | uint32_t paddr; |
63 | int ret, size; | 63 | int ret, size; |
64 | 64 | ||
65 | sizes->surface_bpp = 32; | 65 | sizes->surface_bpp = 32; |
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index bb8026daebc9..690d7e7b6d1e 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c | |||
@@ -278,6 +278,7 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, | |||
278 | uint32_t *iova) | 278 | uint32_t *iova) |
279 | { | 279 | { |
280 | struct msm_gem_object *msm_obj = to_msm_bo(obj); | 280 | struct msm_gem_object *msm_obj = to_msm_bo(obj); |
281 | struct drm_device *dev = obj->dev; | ||
281 | int ret = 0; | 282 | int ret = 0; |
282 | 283 | ||
283 | if (!msm_obj->domain[id].iova) { | 284 | if (!msm_obj->domain[id].iova) { |
@@ -285,6 +286,11 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, | |||
285 | struct msm_mmu *mmu = priv->mmus[id]; | 286 | struct msm_mmu *mmu = priv->mmus[id]; |
286 | struct page **pages = get_pages(obj); | 287 | struct page **pages = get_pages(obj); |
287 | 288 | ||
289 | if (!mmu) { | ||
290 | dev_err(dev->dev, "null MMU pointer\n"); | ||
291 | return -EINVAL; | ||
292 | } | ||
293 | |||
288 | if (IS_ERR(pages)) | 294 | if (IS_ERR(pages)) |
289 | return PTR_ERR(pages); | 295 | return PTR_ERR(pages); |
290 | 296 | ||
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index 92b745986231..4b2ad9181edf 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c | |||
@@ -28,7 +28,7 @@ static int msm_fault_handler(struct iommu_domain *iommu, struct device *dev, | |||
28 | unsigned long iova, int flags, void *arg) | 28 | unsigned long iova, int flags, void *arg) |
29 | { | 29 | { |
30 | DBG("*** fault: iova=%08lx, flags=%d", iova, flags); | 30 | DBG("*** fault: iova=%08lx, flags=%d", iova, flags); |
31 | return 0; | 31 | return -ENOSYS; |
32 | } | 32 | } |
33 | 33 | ||
34 | static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt) | 34 | static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt) |
@@ -40,8 +40,10 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt) | |||
40 | for (i = 0; i < cnt; i++) { | 40 | for (i = 0; i < cnt; i++) { |
41 | struct device *msm_iommu_get_ctx(const char *ctx_name); | 41 | struct device *msm_iommu_get_ctx(const char *ctx_name); |
42 | struct device *ctx = msm_iommu_get_ctx(names[i]); | 42 | struct device *ctx = msm_iommu_get_ctx(names[i]); |
43 | if (IS_ERR_OR_NULL(ctx)) | 43 | if (IS_ERR_OR_NULL(ctx)) { |
44 | dev_warn(dev->dev, "couldn't get %s context", names[i]); | ||
44 | continue; | 45 | continue; |
46 | } | ||
45 | ret = iommu_attach_device(iommu->domain, ctx); | 47 | ret = iommu_attach_device(iommu->domain, ctx); |
46 | if (ret) { | 48 | if (ret) { |
47 | dev_warn(dev->dev, "could not attach iommu to %s", names[i]); | 49 | dev_warn(dev->dev, "could not attach iommu to %s", names[i]); |
@@ -52,6 +54,20 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt) | |||
52 | return 0; | 54 | return 0; |
53 | } | 55 | } |
54 | 56 | ||
57 | static void msm_iommu_detach(struct msm_mmu *mmu, const char **names, int cnt) | ||
58 | { | ||
59 | struct msm_iommu *iommu = to_msm_iommu(mmu); | ||
60 | int i; | ||
61 | |||
62 | for (i = 0; i < cnt; i++) { | ||
63 | struct device *msm_iommu_get_ctx(const char *ctx_name); | ||
64 | struct device *ctx = msm_iommu_get_ctx(names[i]); | ||
65 | if (IS_ERR_OR_NULL(ctx)) | ||
66 | continue; | ||
67 | iommu_detach_device(iommu->domain, ctx); | ||
68 | } | ||
69 | } | ||
70 | |||
55 | static int msm_iommu_map(struct msm_mmu *mmu, uint32_t iova, | 71 | static int msm_iommu_map(struct msm_mmu *mmu, uint32_t iova, |
56 | struct sg_table *sgt, unsigned len, int prot) | 72 | struct sg_table *sgt, unsigned len, int prot) |
57 | { | 73 | { |
@@ -110,7 +126,7 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint32_t iova, | |||
110 | 126 | ||
111 | VERB("unmap[%d]: %08x(%x)", i, iova, bytes); | 127 | VERB("unmap[%d]: %08x(%x)", i, iova, bytes); |
112 | 128 | ||
113 | BUG_ON(!IS_ALIGNED(bytes, PAGE_SIZE)); | 129 | BUG_ON(!PAGE_ALIGNED(bytes)); |
114 | 130 | ||
115 | da += bytes; | 131 | da += bytes; |
116 | } | 132 | } |
@@ -127,6 +143,7 @@ static void msm_iommu_destroy(struct msm_mmu *mmu) | |||
127 | 143 | ||
128 | static const struct msm_mmu_funcs funcs = { | 144 | static const struct msm_mmu_funcs funcs = { |
129 | .attach = msm_iommu_attach, | 145 | .attach = msm_iommu_attach, |
146 | .detach = msm_iommu_detach, | ||
130 | .map = msm_iommu_map, | 147 | .map = msm_iommu_map, |
131 | .unmap = msm_iommu_unmap, | 148 | .unmap = msm_iommu_unmap, |
132 | .destroy = msm_iommu_destroy, | 149 | .destroy = msm_iommu_destroy, |
diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h index 030324482b4a..21da6d154f71 100644 --- a/drivers/gpu/drm/msm/msm_mmu.h +++ b/drivers/gpu/drm/msm/msm_mmu.h | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | struct msm_mmu_funcs { | 23 | struct msm_mmu_funcs { |
24 | int (*attach)(struct msm_mmu *mmu, const char **names, int cnt); | 24 | int (*attach)(struct msm_mmu *mmu, const char **names, int cnt); |
25 | void (*detach)(struct msm_mmu *mmu, const char **names, int cnt); | ||
25 | int (*map)(struct msm_mmu *mmu, uint32_t iova, struct sg_table *sgt, | 26 | int (*map)(struct msm_mmu *mmu, uint32_t iova, struct sg_table *sgt, |
26 | unsigned len, int prot); | 27 | unsigned len, int prot); |
27 | int (*unmap)(struct msm_mmu *mmu, uint32_t iova, struct sg_table *sgt, | 28 | int (*unmap)(struct msm_mmu *mmu, uint32_t iova, struct sg_table *sgt, |
diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 0572035673f3..a70d45647898 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h | |||
@@ -237,13 +237,21 @@ | |||
237 | #define INTEL_BDW_GT3D_IDS(info) \ | 237 | #define INTEL_BDW_GT3D_IDS(info) \ |
238 | _INTEL_BDW_D_IDS(3, info) | 238 | _INTEL_BDW_D_IDS(3, info) |
239 | 239 | ||
240 | #define INTEL_BDW_RSVDM_IDS(info) \ | ||
241 | _INTEL_BDW_M_IDS(4, info) | ||
242 | |||
243 | #define INTEL_BDW_RSVDD_IDS(info) \ | ||
244 | _INTEL_BDW_D_IDS(4, info) | ||
245 | |||
240 | #define INTEL_BDW_M_IDS(info) \ | 246 | #define INTEL_BDW_M_IDS(info) \ |
241 | INTEL_BDW_GT12M_IDS(info), \ | 247 | INTEL_BDW_GT12M_IDS(info), \ |
242 | INTEL_BDW_GT3M_IDS(info) | 248 | INTEL_BDW_GT3M_IDS(info), \ |
249 | INTEL_BDW_RSVDM_IDS(info) | ||
243 | 250 | ||
244 | #define INTEL_BDW_D_IDS(info) \ | 251 | #define INTEL_BDW_D_IDS(info) \ |
245 | INTEL_BDW_GT12D_IDS(info), \ | 252 | INTEL_BDW_GT12D_IDS(info), \ |
246 | INTEL_BDW_GT3D_IDS(info) | 253 | INTEL_BDW_GT3D_IDS(info), \ |
254 | INTEL_BDW_RSVDD_IDS(info) | ||
247 | 255 | ||
248 | #define INTEL_CHV_IDS(info) \ | 256 | #define INTEL_CHV_IDS(info) \ |
249 | INTEL_VGA_DEVICE(0x22b0, info), \ | 257 | INTEL_VGA_DEVICE(0x22b0, info), \ |