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 ...
Unified · Split
| @@ -419,8 +419,9 @@ long drm_ioctl(struct file *filp, · 418 unmodified lines | ||
| 419 | 419 | retcode = -EFAULT; |
| 420 | 420 | goto err_i1; |
| 421 | 421 | } |
| 422 | − } else | |
| 422 | + } else if (cmd & IOC_OUT) { | |
| 423 | 423 | memset(kdata, 0, usize); |
| 424 | + } | |
| 424 | 425 | |
| 425 | 426 | if (ioctl->flags & DRM_UNLOCKED) |
| 426 | 427 | retcode = func(dev, kdata, file_priv); |
| @@ -40,7 +40,7 @@ exynos_dpi_detect(struct drm_connector *connector, bool force) · 39 unmodified lines | ||
| 40 | 40 | { |
| 41 | 41 | struct exynos_dpi *ctx = connector_to_dpi(connector); |
| 42 | 42 | |
| 43 | − if (!ctx->panel->connector) | |
| 43 | + if (ctx->panel && !ctx->panel->connector) | |
| 44 | 44 | drm_panel_attach(ctx->panel, &ctx->connector); |
| 45 | 45 | |
| 46 | 46 | return connector_status_connected; |
| @@ -765,24 +765,24 @@ static int exynos_drm_init(void) · 764 unmodified lines | ||
| 765 | 765 | |
| 766 | 766 | return 0; |
| 767 | 767 | |
| 768 | −err_unregister_pd: | |
| 769 | − platform_device_unregister(exynos_drm_pdev); | |
| 770 | − | |
| 771 | 768 | err_remove_vidi: |
| 772 | 769 | #ifdef CONFIG_DRM_EXYNOS_VIDI |
| 773 | 770 | exynos_drm_remove_vidi(); |
| 771 | + | |
| 772 | +err_unregister_pd: | |
| 774 | 773 | #endif |
| 774 | + platform_device_unregister(exynos_drm_pdev); | |
| 775 | 775 | |
| 776 | 776 | return ret; |
| 777 | 777 | } |
| 778 | 778 | |
| 779 | 779 | static void exynos_drm_exit(void) |
| 780 | 780 | { |
| 781 | + platform_driver_unregister(&exynos_drm_platform_driver); | |
| 781 | 782 | #ifdef CONFIG_DRM_EXYNOS_VIDI |
| 782 | 783 | exynos_drm_remove_vidi(); |
| 783 | 784 | #endif |
| 784 | 785 | platform_device_unregister(exynos_drm_pdev); |
| 785 | − platform_driver_unregister(&exynos_drm_platform_driver); | |
| 786 | 786 | } |
| 787 | 787 | |
| 788 | 788 | module_init(exynos_drm_init); |
| @@ -343,7 +343,7 @@ struct exynos_drm_display * exynos_dpi_probe(struct device *dev); · 342 unmodified lines | ||
| 343 | 343 | int exynos_dpi_remove(struct device *dev); |
| 344 | 344 | #else |
| 345 | 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 | 347 | static inline int exynos_dpi_remove(struct device *dev) { return 0; } |
| 348 | 348 | #endif |
| 349 | 349 | |
| @@ -741,6 +741,8 @@ static void fimd_apply(struct exynos_drm_manager *mgr) · 740 unmodified lines | ||
| 741 | 741 | win_data = &ctx->win_data[i]; |
| 742 | 742 | if (win_data->enabled) |
| 743 | 743 | fimd_win_commit(mgr, i); |
| 744 | + else | |
| 745 | + fimd_win_disable(mgr, i); | |
| 744 | 746 | } |
| 745 | 747 | |
| 746 | 748 | fimd_commit(mgr); |
| @@ -2090,6 +2090,11 @@ out: · 2089 unmodified lines | ||
| 2090 | 2090 | |
| 2091 | 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 | 2098 | DRM_DEBUG_KMS("mode %d\n", mode); |
| 2094 | 2099 | |
| 2095 | 2100 | switch (mode) { |
| @@ -2099,6 +2104,20 @@ static void hdmi_dpms(struct exynos_drm_display *display, int mode) · 3 unmodified lines | ||
| 2099 | 2104 | case DRM_MODE_DPMS_STANDBY: |
| 2100 | 2105 | case DRM_MODE_DPMS_SUSPEND: |
| 2101 | 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 | 2121 | hdmi_poweroff(display); |
| 2103 | 2122 | break; |
| 2104 | 2123 | default: |
| @@ -377,6 +377,20 @@ static void mixer_run(struct mixer_context *ctx) · 376 unmodified lines | ||
| 377 | 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 | 394 | static void vp_video_buffer(struct mixer_context *ctx, int win) |
| 381 | 395 | { |
| 382 | 396 | struct mixer_resources *res = &ctx->mixer_res; |
| @@ -497,13 +511,8 @@ static void vp_video_buffer(struct mixer_context *ctx, int win) · 114 unmodified lines | ||
| 497 | 511 | static void mixer_layer_update(struct mixer_context *ctx) |
| 498 | 512 | { |
| 499 | 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 */ | |
| 505 | − if (!(val & MXR_CFG_LAYER_UPDATE_COUNT_MASK)) | |
| 506 | − mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE); | |
| 515 | + mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE); | |
| 507 | 516 | } |
| 508 | 517 | |
| 509 | 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) · 500 unmodified lines | ||
| 1010 | 1019 | } |
| 1011 | 1020 | mutex_unlock(&mixer_ctx->mixer_mutex); |
| 1012 | 1021 | |
| 1022 | + drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe); | |
| 1023 | + | |
| 1013 | 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) · 4 unmodified lines | ||
| 1020 | 1031 | !atomic_read(&mixer_ctx->wait_vsync_event), |
| 1021 | 1032 | HZ/20)) |
| 1022 | 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 | 1038 | static void mixer_window_suspend(struct exynos_drm_manager *mgr) |
| @@ -1061,7 +1074,7 @@ static void mixer_poweron(struct exynos_drm_manager *mgr) · 35 unmodified lines | ||
| 1061 | 1074 | mutex_unlock(&ctx->mixer_mutex); |
| 1062 | 1075 | return; |
| 1063 | 1076 | } |
| 1064 | − ctx->powered = true; | |
| 1077 | + | |
| 1065 | 1078 | mutex_unlock(&ctx->mixer_mutex); |
| 1066 | 1079 | |
| 1067 | 1080 | pm_runtime_get_sync(ctx->dev); |
| @@ -1072,6 +1085,12 @@ static void mixer_poweron(struct exynos_drm_manager *mgr) · 4 unmodified lines | ||
| 1072 | 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 | 1094 | mixer_reg_write(res, MXR_INT_EN, ctx->int_en); |
| 1076 | 1095 | mixer_win_reset(ctx); |
| 1077 | 1096 | |
| @@ -1084,14 +1103,21 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr) · 6 unmodified lines | ||
| 1084 | 1103 | struct mixer_resources *res = &ctx->mixer_res; |
| 1085 | 1104 | |
| 1086 | 1105 | mutex_lock(&ctx->mixer_mutex); |
| 1087 | − if (!ctx->powered) | |
| 1088 | − goto out; | |
| 1106 | + if (!ctx->powered) { | |
| 1107 | + mutex_unlock(&ctx->mixer_mutex); | |
| 1108 | + return; | |
| 1109 | + } | |
| 1089 | 1110 | mutex_unlock(&ctx->mixer_mutex); |
| 1090 | 1111 | |
| 1112 | + mixer_stop(ctx); | |
| 1091 | 1113 | mixer_window_suspend(mgr); |
| 1092 | 1114 | |
| 1093 | 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 | 1121 | clk_disable_unprepare(res->mixer); |
| 1096 | 1122 | if (ctx->vp_enabled) { |
| 1097 | 1123 | clk_disable_unprepare(res->vp); |
| @@ -1099,12 +1125,6 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr) · 1 unmodified line | ||
| 1099 | 1125 | } |
| 1100 | 1126 | |
| 1101 | 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 | 1130 | static void mixer_dpms(struct exynos_drm_manager *mgr, int mode) |
| @@ -78,6 +78,7 @@ · 77 unmodified lines | ||
| 78 | 78 | #define MXR_STATUS_BIG_ENDIAN (1 << 3) |
| 79 | 79 | #define MXR_STATUS_ENDIAN_MASK (1 << 3) |
| 80 | 80 | #define MXR_STATUS_SYNC_ENABLE (1 << 2) |
| 81 | +#define MXR_STATUS_REG_IDLE (1 << 1) | |
| 81 | 82 | #define MXR_STATUS_REG_RUN (1 << 0) |
| 82 | 83 | |
| 83 | 84 | /* bits for MXR_CFG */ |
| @@ -446,7 +446,9 @@ static int i915_gem_object_info(struct seq_file *m, void* data) · 445 unmodified lines | ||
| 446 | 446 | |
| 447 | 447 | memset(&stats, 0, sizeof(stats)); |
| 448 | 448 | stats.file_priv = file->driver_priv; |
| 449 | + spin_lock(&file->table_lock); | |
| 449 | 450 | idr_for_each(&file->object_idr, per_file_stats, &stats); |
| 451 | + spin_unlock(&file->table_lock); | |
| 450 | 452 | /* |
| 451 | 453 | * Although we have a valid reference on file->pid, that does |
| 452 | 454 | * not guarantee that the task_struct who called get_pid() is |
| @@ -977,6 +977,8 @@ struct i915_power_well { · 976 unmodified lines | ||
| 977 | 977 | bool always_on; |
| 978 | 978 | /* power well enable/disable usage count */ |
| 979 | 979 | int count; |
| 980 | + /* cached hw enabled state */ | |
| 981 | + bool hw_enabled; | |
| 980 | 982 | unsigned long domains; |
| 981 | 983 | unsigned long data; |
| 982 | 984 | const struct i915_power_well_ops *ops; |
| @@ -598,6 +598,7 @@ static int do_switch(struct intel_engine_cs *ring, · 597 unmodified lines | ||
| 598 | 598 | struct intel_context *from = ring->last_context; |
| 599 | 599 | struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(to); |
| 600 | 600 | u32 hw_flags = 0; |
| 601 | + bool uninitialized = false; | |
| 601 | 602 | int ret, i; |
| 602 | 603 | |
| 603 | 604 | if (from != NULL && ring == &dev_priv->ring[RCS]) { |
| @@ -696,19 +697,20 @@ static int do_switch(struct intel_engine_cs *ring, · 92 unmodified lines | ||
| 696 | 697 | i915_gem_context_unreference(from); |
| 697 | 698 | } |
| 698 | 699 | |
| 700 | + uninitialized = !to->is_initialized && from == NULL; | |
| 701 | + to->is_initialized = true; | |
| 702 | + | |
| 699 | 703 | done: |
| 700 | 704 | i915_gem_context_reference(to); |
| 701 | 705 | ring->last_context = to; |
| 702 | 706 | to->last_ring = ring; |
| 703 | 707 | |
| 704 | − if (ring->id == RCS && !to->is_initialized && from == NULL) { | |
| 708 | + if (uninitialized) { | |
| 705 | 709 | ret = i915_gem_render_state_init(ring); |
| 706 | 710 | if (ret) |
| 707 | 711 | DRM_ERROR("init render state: %d\n", ret); |
| 708 | 712 | } |
| 709 | 713 | |
| 710 | − to->is_initialized = true; | |
| 711 | − | |
| 712 | 714 | return 0; |
| 713 | 715 | |
| 714 | 716 | unpin_out: |
| @@ -315,9 +315,6 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb) · 314 unmodified lines | ||
| 315 | 315 | const struct bdb_lfp_backlight_data *backlight_data; |
| 316 | 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 | 318 | backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT); |
| 322 | 319 | if (!backlight_data) |
| 323 | 320 | return; |
| @@ -1088,6 +1085,9 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) · 764 unmodified lines | ||
| 1088 | 1085 | |
| 1089 | 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 | 1091 | /* LFP panel data */ |
| 1092 | 1092 | dev_priv->vbt.lvds_dither = 1; |
| 1093 | 1093 | dev_priv->vbt.lvds_vbt = 0; |
| @@ -4564,7 +4564,10 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) · 4563 unmodified lines | ||
| 4564 | 4564 | if (intel_crtc->active) |
| 4565 | 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 | 4572 | /* Set up the display plane register */ |
| 4570 | 4573 | dspcntr = DISPPLANE_GAMMA_ENABLE; |
| @@ -4598,8 +4601,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) · 27 unmodified lines | ||
| 4598 | 4601 | if (encoder->pre_pll_enable) |
| 4599 | 4602 | encoder->pre_pll_enable(encoder); |
| 4600 | 4603 | |
| 4601 | − is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI); | |
| 4602 | − | |
| 4603 | 4604 | if (!is_dsi) { |
| 4604 | 4605 | if (IS_CHERRYVIEW(dev)) |
| 4605 | 4606 | chv_enable_pll(intel_crtc); |
| @@ -12411,8 +12412,8 @@ intel_display_capture_error_state(struct drm_device *dev) · 7805 unmodified lines | ||
| 12411 | 12412 | |
| 12412 | 12413 | for_each_pipe(i) { |
| 12413 | 12414 | error->pipe[i].power_domain_on = |
| 12414 | − intel_display_power_enabled_sw(dev_priv, | |
| 12415 | − POWER_DOMAIN_PIPE(i)); | |
| 12415 | + intel_display_power_enabled_unlocked(dev_priv, | |
| 12416 | + POWER_DOMAIN_PIPE(i)); | |
| 12416 | 12417 | if (!error->pipe[i].power_domain_on) |
| 12417 | 12418 | continue; |
| 12418 | 12419 | |
| @@ -12447,7 +12448,7 @@ intel_display_capture_error_state(struct drm_device *dev) · 28 unmodified lines | ||
| 12447 | 12448 | enum transcoder cpu_transcoder = transcoders[i]; |
| 12448 | 12449 | |
| 12449 | 12450 | error->transcoder[i].power_domain_on = |
| 12450 | − intel_display_power_enabled_sw(dev_priv, | |
| 12451 | + intel_display_power_enabled_unlocked(dev_priv, | |
| 12451 | 12452 | POWER_DOMAIN_TRANSCODER(cpu_transcoder)); |
| 12452 | 12453 | if (!error->transcoder[i].power_domain_on) |
| 12453 | 12454 | continue; |
| @@ -950,8 +950,8 @@ int intel_power_domains_init(struct drm_i915_private *); · 949 unmodified lines | ||
| 950 | 950 | void intel_power_domains_remove(struct drm_i915_private *); |
| 951 | 951 | bool intel_display_power_enabled(struct drm_i915_private *dev_priv, |
| 952 | 952 | enum intel_display_power_domain domain); |
| 953 | −bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, | |
| 954 | − enum intel_display_power_domain domain); | |
| 953 | +bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, | |
| 954 | + enum intel_display_power_domain domain); | |
| 955 | 955 | void intel_display_power_get(struct drm_i915_private *dev_priv, |
| 956 | 956 | enum intel_display_power_domain domain); |
| 957 | 957 | void intel_display_power_put(struct drm_i915_private *dev_priv, |
| @@ -5603,8 +5603,8 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, · 5602 unmodified lines | ||
| 5603 | 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, | |
| 5607 | − enum intel_display_power_domain domain) | |
| 5606 | +bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, | |
| 5607 | + enum intel_display_power_domain domain) | |
| 5608 | 5608 | { |
| 5609 | 5609 | struct i915_power_domains *power_domains; |
| 5610 | 5610 | struct i915_power_well *power_well; |
| @@ -5615,16 +5615,19 @@ bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, · 4 unmodified lines | ||
| 5615 | 5615 | return false; |
| 5616 | 5616 | |
| 5617 | 5617 | power_domains = &dev_priv->power_domains; |
| 5618 | + | |
| 5618 | 5619 | is_enabled = true; |
| 5620 | + | |
| 5619 | 5621 | for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { |
| 5620 | 5622 | if (power_well->always_on) |
| 5621 | 5623 | continue; |
| 5622 | 5624 | |
| 5623 | − if (!power_well->count) { | |
| 5625 | + if (!power_well->hw_enabled) { | |
| 5624 | 5626 | is_enabled = false; |
| 5625 | 5627 | break; |
| 5626 | 5628 | } |
| 5627 | 5629 | } |
| 5630 | + | |
| 5628 | 5631 | return is_enabled; |
| 5629 | 5632 | } |
| 5630 | 5633 | |
| @@ -5632,30 +5635,15 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv, · 1 unmodified line | ||
| 5632 | 5635 | enum intel_display_power_domain domain) |
| 5633 | 5636 | { |
| 5634 | 5637 | struct i915_power_domains *power_domains; |
| 5635 | − struct i915_power_well *power_well; | |
| 5636 | − bool is_enabled; | |
| 5637 | − int i; | |
| 5638 | − | |
| 5639 | − if (dev_priv->pm.suspended) | |
| 5640 | − return false; | |
| 5638 | + bool ret; | |
| 5641 | 5639 | |
| 5642 | 5640 | power_domains = &dev_priv->power_domains; |
| 5643 | 5641 | |
| 5644 | − is_enabled = true; | |
| 5645 | − | |
| 5646 | 5642 | mutex_lock(&power_domains->lock); |
| 5647 | − for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { | |
| 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 | − } | |
| 5643 | + ret = intel_display_power_enabled_unlocked(dev_priv, domain); | |
| 5656 | 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, · 314 unmodified lines | ||
| 5976 | 5964 | if (!power_well->count++) { |
| 5977 | 5965 | DRM_DEBUG_KMS("enabling %s\n", power_well->name); |
| 5978 | 5966 | power_well->ops->enable(dev_priv, power_well); |
| 5967 | + power_well->hw_enabled = true; | |
| 5979 | 5968 | } |
| 5980 | 5969 | |
| 5981 | 5970 | check_power_well_state(dev_priv, power_well); |
| @@ -6005,6 +5994,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, · 23 unmodified lines | ||
| 6005 | 5994 | |
| 6006 | 5995 | if (!--power_well->count && i915.disable_power_well) { |
| 6007 | 5996 | DRM_DEBUG_KMS("disabling %s\n", power_well->name); |
| 5997 | + power_well->hw_enabled = false; | |
| 6008 | 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) · 256 unmodified lines | ||
| 6267 | 6257 | int i; |
| 6268 | 6258 | |
| 6269 | 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 | 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 | 6265 | mutex_unlock(&power_domains->lock); |
| 6273 | 6266 | } |
| 6274 | 6267 | |
| @@ -277,6 +277,7 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) · 276 unmodified lines | ||
| 277 | 277 | static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"}; |
| 278 | 278 | static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"}; |
| 279 | 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 | 281 | static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"}; |
| 281 | 282 | |
| 282 | 283 | config.phy_init = hdmi_phy_8x74_init; |
| @@ -286,6 +287,7 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) · 3 unmodified lines | ||
| 286 | 287 | config.pwr_reg_names = pwr_reg_names; |
| 287 | 288 | config.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names); |
| 288 | 289 | config.hpd_clk_names = hpd_clk_names; |
| 290 | + config.hpd_freq = hpd_clk_freq; | |
| 289 | 291 | config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); |
| 290 | 292 | config.pwr_clk_names = pwr_clk_names; |
| 291 | 293 | config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names); |
| @@ -87,6 +87,7 @@ struct hdmi_platform_config { · 86 unmodified lines | ||
| 87 | 87 | |
| 88 | 88 | /* clks that need to be on for hpd: */ |
| 89 | 89 | const char **hpd_clk_names; |
| 90 | + const long unsigned *hpd_freq; | |
| 90 | 91 | int hpd_clk_cnt; |
| 91 | 92 | |
| 92 | 93 | /* clks that need to be on for screen pwr (ie pixel clk): */ |
| @@ -127,6 +127,14 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector) · 126 unmodified lines | ||
| 127 | 127 | } |
| 128 | 128 | |
| 129 | 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 | 138 | ret = clk_prepare_enable(hdmi->hpd_clks[i]); |
| 131 | 139 | if (ret) { |
| 132 | 140 | dev_err(dev->dev, "failed to enable hpd clk: %s (%d)\n", |
| @@ -20,6 +20,10 @@ · 19 unmodified lines | ||
| 20 | 20 | #include "msm_mmu.h" |
| 21 | 21 | #include "mdp5_kms.h" |
| 22 | 22 | |
| 23 | +static const char *iommu_ports[] = { | |
| 24 | + "mdp_0", | |
| 25 | +}; | |
| 26 | + | |
| 23 | 27 | static struct mdp5_platform_config *mdp5_get_config(struct platform_device *dev); |
| 24 | 28 | |
| 25 | 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) · 78 unmodified lines | ||
| 104 | 108 | static void mdp5_destroy(struct msm_kms *kms) |
| 105 | 109 | { |
| 106 | 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 | 117 | kfree(mdp5_kms); |
| 108 | 118 | } |
| 109 | 119 | |
| @@ -216,10 +226,6 @@ fail: · 106 unmodified lines | ||
| 216 | 226 | return ret; |
| 217 | 227 | } |
| 218 | 228 | |
| 219 | −static const char *iommu_ports[] = { | |
| 220 | − "mdp_0", | |
| 221 | −}; | |
| 222 | − | |
| 223 | 229 | static int get_clk(struct platform_device *pdev, struct clk **clkp, |
| 224 | 230 | const char *name) |
| 225 | 231 | { |
| @@ -317,17 +323,23 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) · 91 unmodified lines | ||
| 317 | 323 | mmu = msm_iommu_new(dev, config->iommu); |
| 318 | 324 | if (IS_ERR(mmu)) { |
| 319 | 325 | ret = PTR_ERR(mmu); |
| 326 | + dev_err(dev->dev, "failed to init iommu: %d\n", ret); | |
| 320 | 327 | goto fail; |
| 321 | 328 | } |
| 329 | + | |
| 322 | 330 | ret = mmu->funcs->attach(mmu, iommu_ports, |
| 323 | 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 | 335 | goto fail; |
| 336 | + } | |
| 326 | 337 | } else { |
| 327 | 338 | dev_info(dev->dev, "no iommu, fallback to phys " |
| 328 | 339 | "contig buffers for scanout\n"); |
| 329 | 340 | mmu = NULL; |
| 330 | 341 | } |
| 342 | + mdp5_kms->mmu = mmu; | |
| 331 | 343 | |
| 332 | 344 | mdp5_kms->id = msm_register_mmu(dev, mmu); |
| 333 | 345 | if (mdp5_kms->id < 0) { |
| @@ -33,6 +33,7 @@ struct mdp5_kms { · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | /* mapper-id used to request GEM buffer mapped for scanout: */ |
| 35 | 35 | int id; |
| 36 | + struct msm_mmu *mmu; | |
| 36 | 37 | |
| 37 | 38 | /* for tracking smp allocation amongst pipes: */ |
| 38 | 39 | mdp5_smp_state_t smp_state; |
| @@ -159,7 +159,7 @@ static int msm_unload(struct drm_device *dev) · 158 unmodified lines | ||
| 159 | 159 | static int get_mdp_ver(struct platform_device *pdev) |
| 160 | 160 | { |
| 161 | 161 | #ifdef CONFIG_OF |
| 162 | − const static struct of_device_id match_types[] = { { | |
| 162 | + static const struct of_device_id match_types[] = { { | |
| 163 | 163 | .compatible = "qcom,mdss_mdp", |
| 164 | 164 | .data = (void *)5, |
| 165 | 165 | }, { |
| @@ -59,7 +59,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, · 58 unmodified lines | ||
| 59 | 59 | struct drm_framebuffer *fb = NULL; |
| 60 | 60 | struct fb_info *fbi = NULL; |
| 61 | 61 | struct drm_mode_fb_cmd2 mode_cmd = {0}; |
| 62 | − dma_addr_t paddr; | |
| 62 | + uint32_t paddr; | |
| 63 | 63 | int ret, size; |
| 64 | 64 | |
| 65 | 65 | sizes->surface_bpp = 32; |
| @@ -278,6 +278,7 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, · 277 unmodified lines | ||
| 278 | 278 | uint32_t *iova) |
| 279 | 279 | { |
| 280 | 280 | struct msm_gem_object *msm_obj = to_msm_bo(obj); |
| 281 | + struct drm_device *dev = obj->dev; | |
| 281 | 282 | int ret = 0; |
| 282 | 283 | |
| 283 | 284 | if (!msm_obj->domain[id].iova) { |
| @@ -285,6 +286,11 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, · 1 unmodified line | ||
| 285 | 286 | struct msm_mmu *mmu = priv->mmus[id]; |
| 286 | 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 | 294 | if (IS_ERR(pages)) |
| 289 | 295 | return PTR_ERR(pages); |
| 290 | 296 | |
| @@ -28,7 +28,7 @@ static int msm_fault_handler(struct iommu_domain *iommu, struct device *dev, · 27 unmodified lines | ||
| 28 | 28 | unsigned long iova, int flags, void *arg) |
| 29 | 29 | { |
| 30 | 30 | DBG("*** fault: iova=%08lx, flags=%d", iova, flags); |
| 31 | − return 0; | |
| 31 | + return -ENOSYS; | |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 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) · 5 unmodified lines | ||
| 40 | 40 | for (i = 0; i < cnt; i++) { |
| 41 | 41 | struct device *msm_iommu_get_ctx(const char *ctx_name); |
| 42 | 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 | 45 | continue; |
| 46 | + } | |
| 45 | 47 | ret = iommu_attach_device(iommu->domain, ctx); |
| 46 | 48 | if (ret) { |
| 47 | 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) · 4 unmodified lines | ||
| 52 | 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 | 71 | static int msm_iommu_map(struct msm_mmu *mmu, uint32_t iova, |
| 56 | 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, · 52 unmodified lines | ||
| 110 | 126 | |
| 111 | 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 | 131 | da += bytes; |
| 116 | 132 | } |
| @@ -127,6 +143,7 @@ static void msm_iommu_destroy(struct msm_mmu *mmu) · 10 unmodified lines | ||
| 127 | 143 | |
| 128 | 144 | static const struct msm_mmu_funcs funcs = { |
| 129 | 145 | .attach = msm_iommu_attach, |
| 146 | + .detach = msm_iommu_detach, | |
| 130 | 147 | .map = msm_iommu_map, |
| 131 | 148 | .unmap = msm_iommu_unmap, |
| 132 | 149 | .destroy = msm_iommu_destroy, |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | struct msm_mmu_funcs { |
| 24 | 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 | 26 | int (*map)(struct msm_mmu *mmu, uint32_t iova, struct sg_table *sgt, |
| 26 | 27 | unsigned len, int prot); |
| 27 | 28 | int (*unmap)(struct msm_mmu *mmu, uint32_t iova, struct sg_table *sgt, |
| @@ -237,13 +237,21 @@ · 236 unmodified lines | ||
| 237 | 237 | #define INTEL_BDW_GT3D_IDS(info) \ |
| 238 | 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 | 246 | #define INTEL_BDW_M_IDS(info) \ |
| 241 | 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 | 251 | #define INTEL_BDW_D_IDS(info) \ |
| 245 | 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 | 256 | #define INTEL_CHV_IDS(info) \ |
| 249 | 257 | INTEL_VGA_DEVICE(0x22b0, info), \ |