From 4e5a531b408ef65da0489afbcb2842cc5e4bab4f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 21 Dec 2013 15:42:24 -0800 Subject: [PATCH] Baytrail patches added --- ...ctor-port-status-into-a-new-function.patch | 253 ++ ...ix-xHCI-host-issues-on-remote-wakeup.patch | 198 ++ ...sb2-port-capabilities-before-adding-.patch | 171 ++ ...port-register-names-and-use-them-ins.patch | 113 + ...2-Link-power-management-BESL-support.patch | 356 +++ ...k-PM-variables-to-sysfs-and-usb_devi.patch | 208 ++ ...ix-port-BESL-LPM-capability-checking.patch | 46 + ...-t-enable-USB-2.0-Link-PM-by-default.patch | 378 +++ ...way-phantom-LVDS-on-Intel-s-D525MW-m.patch | 46 + ...nable-the-plane-too-early-in-i9xx_cr.patch | 32 + ...drm-i915-drop-redundant-vblank-waits.patch | 40 + ...e-asserts-for-the-crtc-enable-sequen.patch | 45 + ...-drm-i915-add-i9xx-pfit-pipe-asserts.patch | 39 + ...debug-output-back-to-the-right-place.patch | 50 + ...e_name-and-port_name-where-appropria.patch | 44 + ...t_name-in-PCH-port-audio-power-chang.patch | 56 + ...lane-pipe-port-names-as-alphabetical.patch | 276 +++ ...phabetical-names-for-transcoders-too.patch | 64 + ...5-Use-alphabetical-names-for-sprites.patch | 66 + ...LV-GPU-frequency-to-opcode-functions.patch | 99 + ...rm-i915-turbo-RC6-support-for-VLV-v7.patch | 627 +++++ .../0022-drm-i915-fix-VLV-limits.patch | 60 + ...LV-PLL-registers-in-the-dpio-sideban.patch | 183 ++ ...ram-VSwing-and-Preemphasis-control-s.patch | 217 ++ ...5-drop-init_dpio-shouldn-t-be-needed.patch | 52 + ...915-update-VLV-PLL-and-DPIO-code-v11.patch | 663 +++++ ...port-Gen5-CPU-and-PCH-FIFO-underruns.patch | 598 +++++ ...print-Gen5-CPU-PCH-poison-interrupts.patch | 94 + ...he-power-well-inside-haswell_get_pip.patch | 47 + ...pu_transcoder-for-TRANS_DDI_FUNC_CTL.patch | 53 + ...e-CSC_MODE-bits-next-to-the-register.patch | 47 + ...emove-mention-of-Haswell-in-DDI-code.patch | 34 + ..._dport_to_channel-in-vlv_signal_leve.patch | 40 + ...-i915-Make-struct-dpll-intel_clock_t.patch | 81 + ...-encoding-function-to-the-gtt-ppgtt-.patch | 158 ++ ...Fix-page-table-entries-for-Bay-Trail.patch | 81 + ...ut-Haswell-code-from-gen6_pte_encode.patch | 94 + ...king-around-punit-access-in-cur_dela.patch | 40 + ...-field-to-record-which-pins-have-rec.patch | 86 + ...probe-display-on-encoder-which-has-r.patch | 88 + ...V_INFO_FLAGS-into-a-foreach-style-ma.patch | 139 ++ ...-the-line-of-s-by-a-DEV_INFO_FOR_EAC.patch | 46 + ..._INFO_FOR_EACH_FLAG-to-declare-flags.patch | 65 + ...Turn-HAS_DDI-into-a-device_info-flag.patch | 60 + ...915-Introduce-HAS_FPGA_DBG_UNCLAIMED.patch | 73 + ...S_FPGA_DBG_UNCLAIMED-into-a-device_i.patch | 61 + ...re-GPU-freq-drops-to-minimum-after-e.patch | 128 + ...cancel-RPS-work-before-disabling-RPS.patch | 37 + ...te-spearate-VLV-disable_rps-function.patch | 66 + ...-interrupts-earlier-in-the-driver-un.patch | 90 + ...ble-high-bpc-on-pre-1.4-EDID-screens.patch | 43 + ...on-24bpp-support-for-VGA-screens-on-.patch | 37 + ...x-backlight-internal-to-intel_panel..patch | 179 ++ ...-backlight-registers-and-data-with-a.patch | 228 ++ ...retend-we-support-ASLE-ALS-PFIT-or-P.patch | 37 + ...n-don-t-pretend-we-did-something-whe.patch | 61 + ...de-duplication-in-favor-of-asle-inte.patch | 112 + ...klight-registers-need-transcoder-ins.patch | 60 + ...ge-is-the-odd-one-when-it-comes-to-p.patch | 59 + ...nsolidate-pch-pll-computations-a-bit.patch | 66 + ...compute-clock-into-crtc-config.dpll-.patch | 152 ++ ...-clock-computations-to-encoder-compu.patch | 252 ++ ...5-use-pipe_config-for-lvds-dithering.patch | 203 ++ ...orce-matching-p1-for-g4x-ilk-reduced.patch | 47 + ...move-redundant-has_pch_encoder-check.patch | 35 + ...ify-config-pixel_multiplier-handling.patch | 125 + ...out-GMCH-panel-fitting-code-and-use-.patch | 632 +++++ ...e-PCH-pfit-controls-into-pipe_config.patch | 300 +++ ...m-i915-warn-about-invalid-pfit-modes.patch | 66 + ...070-drm-i915-remove-VLV-MSI-IRQ-hack.patch | 42 + ...int-the-info-message-about-incresing.patch | 53 + ...-right-cpu_transcoder-into-pipe_conf.patch | 32 + ...73-drm-i915-force-bpp-for-eDP-panels.patch | 87 + ...justed_mode-from-_set_pipeconf-funct.patch | 81 + ...nt-high-bpc-pipeconf-dither-support-.patch | 101 + ...-drm-i915-allow-high-bpc-modes-on-DP.patch | 36 + ...-intel_crtc-fdi_lanes-to-pipe_config.patch | 191 ++ ...e-readout-support-for-pipe_config-fd.patch | 173 ++ ...p-fdi_set_m_n-into-computation-and-h.patch | 101 + ...i915-compute-fdi-lane-config-earlier.patch | 130 + ...15-Split-up-ironlake_check_fdi_lanes.patch | 77 + ...-fdi-lane-configuration-checks-ahead.patch | 227 ++ ...ount-cpu-ports-for-fdi-B-C-lane-shar.patch | 65 + ...5-fixup-12bpc-hdmi-dotclock-handling.patch | 80 + ...rm-i915-implement-fdi-auto-dithering.patch | 264 ++ ...r_each_intel_crtc_masked-macro-from-.patch | 31 + ...ce-macros-to-check-pipe-config-prope.patch | 59 + ...hw-state-readout-support-for-fdi-m-n.patch | 97 + ...ate-readout-support-for-pipe-timings.patch | 168 ++ ...-opregion-technology-enabled-indicat.patch | 57 + ...opregion-asle-driver-readiness-prope.patch | 81 + ...pregion-init-and-asle-irq-pipestat-e.patch | 52 + ...-redundant-checks-from-intel_enable_.patch | 52 + ...leanup-opregion-asle-pipestat-enable.patch | 114 + ...move-lvds_border_bits-to-pipe_config.patch | 88 + ...-indirection-for-pfit-pipe_config-as.patch | 41 + ...e-border-color-writes-to-pfit_enable.patch | 70 + ...rm_rect-and-assorted-utility-functio.patch | 306 +++ ..._calc_-hscale-vscale-utility-functio.patch | 243 ++ .../0100-drm-Add-drm_rect_debug_print.patch | 76 + .../0101-drm-Add-drm_rect_equals.patch | 49 + ...nt-proper-clipping-for-video-sprites.patch | 314 +++ ...lax-the-sprite-scaling-limits-checks.patch | 102 + ...reference-count-for-i915_hw_contexts.patch | 178 ++ ...15-simplify-DP-DDI-port-width-macros.patch | 141 ++ ...ence-default-context-on-module-unloa.patch | 44 + ...fix-Haswell-pfit-power-well-check-v2.patch | 48 + ...etup-hdmi-for-port-D-edp-in-ddi_init.patch | 69 + ...-drm-i915-put-context-upon-switching.patch | 114 + ...i915-add-context-into-request-struct.patch | 95 + ...adjusted_mode-tracking-for-interlace.patch | 71 + ...2-drm-i915-s-TRANSCONF-PCH_TRANSCONF.patch | 195 ++ ...5-PCH_-prefix-for-transcoder-timings.patch | 267 ++ ...m-i915-make-set_m_n-functions-static.patch | 123 + ...CD-to-data-link-m-n-register-defines.patch | 231 ++ ...make-intel_cpt_verify_modeset-static.patch | 54 + ...rt-mutex_is_locked-on-context-lookup.patch | 40 + ...118-drm-i915-BUG_ON-bad-PPGTT-offset.patch | 40 + .../0119-drm-i915-Extract-PDE-writes.patch | 70 + ...laration-of-intel_gmbus_-is_forced_b.patch | 60 + ...-read-current-freq-from-Punit-on-VLV.patch | 41 + ...-to-switch-for-VLV-mem-freq-detectio.patch | 44 + ...-fix-panel-fitting-on-LVDS-on-ILK-v2.patch | 44 + ...per-DPIO-post-divider-for-VGA-on-VLV.patch | 49 + ...i915-add-intel_display_power_enabled.patch | 148 ++ ...er-well-and-cpu-transcoder-info-to-t.patch | 69 + ...PGA_DBG_RM_NOCLAIM-when-capturing-er.patch | 45 + ...-the-power-well-on-i915_pipe_enabled.patch | 38 + ...sable-DDI-sound-if-intel_crtc-eld_vl.patch | 68 + ...tform-information-to-implemented-wor.patch | 294 +++ ...erences-to-some-workaround-we-implem.patch | 105 + ...-i915-fix-hotplug-event-bit-tracking.patch | 59 + ...W-allow-PCH-clock-gating-for-suspend.patch | 116 + ...le-FBC-WM-if-the-watermark-is-good-o.patch | 42 + ...d-power-context-stolen-mem-handling-.patch | 173 ++ ...tolen-pre-allocated-objects-to-avoid.patch | 61 + ...VLV-support-is-no-longer-preliminary.patch | 35 + ..._to_intel_dp-instead-of-opencoding-t.patch | 45 + ...-replace-is_pch_edp-with-port-PORT_A.patch | 32 + ...-replace-is_pch_edp-with-port-PORT_A.patch | 58 + ...ing-is_pch_edp-in-intel_dp_init_conn.patch | 76 + ...-stop-using-is_pch_edp-in-is_cpu_edp.patch | 56 + ...is_pch_edp-helpers-and-state-variabl.patch | 100 + ...P-init-debug-messages-from-a-single-.patch | 68 + ...vo-TV-clock-computation-to-intel_sdv.patch | 132 + ...5-drop-TVclock-special-casing-on-ilk.patch | 57 + .../0147-drm-i915-rip-out-TV-out-lore.patch | 43 + ...-now-unused-is_foo-tracking-from-crt.patch | 92 + ...VO-TV-out-work-for-multifunction-dev.patch | 156 ++ ...ze-VBT-stuff-inside-drm_i915_private.patch | 666 +++++ ...915-Add-support-for-FBC-on-Ivybridge.patch | 145 ++ ...B-FBC-WaFbcAsynchFlipDisableFbcQueue.patch | 36 + ...-IVB-FBC-WaFbcDisableDpfcClockGating.patch | 57 + .../0154-drm-i915-Enable-FBC-at-Haswell.patch | 114 + ...W-FBC-WaFbcAsynchFlipDisableFbcQueue.patch | 57 + ...-HSW-FBC-WaFbcDisableDpfcClockGating.patch | 76 + ...-Compute-WR-PLL-dividers-dynamically.patch | 685 ++++++ ...-rip-out-an-unused-lvds_reg-variable.patch | 41 + ...sing-platform-tags-to-FBC-workaround.patch | 61 + ...ment-WADPOClockGatingDisable-for-LPT.patch | 37 + ...itter-hw-state-readout-check-support.patch | 179 ++ ...ipe_config-state-to-disable-ilk-pfit.patch | 78 + ...e-config-state-to-control-gmch-pfit-.patch | 61 + ...5-add-support-for-dvo-Chrontel-7010B.patch | 118 + ..._-add-del-to-manipulate-WC-MTRRs-if-.patch | 211 ++ .../0166-i915-Use-arch_phys_wc_-add-del.patch | 100 + ...Print-pretty-names-for-pixel-formats.patch | 106 + ...Print-pretty-names-for-pixel-formats.patch | 67 + ...5-add-encoder-get_config-function-v5.patch | 438 ++++ ...-and-IVB-don-t-have-linetime-waterma.patch | 36 + ...ove-intel_update_linetime_watermarks.patch | 160 ++ ...-mode-htotal-to-calculate-linetime-w.patch | 37 + ...well-linetime-watermarks-calculation.patch | 37 + ...tel_ddi_get_cdclk_freq-return-values.patch | 101 + ...-i915-set-the-IPS-linetime-watermark.patch | 72 + ...SKPD-is-a-64-bit-register-on-Haswell.patch | 37 + ...set-FORCE_ARB_IDLE_PLANES-workaround.patch | 73 + ...-informative-when-reporting-too-larg.patch | 39 + ...-drm-i915-Fix-WARN_ON-on-UP-machines.patch | 44 + ...und-incoherence-with-fence-updates-o.patch | 101 + ...-drm-i915-Cocci-spatch-memdup.spatch.patch | 33 + ...-big-kmallocs-on-reading-error-state.patch | 568 +++++ ...ideband-register-accessors-to-a-new-.patch | 453 ++++ ...r-VLV-IOSF-sideband-accessors-to-use.patch | 304 +++ ...dundant-warnings-on-not-holding-dpio.patch | 73 + ...VLV-IOSF-sideband-functions-logicall.patch | 520 ++++ ...VLV-IOSF-sideband-accessors-to-not-r.patch | 207 ++ ...ble-argument-to-intel_update_sprite_.patch | 142 ++ ...rm-i915-add-haswell_update_sprite_wm.patch | 98 + ...ss-seqno-to-i915_hangcheck_ring_idle.patch | 52 + ...-track-ring-progression-using-seqnos.patch | 137 ++ ...5-introduce-i915_hangcheck_ring_hung.patch | 72 + ...rm-i915-Fix-error-state-memory-leaks.patch | 36 + ...94-drm-i915-pre-fixes-for-checkpatch.patch | 69 + ...915-use-mappable-size-for-fb-kickout.patch | 45 + .../0196-drm-i915-use-drm_mm_takedown.patch | 39 + ...0197-drm-i915-context-debug-messages.patch | 82 + ...rm-i915-Call-context-fini-at-cleanup.patch | 36 + ...elease-scratch-page-at-module-unload.patch | 30 + ...ing-is_cpu_edp-in-intel_disable-post.patch | 64 + ...LV-eDP-and-DP-AUX-clock-divider-calc.patch | 42 + ...e-is_cpu_edp-with-a-check-for-port-A.patch | 227 ++ ...03-drm-i915-remove-unused-is_cpu_edp.patch | 44 + ...915_pipe_enabled-check-in-i915_irq.c.patch | 74 + ...e-readout-check-support-for-cpu_tran.patch | 266 ++ ...t-why-dvo-sdvo-crt-need-a-special-dp.patch | 89 + ...ror-return-code-in-init_pipe_control.patch | 37 + ...5-add-basic-pipe-config-dump-support.patch | 183 ++ ...few-really-redundant-WARNs-in-hsw-mo.patch | 46 + ...promoting-a-simulated-hang-to-wedged.patch | 111 + ...elease-cursor-when-crtc-is-destroyed.patch | 57 + ...Comments-for-semaphore-clarification.patch | 111 + ...Semaphore-MBOX-update-generalization.patch | 151 ++ ...drm-i915-Introduce-VECS-the-4th-ring.patch | 55 + ...215-drm-i915-Add-VECS-semaphore-bits.patch | 134 ++ ...drm-i915-Rename-ring-flush-functions.patch | 71 + .../0217-drm-i915-add-HAS_VEBOX.patch | 65 + .../0218-drm-i915-Vebox-ringbuffer-init.patch | 127 + .../0219-drm-i915-fix-pch_nop-support.patch | 51 + ...5-properly-set-HSW-WM_PIPE-registers.patch | 433 ++++ ...15-properly-set-HSW-WM_LP-watermarks.patch | 352 +++ ...port-for-5-6-data-buffer-partitionin.patch | 133 + ...te-a-more-generic-pm-handler-for-hsw.patch | 80 + ...5-Create-an-ivybridge_irq_preinstall.patch | 78 + ...i915-Add-PM-regs-to-pre-post-install.patch | 80 + ...-PM-interrupt-writes-non-destructive.patch | 196 ++ ...-i915-Convert-irq_refounct-to-struct.patch | 111 + ...-consolidate-interrupt-naming-scheme.patch | 402 ++++ ...229-drm-i915-vebox-interrupt-get-put.patch | 102 + ...230-drm-i915-Enable-vebox-interrupts.patch | 113 + ...0231-drm-i915-add-VEBOX-into-debugfs.patch | 45 + ...5_EXEC_VEBOX-to-i915_gem_do_execbuff.patch | 53 + ...915_PARAM_HAS_VEBOX-to-i915_getparam.patch | 49 + ...i915-fix-up-the-edp-power-well-check.patch | 70 + .../0235-drm-i915-implement-IPS-feature.patch | 244 ++ ...rm-i915-add-enable_ips-module-option.patch | 71 + ...15-add-i915_ips_status-debugfs-entry.patch | 61 + ...Drop-bogus-fbdev-sprite-disable-code.patch | 48 + ...15-Demote-unknown-param-to-DRM_DEBUG.patch | 35 + ...0-drm-i915-Make-stolen-use-pin-pages.patch | 31 + .../0241-drm-i915-Unpin-stolen-pages.patch | 39 + .../0242-drm-i915-unpin-pages-at-unbind.patch | 54 + ...5-Rename-the-gtt_list-to-global_list.patch | 256 ++ ...-hang-using-per-ring-hangcheck_score.patch | 188 ++ ...-drm-i915-remove-i915_hangcheck_hung.patch | 64 + ...5-Use-container_of-in-the-fbdev-code.patch | 54 + ...915_private_t-struct-drm_i915_privat.patch | 82 + ...mize-vblank-waits-in-set_base_atomic.patch | 36 + ...-drm-i915-refactor-sink-bpp-clamping.patch | 120 + ...915-fix-EDID-sink-based-bpp-clamping.patch | 64 + ...15-split-out-intel_pnv_find_best_PLL.patch | 200 ++ ...ind_pll-callback-to-dev_priv-display.patch | 415 ++++ ...-IS_PNV-checks-from-the-split-up-fin.patch | 44 + ...p-the-fdi-dotclock-semantics-for-M-N.patch | 78 + ...-refactor-cpu-eDP-PLL-handling-a-bit.patch | 121 + ...djusted-dotclock-in-adjusted_mode-cl.patch | 329 +++ ...me-no-longer-required-mode-adjusted_.patch | 120 + ...or-strange-pfit-pipe-assignemnt-on-i.patch | 50 + ...sn-t-have-the-ILK-style-LP-watermark.patch | 37 + ...0-drm-i915-Fix-DSPCLK_GATE_D-for-VLV.patch | 50 + ...date-and-tighten-encoder-cloning-che.patch | 196 ++ ...uish-between-error-messages-in-DIDL-.patch | 42 + ...ault-value-for-config-pixel_multipli.patch | 127 + ...lients-and-print-their-object-usage-.patch | 107 + ...0265-drm-i915-add-ibx_irq_preinstall.patch | 89 + ...Include-display_mmio_offset-in-seque.patch | 47 + ...load-the-display-palette-before-enab.patch | 63 + ...enable-the-cursor-right-after-the-pr.patch | 96 + ...the-overlay-right-after-primary-and-.patch | 55 + ...the-same-sequence-when-disabling-pla.patch | 79 + ...erlay-DPMS-call-from-valleyview_crtc.patch | 36 + ...-restore-all-sprite-planes-around-mo.patch | 153 ++ ...-i915-Improve-assert_planes_disabled.patch | 53 + ...15-Spruce-up-assert_sprites_disabled.patch | 66 + ...dpll-running-in-intel_crtc_load_lut-.patch | 48 + ...e-readout-support-for-pixel_multipli.patch | 173 ++ ...drm-i915-update-FBC-maximum-fb-sizes.patch | 62 + ...Add-private-api-for-power-well-usage.patch | 244 ++ ...nfig-quirk-infrastructure-plus-sdvo-.patch | 153 ++ ...drm-i915-enable-30bpp-for-DP-outputs.patch | 48 + ...e-primary-plane-trickle-feed-for-g4x.patch | 68 + ...-trickle-feed-via-MI_ARB_STATE-for-t.patch | 48 + ...-trickle-feed-in-ironlake_init_clock.patch | 50 + ...15-Refactor-ctg-trickle-feed-disable.patch | 177 ++ ...hen-we-dirty-the-scanout-with-render.patch | 100 + .../0286-drm-i915-WA-FBC-Render-Nuke.patch | 136 ++ ...ke-g4x_fixup_plane-operational-again.patch | 58 + ...e-dead-code-from-SDVO-initialisation.patch | 53 + ...NFO_STATE-defines-instead-of-0-and-1.patch | 65 + ...-fix-up-pch-pll-handling-in-mode_set.patch | 103 + ...onally-disable-pch-resources-in-ilk_.patch | 114 + ...ock-down-pch-pll-accouting-some-more.patch | 63 + .../0293-drm-i915-s-pch_pll-shared_dpll.patch | 471 ++++ ...crtc-shared_dpll-from-a-pointer-to-a.patch | 330 +++ ...ove-shared_dpll-into-the-pipe-config.patch | 145 ++ ...m-i915-refactor-PCH_DPLL_SEL-defines.patch | 97 + ...hw-state-readout-for-shared-pch-plls.patch | 123 + ...olidate-num_shared_dplls-assignement.patch | 116 + ...9-drm-i915-metadata-for-shared-dplls.patch | 212 ++ ...-i915-scrap-register-address-storage.patch | 191 ++ ...nable-disable-hooks-for-shared-dplls.patch | 194 ++ ...rtc-checking-from-assert_shared_dpll.patch | 107 + ...-reference-to-i830_sdvo_get_capabili.patch | 31 + ...ize-active_outputs-to-never-read-uni.patch | 41 + ...ialize-ring-hangcheck-upon-ring-init.patch | 33 + ...ightly-increment-hangcheck-score-if-.patch | 215 ++ ...ount-semaphore-waits-towards-a-stuck.patch | 237 ++ ...te-the-addr-seqno-from-the-hangcheck.patch | 40 + ...RN-if-the-fence-pin_count-is-invalid.patch | 38 + ...-sdvo-pixel-multiplier-cross-check-f.patch | 76 + ...311-drm-i915-pnv-dpll-doesn-t-use-m1.patch | 47 + ...ay-pll-hw-state-readout-and-checking.patch | 204 ++ ...-readout_hw_state-from-setup_hw_stat.patch | 60 + ...5-split-up-intel_modeset_check_state.patch | 103 + ...drm-i915-WARN-on-lack-of-shared-dpll.patch | 42 + ...e-readout-and-cross-checking-for-sha.patch | 164 ++ ...pch-pll-enabling-for-pixel-multiplie.patch | 46 + ...arder-to-disable-trickle-feed-on-VLV.patch | 69 + ...-i915-add-struct-i915_ctx_hang_stats.patch | 73 + ...-add-i915_gem_context_get_hang_stats.patch | 86 + ...915-change-i915_add_request-to-macro.patch | 149 ++ ...915-add-batch-bo-to-i915_add_request.patch | 134 ++ ...drm-i915-store-ring-hangcheck-action.patch | 68 + ...d-guilty-batch-buffer-on-ring-resets.patch | 166 ++ ...et-up-PIPECONF-explicitly-on-ilk-ivb.patch | 70 + ...PIPECONF-explicitly-for-i9xx-vlv-pla.patch | 81 + ...tly-set-up-PIPECONF-and-gamma-table-.patch | 77 + ...8-drm-i915-stop-killing-pfit-on-i9xx.patch | 132 + ...y-the-reduced-clock-handling-for-pch.patch | 62 + ...Remove-extra-ring-from-error-message.patch | 32 + ...useless-Enable-panel-fitter-comments.patch | 59 + ...-i915-remove-a-superflous-semi-colon.patch | 31 + ...333-drm-make-drm_mm_init-return-void.patch | 130 + ...heck-encoder-at-DP-connector-destroy.patch | 47 + ...915-extract-intel_edp_init_connector.patch | 198 ++ ...te-errors-from-intel_dp_init_connect.patch | 91 + ...-the-ghost-eDP-connector-unwind-path.patch | 85 + ...ix-the-ghost-eDP-encoder-unwind-path.patch | 89 + ...he-return-value-of-intel_dp_i2c_init.patch | 44 + ...intel_dp_destroy-to-intel_dp_connect.patch | 44 + ...-detect-with-multiple-ISA-bridges-in.patch | 64 + ...wn-DIDL-warning-about-too-many-outpu.patch | 51 + ...ld-warning-on-format-specifier-misma.patch | 39 + ...-drm-i915-Introduce-an-HAS_IPS-macro.patch | 69 + ...cream-into-dmesg-when-a-modeset-fail.patch | 38 + ...duplicated-WaForceL3Serialization-vl.patch | 37 + ...-i915-Detect-invalid-scanout-pitches.patch | 73 + ...drm-i915-Clean-up-VLV-rps-code-a-bit.patch | 121 + ...ait-for-Punit-after-each-freq-change.patch | 121 + ...e-rps-new_delay-comparison-more-read.patch | 37 + ..._INTERRUPT_LIMITS-doesn-t-seem-to-ex.patch | 50 + ...ncrease-the-GPU-frequency-from-the-d.patch | 40 + ...-at-least-RPe-on-VLV-when-increasing.patch | 53 + ...Fix-VLV-PLL-LPF-coefficients-for-DAC.patch | 41 + ...s-LFP-LPF-in-DPIO-PLL-register-names.patch | 77 + ...Don-t-use-the-HDMI-port-color-range-.patch | 42 + ...i915-Fix-VLV-sprite-register-offsets.patch | 91 + ...king-around-ironlake_enable-disable_.patch | 119 + ...iny-race-in-the-ilk-pcu-even-interru.patch | 62 + ...ug_irq_storm_detect-intel_hpd_irq_ha.patch | 91 + ...e-hpd_irq_setup-call-into-intel_hpd_.patch | 125 + ...e-queue_work-into-intel_hpd_irq_hand.patch | 83 + ...e-no-irq-check-into-intel_hpd_irq_ha.patch | 103 + ...5-fix-hpd-interrupt-register-locking.patch | 100 + ...-intel_dp_get_config-function-for-De.patch | 93 + ...r-the-wait_rendering-completion-into.patch | 102 + ...p-the-large-vsnprintf-in-print_error.patch | 196 ++ ...ry-to-tear-down-the-stolen-drm_mm-if.patch | 80 + ...status-page-registers-after-gpu-rese.patch | 121 + ...disable_power_well-default-value-to-.patch | 36 + ...e-bandwidth-capping-for-DP-1.2-sinks.patch | 43 + ...Workaround-incoherence-between-fence.patch | 111 + ...readout-of-the-lvds-dither-bit-on-ge.patch | 99 + ...t-regression-for-non-autoscaled-reso.patch | 72 + ...e-the-DDI_A_4_LANES-bit-from-the-bio.patch | 45 + ...g-standing-SNB-regression-in-power-c.patch | 79 + ...-drm-i915-Sanitize-shared-dpll-state.patch | 81 + ...i915-fix-up-gt-init-sequence-fallout.patch | 65 + ...9-drm-i915-fix-hdmi-portclock-limits.patch | 101 + ...last_vblank-when-disabling-the-power.patch | 68 + ...brightness-overflow-when-doing-scale.patch | 42 + ...all-encoder-s-get_config-unless-enco.patch | 72 + ...disable-backlight-on-vgaswitcheroo-s.patch | 62 + ...npin-backing-storage-in-dmabuf_unmap.patch | 56 + ...eref-pipe-cpu_transcoder-in-the-hang.patch | 215 ++ ...Fix-whitespace-issue-in-i915_gem_gtt.patch | 34 + ...rt-the-verbosity-of-intel_enable_fbc.patch | 47 + ...rm-i915-Make-intel_enable_fbc-static.patch | 45 + ...reason-for-per-chip-disabling-of-FBC.patch | 89 + ...-Use-seq_puts-seq_putc-when-possible.patch | 342 +++ ...ew-style-issues-found-by-checkpatch..patch | 64 + ...ouple-of-should-it-be-static-sparse-.patch | 47 + ...t-once-we-ve-found-the-context-objec.patch | 32 + ...-consolidate-pch-pll-enable-sequence.patch | 207 ++ ...tracked-state-to-select-shared-dplls.patch | 54 + ...te-intel_enable_pll-into-i9xx-and-vl.patch | 110 + ...drm-i915-asserts-for-lvds-pre_enable.patch | 179 ++ ...coder-pre-enable-hooks-togther-on-il.patch | 54 + ...i915-hw-state-readout-for-i9xx-dplls.patch | 130 + ...xx-dpll-enabling-into-crtc-enable-fu.patch | 200 ++ ...ll-pre-on-the-lvds-port-enable-funct.patch | 78 + ...t-hardware-status-bits-from-VLV-DPLL.patch | 45 + ...m-i915-Remove-extra-error-state-NULL.patch | 44 + ...rm-i915-Extract-error-buffer-capture.patch | 118 + ...-i915-make-PDE-PTE-platform-specific.patch | 87 + ...6-drm-i915-Really-share-scratch-page.patch | 62 + ...ombine-scratch-members-into-a-struct.patch | 88 + ...08-drm-i915-Drop-dev-from-pte_encode.patch | 132 + ...915-Use-gtt-shortform-where-possible.patch | 73 + ...rm-i915-Move-fbc-members-out-of-line.patch | 397 +++ ...1-drm-i915-Move-gtt_mtrr-to-i915_gtt.patch | 77 + ...ultiplier-readout-support-for-pch-po.patch | 77 + ...tboot-param-for-fast-loose-mode-sett.patch | 52 + ...e-clock-when-reading-the-pipe-config.patch | 310 +++ ...tched-mode-state-into-crtc-at-setup_.patch | 81 + ...f-panel-fitting-at-flip-time-if-need.patch | 46 + ...-a-no-fb-fb-transition-if-crtc-is-ac.patch | 47 + ...ort-error-state-to-string-conversion.patch | 107 + ...i915-export-error-state-ref-handling.patch | 96 + ...-introduce-i915_error_state_buf_init.patch | 121 + ...drm-i915-add-error_state-sysfs-entry.patch | 138 ++ ...ixup-messages-in-pipe_config_compare.patch | 41 + ...ncoder-get_config-calls-from-crtc-ge.patch | 78 + ...t_for-to-wait-for-Punit-to-change-GP.patch | 70 + ...-explicitly-cast-pipe-cpu_transcoder.patch | 72 + ...5-Explicitly-cast-pipe-intel_dpll_id.patch | 44 + ...gic-for-stolen-preallocated-objects-.patch | 75 + ...spin_locked-for-pipestat-interrupt-e.patch | 90 + ...m-pre-allocate-node-for-create_block.patch | 219 ++ ...-Change-create-block-to-reserve-node.patch | 149 ++ ...-Getter-setter-for-object-attributes.patch | 1051 ++++++++ .../0432-drm-i915-Kill-obj-gtt_offset.patch | 131 + ...15-Embed-drm_mm_node-in-i915-gem-obj.patch | 304 +++ ...434-drm-i915-fix-dvo-DPLL-regression.patch | 118 + ...drm-i915-dvo-needs-a-P2-divisor-of-4.patch | 70 + ...-debugfs-creation-destruction-to-tab.patch | 146 ++ ...that-our-stolen-memory-doesn-t-confl.patch | 62 + ...rm-i915-clean-up-media-reset-on-gm45.patch | 77 + ...-the-bios-reserved-range-is-bigger-t.patch | 35 + ...-DP-RBR-HDMI-DAC-PLL-LPF-coefficient.patch | 43 + ...frob-mm.suspended-when-not-using-ums.patch | 315 +++ ...unused-members-from-drm_i915_private.patch | 29 + ...extract-ibx_display_interrupt_update.patch | 130 + ...-SERR_INT-clearing-for-fifo-underrun.patch | 103 + ...-GEN7_ERR_INT-clearing-for-fifo-unde.patch | 94 + ...t-pch-transcoder-crtc-mapping-code-f.patch | 106 + ...dlers-don-t-need-interrupt-safe-spin.patch | 173 ++ ...m-i915-streamline-hsw_pm_irq_handler.patch | 61 + ...ork-outside-spinlock-in-hsw_pm_irq_h.patch | 42 + ...0450-drm-i915-kill-dev_priv-rps.lock.patch | 229 ++ ...-i915-unify-ring-irq-refcounts-again.patch | 133 + ...t-enable-PM_VEBOX_CS_ERROR_INTERRUPT.patch | 62 + ...i915-Use-for_each_pipe-when-possible.patch | 41 + ...ttempt-to-read-an-unitialized-stack-.patch | 61 + ...-error-state-to-own-compilation-unit.patch | 2138 +++++++++++++++++ ...p-vlv-pre_pll_enable-and-pll-enable-.patch | 130 + ...cpt-pixel-multiplier-enable-sequence.patch | 63 + ...r-DPLL-reg-when-disabling-i9xx-dplls.patch | 73 + ...sw-Set-correct-Haswell-PTE-encodings.patch | 78 + ...m-i915-Define-some-of-the-eLLC-magic.patch | 51 + .../0461-drm-i915-store-eLLC-size.patch | 90 + ...e-eLLC-LLC-by-default-when-available.patch | 70 + ...3-drm-i915-debugfs-entries-for-e-LLC.patch | 55 + ...ify-PM-interrupt-preinstall-sequence.patch | 121 + ...915-unify-GT-PM-irq-postinstall-code.patch | 233 ++ ...-rps-interrupt-enable-disable-helper.patch | 158 ++ ...y-rps-interrupt-enabling-disabling-s.patch | 55 + ...ement-WaFbcWaitForVBlankBeforeEnable.patch | 33 + ...ement-WaFbcAsynchFlipDisableFbcQueue.patch | 42 + ...ement-WaFbcDisableDpfcClockGating-on.patch | 33 + ...plement-WaMPhyProgramming-on-Haswell.patch | 33 + ...ry-to-calculate-RC6-residency-on-GEN.patch | 35 + ...915-Fix-retrieval-of-hangcheck-stats.patch | 80 + ...ce-open-coding-of-DEFAULT_CONTEXT_ID.patch | 52 + ...-i915-introduce-i915_queue_hangcheck.patch | 95 + ...t-and-ppgtt-under-address-space-umbr.patch | 638 +++++ ...t-the-mm-in-the-parent-address-space.patch | 190 ++ ...drm-i915-Create-a-global-list-of-vms.patch | 71 + ...Move-active-inactive-lists-to-new-mm.patch | 462 ++++ ...-stolen-node-on-failed-preallocation.patch | 42 + .../0481-drm-i915-Create-VMAs.patch | 428 ++++ ...d-VSC-structures-for-handling-PSR-fo.patch | 83 + ...Read-the-EDP-DPCD-and-PSR-Capability.patch | 67 + ...ux_clock_divider-logic-in-a-separate.patch | 112 + .../0485-drm-i915-Enable-Disable-PSR.patch | 298 +++ ...Added-debugfs-support-for-PSR-Status.patch | 178 ++ ...ll-PSR-mode-entry-conditions-before-.patch | 225 ++ ...able_psr-module-option-and-disable-p.patch | 90 + ...ate-function-to-disable-enable-back-.patch | 94 + ...0490-drm-i915-Hook-PSR-functionality.patch | 63 + ...-debug-message-lost-in-merge-resolut.patch | 36 + ...SDV-support-from-lpt_pch_init_refclk.patch | 186 ++ ...-FDI-mPHY-functions-from-lpt_init_pc.patch | 130 + ...-lpt_enable_clkout_dp-from-lpt_init_.patch | 79 + ...-checking-for-NULL-instead-of-IS_ERR.patch | 51 + ...rm-i915-use-after-free-on-error-path.patch | 34 + ...5-add-prefault_disable-module-option.patch | 101 + ...m-i915-kill-ivybridge_irq_preinstall.patch | 59 + ...i915-extract-ilk_display_irq_handler.patch | 141 ++ ...i915-extract-ivb_display_irq_handler.patch | 106 + ...-t-read-or-write-GEN6_PMIIR-on-Gen-5.patch | 63 + ...i915-reorganize-ironlake_irq_handler.patch | 97 + ..._READ-DEIER-on-ivybridge_irq_handler.patch | 33 + ...-SNB-support-to-ivybridge_irq_handle.patch | 197 ++ ...915-kill-Ivybridge-vblank-irq-vfuncs.patch | 110 + ...-i915-kill-ivybridge_irq_postinstall.patch | 126 + ...m-i915-Make-i915-events-part-of-uapi.patch | 91 + ...invert-ilk-snb-_gt_irq_handler-check.patch | 36 + ...m-gem-simplify-object-initialization.patch | 184 ++ ...e-debug-breadcrumbs-to-connector-det.patch | 127 + ...error-cleanup-in-i915_gem_object_bin.patch | 80 + ...drm-i915-extend-lpt_enable_clkout_dp.patch | 113 + ...sable-CLKOUT_DP-when-it-s-not-needed.patch | 78 + ...nctions-to-disable-and-restore-LCPLL.patch | 246 ++ ...-stolen-mem-for-OVERLAY_NEEDS_PHYSIC.patch | 39 + ...phics-Base-of-Stolen-Memory-on-all-g.patch | 89 + ...eference-counting-in-i915_gem_create.patch | 70 + ...m_gem_mmap-into-object-search-and-ob.patch | 151 ++ ...9-drm-add-unified-vma-offset-manager.patch | 588 +++++ ...m-convert-to-new-unified-vma-manager.patch | 616 +++++ ...m-gem-fix-mmap-vma-size-calculations.patch | 45 + ...onvert-to-unified-vma-offset-manager.patch | 595 +++++ ...ma-provide-drm_vma_node_unmap-helper.patch | 108 + .../0524-Re-create-dirty-merge-cb54b53.patch | 48 + ...e-all-GT-access-routines-in-the-same.patch | 1423 +++++++++++ ...rivate-interface-for-register-access.patch | 410 ++++ ...-common-register-access-functions-fo.patch | 114 + ...gen-lookup-through-multiple-indirect.patch | 44 + ...-the-register-access-tracepoint-to-b.patch | 79 + ...-i915-fix-the-racy-object-accounting.patch | 75 + ...vo_ch7xxx-fix-vsync-polarity-setting.patch | 34 + ...sages-useful-for-HPD-storm-detection.patch | 56 + ...P-aux_ch-communications-with-a-diffe.patch | 169 ++ ...15-Replace-open-coded-offset_in_page.patch | 38 + ...x-pnv-display-core-clock-readout-out.patch | 92 + ...dereference-NULL-crtc-or-fb-until-af.patch | 53 + ...se-intel_encoder-to-the-upcast-macro.patch | 97 + ...-switch-mode_fixup-to-compute_config.patch | 76 + ...-out-legacy-encoder-mode_fixup-logic.patch | 63 + ...use-native-encoder-mode_set-callback.patch | 92 + ...-use-intel_encoder-for-upcast-helper.patch | 114 + ...Use-native-encoder-mode_set-callback.patch | 98 + ...use-native-encoder-mode_set-callback.patch | 111 + ...use-native-encoder-mode_set-callback.patch | 103 + ...use-native-encoder-mode_set-callback.patch | 76 + ...e-the-native-encoder-mode_set-callba.patch | 69 + ...-the-native-encoder-mode_set-callbac.patch | 118 + ...out-legacy-encoder-mode_set-callback.patch | 49 + ...15-clean-up-crtc-timings-computation.patch | 110 + ...-repeated-reasoning-for-why-FBC-cann.patch | 196 ++ ...-same-pte_encoding-for-ppgtt-as-for-.patch | 55 + .../0552-drm-i915-Remove-useless-define.patch | 32 + ...e-macro-casting-by-using-an-inline-f.patch | 69 + ...led-paramater-to-update_sprite_water.patch | 165 ++ ...e-actual-sprite-width-to-watermarks-.patch | 97 + ...te-the-sprite-WM-based-on-the-source.patch | 60 + ...hsw_wm_get_pixel_rate-to-ilk_pipe_pi.patch | 48 + ...most-wm-compute-functions-to-ilk_-pr.patch | 162 ++ ...pass-mem_value-to-ilk_compute_fbc_wm.patch | 51 + ...the-watermark-latency-type-to-uint16.patch | 53 + ...ut-reading-of-HSW-watermark-latency-.patch | 95 + ...ultiply-the-watermark-latency-values.patch | 59 + ...-IVB-support-to-intel_read_wm_latenc.patch | 41 + .../0564-drm-i915-enable-IPS-for-bpp-24.patch | 34 + ...-dpio_lock-for-VLV-sideband-programm.patch | 157 ++ ...ge-vlv-dp-enable-and-pre_enable-call.patch | 145 ++ ...ge-vlv-hdmi-enable-and-pre_enable-ca.patch | 89 + ...coder-enable-callback-later-in-VLV-c.patch | 60 + ...er-mode-sync-polarity-setting-explic.patch | 59 + .../0570-i915-fix-ACPI-_DSM-warning.patch | 75 + ...i915-hsw-Change-default-LLC-age-to-3.patch | 69 + .../0572-drm-i915-Create-an-init-vm.patch | 70 + ...15-Rework-drop-caches-for-checkpatch.patch | 48 + ...m-i915-Make-proper-functions-for-VMs.patch | 283 +++ ...5-Use-bound-list-for-inactive-shrink.patch | 51 + .../0576-drm-i915-Add-VM-to-pin.patch | 211 ++ ...i915-Use-ggtt_vm-to-save-some-typing.patch | 122 + .../0578-drm-i915-Update-describe_obj.patch | 68 + ...thread-address-space-through-execbuf.patch | 302 +++ ...aching-operate-on-all-address-spaces.patch | 77 + ...0581-drm-i915-BUG_ON-put_pages-later.patch | 42 + ...5-make-reset-hangcheck-code-VM-aware.patch | 98 + ...ILK-support-to-intel_read_wm_latency.patch | 43 + ...he-watermark-latency-values-in-dev_p.patch | 169 ++ ...-stored-cursor-and-plane-latencies-p.patch | 122 + ...-the-watermark-latencies-during-init.patch | 86 + ...-specific-watermark-levels-when-late.patch | 53 + ...-watermark-latency-values-from-dev_p.patch | 290 +++ ...mments-about-units-of-latency-values.patch | 79 + ...minate-dead-domain-clearing-on-reset.patch | 49 + ...-useless-messages-about-DDI-buffer-t.patch | 53 + ...use_fdi_mode-argument-from-intel_pre.patch | 59 + ...I915_CACHE_MLC_LLC-to-L3_LLC-for-Ivy.patch | 151 ++ ...m-i915-Export-intel_framebuffer_fini.patch | 101 + .../0595-drm-i915-Improve-VMA-comments.patch | 34 + ...-drm-gem-create-drm_gem_dumb_destroy.patch | 777 ++++++ ...est_match-flag-to-drm_mm_insert_node.patch | 383 +++ .../0598-drm-const-ify-ioctls-table-v2.patch | 432 ++++ ...oc-instead-of-drm_mm-search-get_bloc.patch | 176 ++ .../0600-Re-create-dirty-merge-32c913e.patch | 35 + ...01-drm-i915-Rework-__i915_gem_shrink.patch | 41 + ...-i915-plumb-VM-into-bind-unbind-code.patch | 530 ++++ ...Use-new-bind-unbind-in-eviction-code.patch | 184 ++ ...-turn-bound_ggtt-checks-to-bound_any.patch | 109 + ...oduce-a-generic-hdmi_infoframe-union.patch | 117 + ...-macro-to-return-the-size-of-a-full-.patch | 37 + ...-let-the-user-of-this-API-create-inv.patch | 66 + ...e-the-bar-data-valid-bit-from-the-ba.patch | 62 + ...duce-helpers-for-the-HDMI-vendor-spe.patch | 176 ++ ...-edid-Move-HDMI_IDENTIFIER-to-hdmi.h.patch | 54 + ...the-HDMI-vendor-infoframe-with-the-g.patch | 163 ++ ...dmi_vendor_infoframe-for-the-HDMI-sp.patch | 185 ++ ...-edid-Fix-add_cea_modes-style-issues.patch | 66 + ...he-HDMI-CEA-block-and-look-for-4k-mo.patch | 199 ++ ...ame-HDMI_IDENTIFIER-to-HDMI_IEEE_OUI.patch | 73 + ...ange-the-write_infoframe-vfunc-to-ta.patch | 337 +++ ...rt-the-infoframe-code-to-the-common-.patch | 147 ++ ...rt-the-infoframe-code-to-the-shared-.patch | 77 + ...the-now-obsolete-infoframe-definitio.patch | 129 + ...BLCLK-flag-in-the-common-infoframe-h.patch | 51 + ...name-set_infoframe-to-write_infofram.patch | 59 + ...bled-instead-of-enable-consistently-.patch | 63 + ...atermark-level-computation-from-the-.patch | 105 + ...ll-fbc_enable-from-hsw_lp_wm_results.patch | 63 + ...hsw_data_buf_partitioning-to-intel_d.patch | 107 + ...26-drm-i915-Silence-a-sparse-warning.patch | 35 + ...915-Fix-up-map-and-fenceable-for-VMA.patch | 57 + .../0628-drm-i915-mm_list-is-per-VMA.patch | 453 ++++ ...rm-i915-Update-error-capture-for-VMs.patch | 163 ++ ...drm-i915-Add-vma-to-list-at-creation.patch | 83 + ...l-watermark-level-validity-check-out.patch | 101 + ...e-hsw_lp_wm_result-to-intel_wm_level.patch | 111 + ...lculate-max-watermark-levels-for-ILK.patch | 165 ++ ...me-watermarks-state-into-a-separate-.patch | 158 ++ ...lane-watermark-parameters-into-a-sep.patch | 198 ++ ...tc-to-our-update-disable_plane-hooks.patch | 129 + ...ry-to-disable-plane-if-it-s-already-.patch | 47 + ...ane-and-crtc-to-intel_update_sprite_.patch | 169 ++ ...call-intel_update_sprite_watermarks-.patch | 46 + ...jects-allocated-from-stolen-memory-i.patch | 107 + ...641-drm-i915-Remove-stale-prototypes.patch | 74 + ...move-i915_gem_object_check_coherency.patch | 125 + .../0643-drm-i915-Fix-endif-comment.patch | 28 + ...5-Make-i915_hangcheck_elapsed-static.patch | 42 + ...-i915-Make-intel_encoder_dpms-static.patch | 48 + ...rm-i915-Remove-intel_modeset_disable.patch | 52 + ...-drm-i915-Make-intel_set_mode-static.patch | 58 + ...-unbreak-i915_gem_object_ggtt_unbind.patch | 41 + ...imit-check-in-hsw_compute_wm_results.patch | 44 + ...ose-HDMI-connectors-on-port-C-on-BYT.patch | 44 + .../0651-drm-i915-Fix-FB-WM-for-HSW.patch | 45 + ...rules-for-reading-cache-lines-throug.patch | 96 + ...hen-an-object-is-pinned-for-use-by-t.patch | 180 ++ ...rules-for-writing-through-the-LLC-wi.patch | 265 ++ ...Allow-the-GPU-to-cache-stolen-memory.patch | 43 + .../0656-drm-kill-dev-context_wait.patch | 57 + .../0657-drm-remove-dev-last_switch.patch | 57 + ...-dev-interrupt_flag-and-dev-dma_flag.patch | 45 + ...kill-dev-ctx_start-and-dev-lck_start.patch | 46 + ...-dev-buf_readers-and-dev-buf_writers.patch | 45 + .../0661-drm-rip-out-dev-last_checked.patch | 43 + .../0662-drm-remove-FASYNC-support.patch | 444 ++++ ...rm_gem_dmabuf_release-in-i915-exynos.patch | 139 ++ ...ddmap-and-drm_mmap-to-use-PAT-WC-ins.patch | 127 + ...pgprot_writecombine-for-AGP-maps-and.patch | 124 + ...GP-cleanup-paths-to-drm_agpsupport.c.patch | 193 ++ ...gag200-nouveau-savage-vmwgfx-Remove-.patch | 336 +++ ...add-and-mtrr_del-fallback-hack-for-n.patch | 69 + ...provide-agp-dummies-for-CONFIG_AGP-n.patch | 318 +++ ...drm-rip-out-drm_core_has_MTRR-checks.patch | 391 +++ ...y-do-a-chipset-flush-after-a-clflush.patch | 136 ++ ...915-WARN_ON-failed-map_and_fenceable.patch | 35 + ...DVO-potentially-turning-off-randomly.patch | 36 + ...unused-leftover-variable-irq_receive.patch | 44 + ...re-distinctive-names-to-ring-hangche.patch | 121 + ...necessary-local-variable-to-suppress.patch | 66 + ...-I915_CACHING_DISPLAY-and-document-c.patch | 66 + ...te-Through-cacheing-for-the-display-.patch | 159 ++ ...he-user-to-set-bo-into-the-DISPLAY-c.patch | 55 + ...i915-remove-set-but-unused-variables.patch | 143 ++ ...int-the-changes-required-for-modeset.patch | 34 + ...-message-when-we-detect-an-early-Has.patch | 65 + ...tune-the-RC6-threshold-for-stability.patch | 56 + ...m-i915-Initialize-seqno-for-VECS-too.patch | 52 + ...915-Get-VECS-semaphore-info-on-error.patch | 51 + ...-error-paths-in-create_stolen_for_pr.patch | 43 + ...i915-Remove-node-only-when-allocated.patch | 56 + ...8-drm-i915-cleanup-map-fence-in-bind.patch | 67 + ...-node-directly-and-rewrap-map-fence-.patch | 41 + ...e-overzealous-warning-from-i915_gem_.patch | 58 + ...-the-power-well-when-redisabling-VGA.patch | 58 + ...clarify-Haswell-power-well-bit-names.patch | 96 + ...5-Only-unmask-required-PM-interrupts.patch | 46 + ...t-store-base-gem-object-in-dma_buf-p.patch | 96 + ...-the-power-well-before-module-unload.patch | 56 + ...ig-option-to-turn-on-i915.preliminar.patch | 65 + ...xec_list-obj-obj_exec_link-in-debugf.patch | 98 + ...915-Switch-eviction-code-to-use-vmas.patch | 132 + ...pare-bind_to_vm-for-preallocated-vma.patch | 93 + ...a-Correct-use-after-free-in-eviction.patch | 101 + ...-make-IVB-FDI-training-match-spec-v3.patch | 210 ++ ...702-drm-i915-Remove-DSPARB_HWCONTROL.patch | 37 + ...703-drm-i915-Remove-HAS_PIPE_CONTROL.patch | 37 + .../0704-drm-Remove-IS_IRONLAKE_D.patch | 39 + ...emove-I915_READ_-NOPID-SYNC_0-SYNC_1.patch | 33 + ...energy-counter-on-SNB-through-debugf.patch | 103 + ...-FCLK-case-to-intel_ddi_get_cdclk_fr.patch | 42 + .../0708-drm-i915-wrap-GTIMR-changes.patch | 151 ++ ...709-drm-i915-wrap-GEN6_PMIMR-changes.patch | 164 ++ ...pdate-GEN6_PMIMR-when-it-s-not-neede.patch | 54 + ...11-drm-i915-add-dev_priv-pm_irq_mask.patch | 71 + ...isable-reenable-IVB-error-interrupts.patch | 56 + ...n-t-queue-PM-events-we-won-t-process.patch | 71 + ...-we-mask-PMIMR-when-adding-work-to-t.patch | 100 + ...15-merge-HSW-and-SNB-PM-irq-handlers.patch | 108 + ...aning-up-the-relocate-entry-function.patch | 126 + ...rop-WaMbcDriverBootEnable-workaround.patch | 93 + ...grab-force_wake-when-restoring-LCPLL.patch | 53 + ...DEIMR-assertion-when-disabling-LCPLL.patch | 48 + ...ackage-C8-states-on-Haswell-disabled.patch | 677 ++++++ ...915-add-i915_pc8_status-debugfs-file.patch | 65 + ...m-i915-add-i915.pc8_timeout-function.patch | 84 + ...rm-i915-enable-Package-C8-by-default.patch | 37 + ...-i915-Use-POSTING_READ-in-lcpll-code.patch | 46 + ...text-size-calculation-on-SNB-IVB-VLV.patch | 78 + ...-Print-seqnos-as-unsigned-in-debugfs.patch | 35 + ...oo-add-driver-control-power-feature..patch | 359 +++ ...h-60Hz-and-59.94Hz-CEA-modes-to-conn.patch | 171 ++ ...ort-for-alternate-clocks-of-4k-modes.patch | 117 + ...ch_cea_mode-return-the-underlying-2D.patch | 119 + ...lper-to-forge-HDMI-vendor-infoframes.patch | 93 + ...reo-3D-flags-to-struct-drm_mode_mode.patch | 101 + ...mandatory-stereo-modes-for-HDMI-sink.patch | 185 ++ ..._hdmi_mode-out-of-do_hdmi_vsdb_modes.patch | 92 + ...layouts-as-an-enum-rather-than-a-bit.patch | 173 ++ ...vant-infoframe-field-when-scanning-o.patch | 96 + ...rite-HDMI-vendor-specific-infoframes.patch | 140 ++ ...Pass-page-flip-ioctl-flags-to-driver.patch | 304 +++ ...-implement-experimental-render-nodes.patch | 408 ++++ .../0740-drm-i915-Support-render-nodes.patch | 110 + ...on-t-mask-EI-UP-interrupt-on-IVB-SNB.patch | 72 + ...anitize-forcewake-registers-on-reset.patch | 60 + ...available-RPS-information-through-sy.patch | 98 + ...he-force-detect-VGA-w-a-to-Valleyvie.patch | 38 + ...requested-frequency-alongside-curren.patch | 57 + ...6-drm-i915-tune-down-hangcheck-noise.patch | 45 + ...915-fix-lvds-dp-panel-fitter-setting.patch | 53 + ...he-ring-private-within-the-struct-in.patch | 275 +++ ...-drm-i915-Use-RCS-flips-on-Ivybridge.patch | 139 ++ ...-kmem_cache_alloc-.GFP_ZERO-to-kmem_.patch | 31 + ...split-PCI-IDs-out-into-i915_drm.h-v4.patch | 444 ++++ ...irk-for-reserving-Intel-graphics-sto.patch | 285 +++ ...-i915-enable-trickle-feed-on-Haswell.patch | 102 + ...Pin-pages-whilst-mapping-the-dma-buf.patch | 94 + ...GA-arbiter-support-for-newer-devices.patch | 137 ++ ...all-sg_free_table-if-sg_alloc_table-.patch | 32 + ...e-config-warnings-when-dealing-with-.patch | 98 + ...ix-up-the-relocate_entry-refactoring.patch | 42 + ...-work-vs.-flush_work-in-the-pageflip.patch | 92 + ...sdvo-input-pixel-multiplier-correctl.patch | 92 + ...x_crtc_clock_get-for-multiplied-pixe.patch | 50 + ...915-Convert-execbuf-code-to-use-vmas.patch | 790 ++++++ ...vma_create-into-lookup_or_create_vma.patch | 159 ++ ...estroy-the-vma-placeholder-during-ex.patch | 55 + ...ore-vma-fixups-around-unbind-destroy.patch | 162 ++ ...ways-prefer-CPU-relocations-with-LLC.patch | 49 + ...re-VLV-IOSF-sideband-ports-accessors.patch | 126 + ...-pipeconf-bit-definition-for-DSI-PLL.patch | 34 + ...-Constify-the-pretty-print-functions.patch | 221 ++ ...rm-use-ida-to-allocate-connector-ids.patch | 166 ++ ...MIPI-DSI-encoder-and-connector-types.patch | 63 + ...15-add-MIPI-DSI-register-definitions.patch | 443 ++++ ...dd-MIPI-DSI-output-type-and-subtypes.patch | 44 + ...i915-add-structs-for-MIPI-DSI-output.patch | 130 + ...dd-MIPI-DSI-command-sending-routines.patch | 593 +++++ ...15-add-basic-MIPI-DSI-output-support.patch | 630 +++++ ...rm-i915-add-VLV-DSI-PLL-Calculations.patch | 463 ++++ ...-i915-fix-PLL-assertions-for-DSI-PLL.patch | 143 ++ ...9-drm-i915-don-t-enable-DPLL-for-DSI.patch | 137 ++ .../0780-drm-i915-Band-Gap-WA.patch | 89 + ...he-MIPI-related-VBT-Block-and-store-.patch | 132 + ...rm-i915-initialize-DSI-output-on-VLV.patch | 33 + .../0783-drm-i915-dsi-s-size_t-int.patch | 175 ++ ...Report-enabled-slices-on-Haswell-GT3.patch | 77 + ...915-Restore-the-preliminary-HW-check.patch | 73 + ...15-Fix-list-corruption-in-vma_unbind.patch | 56 + ...add-an-interrupt-for-a-context-switc.patch | 86 + ...nge-the-comments-in-i915_add_request.patch | 47 + patches.baytrail/0789-drm-i915-It-s-its.patch | 30 + ...0790-drm-i915-add-plumbing-for-SWSCI.patch | 294 +++ ...15-expose-intel_ddi_get_encoder_port.patch | 45 + ...egion-function-to-notify-bios-of-enc.patch | 130 + ...egion-function-to-notify-bios-of-ada.patch | 83 + ...lay-power-state-notification-on-crtc.patch | 48 + ...DP-set-clock-to-accomodate-more-eDP-.patch | 114 + ...lleyview-DP-DPLL-divisor-calc-to-int.patch | 107 + ...rm-i915-Kill-IRONLAKE_FDI_FREQ-check.patch | 53 + ...Rename-ring-outstanding_lazy_request.patch | 148 ++ ...rm-i915-Preallocate-the-lazy-request.patch | 94 + ...-object-reference-whilst-we-shrink-i.patch | 158 ++ ...olen-region-initialisation-if-none-i.patch | 44 + ...itional-pipe-parameter-for-vlv_dpio_.patch | 465 ++++ ...unused-mode_fixup-vfunc-of-struct-in.patch | 73 + ...fine-page-flips-to-BCS-on-Valleyview.patch | 43 + ...not-to-lose-backlight-CBLV-precision.patch | 48 + ...915-name-intel-dp-hooks-per-platform.patch | 81 + ...cklight-enable-later-in-vlv-enable-s.patch | 57 + ...p-power-sequencing-register-port-sel.patch | 74 + ...port-for-per-pipe-power-sequencing-o.patch | 331 +++ ...drm-i915-ban-badly-behaving-contexts.patch | 196 ++ ...-hangcheck-action-and-score-in-error.patch | 132 + ...isabling-of-VGA-memory-until-vgacon-.patch | 145 ++ ...fit-enable-state-separately-from-siz.patch | 164 ++ ...proper-print-format-for-debug-prints.patch | 42 + ...Pass-crtc-to-intel_update_watermarks.patch | 319 +++ ...tel_update_watermarks-in-specific-pl.patch | 142 ++ ...rm-i915-Constify-some-watermark-data.patch | 103 + ..._compute_wm_level-to-compute-WM_PIPE.patch | 90 + .../0819-drm-i915-Refactor-max-WM-level.patch | 58 + ...lly-translate-sync-flags-in-the-dtd-.patch | 45 + ...915-Write-RING_TAIL-once-per-request.patch | 197 ++ ...the-double-list-iteration-from-bound.patch | 40 + ...-sync-flags-to-use-pipe-config-adjus.patch | 39 + ...enable-hotplug-detect-based-probing-.patch | 38 + ...bustify-the-dtd-drm_mode-conversions.patch | 142 ++ ...-crtc-timings-again-for-panel-fixed-.patch | 46 + ...nize-pread-pwrite-with-wait_renderin.patch | 79 + ...Extract-vm-specific-part-of-eviction.patch | 70 + ...-i915-evict-VM-instead-of-everything.patch | 110 + .../0830-drm-i915-kill-set_need_resched.patch | 48 + ...15-move-more-code-to-__i915_drm_thaw.patch | 92 + ...-i915-don-t-save-restore-LBB-on-Gen5.patch | 48 + ...actor-in-pixel-multplier-when-derivi.patch | 68 + ...justed_mode.clock-non-pixel-multipli.patch | 115 + ...915-Add-support-for-pipe_bpp-readout.patch | 118 + ...te-readout-and-checking-for-has_dp_e.patch | 197 ++ ...tel_fuzzy_clock_check-take-in-arbitr.patch | 54 + .../0838-drm-i915-Remove-extra-ring.patch | 36 + ...-drm-i915-Round-l3-parity-reads-down.patch | 39 + ...915-Fix-l3-parity-user-buffer-offset.patch | 68 + ...i915-add-asserts-for-cursor-disabled.patch | 81 + ...-opregon-lid_state-after-we-unmap-it.patch | 32 + ...rm-i915-Add-intel_dotclock_calculate.patch | 121 + ...9xx_crtc_clock_get-use-dpll_hw_state.patch | 82 + ...xx_crtc_clock_get-work-for-PCH-DPLLs.patch | 103 + ...t_clock-and-adjusted_mode.clock-read.patch | 411 ++++ ...i915-Add-PIPE_CONF_CHECK_CLOCK_FUZZY.patch | 71 + ...Add-fuzzy-clock-check-for-port_clock.patch | 48 + ...e-pixel-clock-from-adjusted_mode-not.patch | 40 + ...usted_mode-clock-in-lpt_program_iclk.patch | 69 + ...usted_mode-in-HDMI-12bpc-clock-check.patch | 38 + ...se-adjusted_mode-in-intel_update_fbc.patch | 70 + ...usted_mode-appropriately-when-comput.patch | 190 ++ ...he-clock-from-adjusted-mode-in-intel.patch | 42 + ...usted_mode-when-checking-conditions-.patch | 46 + ...tel_crtc_active-available-outside-in.patch | 107 + ...-i915-Use-pipe-config-in-sprite-code.patch | 38 + ...djusted_mode-in-DSI-PLL-calculations.patch | 47 + ...xplicit-pipe-src-size-to-pipe-config.patch | 419 ++++ ...ut-intel_panel.c-to-obey-80-char-lim.patch | 217 ++ ...nt-the-inteded-use-of-requested_mode.patch | 38 + ...sor-visibility-check-with-negative-c.patch | 46 + ...sor-visibility-checks-also-for-the-r.patch | 58 + ...-garbage-collect-vlv-refclk-function.patch | 62 + ...uble-wide-mode-handling-into-pipe_co.patch | 95 + ...Add-double_wide-readout-and-checking.patch | 48 + ...Check-pixel-clock-limits-on-pre-gen4.patch | 64 + ...c_w-must-be-even-in-LVDS-dual-channe.patch | 52 + ...ix-up-pipe-vs.-double-wide-confusion.patch | 40 + ...-overlay-double-wide-check-over-to-p.patch | 39 + ...-the-DP-aux-read-or-write-is-too-big.patch | 70 + ...port-hpd-connector-status-change-whe.patch | 57 + ...-i915-check-for-more-ASLC-interrupts.patch | 256 ++ ...o-not-update-cursor-in-crtc-mode-set.patch | 74 + ...-enable-the-cursor-on-a-disable-pipe.patch | 52 + ...-i915-write-D_COMP-using-the-mailbox.patch | 77 + ...r-backlight-device-also-when-backlig.patch | 40 + ...mp-crtc-timings-from-the-pipe-config.patch | 56 + .../0879-drm-i915-Fix-HSW-parity-test.patch | 63 + ...m-i915-Add-second-slice-l3-remapping.patch | 480 ++++ ...-i915-Make-l3-remapping-use-the-ring.patch | 138 ++ ...drm-i915-Keep-a-list-of-all-contexts.patch | 128 + ...-drm-i915-Do-remaps-for-all-contexts.patch | 225 ++ ...m-i915-s-HAS_L3_GPU_CACHE-HAS_L3_DPF.patch | 137 ++ ...or-i915_enable_rc6-boot-param-on-VLV.patch | 44 + ...able-rc6p-and-rc6pp-residency-report.patch | 44 + ...t-disable-ERR_INT-on-the-IRQ-handler.patch | 84 + ..._READ-IPS_CTL-before-waiting-for-the.patch | 31 + ...nge-i915_request-power-well-handling.patch | 121 + ...el_display_power_-get-put-to-request.patch | 115 + ...r-power-well-refcount-inc-dec-operat.patch | 111 + .../0892-drm-i915-Add-POWER_DOMAIN_VGA.patch | 64 + ...tel_init_power_well-out-of-intel_mod.patch | 65 + .../0894-drm-i915-cleanup-a-min_t-cast.patch | 34 + ...all-GM45-Acer-laptops-use-inverted-b.patch | 60 + .../0896-Re-create-dirty-merge-b599c89.patch | 35 + ...emporary-va_list-for-two-pass-string.patch | 60 + ...dd-defines-for-downstream-port-types.patch | 42 + ...stream-port-capabilities-are-not-pre.patch | 67 + ...nter-k-cmz.-alloc-sizeof-pointer-.-p.patch | 348 +++ .../0901-drm-i915-Use-kcalloc-more.patch | 129 + ...02-drm-i915-Ditch-INTELFB_CONN_LIMIT.patch | 66 + ...igned-for-overflow-checks-in-execbuf.patch | 78 + ...t-unlock-upon-error-in-i915_gem_idle.patch | 51 + ...hild_device_config-changes-over-time.patch | 272 +++ ...-HDMI-DDI-buffer-translations-from-V.patch | 247 ++ ...he-DDC-and-AUX-bits-of-the-VBT-on-DD.patch | 72 + ...e-assertions-about-VBT-DDI-port-type.patch | 78 + ...nit-DP-or-HDMI-when-not-supported-by.patch | 123 + .../0910-drm-i915-Rip-out-SUPPORTS_EDP.patch | 70 + ...laimed-register-access-due-to-delaye.patch | 91 + ...ble-VGA-before-the-modeset-on-resume.patch | 50 + ...wer-well-init-earlier-during-driver-.patch | 66 + ...-i915-Move-power-well-resume-earlier.patch | 46 + ...tel_uncore_early_sanitize-during-res.patch | 36 + ...plicit-plane-restoration-during-resu.patch | 44 + ...read-DPCD-PSR-capability-only-on-eDP.patch | 43 + ...te-PSR-register-offsets-from-base-ge.patch | 200 ++ ...5-Fix-intel_crtc_mode_get-mode-clock.patch | 46 + ...5-precendence-bug-in-GT_PARITY_ERROR.patch | 36 + ...he-release-of-the-forcewake-by-a-jif.patch | 153 ++ ...some-debug-spam-for-intialising-SDVO.patch | 107 + ...p-and-simplify-i9xx_crtc_mode_set-wr.patch | 105 + ...5-Add-HSW-CRT-output-readout-support.patch | 129 + ...ht-combination-mode-bit-is-gen4-only.patch | 35 + ...0926-drm-i915-reorganize-intel_drv.h.patch | 532 ++++ ...i915-make-intel_pipe_has_type-static.patch | 88 + ...i915-make-intel_crtc_load_lut-static.patch | 212 ++ ...-intel_crtc_fb_gamma_-set-get-static.patch | 99 + ...e-hsw_-disable-restore-_lcpll-static.patch | 58 + ...extern-keywords-from-intel_drv.h-fun.patch | 498 ++++ ...ce-vm-eviction-instead-of-everything.patch | 63 + ...i915-Provide-a-cheap-ggtt-vma-lookup.patch | 86 + ...4-drm-i915-Convert-active-API-to-VMA.patch | 105 + ...e-conditional-seqno-query-into-the-t.patch | 71 + .../0936-drm-i915-Fix-VLV-eDP-timing-v2.patch | 35 + ...-drm-i915-Show-WT-caching-in-debugfs.patch | 45 + ...d-a-tracepoint-for-using-a-semaphore.patch | 78 + ...d-VLV-specific-clock_get-function-v3.patch | 79 + ...-up-broken-precision-in-vlv_crtc_clo.patch | 47 + ...k_index-from-struct-drm_display_mode.patch | 51 + ...h_clock-from-struct-drm_display_mode.patch | 35 + ...crtc_clock-for-struct-drm_display_mo.patch | 49 + ...rtc_clock-in-intel_dump_crtc_timings.patch | 37 + ...se-crtc_clock-with-the-adjusted-mode.patch | 467 ++++ ...imings-adjustments-for-frame-packing.patch | 90 + ...-DRM-core-do-make-stereo-timings-adj.patch | 40 + ...crtc_-h-v-display-for-pipe-src-dimen.patch | 52 + ...g-stereo-modes-a-per-connector-opt-i.patch | 80 + ...-drm-i915-Allow-stereo-modes-on-HDMI.patch | 33 + ...k-to-init-backlight-regs-if-BIOS-fai.patch | 68 + ...-GMBUS-Frequency-based-on-the-CDCLK-.patch | 158 ++ ...te-one-indent-leel-from-vlv_find_bes.patch | 73 + .../0954-drm-i915-Use-DIV_ROUND_CLOSEST.patch | 37 + ...-vlv-use-lower-precision-RC6-counter.patch | 53 + ...e-correct-units-for-rc6-residency-v2.patch | 76 + ...uce-GT-FIFO-error-info-to-a-debug-me.patch | 36 + ...y-i2c-over-aux-seven-times-on-AUX-DE.patch | 37 + ...ot-write-DP_TRAINING_PATTERN_SET-all.patch | 278 +++ ...estroy-connector-sysfs-files-earlier.patch | 199 ++ ...-Make-intel_resume_power_well-static.patch | 46 + ...-fix-typo-s-PatherPoint-PantherPoint.patch | 29 + ...e-integrated-clock-source-handling-v.patch | 106 + ...-enable-planes-as-the-first-last-thi.patch | 156 ++ ...nt-the-Haswell-mode-set-sequence-wor.patch | 78 + ...opulate-pipe_src_-w-h-multiple-times.patch | 60 + ...ean-up-the-ring-scaling-calculations.patch | 63 + ...e-missing-steps-to-i915_driver_load-.patch | 91 + ...ait_seqno-to-use-true-infinite-timeo.patch | 349 +++ ...5-Boost-RPS-frequency-for-CPU-stalls.patch | 571 +++++ ...PS-thresholds-to-more-aggressively-d.patch | 355 +++ .../0972-drm-i915-Simplify-PSR-debugfs.patch | 330 +++ ...vlv-reset-DPIO-on-load-and-resume-v2.patch | 83 + ...n-off-power-gate-for-BIOS-less-syste.patch | 87 + ...ore-detailed-comment-about-the-set_b.patch | 45 + ...usted_mode-in-the-fastboot-hack-to-d.patch | 41 + ...ve-drm_gem_object_handle_unreference.patch | 48 + ..._gem_object_handle_unreference_unloc.patch | 174 ++ ...ogus-NULL-check-from-drm_gem_object_.patch | 34 + ...RN-about-unbalanced-handle-refcounts.patch | 34 + ...rm-gem-fix-up-flink-name-create-race.patch | 224 ++ ...ror-path-in-drm_gem_prime_fd_to_hand.patch | 33 + ..._gem_object_handle_unreference_unloc.patch | 46 + ...x-locking-in-gem-debugfs-procfs-file.patch | 35 + ...itch-dev-object_name_lock-to-a-mutex.patch | 139 ++ ...-put-an-exported-dma_buf-for-adding-.patch | 48 + ...rime-add-return-check-for-dma_buf_fd.patch | 93 + ...oper-pointer-in-drm_gem_prime_handle.patch | 75 + ...ly-close-gem_open-vs.-gem_close-race.patch | 154 ++ ...-locking-refcounting-for-obj-dma_buf.patch | 295 +++ ...-remove-unused-driver_private-access.patch | 37 + ...0992-drm-edid-add-drm_edid_duplicate.patch | 54 + ...3-drm-i915-dp-use-drm_edid_duplicate.patch | 43 + ...drm-Make-vblank_disable_allowed-bool.patch | 151 ++ .../0995-drm-Make-vblank_enabled-bool.patch | 91 + ...6-drm-Make-vblank_inmodeset-unsigned.patch | 37 + ...ct-per-crtc-vblank-stuff-to-a-struct.patch | 549 +++++ .../0998-drm-Make-irq_enabled-bool.patch | 233 ++ .../0999-drm-add-drm_dev_alloc-helper.patch | 249 ++ .../1000-drm-gma500-Add-IS_CDV-macro.patch | 30 + ...endor-and-pci_device-from-struct-drm.patch | 370 +++ ...-fold-in-drm_sg_alloc-into-the-ioctl.patch | 80 + ...y-sg-cleanup-better-from-common-code.patch | 82 + ...dma-setup-teardown-as-legacy-systems.patch | 118 + ...a-clearing-from-drm_setup-to-lastclo.patch | 120 + ...drm-move-drm_lastclose-to-drm_fops.c.patch | 189 ++ .../1007-drm-no-op-out-GET_STATS-ioctl.patch | 59 + ...-drm-Kill-drm-perf-counter-leftovers.patch | 223 ++ ...r-for-checking-DP_ENHANCED_FRAME_CAP.patch | 37 + ...t-rid-of-intel_dp-link_configuration.patch | 160 ++ ..._schedule-whilst-whilsting-for-the-G.patch | 35 + ...915-Remove-yet-another-unused-define.patch | 30 + ...sizeof-for-memset-instead-of-magic-v.patch | 29 + ...v_find_best_dpll-ppm-calculation-saf.patch | 71 + ...015-drm-i915-Don-t-underflow-bestppm.patch | 36 + ...-drm-i915-Rewrite-vlv_find_best_dpll.patch | 140 ++ ...e-magic-the-VLV-p2-divider-step-size.patch | 40 + ...15-Make-sure-we-respect-n.max-on-VLV.patch | 53 + ...9-drm-i915-Clarify-VLV-PLL-p1-limits.patch | 60 + ...0-drm-i915-Allow-p1-divider-2-on-VLV.patch | 36 + ...pect-p2-divider-minimum-limit-on-VLV.patch | 54 + ...ve-the-unused-p-and-m-limits-for-VLV.patch | 52 + ...unused-dot_limit-from-VLV-PLL-limits.patch | 46 + ...imits_vlv_dac-and-intel_limits_vlv_h.patch | 58 + ...ie-about-findind-suitable-PLL-settin.patch | 57 + ...el_PLL_is_valid-in-vlv_find_best_dpl.patch | 110 + ...-drm-i915-Fix-VGA_DISP_DISABLE-check.patch | 44 + ...ote-clock-recovery-failures-to-DRM_E.patch | 46 + ...mary_disabled-in-intel_-enable-disab.patch | 65 + ...prites-to-be-configured-on-a-disable.patch | 162 ++ ...the-time-we-hold-struct-mutex-in-spr.patch | 111 + ...Kill-a-goto-from-sprite-disable-code.patch | 65 + ...-a-bit-of-cleanup-in-the-sprite-code.patch | 63 + ...er-requested-plane-coordinates-only-.patch | 74 + ...fbc-vs.-primary-plane-enable-disable.patch | 64 + ...disable-IPS-when-primary-is-enabled-.patch | 101 + ...intel_flush_display_plane-to-intel_f.patch | 121 + ...intel_-enable-disable-_plane-to-inte.patch | 131 + ...-primary-plane-state-doesn-t-match-e.patch | 42 + ...primary-plane-changes-in-sprite-code.patch | 43 + ...-real-cpu-max-frequency-for-ring-sca.patch | 76 + ...m-i915-Undo-the-PIPEA-quirk-for-i845.patch | 35 + ...hat-the-i965g-gm-4G-limit-is-really-.patch | 38 + ...044-drm-i915-rip-out-gen2-reset-code.patch | 73 + ...event-using-uninitialized-MMIO-funcs.patch | 44 + ...-Move-edram-detection-early_sanitize.patch | 65 + ...m-i915-Create-MMIO-virtual-functions.patch | 282 +++ ...8-drm-i915-Extract-common-MMIO-lines.patch | 92 + ...m-i915-Create-GEN-specific-read-MMIO.patch | 132 + ...-i915-Create-GEN-specific-write-MMIO.patch | 168 ++ ...5-Remove-gen-specific-checks-in-MMIO.patch | 158 ++ .../1052-drm-i915-Keep-intel_drv.h-tidy.patch | 44 + ...ait-for-IPS_ENABLE-when-enabling-IPS.patch | 51 + ...-i915-Do-PCH-and-uncore-init-earlier.patch | 62 + ...te-training-set-in-a-burst-write-wit.patch | 73 + ...-leak-dp_connector-at-intel_ddi_init.patch | 125 + ...e-primary_disabled-in-intel_modeset_.patch | 39 + ...-primary_disabled-to-primary_enabled.patch | 118 + ...-the-initial-error-state-when-kickin.patch | 43 + ...enabling-rps-before-use-by-sysfs-or-.patch | 136 ++ ...-users-in-dmesg-about-reporting-gpu-.patch | 44 + ...ll-the-user-KMS-is-required-for-gen6.patch | 40 + ...id-tweaking-RPS-before-it-is-enabled.patch | 96 + ...e-the-SWSCI-DSLP-default-timeout-to-.patch | 48 + ...pe-off-timeout-handling-for-pre-gen4.patch | 83 + ...-t-save-restore-CACHE_MODE_0-on-gen7.patch | 45 + ...5-vlv-add-doc-names-to-sideband-file.patch | 34 + ...i915-Fix-VLV-frame-counter-registers.patch | 67 + ...ys-select-ACPI_VIDEO-if-ACPI-is-enab.patch | 52 + ...ate-Kconfig-option-for-fbdev-helpers.patch | 305 +++ ...-option-to-disable-the-legacy-fbdev-.patch | 368 +++ ...5-rename-intel_fb.c-to-intel_fbdev.c.patch | 128 + ...-drm-i915-Fix-pre-CTG-vblank-counter.patch | 109 + ...adcrumbs-for-why-the-backlight-is-be.patch | 57 + ...V_ROUND_CLOSEST-to-calculate-dot-vco.patch | 60 + ...-Use-vlv_clock-in-vlv_crtc_clock_get.patch | 40 + ...gister-reads-in-i915_get_crtc_scanou.patch | 122 + ...drm-i915-Fix-scanoutpos-calculations.patch | 106 + ...-the-accuracy-of-get_scanout_pos-on-.patch | 100 + ...15-Fix-gen2-scanout-position-readout.patch | 86 + ...retend-that-gen2-has-a-hardware-fram.patch | 53 + ...1082-drm-dp-constify-DP-DPCD-helpers.patch | 144 ++ ...083-drm-i915-dp-constify-link_status.patch | 51 + ...el_pipe_wm-and-prepare-for-watermark.patch | 301 +++ ...e-compute-pipe-watermarks-except-for.patch | 158 ++ ...1-watermark-merging-out-from-hsw_com.patch | 82 + ...tel_pipe_wm-in-hsw_find_best_results.patch | 116 + ...me-computations-out-from-hsw_compute.patch | 112 + ...-6-DDB-split-only-when-sprites-are-e.patch | 37 + ...-Refactor-wm_lp-to-level-calculation.patch | 50 + ...-fbc_wm_enabled-from-intel_wm_config.patch | 40 + ...urrent-watermark-state-in-dev_priv-w.patch | 185 ++ ...5-Improve-watermark-dirtyness-checks.patch | 188 ++ ...W-watermark-tracking-in-intel_modese.patch | 197 ++ ...a-somewhat-silly-debug-print-from-wa.patch | 37 + ...i915-Adjust-watermark-register-masks.patch | 58 + ...ilk_wm_max-to-ilk_compute_wm_maximum.patch | 67 + ...ilk_check_wm-to-ilk_validate_wm_leve.patch | 57 + ...-6-DDB-split-only-when-sprites-are-e.patch | 38 + ...x-tve-Let-device-core-handle-pinctrl.patch | 50 + .../1101-i2c-stu300-device-tree-support.patch | 91 + ...do-not-request-a-specific-clock-name.patch | 44 + ...nctrl-add-pin-list-based-GPIO-ranges.patch | 148 ++ ...-Intel-BayTrail-GPIO-pinctrl-support.patch | 611 +++++ ...ompile-warning-in-pxa2xx_spi_acpi_ge.patch | 43 + ...rt-to-dma_request_slave_channel_comp.patch | 118 + ...pi-pxa2xx-add-Intel-BayTrail-ACPI-ID.patch | 32 + ...-LPSS-add-support-for-Intel-BayTrail.patch | 185 ++ ...ask-the-UART-TX-completion-interrupt.patch | 126 + ...de-SDIO-private-register-space-size-.patch | 61 + ...A-hda-add-PCI-IDs-for-Intel-BayTrail.patch | 33 + ...oC-fsl-add-imx-wm8962-machine-driver.patch | 446 ++++ ...return-value-from-mv64xxx_i2c_map_re.patch | 37 + ...2C-mv64xxx-use-devm_ioremap_resource.patch | 114 + ...devm_clk_get-to-avoid-missing-clk_pu.patch | 34 + .../1116-I2C-mv64xxx-use-devm_kzalloc.patch | 98 + ...x-fix-error-handling-for-request_irq.patch | 42 + ...2C-mv64xxx-remove-I2C_M_NOSTART-code.patch | 61 + ...4xxx-move-mv64xxx_i2c_prepare_for_io.patch | 90 + ...race-between-FSM-interrupt-and-proce.patch | 144 ++ ...c-imx-Let-device-core-handle-pinctrl.patch | 54 + ...revent-signals-from-aborting-I2C-tra.patch | 48 + ...es-don-t-check-resource-with-devm_io.patch | 148 ++ ...re-fix-race-between-subsequent-xfers.patch | 62 + ...upport-for-I2C-bus-on-Wondermedia-So.patch | 586 +++++ ...-macros-to-access-parts-of-registers.patch | 54 + ...ke-the-registers-offset-configurable.patch | 275 +++ ...64xxx-Add-Allwinner-sun4i-compatible.patch | 68 + ...-i2c-mv64xxx-Fix-transfer-error-code.patch | 33 + ...-i2c-imx-allow-autoloading-on-dt-ids.patch | 30 + ...bus-frequency-to-100kHz-if-clock-fre.patch | 60 + ...ware-make-SDA-hold-time-configurable.patch | 187 ++ ...c-designware-use-div_u64-to-fix-link.patch | 42 + .../1134-of-remove-CONFIG_OF_DEVICE.patch | 88 + ...nline-marking-of-EXPORT_SYMBOL-funct.patch | 42 + ...eck-resource-with-devm_ioremap_resou.patch | 41 + ...e-dw_dmac-driver-to-an-own-directory.patch | 146 ++ ...ver-to-library-part-and-platform-cod.patch | 963 ++++++++ ...39-dma-dw-add-PCI-part-of-the-driver.patch | 162 ++ ...ect-DW_DMAC_BIG_ENDIAN_IO-automagica.patch | 59 + ...ility-to-stay-runtime-resumed-if-the.patch | 125 + ...upport-runtime-PM-for-ACPI-HID-80860.patch | 131 + ...-support-runtime-PM-for-BYT-SD-cards.patch | 31 + ...ix-error-return-code-in-sdhci_acpi_a.patch | 37 + ...d-support-for-eMMC-hardware-reset-fo.patch | 92 + ...dd-support-for-eMMC-hardware-reset-f.patch | 69 + ...-mmc-sdhci-pci-add-another-device-id.patch | 45 + ...8250_dw-Add-support-for-OCTEON-UARTS.patch | 238 ++ ...ment-the-newly-introduced-allwinner-.patch | 29 + ...able-DMA-on-newer-Intel-LPSS-silicon.patch | 48 + ...ci-refactor-EHCI-xHCI-port-switching.patch | 211 ++ ...dw-Report-CTS-asserted-for-auto-flow.patch | 108 + ...53-pinctrl-baytrail-fix-indentations.patch | 46 + ...pinctrl-baytrail-change-lvl-to-level.patch | 36 + ...ytrail-remove-redundant-ptr-variable.patch | 40 + ...baytrail-introduce-to_byt_gpio-macro.patch | 100 + ...aytrail-fix-to-avoid-sparse-warnings.patch | 55 + ...8-ASoC-fsl-imx-wm8962-Fix-error-path.patch | 35 + ...anually-set-RESTART-bit-between-mess.patch | 62 + ...dd-CONFIG_PM_SLEEP-to-suspend-resume.patch | 60 + ...ONFIG_PM_SLEEP-to-suspend-resume-fun.patch | 37 + ...ct-representing-i2c-clk-div-val-pair.patch | 85 + ...enable-clk-before-write-to-registers.patch | 45 + ...ange-platform-device-id_entry-direct.patch | 48 + ...isters-read-write-to-inline-function.patch | 252 ++ ...hange-register-offset-representation.patch | 71 + ...T-flag-and-IEN-bit-operatation-codes.patch | 91 + ...uct-to-hold-more-configurable-quirks.patch | 216 ++ ...-Vybrid-VF610-I2C-controller-support.patch | 88 + .../1170-i2c-use-dev_get_platdata.patch | 425 ++++ ...dd-I2C-Transaction-Generator-support.patch | 370 +++ ...timing-issue-on-Armada-XP-errata-FE-.patch | 84 + ...73-i2c-move-OF-helpers-into-the-core.patch | 1201 +++++++++ ...-i2c-move-ACPI-helpers-into-the-core.patch | 331 +++ ...e-make-HCNT-LCNT-values-configurable.patch | 91 + ...et-SDA-hold-time-HCNT-and-LCNT-confi.patch | 79 + ...nd-MODULE_DEVICE_TABLE-for-ACPI-case.patch | 34 + ...178-dma-dw-improve-comparison-with-0.patch | 60 + .../1179-dma-dw-allow-shared-interrupts.patch | 52 + ...A_SUCCESS-immediately-from-device_tx.patch | 41 + ...A_PAUSED-only-if-cookie-status-is-DM.patch | 32 + ...dd-pin-control-support-to-Intel-low-.patch | 46 + ...0-bit-addressing-mode-enabling-if-I2.patch | 80 + ...ace-platform_driver_probe-to-support.patch | 75 + ...0_dw-don-t-limit-DMA-support-to-ACPI.patch | 72 + ...rovide-a-filter-for-DMA-channel-dete.patch | 54 + ...ial-8250_dw-fix-broken-function-call.patch | 33 + ...ACPI-LPSS-fix-UART-Auto-Flow-Control.patch | 56 + ...SS-add-ACPI-IDs-for-newer-Intel-PCHs.patch | 39 + ...pxa2xx-Restore-private-register-bits.patch | 34 + ...t-PINCTRL_EXYNOS-for-exynos4-5-at-ch.patch | 115 + ...-arch_phys_wc_add-and-add-a-missing-.patch | 41 + ...i-pci-Fix-BYT-sd-card-getting-stuck-.patch | 80 + series | 1202 ++++++++- 1194 files changed, 142933 insertions(+), 2 deletions(-) create mode 100644 patches.baytrail/0001-xhci-Refactor-port-status-into-a-new-function.patch create mode 100644 patches.baytrail/0002-usb-Fix-xHCI-host-issues-on-remote-wakeup.patch create mode 100644 patches.baytrail/0003-usb-xhci-check-usb2-port-capabilities-before-adding-.patch create mode 100644 patches.baytrail/0004-usb-xhci-define-port-register-names-and-use-them-ins.patch create mode 100644 patches.baytrail/0005-usb-xhci-add-USB2-Link-power-management-BESL-support.patch create mode 100644 patches.baytrail/0006-usb-add-usb2-Link-PM-variables-to-sysfs-and-usb_devi.patch create mode 100644 patches.baytrail/0007-xhci-fix-port-BESL-LPM-capability-checking.patch create mode 100644 patches.baytrail/0008-usb-Don-t-enable-USB-2.0-Link-PM-by-default.patch create mode 100644 patches.baytrail/0009-drm-i915-quirk-away-phantom-LVDS-on-Intel-s-D525MW-m.patch create mode 100644 patches.baytrail/0010-drm-i915-don-t-enable-the-plane-too-early-in-i9xx_cr.patch create mode 100644 patches.baytrail/0011-drm-i915-drop-redundant-vblank-waits.patch create mode 100644 patches.baytrail/0012-drm-i915-add-pipe-asserts-for-the-crtc-enable-sequen.patch create mode 100644 patches.baytrail/0013-drm-i915-add-i9xx-pfit-pipe-asserts.patch create mode 100644 patches.baytrail/0014-drm-i915-move-debug-output-back-to-the-right-place.patch create mode 100644 patches.baytrail/0015-drm-i915-Use-pipe_name-and-port_name-where-appropria.patch create mode 100644 patches.baytrail/0016-drm-i915-Use-port_name-in-PCH-port-audio-power-chang.patch create mode 100644 patches.baytrail/0017-drm-i915-Print-plane-pipe-port-names-as-alphabetical.patch create mode 100644 patches.baytrail/0018-drm-i915-Use-alphabetical-names-for-transcoders-too.patch create mode 100644 patches.baytrail/0019-drm-i915-Use-alphabetical-names-for-sprites.patch create mode 100644 patches.baytrail/0020-drm-i915-VLV-GPU-frequency-to-opcode-functions.patch create mode 100644 patches.baytrail/0021-drm-i915-turbo-RC6-support-for-VLV-v7.patch create mode 100644 patches.baytrail/0022-drm-i915-fix-VLV-limits.patch create mode 100644 patches.baytrail/0023-drm-i915-magic-VLV-PLL-registers-in-the-dpio-sideban.patch create mode 100644 patches.baytrail/0024-drm-i915-dp-program-VSwing-and-Preemphasis-control-s.patch create mode 100644 patches.baytrail/0025-drm-i915-drop-init_dpio-shouldn-t-be-needed.patch create mode 100644 patches.baytrail/0026-drm-i915-update-VLV-PLL-and-DPIO-code-v11.patch create mode 100644 patches.baytrail/0027-drm-i915-report-Gen5-CPU-and-PCH-FIFO-underruns.patch create mode 100644 patches.baytrail/0028-drm-i915-print-Gen5-CPU-PCH-poison-interrupts.patch create mode 100644 patches.baytrail/0029-drm-i915-check-the-power-well-inside-haswell_get_pip.patch create mode 100644 patches.baytrail/0030-drm-i915-use-cpu_transcoder-for-TRANS_DDI_FUNC_CTL.patch create mode 100644 patches.baytrail/0031-drm-i915-Move-the-CSC_MODE-bits-next-to-the-register.patch create mode 100644 patches.baytrail/0032-drm-i915-Remove-mention-of-Haswell-in-DDI-code.patch create mode 100644 patches.baytrail/0033-drm-i915-use-vlv_dport_to_channel-in-vlv_signal_leve.patch create mode 100644 patches.baytrail/0034-drm-i915-Make-struct-dpll-intel_clock_t.patch create mode 100644 patches.baytrail/0035-drm-i915-Add-PTE-encoding-function-to-the-gtt-ppgtt-.patch create mode 100644 patches.baytrail/0036-drm-i915-Fix-page-table-entries-for-Bay-Trail.patch create mode 100644 patches.baytrail/0037-drm-i915-Split-out-Haswell-code-from-gen6_pte_encode.patch create mode 100644 patches.baytrail/0038-drm-i915-fix-locking-around-punit-access-in-cur_dela.patch create mode 100644 patches.baytrail/0039-drm-i915-Add-bit-field-to-record-which-pins-have-rec.patch create mode 100644 patches.baytrail/0040-drm-i915-Only-reprobe-display-on-encoder-which-has-r.patch create mode 100644 patches.baytrail/0041-drm-i915-Turn-DEV_INFO_FLAGS-into-a-foreach-style-ma.patch create mode 100644 patches.baytrail/0042-drm-i915-Replace-the-line-of-s-by-a-DEV_INFO_FOR_EAC.patch create mode 100644 patches.baytrail/0043-drm-i915-Use-DEV_INFO_FOR_EACH_FLAG-to-declare-flags.patch create mode 100644 patches.baytrail/0044-drm-i915-Turn-HAS_DDI-into-a-device_info-flag.patch create mode 100644 patches.baytrail/0045-drm-i915-Introduce-HAS_FPGA_DBG_UNCLAIMED.patch create mode 100644 patches.baytrail/0046-drm-i915-Turn-HAS_FPGA_DBG_UNCLAIMED-into-a-device_i.patch create mode 100644 patches.baytrail/0047-drm-i915-make-sure-GPU-freq-drops-to-minimum-after-e.patch create mode 100644 patches.baytrail/0048-drm-i915-cancel-RPS-work-before-disabling-RPS.patch create mode 100644 patches.baytrail/0049-drm-i915-create-spearate-VLV-disable_rps-function.patch create mode 100644 patches.baytrail/0050-drm-i915-disable-interrupts-earlier-in-the-driver-un.patch create mode 100644 patches.baytrail/0051-drm-i915-Disable-high-bpc-on-pre-1.4-EDID-screens.patch create mode 100644 patches.baytrail/0052-drm-i915-Fixup-non-24bpp-support-for-VGA-screens-on-.patch create mode 100644 patches.baytrail/0053-drm-i915-keep-max-backlight-internal-to-intel_panel..patch create mode 100644 patches.baytrail/0054-drm-i915-protect-backlight-registers-and-data-with-a.patch create mode 100644 patches.baytrail/0055-drm-i915-don-t-pretend-we-support-ASLE-ALS-PFIT-or-P.patch create mode 100644 patches.baytrail/0056-drm-i915-opregion-don-t-pretend-we-did-something-whe.patch create mode 100644 patches.baytrail/0057-drm-i915-drop-code-duplication-in-favor-of-asle-inte.patch create mode 100644 patches.baytrail/0058-drm-i915-hsw-backlight-registers-need-transcoder-ins.patch create mode 100644 patches.baytrail/0059-drm-i915-Ivybridge-is-the-odd-one-when-it-comes-to-p.patch create mode 100644 patches.baytrail/0060-drm-i915-consolidate-pch-pll-computations-a-bit.patch create mode 100644 patches.baytrail/0061-drm-i915-shovel-compute-clock-into-crtc-config.dpll-.patch create mode 100644 patches.baytrail/0062-drm-i915-move-dp-clock-computations-to-encoder-compu.patch create mode 100644 patches.baytrail/0063-drm-i915-use-pipe_config-for-lvds-dithering.patch create mode 100644 patches.baytrail/0064-drm-i915-don-t-force-matching-p1-for-g4x-ilk-reduced.patch create mode 100644 patches.baytrail/0065-drm-i915-remove-redundant-has_pch_encoder-check.patch create mode 100644 patches.baytrail/0066-drm-i915-simplify-config-pixel_multiplier-handling.patch create mode 100644 patches.baytrail/0067-drm-i915-factor-out-GMCH-panel-fitting-code-and-use-.patch create mode 100644 patches.baytrail/0068-drm-i915-move-PCH-pfit-controls-into-pipe_config.patch create mode 100644 patches.baytrail/0069-drm-i915-warn-about-invalid-pfit-modes.patch create mode 100644 patches.baytrail/0070-drm-i915-remove-VLV-MSI-IRQ-hack.patch create mode 100644 patches.baytrail/0071-drm-i915-Only-print-the-info-message-about-incresing.patch create mode 100644 patches.baytrail/0072-drm-i915-put-the-right-cpu_transcoder-into-pipe_conf.patch create mode 100644 patches.baytrail/0073-drm-i915-force-bpp-for-eDP-panels.patch create mode 100644 patches.baytrail/0074-drm-i915-drop-adjusted_mode-from-_set_pipeconf-funct.patch create mode 100644 patches.baytrail/0075-drm-i915-implement-high-bpc-pipeconf-dither-support-.patch create mode 100644 patches.baytrail/0076-drm-i915-allow-high-bpc-modes-on-DP.patch create mode 100644 patches.baytrail/0077-drm-i915-move-intel_crtc-fdi_lanes-to-pipe_config.patch create mode 100644 patches.baytrail/0078-drm-i915-hw-state-readout-support-for-pipe_config-fd.patch create mode 100644 patches.baytrail/0079-drm-i915-split-up-fdi_set_m_n-into-computation-and-h.patch create mode 100644 patches.baytrail/0080-drm-i915-compute-fdi-lane-config-earlier.patch create mode 100644 patches.baytrail/0081-drm-i915-Split-up-ironlake_check_fdi_lanes.patch create mode 100644 patches.baytrail/0082-drm-i915-move-fdi-lane-configuration-checks-ahead.patch create mode 100644 patches.baytrail/0083-drm-i915-don-t-count-cpu-ports-for-fdi-B-C-lane-shar.patch create mode 100644 patches.baytrail/0084-drm-i915-fixup-12bpc-hdmi-dotclock-handling.patch create mode 100644 patches.baytrail/0085-drm-i915-implement-fdi-auto-dithering.patch create mode 100644 patches.baytrail/0086-drm-i915-stop-for_each_intel_crtc_masked-macro-from-.patch create mode 100644 patches.baytrail/0087-drm-i915-introduce-macros-to-check-pipe-config-prope.patch create mode 100644 patches.baytrail/0088-drm-i915-hw-state-readout-support-for-fdi-m-n.patch create mode 100644 patches.baytrail/0089-drm-i915-hw-state-readout-support-for-pipe-timings.patch create mode 100644 patches.baytrail/0090-drm-i915-cleanup-opregion-technology-enabled-indicat.patch create mode 100644 patches.baytrail/0091-drm-i915-manage-opregion-asle-driver-readiness-prope.patch create mode 100644 patches.baytrail/0092-drm-i915-untie-opregion-init-and-asle-irq-pipestat-e.patch create mode 100644 patches.baytrail/0093-drm-i915-cleanup-redundant-checks-from-intel_enable_.patch create mode 100644 patches.baytrail/0094-drm-i915-cleanup-opregion-asle-pipestat-enable.patch create mode 100644 patches.baytrail/0095-drm-i915-move-lvds_border_bits-to-pipe_config.patch create mode 100644 patches.baytrail/0096-drm-i915-rip-out-indirection-for-pfit-pipe_config-as.patch create mode 100644 patches.baytrail/0097-drm-i915-move-border-color-writes-to-pfit_enable.patch create mode 100644 patches.baytrail/0098-drm-Add-struct-drm_rect-and-assorted-utility-functio.patch create mode 100644 patches.baytrail/0099-drm-Add-drm_rect_calc_-hscale-vscale-utility-functio.patch create mode 100644 patches.baytrail/0100-drm-Add-drm_rect_debug_print.patch create mode 100644 patches.baytrail/0101-drm-Add-drm_rect_equals.patch create mode 100644 patches.baytrail/0102-drm-i915-Implement-proper-clipping-for-video-sprites.patch create mode 100644 patches.baytrail/0103-drm-i915-Relax-the-sprite-scaling-limits-checks.patch create mode 100644 patches.baytrail/0104-drm-i915-reference-count-for-i915_hw_contexts.patch create mode 100644 patches.baytrail/0105-drm-i915-simplify-DP-DDI-port-width-macros.patch create mode 100644 patches.baytrail/0106-drm-i915-unreference-default-context-on-module-unloa.patch create mode 100644 patches.baytrail/0107-drm-i915-fix-Haswell-pfit-power-well-check-v2.patch create mode 100644 patches.baytrail/0108-drm-i915-don-t-setup-hdmi-for-port-D-edp-in-ddi_init.patch create mode 100644 patches.baytrail/0109-drm-i915-put-context-upon-switching.patch create mode 100644 patches.baytrail/0110-drm-i915-add-context-into-request-struct.patch create mode 100644 patches.baytrail/0111-drm-i915-fix-up-adjusted_mode-tracking-for-interlace.patch create mode 100644 patches.baytrail/0112-drm-i915-s-TRANSCONF-PCH_TRANSCONF.patch create mode 100644 patches.baytrail/0113-drm-i915-PCH_-prefix-for-transcoder-timings.patch create mode 100644 patches.baytrail/0114-drm-i915-make-set_m_n-functions-static.patch create mode 100644 patches.baytrail/0115-drm-i915-Apply-OCD-to-data-link-m-n-register-defines.patch create mode 100644 patches.baytrail/0116-drm-i915-make-intel_cpt_verify_modeset-static.patch create mode 100644 patches.baytrail/0117-drm-i915-Assert-mutex_is_locked-on-context-lookup.patch create mode 100644 patches.baytrail/0118-drm-i915-BUG_ON-bad-PPGTT-offset.patch create mode 100644 patches.baytrail/0119-drm-i915-Extract-PDE-writes.patch create mode 100644 patches.baytrail/0120-drm-i915-Fix-declaration-of-intel_gmbus_-is_forced_b.patch create mode 100644 patches.baytrail/0121-drm-i915-read-current-freq-from-Punit-on-VLV.patch create mode 100644 patches.baytrail/0122-drm-i915-go-back-to-switch-for-VLV-mem-freq-detectio.patch create mode 100644 patches.baytrail/0123-drm-i915-fix-panel-fitting-on-LVDS-on-ILK-v2.patch create mode 100644 patches.baytrail/0124-drm-i915-set-proper-DPIO-post-divider-for-VGA-on-VLV.patch create mode 100644 patches.baytrail/0125-drm-i915-add-intel_display_power_enabled.patch create mode 100644 patches.baytrail/0126-drm-i915-add-power-well-and-cpu-transcoder-info-to-t.patch create mode 100644 patches.baytrail/0127-drm-i915-clear-FPGA_DBG_RM_NOCLAIM-when-capturing-er.patch create mode 100644 patches.baytrail/0128-drm-i915-check-the-power-well-on-i915_pipe_enabled.patch create mode 100644 patches.baytrail/0129-drm-i915-only-disable-DDI-sound-if-intel_crtc-eld_vl.patch create mode 100644 patches.baytrail/0130-drm-i915-Add-platform-information-to-implemented-wor.patch create mode 100644 patches.baytrail/0131-drm-i915-Add-references-to-some-workaround-we-implem.patch create mode 100644 patches.baytrail/0132-drm-i915-fix-hotplug-event-bit-tracking.patch create mode 100644 patches.baytrail/0133-drm-i915-HSW-allow-PCH-clock-gating-for-suspend.patch create mode 100644 patches.baytrail/0134-drm-i915-Re-enable-FBC-WM-if-the-watermark-is-good-o.patch create mode 100644 patches.baytrail/0135-drm-i915-BIOS-and-power-context-stolen-mem-handling-.patch create mode 100644 patches.baytrail/0136-drm-i915-allow-stolen-pre-allocated-objects-to-avoid.patch create mode 100644 patches.baytrail/0137-drm-i915-VLV-support-is-no-longer-preliminary.patch create mode 100644 patches.baytrail/0138-drm-i915-use-enc_to_intel_dp-instead-of-opencoding-t.patch create mode 100644 patches.baytrail/0139-drm-i915-hsw-replace-is_pch_edp-with-port-PORT_A.patch create mode 100644 patches.baytrail/0140-drm-i915-ilk-ivb-replace-is_pch_edp-with-port-PORT_A.patch create mode 100644 patches.baytrail/0141-drm-i915-stop-using-is_pch_edp-in-intel_dp_init_conn.patch create mode 100644 patches.baytrail/0142-drm-i915-stop-using-is_pch_edp-in-is_cpu_edp.patch create mode 100644 patches.baytrail/0143-drm-i915-remove-is_pch_edp-helpers-and-state-variabl.patch create mode 100644 patches.baytrail/0144-drm-i915-print-DP-init-debug-messages-from-a-single-.patch create mode 100644 patches.baytrail/0145-drm-i915-move-sdvo-TV-clock-computation-to-intel_sdv.patch create mode 100644 patches.baytrail/0146-drm-i915-drop-TVclock-special-casing-on-ilk.patch create mode 100644 patches.baytrail/0147-drm-i915-rip-out-TV-out-lore.patch create mode 100644 patches.baytrail/0148-drm-i915-rip-out-now-unused-is_foo-tracking-from-crt.patch create mode 100644 patches.baytrail/0149-drm-i915-make-SDVO-TV-out-work-for-multifunction-dev.patch create mode 100644 patches.baytrail/0150-drm-i915-Organize-VBT-stuff-inside-drm_i915_private.patch create mode 100644 patches.baytrail/0151-drm-i915-Add-support-for-FBC-on-Ivybridge.patch create mode 100644 patches.baytrail/0152-drm-i915-IVB-FBC-WaFbcAsynchFlipDisableFbcQueue.patch create mode 100644 patches.baytrail/0153-drm-i915-IVB-FBC-WaFbcDisableDpfcClockGating.patch create mode 100644 patches.baytrail/0154-drm-i915-Enable-FBC-at-Haswell.patch create mode 100644 patches.baytrail/0155-drm-i915-HSW-FBC-WaFbcAsynchFlipDisableFbcQueue.patch create mode 100644 patches.baytrail/0156-drm-i915-HSW-FBC-WaFbcDisableDpfcClockGating.patch create mode 100644 patches.baytrail/0157-drm-i915-Compute-WR-PLL-dividers-dynamically.patch create mode 100644 patches.baytrail/0158-drm-i915-rip-out-an-unused-lvds_reg-variable.patch create mode 100644 patches.baytrail/0159-drm-i915-Add-missing-platform-tags-to-FBC-workaround.patch create mode 100644 patches.baytrail/0160-drm-i915-implement-WADPOClockGatingDisable-for-LPT.patch create mode 100644 patches.baytrail/0161-drm-i915-panel-fitter-hw-state-readout-check-support.patch create mode 100644 patches.baytrail/0162-drm-i915-Use-pipe_config-state-to-disable-ilk-pfit.patch create mode 100644 patches.baytrail/0163-drm-i915-Use-pipe-config-state-to-control-gmch-pfit-.patch create mode 100644 patches.baytrail/0164-drm-i915-add-support-for-dvo-Chrontel-7010B.patch create mode 100644 patches.baytrail/0165-Add-arch_phys_wc_-add-del-to-manipulate-WC-MTRRs-if-.patch create mode 100644 patches.baytrail/0166-i915-Use-arch_phys_wc_-add-del.patch create mode 100644 patches.baytrail/0167-drm-Print-pretty-names-for-pixel-formats.patch create mode 100644 patches.baytrail/0168-drm-i915-Print-pretty-names-for-pixel-formats.patch create mode 100644 patches.baytrail/0169-drm-i915-add-encoder-get_config-function-v5.patch create mode 100644 patches.baytrail/0170-drm-i915-ILK-SNB-and-IVB-don-t-have-linetime-waterma.patch create mode 100644 patches.baytrail/0171-drm-i915-remove-intel_update_linetime_watermarks.patch create mode 100644 patches.baytrail/0172-drm-i915-use-the-mode-htotal-to-calculate-linetime-w.patch create mode 100644 patches.baytrail/0173-drm-i915-fix-haswell-linetime-watermarks-calculation.patch create mode 100644 patches.baytrail/0174-drm-i915-make-intel_ddi_get_cdclk_freq-return-values.patch create mode 100644 patches.baytrail/0175-drm-i915-set-the-IPS-linetime-watermark.patch create mode 100644 patches.baytrail/0176-drm-i915-MCH_SSKPD-is-a-64-bit-register-on-Haswell.patch create mode 100644 patches.baytrail/0177-drm-i915-set-FORCE_ARB_IDLE_PLANES-workaround.patch create mode 100644 patches.baytrail/0178-drm-i915-Be-more-informative-when-reporting-too-larg.patch create mode 100644 patches.baytrail/0179-drm-i915-Fix-WARN_ON-on-UP-machines.patch create mode 100644 patches.baytrail/0180-drm-i915-Workaround-incoherence-with-fence-updates-o.patch create mode 100644 patches.baytrail/0181-drm-i915-Cocci-spatch-memdup.spatch.patch create mode 100644 patches.baytrail/0182-drm-i915-avoid-big-kmallocs-on-reading-error-state.patch create mode 100644 patches.baytrail/0183-drm-i915-group-sideband-register-accessors-to-a-new-.patch create mode 100644 patches.baytrail/0184-drm-i915-refactor-VLV-IOSF-sideband-accessors-to-use.patch create mode 100644 patches.baytrail/0185-drm-i915-drop-redundant-warnings-on-not-holding-dpio.patch create mode 100644 patches.baytrail/0186-drm-i915-rename-VLV-IOSF-sideband-functions-logicall.patch create mode 100644 patches.baytrail/0187-drm-i915-change-VLV-IOSF-sideband-accessors-to-not-r.patch create mode 100644 patches.baytrail/0188-drm-i915-add-enable-argument-to-intel_update_sprite_.patch create mode 100644 patches.baytrail/0189-drm-i915-add-haswell_update_sprite_wm.patch create mode 100644 patches.baytrail/0190-drm-i915-pass-seqno-to-i915_hangcheck_ring_idle.patch create mode 100644 patches.baytrail/0191-drm-i915-track-ring-progression-using-seqnos.patch create mode 100644 patches.baytrail/0192-drm-i915-introduce-i915_hangcheck_ring_hung.patch create mode 100644 patches.baytrail/0193-drm-i915-Fix-error-state-memory-leaks.patch create mode 100644 patches.baytrail/0194-drm-i915-pre-fixes-for-checkpatch.patch create mode 100644 patches.baytrail/0195-drm-i915-use-mappable-size-for-fb-kickout.patch create mode 100644 patches.baytrail/0196-drm-i915-use-drm_mm_takedown.patch create mode 100644 patches.baytrail/0197-drm-i915-context-debug-messages.patch create mode 100644 patches.baytrail/0198-drm-i915-Call-context-fini-at-cleanup.patch create mode 100644 patches.baytrail/0199-drm-i915-release-scratch-page-at-module-unload.patch create mode 100644 patches.baytrail/0200-drm-i915-stop-using-is_cpu_edp-in-intel_disable-post.patch create mode 100644 patches.baytrail/0201-drm-i915-merge-VLV-eDP-and-DP-AUX-clock-divider-calc.patch create mode 100644 patches.baytrail/0202-drm-i915-replace-is_cpu_edp-with-a-check-for-port-A.patch create mode 100644 patches.baytrail/0203-drm-i915-remove-unused-is_cpu_edp.patch create mode 100644 patches.baytrail/0204-drm-i915-fixup-i915_pipe_enabled-check-in-i915_irq.c.patch create mode 100644 patches.baytrail/0205-drm-i915-hw-state-readout-check-support-for-cpu_tran.patch create mode 100644 patches.baytrail/0206-drm-i915-document-why-dvo-sdvo-crt-need-a-special-dp.patch create mode 100644 patches.baytrail/0207-drm-i915-fix-error-return-code-in-init_pipe_control.patch create mode 100644 patches.baytrail/0208-drm-i915-add-basic-pipe-config-dump-support.patch create mode 100644 patches.baytrail/0209-drm-i915-drop-a-few-really-redundant-WARNs-in-hsw-mo.patch create mode 100644 patches.baytrail/0210-drm-i915-Avoid-promoting-a-simulated-hang-to-wedged.patch create mode 100644 patches.baytrail/0211-drm-i915-release-cursor-when-crtc-is-destroyed.patch create mode 100644 patches.baytrail/0212-drm-i915-Comments-for-semaphore-clarification.patch create mode 100644 patches.baytrail/0213-drm-i915-Semaphore-MBOX-update-generalization.patch create mode 100644 patches.baytrail/0214-drm-i915-Introduce-VECS-the-4th-ring.patch create mode 100644 patches.baytrail/0215-drm-i915-Add-VECS-semaphore-bits.patch create mode 100644 patches.baytrail/0216-drm-i915-Rename-ring-flush-functions.patch create mode 100644 patches.baytrail/0217-drm-i915-add-HAS_VEBOX.patch create mode 100644 patches.baytrail/0218-drm-i915-Vebox-ringbuffer-init.patch create mode 100644 patches.baytrail/0219-drm-i915-fix-pch_nop-support.patch create mode 100644 patches.baytrail/0220-drm-i915-properly-set-HSW-WM_PIPE-registers.patch create mode 100644 patches.baytrail/0221-drm-i915-properly-set-HSW-WM_LP-watermarks.patch create mode 100644 patches.baytrail/0222-drm-i915-add-support-for-5-6-data-buffer-partitionin.patch create mode 100644 patches.baytrail/0223-drm-i915-Create-a-more-generic-pm-handler-for-hsw.patch create mode 100644 patches.baytrail/0224-drm-i915-Create-an-ivybridge_irq_preinstall.patch create mode 100644 patches.baytrail/0225-drm-i915-Add-PM-regs-to-pre-post-install.patch create mode 100644 patches.baytrail/0226-drm-i915-make-PM-interrupt-writes-non-destructive.patch create mode 100644 patches.baytrail/0227-drm-i915-Convert-irq_refounct-to-struct.patch create mode 100644 patches.baytrail/0228-drm-i915-consolidate-interrupt-naming-scheme.patch create mode 100644 patches.baytrail/0229-drm-i915-vebox-interrupt-get-put.patch create mode 100644 patches.baytrail/0230-drm-i915-Enable-vebox-interrupts.patch create mode 100644 patches.baytrail/0231-drm-i915-add-VEBOX-into-debugfs.patch create mode 100644 patches.baytrail/0232-drm-i915-add-I915_EXEC_VEBOX-to-i915_gem_do_execbuff.patch create mode 100644 patches.baytrail/0233-drm-i915-add-I915_PARAM_HAS_VEBOX-to-i915_getparam.patch create mode 100644 patches.baytrail/0234-drm-i915-fix-up-the-edp-power-well-check.patch create mode 100644 patches.baytrail/0235-drm-i915-implement-IPS-feature.patch create mode 100644 patches.baytrail/0236-drm-i915-add-enable_ips-module-option.patch create mode 100644 patches.baytrail/0237-drm-i915-add-i915_ips_status-debugfs-entry.patch create mode 100644 patches.baytrail/0238-drm-i915-Drop-bogus-fbdev-sprite-disable-code.patch create mode 100644 patches.baytrail/0239-drm-i915-Demote-unknown-param-to-DRM_DEBUG.patch create mode 100644 patches.baytrail/0240-drm-i915-Make-stolen-use-pin-pages.patch create mode 100644 patches.baytrail/0241-drm-i915-Unpin-stolen-pages.patch create mode 100644 patches.baytrail/0242-drm-i915-unpin-pages-at-unbind.patch create mode 100644 patches.baytrail/0243-drm-i915-Rename-the-gtt_list-to-global_list.patch create mode 100644 patches.baytrail/0244-drm-i915-detect-hang-using-per-ring-hangcheck_score.patch create mode 100644 patches.baytrail/0245-drm-i915-remove-i915_hangcheck_hung.patch create mode 100644 patches.baytrail/0246-drm-i915-Use-container_of-in-the-fbdev-code.patch create mode 100644 patches.baytrail/0247-drm-i915-s-drm_i915_private_t-struct-drm_i915_privat.patch create mode 100644 patches.baytrail/0248-drm-i915-optimize-vblank-waits-in-set_base_atomic.patch create mode 100644 patches.baytrail/0249-drm-i915-refactor-sink-bpp-clamping.patch create mode 100644 patches.baytrail/0250-drm-i915-fix-EDID-sink-based-bpp-clamping.patch create mode 100644 patches.baytrail/0251-drm-i915-split-out-intel_pnv_find_best_PLL.patch create mode 100644 patches.baytrail/0252-drm-i915-move-find_pll-callback-to-dev_priv-display.patch create mode 100644 patches.baytrail/0253-drm-i915-fold-in-IS_PNV-checks-from-the-split-up-fin.patch create mode 100644 patches.baytrail/0254-drm-i915-clear-up-the-fdi-dotclock-semantics-for-M-N.patch create mode 100644 patches.baytrail/0255-drm-i915-refactor-cpu-eDP-PLL-handling-a-bit.patch create mode 100644 patches.baytrail/0256-drm-i915-store-adjusted-dotclock-in-adjusted_mode-cl.patch create mode 100644 patches.baytrail/0257-drm-i915-Drop-some-no-longer-required-mode-adjusted_.patch create mode 100644 patches.baytrail/0258-drm-i915-check-for-strange-pfit-pipe-assignemnt-on-i.patch create mode 100644 patches.baytrail/0259-drm-i915-VLV-doesn-t-have-the-ILK-style-LP-watermark.patch create mode 100644 patches.baytrail/0260-drm-i915-Fix-DSPCLK_GATE_D-for-VLV.patch create mode 100644 patches.baytrail/0261-drm-i915-consolidate-and-tighten-encoder-cloning-che.patch create mode 100644 patches.baytrail/0262-drm-i915-distinguish-between-error-messages-in-DIDL-.patch create mode 100644 patches.baytrail/0263-drm-i915-set-default-value-for-config-pixel_multipli.patch create mode 100644 patches.baytrail/0264-drm-i915-Track-clients-and-print-their-object-usage-.patch create mode 100644 patches.baytrail/0265-drm-i915-add-ibx_irq_preinstall.patch create mode 100644 patches.baytrail/0266-Revert-drm-i915-Include-display_mmio_offset-in-seque.patch create mode 100644 patches.baytrail/0267-drm-i915-Always-load-the-display-palette-before-enab.patch create mode 100644 patches.baytrail/0268-drm-i915-Always-enable-the-cursor-right-after-the-pr.patch create mode 100644 patches.baytrail/0269-drm-i915-Enable-the-overlay-right-after-primary-and-.patch create mode 100644 patches.baytrail/0270-drm-i915-Follow-the-same-sequence-when-disabling-pla.patch create mode 100644 patches.baytrail/0271-drm-i915-Drop-overlay-DPMS-call-from-valleyview_crtc.patch create mode 100644 patches.baytrail/0272-drm-i915-Disable-restore-all-sprite-planes-around-mo.patch create mode 100644 patches.baytrail/0273-drm-i915-Improve-assert_planes_disabled.patch create mode 100644 patches.baytrail/0274-drm-i915-Spruce-up-assert_sprites_disabled.patch create mode 100644 patches.baytrail/0275-drm-i915-Assert-dpll-running-in-intel_crtc_load_lut-.patch create mode 100644 patches.baytrail/0276-drm-i915-hw-state-readout-support-for-pixel_multipli.patch create mode 100644 patches.baytrail/0277-drm-i915-update-FBC-maximum-fb-sizes.patch create mode 100644 patches.baytrail/0278-i915-drm-Add-private-api-for-power-well-usage.patch create mode 100644 patches.baytrail/0279-drm-i915-pipe-config-quirk-infrastructure-plus-sdvo-.patch create mode 100644 patches.baytrail/0280-drm-i915-enable-30bpp-for-DP-outputs.patch create mode 100644 patches.baytrail/0281-drm-i915-Disable-primary-plane-trickle-feed-for-g4x.patch create mode 100644 patches.baytrail/0282-drm-i915-Disable-trickle-feed-via-MI_ARB_STATE-for-t.patch create mode 100644 patches.baytrail/0283-drm-i915-Disable-trickle-feed-in-ironlake_init_clock.patch create mode 100644 patches.baytrail/0284-drm-i915-Refactor-ctg-trickle-feed-disable.patch create mode 100644 patches.baytrail/0285-drm-i915-Track-when-we-dirty-the-scanout-with-render.patch create mode 100644 patches.baytrail/0286-drm-i915-WA-FBC-Render-Nuke.patch create mode 100644 patches.baytrail/0287-drm-i915-Make-g4x_fixup_plane-operational-again.patch create mode 100644 patches.baytrail/0288-drm-i915-Remove-dead-code-from-SDVO-initialisation.patch create mode 100644 patches.baytrail/0289-drm-i915-Use-FBINFO_STATE-defines-instead-of-0-and-1.patch create mode 100644 patches.baytrail/0290-drm-i915-fix-up-pch-pll-handling-in-mode_set.patch create mode 100644 patches.baytrail/0291-drm-i915-conditionally-disable-pch-resources-in-ilk_.patch create mode 100644 patches.baytrail/0292-drm-i915-lock-down-pch-pll-accouting-some-more.patch create mode 100644 patches.baytrail/0293-drm-i915-s-pch_pll-shared_dpll.patch create mode 100644 patches.baytrail/0294-drm-i915-switch-crtc-shared_dpll-from-a-pointer-to-a.patch create mode 100644 patches.baytrail/0295-drm-i915-move-shared_dpll-into-the-pipe-config.patch create mode 100644 patches.baytrail/0296-drm-i915-refactor-PCH_DPLL_SEL-defines.patch create mode 100644 patches.baytrail/0297-drm-i915-hw-state-readout-for-shared-pch-plls.patch create mode 100644 patches.baytrail/0298-drm-i915-consolidate-num_shared_dplls-assignement.patch create mode 100644 patches.baytrail/0299-drm-i915-metadata-for-shared-dplls.patch create mode 100644 patches.baytrail/0300-drm-i915-scrap-register-address-storage.patch create mode 100644 patches.baytrail/0301-drm-i915-enable-disable-hooks-for-shared-dplls.patch create mode 100644 patches.baytrail/0302-drm-i915-drop-crtc-checking-from-assert_shared_dpll.patch create mode 100644 patches.baytrail/0303-drm-i915-Fix-old-reference-to-i830_sdvo_get_capabili.patch create mode 100644 patches.baytrail/0304-drm-i915-Initialize-active_outputs-to-never-read-uni.patch create mode 100644 patches.baytrail/0305-drm-i915-Initialize-ring-hangcheck-upon-ring-init.patch create mode 100644 patches.baytrail/0306-drm-i915-Only-slightly-increment-hangcheck-score-if-.patch create mode 100644 patches.baytrail/0307-drm-i915-Don-t-count-semaphore-waits-towards-a-stuck.patch create mode 100644 patches.baytrail/0308-drm-i915-Eliminate-the-addr-seqno-from-the-hangcheck.patch create mode 100644 patches.baytrail/0309-drm-i915-WARN-if-the-fence-pin_count-is-invalid.patch create mode 100644 patches.baytrail/0310-drm-i915-disable-sdvo-pixel-multiplier-cross-check-f.patch create mode 100644 patches.baytrail/0311-drm-i915-pnv-dpll-doesn-t-use-m1.patch create mode 100644 patches.baytrail/0312-drm-i915-display-pll-hw-state-readout-and-checking.patch create mode 100644 patches.baytrail/0313-drm-i915-extract-readout_hw_state-from-setup_hw_stat.patch create mode 100644 patches.baytrail/0314-drm-i915-split-up-intel_modeset_check_state.patch create mode 100644 patches.baytrail/0315-drm-i915-WARN-on-lack-of-shared-dpll.patch create mode 100644 patches.baytrail/0316-drm-i915-hw-state-readout-and-cross-checking-for-sha.patch create mode 100644 patches.baytrail/0317-drm-i915-fix-up-pch-pll-enabling-for-pixel-multiplie.patch create mode 100644 patches.baytrail/0318-drm-i915-Try-harder-to-disable-trickle-feed-on-VLV.patch create mode 100644 patches.baytrail/0319-drm-i915-add-struct-i915_ctx_hang_stats.patch create mode 100644 patches.baytrail/0320-drm-i915-add-i915_gem_context_get_hang_stats.patch create mode 100644 patches.baytrail/0321-drm-i915-change-i915_add_request-to-macro.patch create mode 100644 patches.baytrail/0322-drm-i915-add-batch-bo-to-i915_add_request.patch create mode 100644 patches.baytrail/0323-drm-i915-store-ring-hangcheck-action.patch create mode 100644 patches.baytrail/0324-drm-i915-find-guilty-batch-buffer-on-ring-resets.patch create mode 100644 patches.baytrail/0325-drm-i915-set-up-PIPECONF-explicitly-on-ilk-ivb.patch create mode 100644 patches.baytrail/0326-drm-i915-set-up-PIPECONF-explicitly-for-i9xx-vlv-pla.patch create mode 100644 patches.baytrail/0327-drm-i915-explicitly-set-up-PIPECONF-and-gamma-table-.patch create mode 100644 patches.baytrail/0328-drm-i915-stop-killing-pfit-on-i9xx.patch create mode 100644 patches.baytrail/0329-drm-i915-simplify-the-reduced-clock-handling-for-pch.patch create mode 100644 patches.baytrail/0330-drm-i915-Remove-extra-ring-from-error-message.patch create mode 100644 patches.baytrail/0331-drm-i915-Kill-useless-Enable-panel-fitter-comments.patch create mode 100644 patches.baytrail/0332-drm-i915-remove-a-superflous-semi-colon.patch create mode 100644 patches.baytrail/0333-drm-make-drm_mm_init-return-void.patch create mode 100644 patches.baytrail/0334-drm-i915-don-t-check-encoder-at-DP-connector-destroy.patch create mode 100644 patches.baytrail/0335-drm-i915-extract-intel_edp_init_connector.patch create mode 100644 patches.baytrail/0336-drm-i915-propagate-errors-from-intel_dp_init_connect.patch create mode 100644 patches.baytrail/0337-drm-i915-fix-the-ghost-eDP-connector-unwind-path.patch create mode 100644 patches.baytrail/0338-drm-i915-fix-the-ghost-eDP-encoder-unwind-path.patch create mode 100644 patches.baytrail/0339-drm-i915-check-the-return-value-of-intel_dp_i2c_init.patch create mode 100644 patches.baytrail/0340-drm-i915-rename-intel_dp_destroy-to-intel_dp_connect.patch create mode 100644 patches.baytrail/0341-drm-i915-Fix-PCH-detect-with-multiple-ISA-bridges-in.patch create mode 100644 patches.baytrail/0342-drm-i915-tune-down-DIDL-warning-about-too-many-outpu.patch create mode 100644 patches.baytrail/0343-drm-i915-fix-build-warning-on-format-specifier-misma.patch create mode 100644 patches.baytrail/0344-drm-i915-Introduce-an-HAS_IPS-macro.patch create mode 100644 patches.baytrail/0345-drm-i915-don-t-scream-into-dmesg-when-a-modeset-fail.patch create mode 100644 patches.baytrail/0346-drm-i915-Remove-duplicated-WaForceL3Serialization-vl.patch create mode 100644 patches.baytrail/0347-drm-i915-Detect-invalid-scanout-pitches.patch create mode 100644 patches.baytrail/0348-drm-i915-Clean-up-VLV-rps-code-a-bit.patch create mode 100644 patches.baytrail/0349-drm-i915-Don-t-wait-for-Punit-after-each-freq-change.patch create mode 100644 patches.baytrail/0350-drm-i915-Make-the-rps-new_delay-comparison-more-read.patch create mode 100644 patches.baytrail/0351-drm-i915-GEN6_RP_INTERRUPT_LIMITS-doesn-t-seem-to-ex.patch create mode 100644 patches.baytrail/0352-drm-i915-Don-t-increase-the-GPU-frequency-from-the-d.patch create mode 100644 patches.baytrail/0353-drm-i915-Jump-to-at-least-RPe-on-VLV-when-increasing.patch create mode 100644 patches.baytrail/0354-drm-i915-Fix-VLV-PLL-LPF-coefficients-for-DAC.patch create mode 100644 patches.baytrail/0355-drm-i915-s-LFP-LPF-in-DPIO-PLL-register-names.patch create mode 100644 patches.baytrail/0356-Revert-drm-i915-Don-t-use-the-HDMI-port-color-range-.patch create mode 100644 patches.baytrail/0357-drm-i915-Fix-VLV-sprite-register-offsets.patch create mode 100644 patches.baytrail/0358-drm-i915-fix-locking-around-ironlake_enable-disable_.patch create mode 100644 patches.baytrail/0359-drm-i915-close-tiny-race-in-the-ilk-pcu-even-interru.patch create mode 100644 patches.baytrail/0360-drm-i915-s-hotplug_irq_storm_detect-intel_hpd_irq_ha.patch create mode 100644 patches.baytrail/0361-drm-i915-fold-the-hpd_irq_setup-call-into-intel_hpd_.patch create mode 100644 patches.baytrail/0362-drm-i915-fold-the-queue_work-into-intel_hpd_irq_hand.patch create mode 100644 patches.baytrail/0363-drm-i915-fold-the-no-irq-check-into-intel_hpd_irq_ha.patch create mode 100644 patches.baytrail/0364-drm-i915-fix-hpd-interrupt-register-locking.patch create mode 100644 patches.baytrail/0365-drm-i915-correct-intel_dp_get_config-function-for-De.patch create mode 100644 patches.baytrail/0366-drm-i915-Refactor-the-wait_rendering-completion-into.patch create mode 100644 patches.baytrail/0367-drm-i915-Break-up-the-large-vsnprintf-in-print_error.patch create mode 100644 patches.baytrail/0368-drm-i915-Don-t-try-to-tear-down-the-stolen-drm_mm-if.patch create mode 100644 patches.baytrail/0369-drm-i915-reinit-status-page-registers-after-gpu-rese.patch create mode 100644 patches.baytrail/0370-drm-i915-switch-disable_power_well-default-value-to-.patch create mode 100644 patches.baytrail/0371-drm-i915-fix-lane-bandwidth-capping-for-DP-1.2-sinks.patch create mode 100644 patches.baytrail/0372-Revert-drm-i915-Workaround-incoherence-between-fence.patch create mode 100644 patches.baytrail/0373-drm-i915-fix-up-readout-of-the-lvds-dither-bit-on-ge.patch create mode 100644 patches.baytrail/0374-drm-i915-fix-pfit-regression-for-non-autoscaled-reso.patch create mode 100644 patches.baytrail/0375-drm-i915-Preserve-the-DDI_A_4_LANES-bit-from-the-bio.patch create mode 100644 patches.baytrail/0376-drm-i915-fix-long-standing-SNB-regression-in-power-c.patch create mode 100644 patches.baytrail/0377-drm-i915-Sanitize-shared-dpll-state.patch create mode 100644 patches.baytrail/0378-drm-i915-fix-up-gt-init-sequence-fallout.patch create mode 100644 patches.baytrail/0379-drm-i915-fix-hdmi-portclock-limits.patch create mode 100644 patches.baytrail/0380-drm-i915-update-last_vblank-when-disabling-the-power.patch create mode 100644 patches.baytrail/0381-drm-i915-avoid-brightness-overflow-when-doing-scale.patch create mode 100644 patches.baytrail/0382-drm-i915-Don-t-call-encoder-s-get_config-unless-enco.patch create mode 100644 patches.baytrail/0383-drm-i915-do-not-disable-backlight-on-vgaswitcheroo-s.patch create mode 100644 patches.baytrail/0384-drm-i915-unpin-backing-storage-in-dmabuf_unmap.patch create mode 100644 patches.baytrail/0385-drm-i915-Don-t-deref-pipe-cpu_transcoder-in-the-hang.patch create mode 100644 patches.baytrail/0386-drm-i915-Fix-whitespace-issue-in-i915_gem_gtt.patch create mode 100644 patches.baytrail/0387-drm-i915-invert-the-verbosity-of-intel_enable_fbc.patch create mode 100644 patches.baytrail/0388-drm-i915-Make-intel_enable_fbc-static.patch create mode 100644 patches.baytrail/0389-drm-i915-Fix-reason-for-per-chip-disabling-of-FBC.patch create mode 100644 patches.baytrail/0390-drm-i915-Use-seq_puts-seq_putc-when-possible.patch create mode 100644 patches.baytrail/0391-drm-i915-Fix-a-few-style-issues-found-by-checkpatch..patch create mode 100644 patches.baytrail/0392-drm-i915-Fix-a-couple-of-should-it-be-static-sparse-.patch create mode 100644 patches.baytrail/0393-drm-i915-Bail-out-once-we-ve-found-the-context-objec.patch create mode 100644 patches.baytrail/0394-drm-i915-consolidate-pch-pll-enable-sequence.patch create mode 100644 patches.baytrail/0395-drm-i915-use-sw-tracked-state-to-select-shared-dplls.patch create mode 100644 patches.baytrail/0396-drm-i915-duplicate-intel_enable_pll-into-i9xx-and-vl.patch create mode 100644 patches.baytrail/0397-drm-i915-asserts-for-lvds-pre_enable.patch create mode 100644 patches.baytrail/0398-drm-i915-move-encoder-pre-enable-hooks-togther-on-il.patch create mode 100644 patches.baytrail/0399-drm-i915-hw-state-readout-for-i9xx-dplls.patch create mode 100644 patches.baytrail/0400-drm-i915-move-i9xx-dpll-enabling-into-crtc-enable-fu.patch create mode 100644 patches.baytrail/0401-drm-i915-s-pre_pll-pre-on-the-lvds-port-enable-funct.patch create mode 100644 patches.baytrail/0402-drm-i915-Mask-out-hardware-status-bits-from-VLV-DPLL.patch create mode 100644 patches.baytrail/0403-drm-i915-Remove-extra-error-state-NULL.patch create mode 100644 patches.baytrail/0404-drm-i915-Extract-error-buffer-capture.patch create mode 100644 patches.baytrail/0405-drm-i915-make-PDE-PTE-platform-specific.patch create mode 100644 patches.baytrail/0406-drm-i915-Really-share-scratch-page.patch create mode 100644 patches.baytrail/0407-drm-i915-Combine-scratch-members-into-a-struct.patch create mode 100644 patches.baytrail/0408-drm-i915-Drop-dev-from-pte_encode.patch create mode 100644 patches.baytrail/0409-drm-i915-Use-gtt-shortform-where-possible.patch create mode 100644 patches.baytrail/0410-drm-i915-Move-fbc-members-out-of-line.patch create mode 100644 patches.baytrail/0411-drm-i915-Move-gtt_mtrr-to-i915_gtt.patch create mode 100644 patches.baytrail/0412-drm-i915-pixel-multiplier-readout-support-for-pch-po.patch create mode 100644 patches.baytrail/0413-drm-i915-add-fastboot-param-for-fast-loose-mode-sett.patch create mode 100644 patches.baytrail/0414-drm-i915-get-mode-clock-when-reading-the-pipe-config.patch create mode 100644 patches.baytrail/0415-drm-i915-copy-fetched-mode-state-into-crtc-at-setup_.patch create mode 100644 patches.baytrail/0416-drm-i915-turn-off-panel-fitting-at-flip-time-if-need.patch create mode 100644 patches.baytrail/0417-drm-i915-flip-on-a-no-fb-fb-transition-if-crtc-is-ac.patch create mode 100644 patches.baytrail/0418-drm-i915-export-error-state-to-string-conversion.patch create mode 100644 patches.baytrail/0419-drm-i915-export-error-state-ref-handling.patch create mode 100644 patches.baytrail/0420-drm-i915-introduce-i915_error_state_buf_init.patch create mode 100644 patches.baytrail/0421-drm-i915-add-error_state-sysfs-entry.patch create mode 100644 patches.baytrail/0422-drm-i915-fixup-messages-in-pipe_config_compare.patch create mode 100644 patches.baytrail/0423-drm-i915-split-encoder-get_config-calls-from-crtc-ge.patch create mode 100644 patches.baytrail/0424-drm-i915-Use-wait_for-to-wait-for-Punit-to-change-GP.patch create mode 100644 patches.baytrail/0425-drm-i915-explicitly-cast-pipe-cpu_transcoder.patch create mode 100644 patches.baytrail/0426-drm-i915-Explicitly-cast-pipe-intel_dpll_id.patch create mode 100644 patches.baytrail/0427-drm-i915-less-magic-for-stolen-preallocated-objects-.patch create mode 100644 patches.baytrail/0428-drm-i915-assert_spin_locked-for-pipestat-interrupt-e.patch create mode 100644 patches.baytrail/0429-drm-pre-allocate-node-for-create_block.patch create mode 100644 patches.baytrail/0430-drm-Change-create-block-to-reserve-node.patch create mode 100644 patches.baytrail/0431-drm-i915-Getter-setter-for-object-attributes.patch create mode 100644 patches.baytrail/0432-drm-i915-Kill-obj-gtt_offset.patch create mode 100644 patches.baytrail/0433-drm-i915-Embed-drm_mm_node-in-i915-gem-obj.patch create mode 100644 patches.baytrail/0434-drm-i915-fix-dvo-DPLL-regression.patch create mode 100644 patches.baytrail/0435-drm-i915-dvo-needs-a-P2-divisor-of-4.patch create mode 100644 patches.baytrail/0436-drm-i915-convert-debugfs-creation-destruction-to-tab.patch create mode 100644 patches.baytrail/0437-drm-i915-Verify-that-our-stolen-memory-doesn-t-confl.patch create mode 100644 patches.baytrail/0438-drm-i915-clean-up-media-reset-on-gm45.patch create mode 100644 patches.baytrail/0439-drm-i915-WARN-if-the-bios-reserved-range-is-bigger-t.patch create mode 100644 patches.baytrail/0440-drm-i915-Fix-VLV-DP-RBR-HDMI-DAC-PLL-LPF-coefficient.patch create mode 100644 patches.baytrail/0441-drm-i915-don-t-frob-mm.suspended-when-not-using-ums.patch create mode 100644 patches.baytrail/0442-drm-i915-remove-unused-members-from-drm_i915_private.patch create mode 100644 patches.baytrail/0443-drm-i915-extract-ibx_display_interrupt_update.patch create mode 100644 patches.baytrail/0444-drm-i915-improve-SERR_INT-clearing-for-fifo-underrun.patch create mode 100644 patches.baytrail/0445-drm-i915-improve-GEN7_ERR_INT-clearing-for-fifo-unde.patch create mode 100644 patches.baytrail/0446-drm-i915-kill-lpt-pch-transcoder-crtc-mapping-code-f.patch create mode 100644 patches.baytrail/0447-drm-i915-irq-handlers-don-t-need-interrupt-safe-spin.patch create mode 100644 patches.baytrail/0448-drm-i915-streamline-hsw_pm_irq_handler.patch create mode 100644 patches.baytrail/0449-drm-i915-queue-work-outside-spinlock-in-hsw_pm_irq_h.patch create mode 100644 patches.baytrail/0450-drm-i915-kill-dev_priv-rps.lock.patch create mode 100644 patches.baytrail/0451-drm-i915-unify-ring-irq-refcounts-again.patch create mode 100644 patches.baytrail/0452-drm-i915-don-t-enable-PM_VEBOX_CS_ERROR_INTERRUPT.patch create mode 100644 patches.baytrail/0453-drm-i915-Use-for_each_pipe-when-possible.patch create mode 100644 patches.baytrail/0454-drm-i915-Don-t-attempt-to-read-an-unitialized-stack-.patch create mode 100644 patches.baytrail/0455-drm-i915-move-error-state-to-own-compilation-unit.patch create mode 100644 patches.baytrail/0456-drm-i915-clean-up-vlv-pre_pll_enable-and-pll-enable-.patch create mode 100644 patches.baytrail/0457-drm-i915-Fix-up-cpt-pixel-multiplier-enable-sequence.patch create mode 100644 patches.baytrail/0458-drm-i915-clear-DPLL-reg-when-disabling-i9xx-dplls.patch create mode 100644 patches.baytrail/0459-drm-i915-hsw-Set-correct-Haswell-PTE-encodings.patch create mode 100644 patches.baytrail/0460-drm-i915-Define-some-of-the-eLLC-magic.patch create mode 100644 patches.baytrail/0461-drm-i915-store-eLLC-size.patch create mode 100644 patches.baytrail/0462-drm-i915-Use-eLLC-LLC-by-default-when-available.patch create mode 100644 patches.baytrail/0463-drm-i915-debugfs-entries-for-e-LLC.patch create mode 100644 patches.baytrail/0464-drm-i915-unify-PM-interrupt-preinstall-sequence.patch create mode 100644 patches.baytrail/0465-drm-i915-unify-GT-PM-irq-postinstall-code.patch create mode 100644 patches.baytrail/0466-drm-i915-extract-rps-interrupt-enable-disable-helper.patch create mode 100644 patches.baytrail/0467-drm-i915-simplify-rps-interrupt-enabling-disabling-s.patch create mode 100644 patches.baytrail/0468-drm-i915-We-implement-WaFbcWaitForVBlankBeforeEnable.patch create mode 100644 patches.baytrail/0469-drm-i915-We-implement-WaFbcAsynchFlipDisableFbcQueue.patch create mode 100644 patches.baytrail/0470-drm-i915-We-implement-WaFbcDisableDpfcClockGating-on.patch create mode 100644 patches.baytrail/0471-drm-i915-We-implement-WaMPhyProgramming-on-Haswell.patch create mode 100644 patches.baytrail/0472-drm-i915-Don-t-try-to-calculate-RC6-residency-on-GEN.patch create mode 100644 patches.baytrail/0473-drm-i915-Fix-retrieval-of-hangcheck-stats.patch create mode 100644 patches.baytrail/0474-drm-i915-Replace-open-coding-of-DEFAULT_CONTEXT_ID.patch create mode 100644 patches.baytrail/0475-drm-i915-introduce-i915_queue_hangcheck.patch create mode 100644 patches.baytrail/0476-drm-i915-Move-gtt-and-ppgtt-under-address-space-umbr.patch create mode 100644 patches.baytrail/0477-drm-i915-Put-the-mm-in-the-parent-address-space.patch create mode 100644 patches.baytrail/0478-drm-i915-Create-a-global-list-of-vms.patch create mode 100644 patches.baytrail/0479-drm-i915-Move-active-inactive-lists-to-new-mm.patch create mode 100644 patches.baytrail/0480-drm-i915-Free-stolen-node-on-failed-preallocation.patch create mode 100644 patches.baytrail/0481-drm-i915-Create-VMAs.patch create mode 100644 patches.baytrail/0482-drm-Added-SDP-and-VSC-structures-for-handling-PSR-fo.patch create mode 100644 patches.baytrail/0483-drm-i915-Read-the-EDP-DPCD-and-PSR-Capability.patch create mode 100644 patches.baytrail/0484-drm-i915-split-aux_clock_divider-logic-in-a-separate.patch create mode 100644 patches.baytrail/0485-drm-i915-Enable-Disable-PSR.patch create mode 100644 patches.baytrail/0486-drm-i915-Added-debugfs-support-for-PSR-Status.patch create mode 100644 patches.baytrail/0487-drm-i915-Match-all-PSR-mode-entry-conditions-before-.patch create mode 100644 patches.baytrail/0488-drm-intel-add-enable_psr-module-option-and-disable-p.patch create mode 100644 patches.baytrail/0489-drm-i915-add-update-function-to-disable-enable-back-.patch create mode 100644 patches.baytrail/0490-drm-i915-Hook-PSR-functionality.patch create mode 100644 patches.baytrail/0491-drm-i915-restore-debug-message-lost-in-merge-resolut.patch create mode 100644 patches.baytrail/0492-drm-i915-remove-SDV-support-from-lpt_pch_init_refclk.patch create mode 100644 patches.baytrail/0493-drm-i915-extract-FDI-mPHY-functions-from-lpt_init_pc.patch create mode 100644 patches.baytrail/0494-drm-i915-extract-lpt_enable_clkout_dp-from-lpt_init_.patch create mode 100644 patches.baytrail/0495-drm-i915-checking-for-NULL-instead-of-IS_ERR.patch create mode 100644 patches.baytrail/0496-drm-i915-use-after-free-on-error-path.patch create mode 100644 patches.baytrail/0497-drm-i915-add-prefault_disable-module-option.patch create mode 100644 patches.baytrail/0498-drm-i915-kill-ivybridge_irq_preinstall.patch create mode 100644 patches.baytrail/0499-drm-i915-extract-ilk_display_irq_handler.patch create mode 100644 patches.baytrail/0500-drm-i915-extract-ivb_display_irq_handler.patch create mode 100644 patches.baytrail/0501-drm-i915-don-t-read-or-write-GEN6_PMIIR-on-Gen-5.patch create mode 100644 patches.baytrail/0502-drm-i915-reorganize-ironlake_irq_handler.patch create mode 100644 patches.baytrail/0503-drm-i915-POSTING_READ-DEIER-on-ivybridge_irq_handler.patch create mode 100644 patches.baytrail/0504-drm-i915-add-ILK-SNB-support-to-ivybridge_irq_handle.patch create mode 100644 patches.baytrail/0505-drm-i915-kill-Ivybridge-vblank-irq-vfuncs.patch create mode 100644 patches.baytrail/0506-drm-i915-kill-ivybridge_irq_postinstall.patch create mode 100644 patches.baytrail/0507-drm-i915-Make-i915-events-part-of-uapi.patch create mode 100644 patches.baytrail/0508-drm-i915-invert-ilk-snb-_gt_irq_handler-check.patch create mode 100644 patches.baytrail/0509-drm-gem-simplify-object-initialization.patch create mode 100644 patches.baytrail/0510-drm-i915-Add-some-debug-breadcrumbs-to-connector-det.patch create mode 100644 patches.baytrail/0511-drm-i915-fix-up-error-cleanup-in-i915_gem_object_bin.patch create mode 100644 patches.baytrail/0512-drm-i915-extend-lpt_enable_clkout_dp.patch create mode 100644 patches.baytrail/0513-drm-i915-disable-CLKOUT_DP-when-it-s-not-needed.patch create mode 100644 patches.baytrail/0514-drm-i915-add-functions-to-disable-and-restore-LCPLL.patch create mode 100644 patches.baytrail/0515-drm-i915-disable-stolen-mem-for-OVERLAY_NEEDS_PHYSIC.patch create mode 100644 patches.baytrail/0516-drm-i915-Use-Graphics-Base-of-Stolen-Memory-on-all-g.patch create mode 100644 patches.baytrail/0517-drm-i915-fix-reference-counting-in-i915_gem_create.patch create mode 100644 patches.baytrail/0518-drm-gem-Split-drm_gem_mmap-into-object-search-and-ob.patch create mode 100644 patches.baytrail/0519-drm-add-unified-vma-offset-manager.patch create mode 100644 patches.baytrail/0520-drm-gem-convert-to-new-unified-vma-manager.patch create mode 100644 patches.baytrail/0521-drm-gem-fix-mmap-vma-size-calculations.patch create mode 100644 patches.baytrail/0522-drm-ttm-convert-to-unified-vma-offset-manager.patch create mode 100644 patches.baytrail/0523-drm-vma-provide-drm_vma_node_unmap-helper.patch create mode 100644 patches.baytrail/0524-Re-create-dirty-merge-cb54b53.patch create mode 100644 patches.baytrail/0525-drm-i915-Colocate-all-GT-access-routines-in-the-same.patch create mode 100644 patches.baytrail/0526-drm-i915-Use-a-private-interface-for-register-access.patch create mode 100644 patches.baytrail/0527-drm-i915-Use-the-common-register-access-functions-fo.patch create mode 100644 patches.baytrail/0528-drm-i915-Squash-gen-lookup-through-multiple-indirect.patch create mode 100644 patches.baytrail/0529-drm-i915-Convert-the-register-access-tracepoint-to-b.patch create mode 100644 patches.baytrail/0530-drm-i915-fix-the-racy-object-accounting.patch create mode 100644 patches.baytrail/0531-drm-i915-dvo_ch7xxx-fix-vsync-polarity-setting.patch create mode 100644 patches.baytrail/0532-drm-i915-Add-messages-useful-for-HPD-storm-detection.patch create mode 100644 patches.baytrail/0533-drm-i915-Retry-DP-aux_ch-communications-with-a-diffe.patch create mode 100644 patches.baytrail/0534-drm-i915-Replace-open-coded-offset_in_page.patch create mode 100644 patches.baytrail/0535-drm-i915-fix-pnv-display-core-clock-readout-out.patch create mode 100644 patches.baytrail/0536-drm-i915-Do-not-dereference-NULL-crtc-or-fb-until-af.patch create mode 100644 patches.baytrail/0537-drm-i915-dvo-use-intel_encoder-to-the-upcast-macro.patch create mode 100644 patches.baytrail/0538-drm-i915-dvo-switch-mode_fixup-to-compute_config.patch create mode 100644 patches.baytrail/0539-drm-i915-rip-out-legacy-encoder-mode_fixup-logic.patch create mode 100644 patches.baytrail/0540-drm-i915-dvo-use-native-encoder-mode_set-callback.patch create mode 100644 patches.baytrail/0541-drm-i915-sdvo-use-intel_encoder-for-upcast-helper.patch create mode 100644 patches.baytrail/0542-drm-i915-tv-Use-native-encoder-mode_set-callback.patch create mode 100644 patches.baytrail/0543-drm-i915-crt-use-native-encoder-mode_set-callback.patch create mode 100644 patches.baytrail/0544-drm-i915-hdmi-use-native-encoder-mode_set-callback.patch create mode 100644 patches.baytrail/0545-drm-i915-dp-use-native-encoder-mode_set-callback.patch create mode 100644 patches.baytrail/0546-drm-i915-lvds-use-the-native-encoder-mode_set-callba.patch create mode 100644 patches.baytrail/0547-drm-i915-ddi-use-the-native-encoder-mode_set-callbac.patch create mode 100644 patches.baytrail/0548-drm-i915-rip-out-legacy-encoder-mode_set-callback.patch create mode 100644 patches.baytrail/0549-drm-i915-clean-up-crtc-timings-computation.patch create mode 100644 patches.baytrail/0550-drm-i915-Squelch-repeated-reasoning-for-why-FBC-cann.patch create mode 100644 patches.baytrail/0551-drm-i915-Use-the-same-pte_encoding-for-ppgtt-as-for-.patch create mode 100644 patches.baytrail/0552-drm-i915-Remove-useless-define.patch create mode 100644 patches.baytrail/0553-drm-i915-Tidy-the-macro-casting-by-using-an-inline-f.patch create mode 100644 patches.baytrail/0554-drm-i915-Add-scaled-paramater-to-update_sprite_water.patch create mode 100644 patches.baytrail/0555-drm-i915-Pass-the-actual-sprite-width-to-watermarks-.patch create mode 100644 patches.baytrail/0556-drm-i915-Calculate-the-sprite-WM-based-on-the-source.patch create mode 100644 patches.baytrail/0557-drm-i915-Rename-hsw_wm_get_pixel_rate-to-ilk_pipe_pi.patch create mode 100644 patches.baytrail/0558-drm-i915-Rename-most-wm-compute-functions-to-ilk_-pr.patch create mode 100644 patches.baytrail/0559-drm-i915-Don-t-pass-mem_value-to-ilk_compute_fbc_wm.patch create mode 100644 patches.baytrail/0560-drm-i915-Change-the-watermark-latency-type-to-uint16.patch create mode 100644 patches.baytrail/0561-drm-i915-Split-out-reading-of-HSW-watermark-latency-.patch create mode 100644 patches.baytrail/0562-drm-i915-Don-t-multiply-the-watermark-latency-values.patch create mode 100644 patches.baytrail/0563-drm-i915-Add-SNB-IVB-support-to-intel_read_wm_latenc.patch create mode 100644 patches.baytrail/0564-drm-i915-enable-IPS-for-bpp-24.patch create mode 100644 patches.baytrail/0565-drm-i915-Acquire-dpio_lock-for-VLV-sideband-programm.patch create mode 100644 patches.baytrail/0566-drm-i915-rearrange-vlv-dp-enable-and-pre_enable-call.patch create mode 100644 patches.baytrail/0567-drm-i915-rearrange-vlv-hdmi-enable-and-pre_enable-ca.patch create mode 100644 patches.baytrail/0568-drm-i915-move-encoder-enable-callback-later-in-VLV-c.patch create mode 100644 patches.baytrail/0569-drm-i915-make-user-mode-sync-polarity-setting-explic.patch create mode 100644 patches.baytrail/0570-i915-fix-ACPI-_DSM-warning.patch create mode 100644 patches.baytrail/0571-drm-i915-hsw-Change-default-LLC-age-to-3.patch create mode 100644 patches.baytrail/0572-drm-i915-Create-an-init-vm.patch create mode 100644 patches.baytrail/0573-drm-i915-Rework-drop-caches-for-checkpatch.patch create mode 100644 patches.baytrail/0574-drm-i915-Make-proper-functions-for-VMs.patch create mode 100644 patches.baytrail/0575-drm-i915-Use-bound-list-for-inactive-shrink.patch create mode 100644 patches.baytrail/0576-drm-i915-Add-VM-to-pin.patch create mode 100644 patches.baytrail/0577-drm-i915-Use-ggtt_vm-to-save-some-typing.patch create mode 100644 patches.baytrail/0578-drm-i915-Update-describe_obj.patch create mode 100644 patches.baytrail/0579-drm-i915-thread-address-space-through-execbuf.patch create mode 100644 patches.baytrail/0580-drm-i915-make-caching-operate-on-all-address-spaces.patch create mode 100644 patches.baytrail/0581-drm-i915-BUG_ON-put_pages-later.patch create mode 100644 patches.baytrail/0582-drm-i915-make-reset-hangcheck-code-VM-aware.patch create mode 100644 patches.baytrail/0583-drm-i915-Add-ILK-support-to-intel_read_wm_latency.patch create mode 100644 patches.baytrail/0584-drm-i915-Store-the-watermark-latency-values-in-dev_p.patch create mode 100644 patches.baytrail/0585-drm-i915-Use-the-stored-cursor-and-plane-latencies-p.patch create mode 100644 patches.baytrail/0586-drm-i915-Print-the-watermark-latencies-during-init.patch create mode 100644 patches.baytrail/0587-drm-i915-Disable-specific-watermark-levels-when-late.patch create mode 100644 patches.baytrail/0588-drm-i915-Use-the-watermark-latency-values-from-dev_p.patch create mode 100644 patches.baytrail/0589-drm-i915-Add-comments-about-units-of-latency-values.patch create mode 100644 patches.baytrail/0590-drm-i915-eliminate-dead-domain-clearing-on-reset.patch create mode 100644 patches.baytrail/0591-drm-i915-silence-useless-messages-about-DDI-buffer-t.patch create mode 100644 patches.baytrail/0592-drm-i915-remove-use_fdi_mode-argument-from-intel_pre.patch create mode 100644 patches.baytrail/0593-drm-i915-Rename-I915_CACHE_MLC_LLC-to-L3_LLC-for-Ivy.patch create mode 100644 patches.baytrail/0594-drm-i915-Export-intel_framebuffer_fini.patch create mode 100644 patches.baytrail/0595-drm-i915-Improve-VMA-comments.patch create mode 100644 patches.baytrail/0596-drm-gem-create-drm_gem_dumb_destroy.patch create mode 100644 patches.baytrail/0597-drm-mm-add-best_match-flag-to-drm_mm_insert_node.patch create mode 100644 patches.baytrail/0598-drm-const-ify-ioctls-table-v2.patch create mode 100644 patches.baytrail/0599-drm-i915-pre-alloc-instead-of-drm_mm-search-get_bloc.patch create mode 100644 patches.baytrail/0600-Re-create-dirty-merge-32c913e.patch create mode 100644 patches.baytrail/0601-drm-i915-Rework-__i915_gem_shrink.patch create mode 100644 patches.baytrail/0602-drm-i915-plumb-VM-into-bind-unbind-code.patch create mode 100644 patches.baytrail/0603-drm-i915-Use-new-bind-unbind-in-eviction-code.patch create mode 100644 patches.baytrail/0604-drm-i915-turn-bound_ggtt-checks-to-bound_any.patch create mode 100644 patches.baytrail/0605-video-hdmi-Introduce-a-generic-hdmi_infoframe-union.patch create mode 100644 patches.baytrail/0606-video-hdmi-Add-a-macro-to-return-the-size-of-a-full-.patch create mode 100644 patches.baytrail/0607-video-hdmi-Don-t-let-the-user-of-this-API-create-inv.patch create mode 100644 patches.baytrail/0608-video-hdmi-Derive-the-bar-data-valid-bit-from-the-ba.patch create mode 100644 patches.baytrail/0609-video-hdmi-Introduce-helpers-for-the-HDMI-vendor-spe.patch create mode 100644 patches.baytrail/0610-drm-edid-Move-HDMI_IDENTIFIER-to-hdmi.h.patch create mode 100644 patches.baytrail/0611-video-hdmi-Hook-the-HDMI-vendor-infoframe-with-the-g.patch create mode 100644 patches.baytrail/0612-video-hdmi-Use-hdmi_vendor_infoframe-for-the-HDMI-sp.patch create mode 100644 patches.baytrail/0613-drm-edid-Fix-add_cea_modes-style-issues.patch create mode 100644 patches.baytrail/0614-drm-edid-Parse-the-HDMI-CEA-block-and-look-for-4k-mo.patch create mode 100644 patches.baytrail/0615-video-hdmi-Rename-HDMI_IDENTIFIER-to-HDMI_IEEE_OUI.patch create mode 100644 patches.baytrail/0616-drm-i915-hdmi-Change-the-write_infoframe-vfunc-to-ta.patch create mode 100644 patches.baytrail/0617-drm-i915-hdmi-Port-the-infoframe-code-to-the-common-.patch create mode 100644 patches.baytrail/0618-drm-i915-sdvo-Port-the-infoframe-code-to-the-shared-.patch create mode 100644 patches.baytrail/0619-drm-i915-Remove-the-now-obsolete-infoframe-definitio.patch create mode 100644 patches.baytrail/0620-drm-Handle-the-DBLCLK-flag-in-the-common-infoframe-h.patch create mode 100644 patches.baytrail/0621-drm-i915-hmdi-Rename-set_infoframe-to-write_infofram.patch create mode 100644 patches.baytrail/0622-drm-i915-Use-enabled-instead-of-enable-consistently-.patch create mode 100644 patches.baytrail/0623-drm-i915-Split-watermark-level-computation-from-the-.patch create mode 100644 patches.baytrail/0624-drm-i915-Kill-fbc_enable-from-hsw_lp_wm_results.patch create mode 100644 patches.baytrail/0625-drm-i915-Rename-hsw_data_buf_partitioning-to-intel_d.patch create mode 100644 patches.baytrail/0626-drm-i915-Silence-a-sparse-warning.patch create mode 100644 patches.baytrail/0627-drm-i915-Fix-up-map-and-fenceable-for-VMA.patch create mode 100644 patches.baytrail/0628-drm-i915-mm_list-is-per-VMA.patch create mode 100644 patches.baytrail/0629-drm-i915-Update-error-capture-for-VMs.patch create mode 100644 patches.baytrail/0630-drm-i915-Add-vma-to-list-at-creation.patch create mode 100644 patches.baytrail/0631-drm-i915-Pull-watermark-level-validity-check-out.patch create mode 100644 patches.baytrail/0632-drm-i915-Rename-hsw_lp_wm_result-to-intel_wm_level.patch create mode 100644 patches.baytrail/0633-drm-i915-Calculate-max-watermark-levels-for-ILK.patch create mode 100644 patches.baytrail/0634-drm-i915-Pull-some-watermarks-state-into-a-separate-.patch create mode 100644 patches.baytrail/0635-drm-i915-Split-plane-watermark-parameters-into-a-sep.patch create mode 100644 patches.baytrail/0636-drm-i915-Pass-crtc-to-our-update-disable_plane-hooks.patch create mode 100644 patches.baytrail/0637-drm-i915-Don-t-try-to-disable-plane-if-it-s-already-.patch create mode 100644 patches.baytrail/0638-drm-i915-Pass-plane-and-crtc-to-intel_update_sprite_.patch create mode 100644 patches.baytrail/0639-drm-i915-Always-call-intel_update_sprite_watermarks-.patch create mode 100644 patches.baytrail/0640-drm-i915-List-objects-allocated-from-stolen-memory-i.patch create mode 100644 patches.baytrail/0641-drm-i915-Remove-stale-prototypes.patch create mode 100644 patches.baytrail/0642-drm-i915-Remove-i915_gem_object_check_coherency.patch create mode 100644 patches.baytrail/0643-drm-i915-Fix-endif-comment.patch create mode 100644 patches.baytrail/0644-drm-i915-Make-i915_hangcheck_elapsed-static.patch create mode 100644 patches.baytrail/0645-drm-i915-Make-intel_encoder_dpms-static.patch create mode 100644 patches.baytrail/0646-drm-i915-Remove-intel_modeset_disable.patch create mode 100644 patches.baytrail/0647-drm-i915-Make-intel_set_mode-static.patch create mode 100644 patches.baytrail/0648-drm-i915-unbreak-i915_gem_object_ggtt_unbind.patch create mode 100644 patches.baytrail/0649-drm-i915-fix-a-limit-check-in-hsw_compute_wm_results.patch create mode 100644 patches.baytrail/0650-drm-i915-expose-HDMI-connectors-on-port-C-on-BYT.patch create mode 100644 patches.baytrail/0651-drm-i915-Fix-FB-WM-for-HSW.patch create mode 100644 patches.baytrail/0652-drm-i915-Update-rules-for-reading-cache-lines-throug.patch create mode 100644 patches.baytrail/0653-drm-i915-Track-when-an-object-is-pinned-for-use-by-t.patch create mode 100644 patches.baytrail/0654-drm-i915-Update-rules-for-writing-through-the-LLC-wi.patch create mode 100644 patches.baytrail/0655-drm-i915-Allow-the-GPU-to-cache-stolen-memory.patch create mode 100644 patches.baytrail/0656-drm-kill-dev-context_wait.patch create mode 100644 patches.baytrail/0657-drm-remove-dev-last_switch.patch create mode 100644 patches.baytrail/0658-drm-kill-dev-interrupt_flag-and-dev-dma_flag.patch create mode 100644 patches.baytrail/0659-drm-kill-dev-ctx_start-and-dev-lck_start.patch create mode 100644 patches.baytrail/0660-drm-kill-dev-buf_readers-and-dev-buf_writers.patch create mode 100644 patches.baytrail/0661-drm-rip-out-dev-last_checked.patch create mode 100644 patches.baytrail/0662-drm-remove-FASYNC-support.patch create mode 100644 patches.baytrail/0663-drm-use-common-drm_gem_dmabuf_release-in-i915-exynos.patch create mode 100644 patches.baytrail/0664-drm-Update-drm_addmap-and-drm_mmap-to-use-PAT-WC-ins.patch create mode 100644 patches.baytrail/0665-drm-agpgart-Use-pgprot_writecombine-for-AGP-maps-and.patch create mode 100644 patches.baytrail/0666-drm-agp-move-AGP-cleanup-paths-to-drm_agpsupport.c.patch create mode 100644 patches.baytrail/0667-drm-ast-cirrus-mgag200-nouveau-savage-vmwgfx-Remove-.patch create mode 100644 patches.baytrail/0668-drm-Remove-mtrr_add-and-mtrr_del-fallback-hack-for-n.patch create mode 100644 patches.baytrail/0669-drm-provide-agp-dummies-for-CONFIG_AGP-n.patch create mode 100644 patches.baytrail/0670-drm-rip-out-drm_core_has_MTRR-checks.patch create mode 100644 patches.baytrail/0671-drm-i915-Only-do-a-chipset-flush-after-a-clflush.patch create mode 100644 patches.baytrail/0672-drm-i915-WARN_ON-failed-map_and_fenceable.patch create mode 100644 patches.baytrail/0673-i915-Fix-SDVO-potentially-turning-off-randomly.patch create mode 100644 patches.baytrail/0674-drm-i915-remove-unused-leftover-variable-irq_receive.patch create mode 100644 patches.baytrail/0675-drm-i915-give-more-distinctive-names-to-ring-hangche.patch create mode 100644 patches.baytrail/0676-drm-i915-drop-unnecessary-local-variable-to-suppress.patch create mode 100644 patches.baytrail/0677-drm-i915-reserve-I915_CACHING_DISPLAY-and-document-c.patch create mode 100644 patches.baytrail/0678-drm-i915-Use-Write-Through-cacheing-for-the-display-.patch create mode 100644 patches.baytrail/0679-drm-i915-Allow-the-user-to-set-bo-into-the-DISPLAY-c.patch create mode 100644 patches.baytrail/0680-drm-i915-remove-set-but-unused-variables.patch create mode 100644 patches.baytrail/0681-drm-i915-Print-the-changes-required-for-modeset.patch create mode 100644 patches.baytrail/0682-drm-i915-print-a-message-when-we-detect-an-early-Has.patch create mode 100644 patches.baytrail/0683-drm-i915-tune-the-RC6-threshold-for-stability.patch create mode 100644 patches.baytrail/0684-drm-i915-Initialize-seqno-for-VECS-too.patch create mode 100644 patches.baytrail/0685-drm-i915-Get-VECS-semaphore-info-on-error.patch create mode 100644 patches.baytrail/0686-drm-i915-clarify-error-paths-in-create_stolen_for_pr.patch create mode 100644 patches.baytrail/0687-drm-i915-Remove-node-only-when-allocated.patch create mode 100644 patches.baytrail/0688-drm-i915-cleanup-map-fence-in-bind.patch create mode 100644 patches.baytrail/0689-drm-i915-use-vma-node-directly-and-rewrap-map-fence-.patch create mode 100644 patches.baytrail/0690-drm-i915-Drop-the-overzealous-warning-from-i915_gem_.patch create mode 100644 patches.baytrail/0691-drm-i915-check-the-power-well-when-redisabling-VGA.patch create mode 100644 patches.baytrail/0692-drm-i915-clarify-Haswell-power-well-bit-names.patch create mode 100644 patches.baytrail/0693-drm-i915-Only-unmask-required-PM-interrupts.patch create mode 100644 patches.baytrail/0694-drm-i915-explicit-store-base-gem-object-in-dma_buf-p.patch create mode 100644 patches.baytrail/0695-drm-i915-enable-the-power-well-before-module-unload.patch create mode 100644 patches.baytrail/0696-i915-Add-a-Kconfig-option-to-turn-on-i915.preliminar.patch create mode 100644 patches.baytrail/0697-drm-i915-s-obj-exec_list-obj-obj_exec_link-in-debugf.patch create mode 100644 patches.baytrail/0698-drm-i915-Switch-eviction-code-to-use-vmas.patch create mode 100644 patches.baytrail/0699-drm-i915-prepare-bind_to_vm-for-preallocated-vma.patch create mode 100644 patches.baytrail/0700-drm-i915-vma-Correct-use-after-free-in-eviction.patch create mode 100644 patches.baytrail/0701-drm-i915-make-IVB-FDI-training-match-spec-v3.patch create mode 100644 patches.baytrail/0702-drm-i915-Remove-DSPARB_HWCONTROL.patch create mode 100644 patches.baytrail/0703-drm-i915-Remove-HAS_PIPE_CONTROL.patch create mode 100644 patches.baytrail/0704-drm-Remove-IS_IRONLAKE_D.patch create mode 100644 patches.baytrail/0705-drm-i915-Remove-I915_READ_-NOPID-SYNC_0-SYNC_1.patch create mode 100644 patches.baytrail/0706-drm-i915-Expose-energy-counter-on-SNB-through-debugf.patch create mode 100644 patches.baytrail/0707-drm-i915-add-the-FCLK-case-to-intel_ddi_get_cdclk_fr.patch create mode 100644 patches.baytrail/0708-drm-i915-wrap-GTIMR-changes.patch create mode 100644 patches.baytrail/0709-drm-i915-wrap-GEN6_PMIMR-changes.patch create mode 100644 patches.baytrail/0710-drm-i915-don-t-update-GEN6_PMIMR-when-it-s-not-neede.patch create mode 100644 patches.baytrail/0711-drm-i915-add-dev_priv-pm_irq_mask.patch create mode 100644 patches.baytrail/0712-drm-i915-don-t-disable-reenable-IVB-error-interrupts.patch create mode 100644 patches.baytrail/0713-drm-i915-don-t-queue-PM-events-we-won-t-process.patch create mode 100644 patches.baytrail/0714-drm-i915-fix-how-we-mask-PMIMR-when-adding-work-to-t.patch create mode 100644 patches.baytrail/0715-drm-i915-merge-HSW-and-SNB-PM-irq-handlers.patch create mode 100644 patches.baytrail/0716-drm-i915-Cleaning-up-the-relocate-entry-function.patch create mode 100644 patches.baytrail/0717-drm-i915-drop-WaMbcDriverBootEnable-workaround.patch create mode 100644 patches.baytrail/0718-drm-i915-grab-force_wake-when-restoring-LCPLL.patch create mode 100644 patches.baytrail/0719-drm-i915-fix-SDEIMR-assertion-when-disabling-LCPLL.patch create mode 100644 patches.baytrail/0720-drm-i915-allow-package-C8-states-on-Haswell-disabled.patch create mode 100644 patches.baytrail/0721-drm-i915-add-i915_pc8_status-debugfs-file.patch create mode 100644 patches.baytrail/0722-drm-i915-add-i915.pc8_timeout-function.patch create mode 100644 patches.baytrail/0723-drm-i915-enable-Package-C8-by-default.patch create mode 100644 patches.baytrail/0724-drm-i915-Use-POSTING_READ-in-lcpll-code.patch create mode 100644 patches.baytrail/0725-drm-i915-Fix-context-size-calculation-on-SNB-IVB-VLV.patch create mode 100644 patches.baytrail/0726-drm-i915-Print-seqnos-as-unsigned-in-debugfs.patch create mode 100644 patches.baytrail/0727-gpu-vga_switcheroo-add-driver-control-power-feature..patch create mode 100644 patches.baytrail/0728-drm-edid-Add-both-60Hz-and-59.94Hz-CEA-modes-to-conn.patch create mode 100644 patches.baytrail/0729-drm-Add-support-for-alternate-clocks-of-4k-modes.patch create mode 100644 patches.baytrail/0730-drm-Make-drm_match_cea_mode-return-the-underlying-2D.patch create mode 100644 patches.baytrail/0731-drm-Add-a-helper-to-forge-HDMI-vendor-infoframes.patch create mode 100644 patches.baytrail/0732-drm-Add-HDMI-stereo-3D-flags-to-struct-drm_mode_mode.patch create mode 100644 patches.baytrail/0733-drm-edid-Expose-mandatory-stereo-modes-for-HDMI-sink.patch create mode 100644 patches.baytrail/0734-drm-Extract-add_hdmi_mode-out-of-do_hdmi_vsdb_modes.patch create mode 100644 patches.baytrail/0735-drm-Code-stereo-layouts-as-an-enum-rather-than-a-bit.patch create mode 100644 patches.baytrail/0736-drm-Set-the-relevant-infoframe-field-when-scanning-o.patch create mode 100644 patches.baytrail/0737-drm-i915-hdmi-Write-HDMI-vendor-specific-infoframes.patch create mode 100644 patches.baytrail/0738-drm-Pass-page-flip-ioctl-flags-to-driver.patch create mode 100644 patches.baytrail/0739-drm-implement-experimental-render-nodes.patch create mode 100644 patches.baytrail/0740-drm-i915-Support-render-nodes.patch create mode 100644 patches.baytrail/0741-drm-i915-Don-t-mask-EI-UP-interrupt-on-IVB-SNB.patch create mode 100644 patches.baytrail/0742-drm-i915-sanitize-forcewake-registers-on-reset.patch create mode 100644 patches.baytrail/0743-drm-i915-Adjust-available-RPS-information-through-sy.patch create mode 100644 patches.baytrail/0744-drm-i915-Apply-the-force-detect-VGA-w-a-to-Valleyvie.patch create mode 100644 patches.baytrail/0745-drm-i915-Report-requested-frequency-alongside-curren.patch create mode 100644 patches.baytrail/0746-drm-i915-tune-down-hangcheck-noise.patch create mode 100644 patches.baytrail/0747-drm-i915-fix-lvds-dp-panel-fitter-setting.patch create mode 100644 patches.baytrail/0748-drm-i915-Embed-the-ring-private-within-the-struct-in.patch create mode 100644 patches.baytrail/0749-drm-i915-Use-RCS-flips-on-Ivybridge.patch create mode 100644 patches.baytrail/0750-i915_gem-Convert-kmem_cache_alloc-.GFP_ZERO-to-kmem_.patch create mode 100644 patches.baytrail/0751-drm-i915-split-PCI-IDs-out-into-i915_drm.h-v4.patch create mode 100644 patches.baytrail/0752-x86-add-early-quirk-for-reserving-Intel-graphics-sto.patch create mode 100644 patches.baytrail/0753-drm-i915-enable-trickle-feed-on-Haswell.patch create mode 100644 patches.baytrail/0754-drm-i915-Pin-pages-whilst-mapping-the-dma-buf.patch create mode 100644 patches.baytrail/0755-i915-Update-VGA-arbiter-support-for-newer-devices.patch create mode 100644 patches.baytrail/0756-drm-i915-Don-t-call-sg_free_table-if-sg_alloc_table-.patch create mode 100644 patches.baytrail/0757-drm-i915-Fix-pipe-config-warnings-when-dealing-with-.patch create mode 100644 patches.baytrail/0758-drm-i915-fix-up-the-relocate_entry-refactoring.patch create mode 100644 patches.baytrail/0759-drm-i915-fix-hpd-work-vs.-flush_work-in-the-pageflip.patch create mode 100644 patches.baytrail/0760-drm-i915-handle-sdvo-input-pixel-multiplier-correctl.patch create mode 100644 patches.baytrail/0761-drm-i915-fix-i9xx_crtc_clock_get-for-multiplied-pixe.patch create mode 100644 patches.baytrail/0762-drm-i915-Convert-execbuf-code-to-use-vmas.patch create mode 100644 patches.baytrail/0763-drm-i915-inline-vma_create-into-lookup_or_create_vma.patch create mode 100644 patches.baytrail/0764-drm-i915-Don-t-destroy-the-vma-placeholder-during-ex.patch create mode 100644 patches.baytrail/0765-drm-i915-More-vma-fixups-around-unbind-destroy.patch create mode 100644 patches.baytrail/0766-drm-i915-Always-prefer-CPU-relocations-with-LLC.patch create mode 100644 patches.baytrail/0767-drm-i915-add-more-VLV-IOSF-sideband-ports-accessors.patch create mode 100644 patches.baytrail/0768-drm-i915-add-VLV-pipeconf-bit-definition-for-DSI-PLL.patch create mode 100644 patches.baytrail/0769-drm-Constify-the-pretty-print-functions.patch create mode 100644 patches.baytrail/0770-drm-use-ida-to-allocate-connector-ids.patch create mode 100644 patches.baytrail/0771-drm-add-MIPI-DSI-encoder-and-connector-types.patch create mode 100644 patches.baytrail/0772-drm-i915-add-MIPI-DSI-register-definitions.patch create mode 100644 patches.baytrail/0773-drm-i915-add-MIPI-DSI-output-type-and-subtypes.patch create mode 100644 patches.baytrail/0774-drm-i915-add-structs-for-MIPI-DSI-output.patch create mode 100644 patches.baytrail/0775-drm-i915-add-MIPI-DSI-command-sending-routines.patch create mode 100644 patches.baytrail/0776-drm-i915-add-basic-MIPI-DSI-output-support.patch create mode 100644 patches.baytrail/0777-drm-i915-add-VLV-DSI-PLL-Calculations.patch create mode 100644 patches.baytrail/0778-drm-i915-fix-PLL-assertions-for-DSI-PLL.patch create mode 100644 patches.baytrail/0779-drm-i915-don-t-enable-DPLL-for-DSI.patch create mode 100644 patches.baytrail/0780-drm-i915-Band-Gap-WA.patch create mode 100644 patches.baytrail/0781-drm-i915-Parse-the-MIPI-related-VBT-Block-and-store-.patch create mode 100644 patches.baytrail/0782-drm-i915-initialize-DSI-output-on-VLV.patch create mode 100644 patches.baytrail/0783-drm-i915-dsi-s-size_t-int.patch create mode 100644 patches.baytrail/0784-drm-i915-Report-enabled-slices-on-Haswell-GT3.patch create mode 100644 patches.baytrail/0785-drm-i915-Restore-the-preliminary-HW-check.patch create mode 100644 patches.baytrail/0786-drm-i915-Fix-list-corruption-in-vma_unbind.patch create mode 100644 patches.baytrail/0787-drm-i915-Do-not-add-an-interrupt-for-a-context-switc.patch create mode 100644 patches.baytrail/0788-drm-i915-Rearrange-the-comments-in-i915_add_request.patch create mode 100644 patches.baytrail/0789-drm-i915-It-s-its.patch create mode 100644 patches.baytrail/0790-drm-i915-add-plumbing-for-SWSCI.patch create mode 100644 patches.baytrail/0791-drm-i915-expose-intel_ddi_get_encoder_port.patch create mode 100644 patches.baytrail/0792-drm-i915-add-opregion-function-to-notify-bios-of-enc.patch create mode 100644 patches.baytrail/0793-drm-i915-add-opregion-function-to-notify-bios-of-ada.patch create mode 100644 patches.baytrail/0794-drm-i915-do-display-power-state-notification-on-crtc.patch create mode 100644 patches.baytrail/0795-drm-i915-Modify-DP-set-clock-to-accomodate-more-eDP-.patch create mode 100644 patches.baytrail/0796-drm-i915-Move-Valleyview-DP-DPLL-divisor-calc-to-int.patch create mode 100644 patches.baytrail/0797-drm-i915-Kill-IRONLAKE_FDI_FREQ-check.patch create mode 100644 patches.baytrail/0798-drm-i915-Rename-ring-outstanding_lazy_request.patch create mode 100644 patches.baytrail/0799-drm-i915-Preallocate-the-lazy-request.patch create mode 100644 patches.baytrail/0800-drm-i915-Hold-an-object-reference-whilst-we-shrink-i.patch create mode 100644 patches.baytrail/0801-drm-i915-Skip-stolen-region-initialisation-if-none-i.patch create mode 100644 patches.baytrail/0802-drm-i915-Add-additional-pipe-parameter-for-vlv_dpio_.patch create mode 100644 patches.baytrail/0803-drm-i915-Remove-unused-mode_fixup-vfunc-of-struct-in.patch create mode 100644 patches.baytrail/0804-drm-i915-Confine-page-flips-to-BCS-on-Valleyview.patch create mode 100644 patches.baytrail/0805-drm-i915-try-not-to-lose-backlight-CBLV-precision.patch create mode 100644 patches.baytrail/0806-drm-i915-name-intel-dp-hooks-per-platform.patch create mode 100644 patches.baytrail/0807-drm-i915-move-backlight-enable-later-in-vlv-enable-s.patch create mode 100644 patches.baytrail/0808-drm-i915-clean-up-power-sequencing-register-port-sel.patch create mode 100644 patches.baytrail/0809-drm-i915-add-support-for-per-pipe-power-sequencing-o.patch create mode 100644 patches.baytrail/0810-drm-i915-ban-badly-behaving-contexts.patch create mode 100644 patches.baytrail/0811-drm-i915-include-hangcheck-action-and-score-in-error.patch create mode 100644 patches.baytrail/0812-drm-i915-Delay-disabling-of-VGA-memory-until-vgacon-.patch create mode 100644 patches.baytrail/0813-drm-i915-Track-pfit-enable-state-separately-from-siz.patch create mode 100644 patches.baytrail/0814-drm-i915-Use-proper-print-format-for-debug-prints.patch create mode 100644 patches.baytrail/0815-drm-i915-Pass-crtc-to-intel_update_watermarks.patch create mode 100644 patches.baytrail/0816-drm-i915-Call-intel_update_watermarks-in-specific-pl.patch create mode 100644 patches.baytrail/0817-drm-i915-Constify-some-watermark-data.patch create mode 100644 patches.baytrail/0818-drm-i915-Use-ilk_compute_wm_level-to-compute-WM_PIPE.patch create mode 100644 patches.baytrail/0819-drm-i915-Refactor-max-WM-level.patch create mode 100644 patches.baytrail/0820-drm-i915-sdvo-Fully-translate-sync-flags-in-the-dtd-.patch create mode 100644 patches.baytrail/0821-drm-i915-Write-RING_TAIL-once-per-request.patch create mode 100644 patches.baytrail/0822-drm-i915-Remove-the-double-list-iteration-from-bound.patch create mode 100644 patches.baytrail/0823-drm-i915-Fix-HSW-sync-flags-to-use-pipe-config-adjus.patch create mode 100644 patches.baytrail/0824-drm-i915-vlv-re-enable-hotplug-detect-based-probing-.patch create mode 100644 patches.baytrail/0825-drm-i915-sdvo-Robustify-the-dtd-drm_mode-conversions.patch create mode 100644 patches.baytrail/0826-drm-i915-dvo-set-crtc-timings-again-for-panel-fixed-.patch create mode 100644 patches.baytrail/0827-drm-i915-Synchronize-pread-pwrite-with-wait_renderin.patch create mode 100644 patches.baytrail/0828-drm-i915-Extract-vm-specific-part-of-eviction.patch create mode 100644 patches.baytrail/0829-drm-i915-evict-VM-instead-of-everything.patch create mode 100644 patches.baytrail/0830-drm-i915-kill-set_need_resched.patch create mode 100644 patches.baytrail/0831-drm-i915-move-more-code-to-__i915_drm_thaw.patch create mode 100644 patches.baytrail/0832-drm-i915-don-t-save-restore-LBB-on-Gen5.patch create mode 100644 patches.baytrail/0833-drm-i915-Don-t-factor-in-pixel-multplier-when-derivi.patch create mode 100644 patches.baytrail/0834-drm-i915-Make-adjusted_mode.clock-non-pixel-multipli.patch create mode 100644 patches.baytrail/0835-drm-i915-Add-support-for-pipe_bpp-readout.patch create mode 100644 patches.baytrail/0836-drm-i915-Add-state-readout-and-checking-for-has_dp_e.patch create mode 100644 patches.baytrail/0837-drm-i915-Make-intel_fuzzy_clock_check-take-in-arbitr.patch create mode 100644 patches.baytrail/0838-drm-i915-Remove-extra-ring.patch create mode 100644 patches.baytrail/0839-drm-i915-Round-l3-parity-reads-down.patch create mode 100644 patches.baytrail/0840-drm-i915-Fix-l3-parity-user-buffer-offset.patch create mode 100644 patches.baytrail/0841-drm-i915-add-asserts-for-cursor-disabled.patch create mode 100644 patches.baytrail/0842-drm-i915-clear-opregon-lid_state-after-we-unmap-it.patch create mode 100644 patches.baytrail/0843-drm-i915-Add-intel_dotclock_calculate.patch create mode 100644 patches.baytrail/0844-drm-i915-Make-i9xx_crtc_clock_get-use-dpll_hw_state.patch create mode 100644 patches.baytrail/0845-drm-i915-Make-i9xx_crtc_clock_get-work-for-PCH-DPLLs.patch create mode 100644 patches.baytrail/0846-drm-i915-Fix-port_clock-and-adjusted_mode.clock-read.patch create mode 100644 patches.baytrail/0847-drm-i915-Add-PIPE_CONF_CHECK_CLOCK_FUZZY.patch create mode 100644 patches.baytrail/0848-drm-i915-Add-fuzzy-clock-check-for-port_clock.patch create mode 100644 patches.baytrail/0849-drm-i915-Grab-the-pixel-clock-from-adjusted_mode-not.patch create mode 100644 patches.baytrail/0850-drm-i915-Use-adjusted_mode-clock-in-lpt_program_iclk.patch create mode 100644 patches.baytrail/0851-drm-i915-Use-adjusted_mode-in-HDMI-12bpc-clock-check.patch create mode 100644 patches.baytrail/0852-drm-i915-Use-adjusted_mode-in-intel_update_fbc.patch create mode 100644 patches.baytrail/0853-drm-i915-Use-adjusted_mode-appropriately-when-comput.patch create mode 100644 patches.baytrail/0854-drm-i915-Check-the-clock-from-adjusted-mode-in-intel.patch create mode 100644 patches.baytrail/0855-drm-i915-Use-adjusted_mode-when-checking-conditions-.patch create mode 100644 patches.baytrail/0856-drm-i915-Make-intel_crtc_active-available-outside-in.patch create mode 100644 patches.baytrail/0857-drm-i915-Use-pipe-config-in-sprite-code.patch create mode 100644 patches.baytrail/0858-drm-i915-Use-adjusted_mode-in-DSI-PLL-calculations.patch create mode 100644 patches.baytrail/0859-drm-i915-Add-explicit-pipe-src-size-to-pipe-config.patch create mode 100644 patches.baytrail/0860-drm-i915-re-layout-intel_panel.c-to-obey-80-char-lim.patch create mode 100644 patches.baytrail/0861-drm-i915-Document-the-inteded-use-of-requested_mode.patch create mode 100644 patches.baytrail/0862-drm-i915-Fix-cursor-visibility-check-with-negative-c.patch create mode 100644 patches.baytrail/0863-drm-i915-Fix-cursor-visibility-checks-also-for-the-r.patch create mode 100644 patches.baytrail/0864-drm-i915-garbage-collect-vlv-refclk-function.patch create mode 100644 patches.baytrail/0865-drm-i915-Move-double-wide-mode-handling-into-pipe_co.patch create mode 100644 patches.baytrail/0866-drm-i915-Add-double_wide-readout-and-checking.patch create mode 100644 patches.baytrail/0867-drm-i915-Check-pixel-clock-limits-on-pre-gen4.patch create mode 100644 patches.baytrail/0868-drm-i915-pipe_src_w-must-be-even-in-LVDS-dual-channe.patch create mode 100644 patches.baytrail/0869-drm-i915-Fix-up-pipe-vs.-double-wide-confusion.patch create mode 100644 patches.baytrail/0870-drm-i915-Convert-overlay-double-wide-check-over-to-p.patch create mode 100644 patches.baytrail/0871-drm-i915-WARN-is-the-DP-aux-read-or-write-is-too-big.patch create mode 100644 patches.baytrail/0872-drm-i915-only-report-hpd-connector-status-change-whe.patch create mode 100644 patches.baytrail/0873-drm-i915-check-for-more-ASLC-interrupts.patch create mode 100644 patches.baytrail/0874-drm-i915-do-not-update-cursor-in-crtc-mode-set.patch create mode 100644 patches.baytrail/0875-drm-i915-Don-t-enable-the-cursor-on-a-disable-pipe.patch create mode 100644 patches.baytrail/0876-drm-i915-write-D_COMP-using-the-mailbox.patch create mode 100644 patches.baytrail/0877-drm-i915-register-backlight-device-also-when-backlig.patch create mode 100644 patches.baytrail/0878-drm-i915-dump-crtc-timings-from-the-pipe-config.patch create mode 100644 patches.baytrail/0879-drm-i915-Fix-HSW-parity-test.patch create mode 100644 patches.baytrail/0880-drm-i915-Add-second-slice-l3-remapping.patch create mode 100644 patches.baytrail/0881-drm-i915-Make-l3-remapping-use-the-ring.patch create mode 100644 patches.baytrail/0882-drm-i915-Keep-a-list-of-all-contexts.patch create mode 100644 patches.baytrail/0883-drm-i915-Do-remaps-for-all-contexts.patch create mode 100644 patches.baytrail/0884-drm-i915-s-HAS_L3_GPU_CACHE-HAS_L3_DPF.patch create mode 100644 patches.baytrail/0885-drm-i915-vlv-honor-i915_enable_rc6-boot-param-on-VLV.patch create mode 100644 patches.baytrail/0886-drm-i915-vlv-disable-rc6p-and-rc6pp-residency-report.patch create mode 100644 patches.baytrail/0887-drm-i915-don-t-disable-ERR_INT-on-the-IRQ-handler.patch create mode 100644 patches.baytrail/0888-drm-i915-POSTING_READ-IPS_CTL-before-waiting-for-the.patch create mode 100644 patches.baytrail/0889-drm-i915-Change-i915_request-power-well-handling.patch create mode 100644 patches.baytrail/0890-drm-i915-Add-intel_display_power_-get-put-to-request.patch create mode 100644 patches.baytrail/0891-drm-i915-Refactor-power-well-refcount-inc-dec-operat.patch create mode 100644 patches.baytrail/0892-drm-i915-Add-POWER_DOMAIN_VGA.patch create mode 100644 patches.baytrail/0893-drm-i915-Pull-intel_init_power_well-out-of-intel_mod.patch create mode 100644 patches.baytrail/0894-drm-i915-cleanup-a-min_t-cast.patch create mode 100644 patches.baytrail/0895-drm-i915-assume-all-GM45-Acer-laptops-use-inverted-b.patch create mode 100644 patches.baytrail/0896-Re-create-dirty-merge-b599c89.patch create mode 100644 patches.baytrail/0897-drm-i915-Use-a-temporary-va_list-for-two-pass-string.patch create mode 100644 patches.baytrail/0898-drm-dp-add-defines-for-downstream-port-types.patch create mode 100644 patches.baytrail/0899-drm-i915-dp-downstream-port-capabilities-are-not-pre.patch create mode 100644 patches.baytrail/0900-drm-i915-use-pointer-k-cmz.-alloc-sizeof-pointer-.-p.patch create mode 100644 patches.baytrail/0901-drm-i915-Use-kcalloc-more.patch create mode 100644 patches.baytrail/0902-drm-i915-Ditch-INTELFB_CONN_LIMIT.patch create mode 100644 patches.baytrail/0903-drm-i915-Use-unsigned-for-overflow-checks-in-execbuf.patch create mode 100644 patches.baytrail/0904-drm-i915-Do-not-unlock-upon-error-in-i915_gem_idle.patch create mode 100644 patches.baytrail/0905-drm-i915-VBT-s-child_device_config-changes-over-time.patch create mode 100644 patches.baytrail/0906-drm-i915-use-the-HDMI-DDI-buffer-translations-from-V.patch create mode 100644 patches.baytrail/0907-drm-i915-check-the-DDC-and-AUX-bits-of-the-VBT-on-DD.patch create mode 100644 patches.baytrail/0908-drm-i915-add-some-assertions-about-VBT-DDI-port-type.patch create mode 100644 patches.baytrail/0909-drm-i915-don-t-init-DP-or-HDMI-when-not-supported-by.patch create mode 100644 patches.baytrail/0910-drm-i915-Rip-out-SUPPORTS_EDP.patch create mode 100644 patches.baytrail/0911-drm-i915-Fix-unclaimed-register-access-due-to-delaye.patch create mode 100644 patches.baytrail/0912-drm-i915-Redisable-VGA-before-the-modeset-on-resume.patch create mode 100644 patches.baytrail/0913-drm-i915-Move-power-well-init-earlier-during-driver-.patch create mode 100644 patches.baytrail/0914-drm-i915-Move-power-well-resume-earlier.patch create mode 100644 patches.baytrail/0915-drm-i915-Call-intel_uncore_early_sanitize-during-res.patch create mode 100644 patches.baytrail/0916-drm-i915-Drop-explicit-plane-restoration-during-resu.patch create mode 100644 patches.baytrail/0917-drm-i915-dp-read-DPCD-PSR-capability-only-on-eDP.patch create mode 100644 patches.baytrail/0918-drm-i915-Calculate-PSR-register-offsets-from-base-ge.patch create mode 100644 patches.baytrail/0919-drm-i915-Fix-intel_crtc_mode_get-mode-clock.patch create mode 100644 patches.baytrail/0920-drm-i915-precendence-bug-in-GT_PARITY_ERROR.patch create mode 100644 patches.baytrail/0921-drm-i915-Delay-the-release-of-the-forcewake-by-a-jif.patch create mode 100644 patches.baytrail/0922-drm-i915-Add-some-debug-spam-for-intialising-SDVO.patch create mode 100644 patches.baytrail/0923-drm-i915-clean-up-and-simplify-i9xx_crtc_mode_set-wr.patch create mode 100644 patches.baytrail/0924-drm-i915-Add-HSW-CRT-output-readout-support.patch create mode 100644 patches.baytrail/0925-drm-i915-backlight-combination-mode-bit-is-gen4-only.patch create mode 100644 patches.baytrail/0926-drm-i915-reorganize-intel_drv.h.patch create mode 100644 patches.baytrail/0927-drm-i915-make-intel_pipe_has_type-static.patch create mode 100644 patches.baytrail/0928-drm-i915-make-intel_crtc_load_lut-static.patch create mode 100644 patches.baytrail/0929-drm-i915-make-intel_crtc_fb_gamma_-set-get-static.patch create mode 100644 patches.baytrail/0930-drm-i915-make-hsw_-disable-restore-_lcpll-static.patch create mode 100644 patches.baytrail/0931-drm-i915-remove-extern-keywords-from-intel_drv.h-fun.patch create mode 100644 patches.baytrail/0932-drm-i915-trace-vm-eviction-instead-of-everything.patch create mode 100644 patches.baytrail/0933-drm-i915-Provide-a-cheap-ggtt-vma-lookup.patch create mode 100644 patches.baytrail/0934-drm-i915-Convert-active-API-to-VMA.patch create mode 100644 patches.baytrail/0935-drm-i915-Move-the-conditional-seqno-query-into-the-t.patch create mode 100644 patches.baytrail/0936-drm-i915-Fix-VLV-eDP-timing-v2.patch create mode 100644 patches.baytrail/0937-drm-i915-Show-WT-caching-in-debugfs.patch create mode 100644 patches.baytrail/0938-drm-i915-Add-a-tracepoint-for-using-a-semaphore.patch create mode 100644 patches.baytrail/0939-drm-i915-vlv-add-VLV-specific-clock_get-function-v3.patch create mode 100644 patches.baytrail/0940-drm-i915-vlv-fix-up-broken-precision-in-vlv_crtc_clo.patch create mode 100644 patches.baytrail/0941-drm-Remove-clock_index-from-struct-drm_display_mode.patch create mode 100644 patches.baytrail/0942-drm-Remove-synth_clock-from-struct-drm_display_mode.patch create mode 100644 patches.baytrail/0943-drm-Introduce-a-crtc_clock-for-struct-drm_display_mo.patch create mode 100644 patches.baytrail/0944-drm-i915-Use-crtc_clock-in-intel_dump_crtc_timings.patch create mode 100644 patches.baytrail/0945-drm-i915-Use-crtc_clock-with-the-adjusted-mode.patch create mode 100644 patches.baytrail/0946-drm-Implement-timings-adjustments-for-frame-packing.patch create mode 100644 patches.baytrail/0947-drm-i915-Ask-the-DRM-core-do-make-stereo-timings-adj.patch create mode 100644 patches.baytrail/0948-drm-i915-Prefer-crtc_-h-v-display-for-pipe-src-dimen.patch create mode 100644 patches.baytrail/0949-drm-Make-exposing-stereo-modes-a-per-connector-opt-i.patch create mode 100644 patches.baytrail/0950-drm-i915-Allow-stereo-modes-on-HDMI.patch create mode 100644 patches.baytrail/0951-drm-i915-vlv-hack-to-init-backlight-regs-if-BIOS-fai.patch create mode 100644 patches.baytrail/0952-drm-i915-Program-GMBUS-Frequency-based-on-the-CDCLK-.patch create mode 100644 patches.baytrail/0953-drm-i915-Eliminate-one-indent-leel-from-vlv_find_bes.patch create mode 100644 patches.baytrail/0954-drm-i915-Use-DIV_ROUND_CLOSEST.patch create mode 100644 patches.baytrail/0955-drm-i915-vlv-use-lower-precision-RC6-counter.patch create mode 100644 patches.baytrail/0956-drm-i915-vlv-use-correct-units-for-rc6-residency-v2.patch create mode 100644 patches.baytrail/0957-drm-i915-vlv-reduce-GT-FIFO-error-info-to-a-debug-me.patch create mode 100644 patches.baytrail/0958-drm-i915-dp-retry-i2c-over-aux-seven-times-on-AUX-DE.patch create mode 100644 patches.baytrail/0959-drm-i915-dp-do-not-write-DP_TRAINING_PATTERN_SET-all.patch create mode 100644 patches.baytrail/0960-drm-i915-destroy-connector-sysfs-files-earlier.patch create mode 100644 patches.baytrail/0961-drm-i915-Make-intel_resume_power_well-static.patch create mode 100644 patches.baytrail/0962-drm-i915-fix-typo-s-PatherPoint-PantherPoint.patch create mode 100644 patches.baytrail/0963-i915-vlv-untangle-integrated-clock-source-handling-v.patch create mode 100644 patches.baytrail/0964-drm-i915-Disable-enable-planes-as-the-first-last-thi.patch create mode 100644 patches.baytrail/0965-drm-i915-implement-the-Haswell-mode-set-sequence-wor.patch create mode 100644 patches.baytrail/0966-drm-i915-Don-t-populate-pipe_src_-w-h-multiple-times.patch create mode 100644 patches.baytrail/0967-drm-i915-Clean-up-the-ring-scaling-calculations.patch create mode 100644 patches.baytrail/0968-drm-i915-Add-some-missing-steps-to-i915_driver_load-.patch create mode 100644 patches.baytrail/0969-drm-i915-Fix-__wait_seqno-to-use-true-infinite-timeo.patch create mode 100644 patches.baytrail/0970-drm-i915-Boost-RPS-frequency-for-CPU-stalls.patch create mode 100644 patches.baytrail/0971-drm-i915-Tweak-RPS-thresholds-to-more-aggressively-d.patch create mode 100644 patches.baytrail/0972-drm-i915-Simplify-PSR-debugfs.patch create mode 100644 patches.baytrail/0973-drm-i915-vlv-reset-DPIO-on-load-and-resume-v2.patch create mode 100644 patches.baytrail/0974-drm-i915-vlv-Turn-off-power-gate-for-BIOS-less-syste.patch create mode 100644 patches.baytrail/0975-drm-i915-Add-a-more-detailed-comment-about-the-set_b.patch create mode 100644 patches.baytrail/0976-drm-i915-Use-adjusted_mode-in-the-fastboot-hack-to-d.patch create mode 100644 patches.baytrail/0977-drm-gem-remove-drm_gem_object_handle_unreference.patch create mode 100644 patches.baytrail/0978-drm-gem-move-drm_gem_object_handle_unreference_unloc.patch create mode 100644 patches.baytrail/0979-drm-gem-remove-bogus-NULL-check-from-drm_gem_object_.patch create mode 100644 patches.baytrail/0980-drm-gem-WARN-about-unbalanced-handle-refcounts.patch create mode 100644 patches.baytrail/0981-drm-gem-fix-up-flink-name-create-race.patch create mode 100644 patches.baytrail/0982-drm-prime-fix-error-path-in-drm_gem_prime_fd_to_hand.patch create mode 100644 patches.baytrail/0983-drm-gem-make-drm_gem_object_handle_unreference_unloc.patch create mode 100644 patches.baytrail/0984-drm-fix-locking-in-gem-debugfs-procfs-file.patch create mode 100644 patches.baytrail/0985-drm-gem-switch-dev-object_name_lock-to-a-mutex.patch create mode 100644 patches.baytrail/0986-drm-prime-fix-to-put-an-exported-dma_buf-for-adding-.patch create mode 100644 patches.baytrail/0987-drm-prime-add-return-check-for-dma_buf_fd.patch create mode 100644 patches.baytrail/0988-drm-prime-use-proper-pointer-in-drm_gem_prime_handle.patch create mode 100644 patches.baytrail/0989-drm-gem-completely-close-gem_open-vs.-gem_close-race.patch create mode 100644 patches.baytrail/0990-drm-prime-proper-locking-refcounting-for-obj-dma_buf.patch create mode 100644 patches.baytrail/0991-drm-cirrus-remove-unused-driver_private-access.patch create mode 100644 patches.baytrail/0992-drm-edid-add-drm_edid_duplicate.patch create mode 100644 patches.baytrail/0993-drm-i915-dp-use-drm_edid_duplicate.patch create mode 100644 patches.baytrail/0994-drm-Make-vblank_disable_allowed-bool.patch create mode 100644 patches.baytrail/0995-drm-Make-vblank_enabled-bool.patch create mode 100644 patches.baytrail/0996-drm-Make-vblank_inmodeset-unsigned.patch create mode 100644 patches.baytrail/0997-drm-Collect-per-crtc-vblank-stuff-to-a-struct.patch create mode 100644 patches.baytrail/0998-drm-Make-irq_enabled-bool.patch create mode 100644 patches.baytrail/0999-drm-add-drm_dev_alloc-helper.patch create mode 100644 patches.baytrail/1000-drm-gma500-Add-IS_CDV-macro.patch create mode 100644 patches.baytrail/1001-drm-Remove-pci_vendor-and-pci_device-from-struct-drm.patch create mode 100644 patches.baytrail/1002-drm-fold-in-drm_sg_alloc-into-the-ioctl.patch create mode 100644 patches.baytrail/1003-drm-hide-legacy-sg-cleanup-better-from-common-code.patch create mode 100644 patches.baytrail/1004-drm-mark-dma-setup-teardown-as-legacy-systems.patch create mode 100644 patches.baytrail/1005-drm-move-dev-data-clearing-from-drm_setup-to-lastclo.patch create mode 100644 patches.baytrail/1006-drm-move-drm_lastclose-to-drm_fops.c.patch create mode 100644 patches.baytrail/1007-drm-no-op-out-GET_STATS-ioctl.patch create mode 100644 patches.baytrail/1008-drm-Kill-drm-perf-counter-leftovers.patch create mode 100644 patches.baytrail/1009-drm-dp-add-helper-for-checking-DP_ENHANCED_FRAME_CAP.patch create mode 100644 patches.baytrail/1010-drm-i915-dp-get-rid-of-intel_dp-link_configuration.patch create mode 100644 patches.baytrail/1011-drm-i915-Call-io_schedule-whilst-whilsting-for-the-G.patch create mode 100644 patches.baytrail/1012-drm-i915-Remove-yet-another-unused-define.patch create mode 100644 patches.baytrail/1013-drm-i915-dp-use-sizeof-for-memset-instead-of-magic-v.patch create mode 100644 patches.baytrail/1014-drm-i915-Make-vlv_find_best_dpll-ppm-calculation-saf.patch create mode 100644 patches.baytrail/1015-drm-i915-Don-t-underflow-bestppm.patch create mode 100644 patches.baytrail/1016-drm-i915-Rewrite-vlv_find_best_dpll.patch create mode 100644 patches.baytrail/1017-drm-i915-De-magic-the-VLV-p2-divider-step-size.patch create mode 100644 patches.baytrail/1018-drm-i915-Make-sure-we-respect-n.max-on-VLV.patch create mode 100644 patches.baytrail/1019-drm-i915-Clarify-VLV-PLL-p1-limits.patch create mode 100644 patches.baytrail/1020-drm-i915-Allow-p1-divider-2-on-VLV.patch create mode 100644 patches.baytrail/1021-drm-i915-Respect-p2-divider-minimum-limit-on-VLV.patch create mode 100644 patches.baytrail/1022-drm-i915-Remove-the-unused-p-and-m-limits-for-VLV.patch create mode 100644 patches.baytrail/1023-drm-i915-Remove-unused-dot_limit-from-VLV-PLL-limits.patch create mode 100644 patches.baytrail/1024-drm-i915-intel_limits_vlv_dac-and-intel_limits_vlv_h.patch create mode 100644 patches.baytrail/1025-drm-i915-Don-t-lie-about-findind-suitable-PLL-settin.patch create mode 100644 patches.baytrail/1026-drm-i915-Use-intel_PLL_is_valid-in-vlv_find_best_dpl.patch create mode 100644 patches.baytrail/1027-drm-i915-Fix-VGA_DISP_DISABLE-check.patch create mode 100644 patches.baytrail/1028-drm-i915-dp-promote-clock-recovery-failures-to-DRM_E.patch create mode 100644 patches.baytrail/1029-drm-i915-Set-primary_disabled-in-intel_-enable-disab.patch create mode 100644 patches.baytrail/1030-drm-i915-Allow-sprites-to-be-configured-on-a-disable.patch create mode 100644 patches.baytrail/1031-drm-i915-Reduce-the-time-we-hold-struct-mutex-in-spr.patch create mode 100644 patches.baytrail/1032-drm-i915-Kill-a-goto-from-sprite-disable-code.patch create mode 100644 patches.baytrail/1033-drm-i915-Do-a-bit-of-cleanup-in-the-sprite-code.patch create mode 100644 patches.baytrail/1034-drm-i915-Save-user-requested-plane-coordinates-only-.patch create mode 100644 patches.baytrail/1035-drm-i915-Do-the-fbc-vs.-primary-plane-enable-disable.patch create mode 100644 patches.baytrail/1036-drm-i915-Enable-disable-IPS-when-primary-is-enabled-.patch create mode 100644 patches.baytrail/1037-drm-i915-Rename-intel_flush_display_plane-to-intel_f.patch create mode 100644 patches.baytrail/1038-drm-i915-Rename-intel_-enable-disable-_plane-to-inte.patch create mode 100644 patches.baytrail/1039-drm-i915-WARN-if-primary-plane-state-doesn-t-match-e.patch create mode 100644 patches.baytrail/1040-drm-i915-Flush-primary-plane-changes-in-sprite-code.patch create mode 100644 patches.baytrail/1041-drm-i915-Use-the-real-cpu-max-frequency-for-ring-sca.patch create mode 100644 patches.baytrail/1042-drm-i915-Undo-the-PIPEA-quirk-for-i845.patch create mode 100644 patches.baytrail/1043-drm-i915-check-that-the-i965g-gm-4G-limit-is-really-.patch create mode 100644 patches.baytrail/1044-drm-i915-rip-out-gen2-reset-code.patch create mode 100644 patches.baytrail/1045-drm-i915-Prevent-using-uninitialized-MMIO-funcs.patch create mode 100644 patches.baytrail/1046-drm-i915-Move-edram-detection-early_sanitize.patch create mode 100644 patches.baytrail/1047-drm-i915-Create-MMIO-virtual-functions.patch create mode 100644 patches.baytrail/1048-drm-i915-Extract-common-MMIO-lines.patch create mode 100644 patches.baytrail/1049-drm-i915-Create-GEN-specific-read-MMIO.patch create mode 100644 patches.baytrail/1050-drm-i915-Create-GEN-specific-write-MMIO.patch create mode 100644 patches.baytrail/1051-drm-i915-Remove-gen-specific-checks-in-MMIO.patch create mode 100644 patches.baytrail/1052-drm-i915-Keep-intel_drv.h-tidy.patch create mode 100644 patches.baytrail/1053-drm-i915-wait-for-IPS_ENABLE-when-enabling-IPS.patch create mode 100644 patches.baytrail/1054-drm-i915-Do-PCH-and-uncore-init-earlier.patch create mode 100644 patches.baytrail/1055-drm-i915-dp-update-training-set-in-a-burst-write-wit.patch create mode 100644 patches.baytrail/1056-drm-i915-don-t-leak-dp_connector-at-intel_ddi_init.patch create mode 100644 patches.baytrail/1057-drm-i915-Populate-primary_disabled-in-intel_modeset_.patch create mode 100644 patches.baytrail/1058-drm-i915-Rename-primary_disabled-to-primary_enabled.patch create mode 100644 patches.baytrail/1059-drm-i915-Capture-the-initial-error-state-when-kickin.patch create mode 100644 patches.baytrail/1060-drm-i915-Finish-enabling-rps-before-use-by-sysfs-or-.patch create mode 100644 patches.baytrail/1061-drm-i915-Educate-users-in-dmesg-about-reporting-gpu-.patch create mode 100644 patches.baytrail/1062-drm-i915-tell-the-user-KMS-is-required-for-gen6.patch create mode 100644 patches.baytrail/1063-drm-i915-Avoid-tweaking-RPS-before-it-is-enabled.patch create mode 100644 patches.baytrail/1064-drm-i915-increase-the-SWSCI-DSLP-default-timeout-to-.patch create mode 100644 patches.baytrail/1065-drm-i915-Fix-pipe-off-timeout-handling-for-pre-gen4.patch create mode 100644 patches.baytrail/1066-drm-i915-don-t-save-restore-CACHE_MODE_0-on-gen7.patch create mode 100644 patches.baytrail/1067-drm-i915-vlv-add-doc-names-to-sideband-file.patch create mode 100644 patches.baytrail/1068-drm-i915-Fix-VLV-frame-counter-registers.patch create mode 100644 patches.baytrail/1069-drm-nouveau-always-select-ACPI_VIDEO-if-ACPI-is-enab.patch create mode 100644 patches.baytrail/1070-drm-Add-separate-Kconfig-option-for-fbdev-helpers.patch create mode 100644 patches.baytrail/1071-drm-i915-Kconfig-option-to-disable-the-legacy-fbdev-.patch create mode 100644 patches.baytrail/1072-drm-i915-rename-intel_fb.c-to-intel_fbdev.c.patch create mode 100644 patches.baytrail/1073-drm-i915-Fix-pre-CTG-vblank-counter.patch create mode 100644 patches.baytrail/1074-drm-i915-Add-breadcrumbs-for-why-the-backlight-is-be.patch create mode 100644 patches.baytrail/1075-drm-i915-Use-DIV_ROUND_CLOSEST-to-calculate-dot-vco.patch create mode 100644 patches.baytrail/1076-drm-i915-Use-vlv_clock-in-vlv_crtc_clock_get.patch create mode 100644 patches.baytrail/1077-drm-i915-Skip-register-reads-in-i915_get_crtc_scanou.patch create mode 100644 patches.baytrail/1078-drm-i915-Fix-scanoutpos-calculations.patch create mode 100644 patches.baytrail/1079-drm-i915-Improve-the-accuracy-of-get_scanout_pos-on-.patch create mode 100644 patches.baytrail/1080-drm-i915-Fix-gen2-scanout-position-readout.patch create mode 100644 patches.baytrail/1081-drm-i915-Don-t-pretend-that-gen2-has-a-hardware-fram.patch create mode 100644 patches.baytrail/1082-drm-dp-constify-DP-DPCD-helpers.patch create mode 100644 patches.baytrail/1083-drm-i915-dp-constify-link_status.patch create mode 100644 patches.baytrail/1084-drm-i915-Add-intel_pipe_wm-and-prepare-for-watermark.patch create mode 100644 patches.baytrail/1085-drm-i915-Don-t-re-compute-pipe-watermarks-except-for.patch create mode 100644 patches.baytrail/1086-drm-i915-Move-LP1-watermark-merging-out-from-hsw_com.patch create mode 100644 patches.baytrail/1087-drm-i915-Use-intel_pipe_wm-in-hsw_find_best_results.patch create mode 100644 patches.baytrail/1088-drm-i915-Move-some-computations-out-from-hsw_compute.patch create mode 100644 patches.baytrail/1089-drm-i915-Check-5-6-DDB-split-only-when-sprites-are-e.patch create mode 100644 patches.baytrail/1090-drm-i915-Refactor-wm_lp-to-level-calculation.patch create mode 100644 patches.baytrail/1091-drm-i915-Kill-fbc_wm_enabled-from-intel_wm_config.patch create mode 100644 patches.baytrail/1092-drm-i915-Store-current-watermark-state-in-dev_priv-w.patch create mode 100644 patches.baytrail/1093-drm-i915-Improve-watermark-dirtyness-checks.patch create mode 100644 patches.baytrail/1094-drm-i915-Init-HSW-watermark-tracking-in-intel_modese.patch create mode 100644 patches.baytrail/1095-drm-i915-Remove-a-somewhat-silly-debug-print-from-wa.patch create mode 100644 patches.baytrail/1096-drm-i915-Adjust-watermark-register-masks.patch create mode 100644 patches.baytrail/1097-drm-i915-Rename-ilk_wm_max-to-ilk_compute_wm_maximum.patch create mode 100644 patches.baytrail/1098-drm-i915-Rename-ilk_check_wm-to-ilk_validate_wm_leve.patch create mode 100644 patches.baytrail/1099-drm-i915-Check-5-6-DDB-split-only-when-sprites-are-e.patch create mode 100644 patches.baytrail/1100-imx-drm-imx-tve-Let-device-core-handle-pinctrl.patch create mode 100644 patches.baytrail/1101-i2c-stu300-device-tree-support.patch create mode 100644 patches.baytrail/1102-i2c-stu300-do-not-request-a-specific-clock-name.patch create mode 100644 patches.baytrail/1103-pinctrl-add-pin-list-based-GPIO-ranges.patch create mode 100644 patches.baytrail/1104-pinctrl-add-Intel-BayTrail-GPIO-pinctrl-support.patch create mode 100644 patches.baytrail/1105-spi-pxa2xx-fix-compile-warning-in-pxa2xx_spi_acpi_ge.patch create mode 100644 patches.baytrail/1106-spi-pxa2xx-convert-to-dma_request_slave_channel_comp.patch create mode 100644 patches.baytrail/1107-spi-pxa2xx-add-Intel-BayTrail-ACPI-ID.patch create mode 100644 patches.baytrail/1108-ACPI-LPSS-add-support-for-Intel-BayTrail.patch create mode 100644 patches.baytrail/1109-ACPI-LPSS-mask-the-UART-TX-completion-interrupt.patch create mode 100644 patches.baytrail/1110-ACPI-LPSS-override-SDIO-private-register-space-size-.patch create mode 100644 patches.baytrail/1111-ALSA-hda-add-PCI-IDs-for-Intel-BayTrail.patch create mode 100644 patches.baytrail/1112-ASoC-fsl-add-imx-wm8962-machine-driver.patch create mode 100644 patches.baytrail/1113-I2C-mv64xxx-use-return-value-from-mv64xxx_i2c_map_re.patch create mode 100644 patches.baytrail/1114-I2C-mv64xxx-use-devm_ioremap_resource.patch create mode 100644 patches.baytrail/1115-I2C-mv64xxx-use-devm_clk_get-to-avoid-missing-clk_pu.patch create mode 100644 patches.baytrail/1116-I2C-mv64xxx-use-devm_kzalloc.patch create mode 100644 patches.baytrail/1117-I2C-mv64xxx-fix-error-handling-for-request_irq.patch create mode 100644 patches.baytrail/1118-I2C-mv64xxx-remove-I2C_M_NOSTART-code.patch create mode 100644 patches.baytrail/1119-I2C-mv64xxx-move-mv64xxx_i2c_prepare_for_io.patch create mode 100644 patches.baytrail/1120-I2C-mv64xxx-fix-race-between-FSM-interrupt-and-proce.patch create mode 100644 patches.baytrail/1121-i2c-imx-Let-device-core-handle-pinctrl.patch create mode 100644 patches.baytrail/1122-i2c-designware-prevent-signals-from-aborting-I2C-tra.patch create mode 100644 patches.baytrail/1123-drivers-i2c-busses-don-t-check-resource-with-devm_io.patch create mode 100644 patches.baytrail/1124-i2c-designware-fix-race-between-subsequent-xfers.patch create mode 100644 patches.baytrail/1125-i2c-vt8500-Add-support-for-I2C-bus-on-Wondermedia-So.patch create mode 100644 patches.baytrail/1126-i2c-mv64xxx-Add-macros-to-access-parts-of-registers.patch create mode 100644 patches.baytrail/1127-i2c-mv64xxx-make-the-registers-offset-configurable.patch create mode 100644 patches.baytrail/1128-i2c-mv64xxx-Add-Allwinner-sun4i-compatible.patch create mode 100644 patches.baytrail/1129-i2c-mv64xxx-Fix-transfer-error-code.patch create mode 100644 patches.baytrail/1130-i2c-imx-allow-autoloading-on-dt-ids.patch create mode 100644 patches.baytrail/1131-i2c-mv64xxx-Set-bus-frequency-to-100kHz-if-clock-fre.patch create mode 100644 patches.baytrail/1132-i2c-designware-make-SDA-hold-time-configurable.patch create mode 100644 patches.baytrail/1133-i2c-designware-use-div_u64-to-fix-link.patch create mode 100644 patches.baytrail/1134-of-remove-CONFIG_OF_DEVICE.patch create mode 100644 patches.baytrail/1135-dw_dmac-remove-inline-marking-of-EXPORT_SYMBOL-funct.patch create mode 100644 patches.baytrail/1136-dw_dmac-don-t-check-resource-with-devm_ioremap_resou.patch create mode 100644 patches.baytrail/1137-dma-move-dw_dmac-driver-to-an-own-directory.patch create mode 100644 patches.baytrail/1138-dma-dw-split-driver-to-library-part-and-platform-cod.patch create mode 100644 patches.baytrail/1139-dma-dw-add-PCI-part-of-the-driver.patch create mode 100644 patches.baytrail/1140-dmaengine-dw-select-DW_DMAC_BIG_ENDIAN_IO-automagica.patch create mode 100644 patches.baytrail/1141-mmc-sdhci-add-ability-to-stay-runtime-resumed-if-the.patch create mode 100644 patches.baytrail/1142-mmc-sdhci-acpi-support-runtime-PM-for-ACPI-HID-80860.patch create mode 100644 patches.baytrail/1143-mmc-sdhci-pci-support-runtime-PM-for-BYT-SD-cards.patch create mode 100644 patches.baytrail/1144-mmc-sdhci-acpi-fix-error-return-code-in-sdhci_acpi_a.patch create mode 100644 patches.baytrail/1145-mmc-sdhci-pci-add-support-for-eMMC-hardware-reset-fo.patch create mode 100644 patches.baytrail/1146-mmc-sdhci-acpi-add-support-for-eMMC-hardware-reset-f.patch create mode 100644 patches.baytrail/1147-mmc-sdhci-pci-add-another-device-id.patch create mode 100644 patches.baytrail/1148-tty-8250_dw-Add-support-for-OCTEON-UARTS.patch create mode 100644 patches.baytrail/1149-i2c-mv64xxx-Document-the-newly-introduced-allwinner-.patch create mode 100644 patches.baytrail/1150-spi-pxa2xx-enable-DMA-on-newer-Intel-LPSS-silicon.patch create mode 100644 patches.baytrail/1151-Intel-xhci-refactor-EHCI-xHCI-port-switching.patch create mode 100644 patches.baytrail/1152-serial-8250_dw-Report-CTS-asserted-for-auto-flow.patch create mode 100644 patches.baytrail/1153-pinctrl-baytrail-fix-indentations.patch create mode 100644 patches.baytrail/1154-pinctrl-baytrail-change-lvl-to-level.patch create mode 100644 patches.baytrail/1155-pinctrl-baytrail-remove-redundant-ptr-variable.patch create mode 100644 patches.baytrail/1156-pinctrl-baytrail-introduce-to_byt_gpio-macro.patch create mode 100644 patches.baytrail/1157-pinctrl-baytrail-fix-to-avoid-sparse-warnings.patch create mode 100644 patches.baytrail/1158-ASoC-fsl-imx-wm8962-Fix-error-path.patch create mode 100644 patches.baytrail/1159-i2c-designware-Manually-set-RESTART-bit-between-mess.patch create mode 100644 patches.baytrail/1160-i2c-designware-add-CONFIG_PM_SLEEP-to-suspend-resume.patch create mode 100644 patches.baytrail/1161-i2c-stu300-add-CONFIG_PM_SLEEP-to-suspend-resume-fun.patch create mode 100644 patches.baytrail/1162-i2c-imx-use-struct-representing-i2c-clk-div-val-pair.patch create mode 100644 patches.baytrail/1163-i2c-imx-enable-clk-before-write-to-registers.patch create mode 100644 patches.baytrail/1164-i2c-imx-don-t-change-platform-device-id_entry-direct.patch create mode 100644 patches.baytrail/1165-i2c-imx-wrap-registers-read-write-to-inline-function.patch create mode 100644 patches.baytrail/1166-i2c-imx-change-register-offset-representation.patch create mode 100644 patches.baytrail/1167-i2c-imx-add-INT-flag-and-IEN-bit-operatation-codes.patch create mode 100644 patches.baytrail/1168-i2c-imx-add-struct-to-hold-more-configurable-quirks.patch create mode 100644 patches.baytrail/1169-i2c-imx-Add-Vybrid-VF610-I2C-controller-support.patch create mode 100644 patches.baytrail/1170-i2c-use-dev_get_platdata.patch create mode 100644 patches.baytrail/1171-i2c-mv64xxx-Add-I2C-Transaction-Generator-support.patch create mode 100644 patches.baytrail/1172-i2c-mv64xxx-Fix-timing-issue-on-Armada-XP-errata-FE-.patch create mode 100644 patches.baytrail/1173-i2c-move-OF-helpers-into-the-core.patch create mode 100644 patches.baytrail/1174-i2c-move-ACPI-helpers-into-the-core.patch create mode 100644 patches.baytrail/1175-i2c-designware-make-HCNT-LCNT-values-configurable.patch create mode 100644 patches.baytrail/1176-i2c-designware-get-SDA-hold-time-HCNT-and-LCNT-confi.patch create mode 100644 patches.baytrail/1177-dma-dw-append-MODULE_DEVICE_TABLE-for-ACPI-case.patch create mode 100644 patches.baytrail/1178-dma-dw-improve-comparison-with-0.patch create mode 100644 patches.baytrail/1179-dma-dw-allow-shared-interrupts.patch create mode 100644 patches.baytrail/1180-dma-dw-return-DMA_SUCCESS-immediately-from-device_tx.patch create mode 100644 patches.baytrail/1181-dma-dw-return-DMA_PAUSED-only-if-cookie-status-is-DM.patch create mode 100644 patches.baytrail/1182-x86-intel-lpss-Add-pin-control-support-to-Intel-low-.patch create mode 100644 patches.baytrail/1183-i2c-designware-10-bit-addressing-mode-enabling-if-I2.patch create mode 100644 patches.baytrail/1184-i2c-i2c-imx-replace-platform_driver_probe-to-support.patch create mode 100644 patches.baytrail/1185-serial-8250_dw-don-t-limit-DMA-support-to-ACPI.patch create mode 100644 patches.baytrail/1186-serial-8250_dw-provide-a-filter-for-DMA-channel-dete.patch create mode 100644 patches.baytrail/1187-serial-8250_dw-fix-broken-function-call.patch create mode 100644 patches.baytrail/1188-ACPI-LPSS-fix-UART-Auto-Flow-Control.patch create mode 100644 patches.baytrail/1189-ACPI-LPSS-add-ACPI-IDs-for-newer-Intel-PCHs.patch create mode 100644 patches.baytrail/1190-spi-pxa2xx-Restore-private-register-bits.patch create mode 100644 patches.baytrail/1191-ARM-EXYNOS-Select-PINCTRL_EXYNOS-for-exynos4-5-at-ch.patch create mode 100644 patches.baytrail/1192-radeon-Switch-to-arch_phys_wc_add-and-add-a-missing-.patch create mode 100644 patches.baytrail/1193-PENDING-mmc-sdhci-pci-Fix-BYT-sd-card-getting-stuck-.patch diff --git a/patches.baytrail/0001-xhci-Refactor-port-status-into-a-new-function.patch b/patches.baytrail/0001-xhci-Refactor-port-status-into-a-new-function.patch new file mode 100644 index 000000000000..b1a1b31ed65f --- /dev/null +++ b/patches.baytrail/0001-xhci-Refactor-port-status-into-a-new-function.patch @@ -0,0 +1,253 @@ +From a0e5974cd8eb63b95d53b73932035542cf56ca08 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Tue, 2 Apr 2013 08:42:20 -0700 +Subject: xhci: Refactor port status into a new function. + +The hub control function is *way* too long. Refactor it into a new +function, and document the side effects of calling that function. + +Signed-off-by: Sarah Sharp +(cherry picked from commit eae5b17621d1053c81bec24e5dd5094bf50b31c6) +Signed-off-by: Darren Hart +--- + drivers/usb/host/xhci-hub.c | 210 +++++++++++++++++++++++++------------------- + 1 file changed, 119 insertions(+), 91 deletions(-) + +diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c +index 7cdcfd024744..458a89119aab 100644 +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -534,6 +534,118 @@ void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u16 wIndex) + } + } + ++/* ++ * Converts a raw xHCI port status into the format that external USB 2.0 or USB ++ * 3.0 hubs use. ++ * ++ * Possible side effects: ++ * - Mark a port as being done with device resume, ++ * and ring the endpoint doorbells. ++ * - Stop the Synopsys redriver Compliance Mode polling. ++ */ ++static u32 xhci_get_port_status(struct usb_hcd *hcd, ++ struct xhci_bus_state *bus_state, ++ __le32 __iomem **port_array, ++ u16 wIndex, u32 raw_port_status) ++{ ++ struct xhci_hcd *xhci = hcd_to_xhci(hcd); ++ u32 status = 0; ++ int slot_id; ++ ++ /* wPortChange bits */ ++ if (raw_port_status & PORT_CSC) ++ status |= USB_PORT_STAT_C_CONNECTION << 16; ++ if (raw_port_status & PORT_PEC) ++ status |= USB_PORT_STAT_C_ENABLE << 16; ++ if ((raw_port_status & PORT_OCC)) ++ status |= USB_PORT_STAT_C_OVERCURRENT << 16; ++ if ((raw_port_status & PORT_RC)) ++ status |= USB_PORT_STAT_C_RESET << 16; ++ /* USB3.0 only */ ++ if (hcd->speed == HCD_USB3) { ++ if ((raw_port_status & PORT_PLC)) ++ status |= USB_PORT_STAT_C_LINK_STATE << 16; ++ if ((raw_port_status & PORT_WRC)) ++ status |= USB_PORT_STAT_C_BH_RESET << 16; ++ } ++ ++ if (hcd->speed != HCD_USB3) { ++ if ((raw_port_status & PORT_PLS_MASK) == XDEV_U3 ++ && (raw_port_status & PORT_POWER)) ++ status |= USB_PORT_STAT_SUSPEND; ++ } ++ if ((raw_port_status & PORT_PLS_MASK) == XDEV_RESUME && ++ !DEV_SUPERSPEED(raw_port_status)) { ++ if ((raw_port_status & PORT_RESET) || ++ !(raw_port_status & PORT_PE)) ++ return 0xffffffff; ++ if (time_after_eq(jiffies, ++ bus_state->resume_done[wIndex])) { ++ xhci_dbg(xhci, "Resume USB2 port %d\n", ++ wIndex + 1); ++ bus_state->resume_done[wIndex] = 0; ++ clear_bit(wIndex, &bus_state->resuming_ports); ++ xhci_set_link_state(xhci, port_array, wIndex, ++ XDEV_U0); ++ xhci_dbg(xhci, "set port %d resume\n", ++ wIndex + 1); ++ slot_id = xhci_find_slot_id_by_port(hcd, xhci, ++ wIndex + 1); ++ if (!slot_id) { ++ xhci_dbg(xhci, "slot_id is zero\n"); ++ return 0xffffffff; ++ } ++ xhci_ring_device(xhci, slot_id); ++ bus_state->port_c_suspend |= 1 << wIndex; ++ bus_state->suspended_ports &= ~(1 << wIndex); ++ } else { ++ /* ++ * The resume has been signaling for less than ++ * 20ms. Report the port status as SUSPEND, ++ * let the usbcore check port status again ++ * and clear resume signaling later. ++ */ ++ status |= USB_PORT_STAT_SUSPEND; ++ } ++ } ++ if ((raw_port_status & PORT_PLS_MASK) == XDEV_U0 ++ && (raw_port_status & PORT_POWER) ++ && (bus_state->suspended_ports & (1 << wIndex))) { ++ bus_state->suspended_ports &= ~(1 << wIndex); ++ if (hcd->speed != HCD_USB3) ++ bus_state->port_c_suspend |= 1 << wIndex; ++ } ++ if (raw_port_status & PORT_CONNECT) { ++ status |= USB_PORT_STAT_CONNECTION; ++ status |= xhci_port_speed(raw_port_status); ++ } ++ if (raw_port_status & PORT_PE) ++ status |= USB_PORT_STAT_ENABLE; ++ if (raw_port_status & PORT_OC) ++ status |= USB_PORT_STAT_OVERCURRENT; ++ if (raw_port_status & PORT_RESET) ++ status |= USB_PORT_STAT_RESET; ++ if (raw_port_status & PORT_POWER) { ++ if (hcd->speed == HCD_USB3) ++ status |= USB_SS_PORT_STAT_POWER; ++ else ++ status |= USB_PORT_STAT_POWER; ++ } ++ /* Update Port Link State for super speed ports*/ ++ if (hcd->speed == HCD_USB3) { ++ xhci_hub_report_link_state(&status, raw_port_status); ++ /* ++ * Verify if all USB3 Ports Have entered U0 already. ++ * Delete Compliance Mode Timer if so. ++ */ ++ xhci_del_comp_mod_timer(xhci, raw_port_status, wIndex); ++ } ++ if (bus_state->port_c_suspend & (1 << wIndex)) ++ status |= 1 << USB_PORT_FEAT_C_SUSPEND; ++ ++ return status; ++} ++ + int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + u16 wIndex, char *buf, u16 wLength) + { +@@ -598,104 +710,20 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + if (!wIndex || wIndex > max_ports) + goto error; + wIndex--; +- status = 0; + temp = xhci_readl(xhci, port_array[wIndex]); + if (temp == 0xffffffff) { + retval = -ENODEV; + break; + } +- xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp); +- +- /* wPortChange bits */ +- if (temp & PORT_CSC) +- status |= USB_PORT_STAT_C_CONNECTION << 16; +- if (temp & PORT_PEC) +- status |= USB_PORT_STAT_C_ENABLE << 16; +- if ((temp & PORT_OCC)) +- status |= USB_PORT_STAT_C_OVERCURRENT << 16; +- if ((temp & PORT_RC)) +- status |= USB_PORT_STAT_C_RESET << 16; +- /* USB3.0 only */ +- if (hcd->speed == HCD_USB3) { +- if ((temp & PORT_PLC)) +- status |= USB_PORT_STAT_C_LINK_STATE << 16; +- if ((temp & PORT_WRC)) +- status |= USB_PORT_STAT_C_BH_RESET << 16; +- } ++ status = xhci_get_port_status(hcd, bus_state, port_array, ++ wIndex, temp); ++ if (status == 0xffffffff) ++ goto error; + +- if (hcd->speed != HCD_USB3) { +- if ((temp & PORT_PLS_MASK) == XDEV_U3 +- && (temp & PORT_POWER)) +- status |= USB_PORT_STAT_SUSPEND; +- } +- if ((temp & PORT_PLS_MASK) == XDEV_RESUME && +- !DEV_SUPERSPEED(temp)) { +- if ((temp & PORT_RESET) || !(temp & PORT_PE)) +- goto error; +- if (time_after_eq(jiffies, +- bus_state->resume_done[wIndex])) { +- xhci_dbg(xhci, "Resume USB2 port %d\n", +- wIndex + 1); +- bus_state->resume_done[wIndex] = 0; +- clear_bit(wIndex, &bus_state->resuming_ports); +- xhci_set_link_state(xhci, port_array, wIndex, +- XDEV_U0); +- xhci_dbg(xhci, "set port %d resume\n", +- wIndex + 1); +- slot_id = xhci_find_slot_id_by_port(hcd, xhci, +- wIndex + 1); +- if (!slot_id) { +- xhci_dbg(xhci, "slot_id is zero\n"); +- goto error; +- } +- xhci_ring_device(xhci, slot_id); +- bus_state->port_c_suspend |= 1 << wIndex; +- bus_state->suspended_ports &= ~(1 << wIndex); +- } else { +- /* +- * The resume has been signaling for less than +- * 20ms. Report the port status as SUSPEND, +- * let the usbcore check port status again +- * and clear resume signaling later. +- */ +- status |= USB_PORT_STAT_SUSPEND; +- } +- } +- if ((temp & PORT_PLS_MASK) == XDEV_U0 +- && (temp & PORT_POWER) +- && (bus_state->suspended_ports & (1 << wIndex))) { +- bus_state->suspended_ports &= ~(1 << wIndex); +- if (hcd->speed != HCD_USB3) +- bus_state->port_c_suspend |= 1 << wIndex; +- } +- if (temp & PORT_CONNECT) { +- status |= USB_PORT_STAT_CONNECTION; +- status |= xhci_port_speed(temp); +- } +- if (temp & PORT_PE) +- status |= USB_PORT_STAT_ENABLE; +- if (temp & PORT_OC) +- status |= USB_PORT_STAT_OVERCURRENT; +- if (temp & PORT_RESET) +- status |= USB_PORT_STAT_RESET; +- if (temp & PORT_POWER) { +- if (hcd->speed == HCD_USB3) +- status |= USB_SS_PORT_STAT_POWER; +- else +- status |= USB_PORT_STAT_POWER; +- } +- /* Update Port Link State for super speed ports*/ +- if (hcd->speed == HCD_USB3) { +- xhci_hub_report_link_state(&status, temp); +- /* +- * Verify if all USB3 Ports Have entered U0 already. +- * Delete Compliance Mode Timer if so. +- */ +- xhci_del_comp_mod_timer(xhci, temp, wIndex); +- } +- if (bus_state->port_c_suspend & (1 << wIndex)) +- status |= 1 << USB_PORT_FEAT_C_SUSPEND; ++ xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", ++ wIndex, temp); + xhci_dbg(xhci, "Get port status returned 0x%x\n", status); ++ + put_unaligned(cpu_to_le32(status), (__le32 *) buf); + break; + case SetPortFeature: +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0002-usb-Fix-xHCI-host-issues-on-remote-wakeup.patch b/patches.baytrail/0002-usb-Fix-xHCI-host-issues-on-remote-wakeup.patch new file mode 100644 index 000000000000..8d1b2da008af --- /dev/null +++ b/patches.baytrail/0002-usb-Fix-xHCI-host-issues-on-remote-wakeup.patch @@ -0,0 +1,198 @@ +From 751f65aeec205eb72c33c07e8b7e50449d811ba9 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Tue, 20 Aug 2013 08:12:12 -0700 +Subject: usb: Fix xHCI host issues on remote wakeup. + +When a device signals remote wakeup on a roothub, and the suspend change +bit is set, the host controller driver must not give control back to the +USB core until the port goes back into the active state. + +EHCI accomplishes this by waiting in the get port status function until +the PORT_RESUME bit is cleared: + + /* stop resume signaling */ + temp &= ~(PORT_RWC_BITS | PORT_SUSPEND | PORT_RESUME); + ehci_writel(ehci, temp, status_reg); + clear_bit(wIndex, &ehci->resuming_ports); + retval = ehci_handshake(ehci, status_reg, + PORT_RESUME, 0, 2000 /* 2msec */); + +Similarly, the xHCI host should wait until the port goes into U0, before +passing control up to the USB core. When the port transitions from the +RExit state to U0, the xHCI driver will get a port status change event. +We need to wait for that event before passing control up to the USB +core. + +After the port transitions to the active state, the USB core should time +a recovery interval before it talks to the device. The length of that +recovery interval is TRSMRCY, 10 ms, mentioned in the USB 2.0 spec, +section 7.1.7.7. The previous xHCI code (which did not wait for the +port to go into U0) would cause the USB core to violate that recovery +interval. + +This bug caused numerous USB device disconnects on remote wakeup under +ChromeOS and a Lynx Point LP xHCI host that takes up to 20 ms to move +from RExit to U0. ChromeOS is very aggressive about power savings, and +sets the autosuspend_delay to 100 ms, and disables USB persist. + +I attempted to replicate this bug with Ubuntu 12.04, but could not. I +used Ubuntu 12.04 on the same platform, with the same BIOS that the bug +was triggered on ChromeOS with. I also changed the USB sysfs settings +as described above, but still could not reproduce the bug under Ubuntu. +It may be that ChromeOS userspace triggers this bug through additional +settings. + +Signed-off-by: Sarah Sharp +(cherry picked from commit 8b3d45705e54075cfb9d4212dbca9ea82c85c4b8) +Signed-off-by: Darren Hart +--- + drivers/usb/host/xhci-hub.c | 45 ++++++++++++++++++++++++++++++++++---------- + drivers/usb/host/xhci-mem.c | 2 ++ + drivers/usb/host/xhci-ring.c | 13 +++++++++++++ + drivers/usb/host/xhci.h | 10 ++++++++++ + 4 files changed, 60 insertions(+), 10 deletions(-) + +diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c +index 458a89119aab..1f94d42bcc56 100644 +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -542,11 +542,15 @@ void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u16 wIndex) + * - Mark a port as being done with device resume, + * and ring the endpoint doorbells. + * - Stop the Synopsys redriver Compliance Mode polling. ++ * - Drop and reacquire the xHCI lock, in order to wait for port resume. + */ + static u32 xhci_get_port_status(struct usb_hcd *hcd, + struct xhci_bus_state *bus_state, + __le32 __iomem **port_array, +- u16 wIndex, u32 raw_port_status) ++ u16 wIndex, u32 raw_port_status, ++ unsigned long flags) ++ __releases(&xhci->lock) ++ __acquires(&xhci->lock) + { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + u32 status = 0; +@@ -581,21 +585,42 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, + return 0xffffffff; + if (time_after_eq(jiffies, + bus_state->resume_done[wIndex])) { ++ int time_left; ++ + xhci_dbg(xhci, "Resume USB2 port %d\n", + wIndex + 1); + bus_state->resume_done[wIndex] = 0; + clear_bit(wIndex, &bus_state->resuming_ports); ++ ++ set_bit(wIndex, &bus_state->rexit_ports); + xhci_set_link_state(xhci, port_array, wIndex, + XDEV_U0); +- xhci_dbg(xhci, "set port %d resume\n", +- wIndex + 1); +- slot_id = xhci_find_slot_id_by_port(hcd, xhci, +- wIndex + 1); +- if (!slot_id) { +- xhci_dbg(xhci, "slot_id is zero\n"); +- return 0xffffffff; ++ ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ time_left = wait_for_completion_timeout( ++ &bus_state->rexit_done[wIndex], ++ msecs_to_jiffies( ++ XHCI_MAX_REXIT_TIMEOUT)); ++ spin_lock_irqsave(&xhci->lock, flags); ++ ++ if (time_left) { ++ slot_id = xhci_find_slot_id_by_port(hcd, ++ xhci, wIndex + 1); ++ if (!slot_id) { ++ xhci_dbg(xhci, "slot_id is zero\n"); ++ return 0xffffffff; ++ } ++ xhci_ring_device(xhci, slot_id); ++ } else { ++ int port_status = xhci_readl(xhci, ++ port_array[wIndex]); ++ xhci_warn(xhci, "Port resume took longer than %i msec, port status = 0x%x\n", ++ XHCI_MAX_REXIT_TIMEOUT, ++ port_status); ++ status |= USB_PORT_STAT_SUSPEND; ++ clear_bit(wIndex, &bus_state->rexit_ports); + } +- xhci_ring_device(xhci, slot_id); ++ + bus_state->port_c_suspend |= 1 << wIndex; + bus_state->suspended_ports &= ~(1 << wIndex); + } else { +@@ -716,7 +741,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + break; + } + status = xhci_get_port_status(hcd, bus_state, port_array, +- wIndex, temp); ++ wIndex, temp, flags); + if (status == 0xffffffff) + goto error; + +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index f2e57a1112c9..19a0cc38b6d9 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -2448,6 +2448,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) + for (i = 0; i < USB_MAXCHILDREN; ++i) { + xhci->bus_state[0].resume_done[i] = 0; + xhci->bus_state[1].resume_done[i] = 0; ++ /* Only the USB 2.0 completions will ever be used. */ ++ init_completion(&xhci->bus_state[1].rexit_done[i]); + } + + if (scratchpad_alloc(xhci, flags)) +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index bcfb08e41eb6..bfa24cd06b79 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1732,6 +1732,19 @@ static void handle_port_status(struct xhci_hcd *xhci, + } + } + ++ /* ++ * Check to see if xhci-hub.c is waiting on RExit to U0 transition (or ++ * RExit to a disconnect state). If so, let the the driver know it's ++ * out of the RExit state. ++ */ ++ if (!DEV_SUPERSPEED(temp) && ++ test_and_clear_bit(faked_port_index, ++ &bus_state->rexit_ports)) { ++ complete(&bus_state->rexit_done[faked_port_index]); ++ bogus_port_status = true; ++ goto cleanup; ++ } ++ + if (hcd->speed != HCD_USB3) + xhci_test_and_clear_bit(xhci, port_array, faked_port_index, + PORT_PLC); +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 627fcd9388ca..cd35c1fc596f 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1386,8 +1386,18 @@ struct xhci_bus_state { + unsigned long resume_done[USB_MAXCHILDREN]; + /* which ports have started to resume */ + unsigned long resuming_ports; ++ /* Which ports are waiting on RExit to U0 transition. */ ++ unsigned long rexit_ports; ++ struct completion rexit_done[USB_MAXCHILDREN]; + }; + ++ ++/* ++ * It can take up to 20 ms to transition from RExit to U0 on the ++ * Intel Lynx Point LP xHCI host. ++ */ ++#define XHCI_MAX_REXIT_TIMEOUT (20 * 1000) ++ + static inline unsigned int hcd_index(struct usb_hcd *hcd) + { + if (hcd->speed == HCD_USB3) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0003-usb-xhci-check-usb2-port-capabilities-before-adding-.patch b/patches.baytrail/0003-usb-xhci-check-usb2-port-capabilities-before-adding-.patch new file mode 100644 index 000000000000..a7fa62d4a2c2 --- /dev/null +++ b/patches.baytrail/0003-usb-xhci-check-usb2-port-capabilities-before-adding-.patch @@ -0,0 +1,171 @@ +From 1c3285798797058421f167d3ae49b1d938d0dbc0 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 23 May 2013 17:14:28 +0300 +Subject: usb: xhci: check usb2 port capabilities before adding hw link PM + support + +Hardware link powermanagement in usb2 is a per-port capability. +Previously support for hw lpm was enabled for all ports if any usb2 port supported it. + +Now instead cache the capability values and check them for each port individually + +Signed-off-by: Mathias Nyman +Signed-off-by: Sarah Sharp +(cherry picked from commit b630d4b9d05ba2e66878ca4614946d0f950d4111) +Signed-off-by: Benson Leung + + +Reviewed-on: https://chromium-review.googlesource.com/169210 +Reviewed-by: Julius Werner +Commit-Queue: Benson Leung +Tested-by: Benson Leung +Signed-off-by: Darren Hart +--- + drivers/usb/host/xhci-mem.c | 33 +++++++++++++++++++++++++++++---- + drivers/usb/host/xhci.c | 27 ++++++++++++++++++++++++++- + drivers/usb/host/xhci.h | 3 +++ + 3 files changed, 58 insertions(+), 5 deletions(-) + +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index 19a0cc38b6d9..0fc539dc1cb8 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1860,6 +1860,7 @@ no_bw: + kfree(xhci->usb3_ports); + kfree(xhci->port_array); + kfree(xhci->rh_bw); ++ kfree(xhci->ext_caps); + + xhci->page_size = 0; + xhci->page_shift = 0; +@@ -2047,7 +2048,7 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci) + } + + static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, +- __le32 __iomem *addr, u8 major_revision) ++ __le32 __iomem *addr, u8 major_revision, int max_caps) + { + u32 temp, port_offset, port_count; + int i; +@@ -2072,6 +2073,10 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, + /* WTF? "Valid values are ‘1’ to MaxPorts" */ + return; + ++ /* cache usb2 port capabilities */ ++ if (major_revision < 0x03 && xhci->num_ext_caps < max_caps) ++ xhci->ext_caps[xhci->num_ext_caps++] = temp; ++ + /* Check the host's USB2 LPM capability */ + if ((xhci->hci_version == 0x96) && (major_revision != 0x03) && + (temp & XHCI_L1C)) { +@@ -2129,10 +2134,11 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, + */ + static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) + { +- __le32 __iomem *addr; +- u32 offset; ++ __le32 __iomem *addr, *tmp_addr; ++ u32 offset, tmp_offset; + unsigned int num_ports; + int i, j, port_index; ++ int cap_count = 0; + + addr = &xhci->cap_regs->hcc_params; + offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr)); +@@ -2165,13 +2171,32 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) + * See section 5.3.6 for offset calculation. + */ + addr = &xhci->cap_regs->hc_capbase + offset; ++ ++ tmp_addr = addr; ++ tmp_offset = offset; ++ ++ /* count extended protocol capability entries for later caching */ ++ do { ++ u32 cap_id; ++ cap_id = xhci_readl(xhci, tmp_addr); ++ if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL) ++ cap_count++; ++ tmp_offset = XHCI_EXT_CAPS_NEXT(cap_id); ++ tmp_addr += tmp_offset; ++ } while (tmp_offset); ++ ++ xhci->ext_caps = kzalloc(sizeof(*xhci->ext_caps) * cap_count, flags); ++ if (!xhci->ext_caps) ++ return -ENOMEM; ++ + while (1) { + u32 cap_id; + + cap_id = xhci_readl(xhci, addr); + if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL) + xhci_add_in_port(xhci, num_ports, addr, +- (u8) XHCI_EXT_PORT_MAJOR(cap_id)); ++ (u8) XHCI_EXT_PORT_MAJOR(cap_id), ++ cap_count); + offset = XHCI_EXT_CAPS_NEXT(cap_id); + if (!offset || (xhci->num_usb2_ports + xhci->num_usb3_ports) + == num_ports) +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 4a5251f3614c..ae20252e22aa 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -4045,15 +4045,40 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, + return 0; + } + ++/* check if a usb2 port supports a given extened capability protocol ++ * only USB2 ports extended protocol capability values are cached. ++ * Return 1 if capability is supported ++ */ ++static int xhci_check_usb2_port_capability(struct xhci_hcd *xhci, int port, ++ unsigned capability) ++{ ++ u32 port_offset, port_count; ++ int i; ++ ++ for (i = 0; i < xhci->num_ext_caps; i++) { ++ if (xhci->ext_caps[i] & capability) { ++ /* port offsets starts at 1 */ ++ port_offset = XHCI_EXT_PORT_OFF(xhci->ext_caps[i]) - 1; ++ port_count = XHCI_EXT_PORT_COUNT(xhci->ext_caps[i]); ++ if (port >= port_offset && ++ port < port_offset + port_count) ++ return 1; ++ } ++ } ++ return 0; ++} ++ + int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) + { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + int ret; ++ int portnum = udev->portnum - 1; + + ret = xhci_usb2_software_lpm_test(hcd, udev); + if (!ret) { + xhci_dbg(xhci, "software LPM test succeed\n"); +- if (xhci->hw_lpm_support == 1) { ++ if (xhci->hw_lpm_support == 1 && ++ xhci_check_usb2_port_capability(xhci, portnum, XHCI_HLC)) { + udev->usb2_hw_lpm_capable = 1; + ret = xhci_set_usb2_hardware_lpm(hcd, udev, 1); + if (!ret) +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index cd35c1fc596f..140b2edebde4 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1543,6 +1543,9 @@ struct xhci_hcd { + unsigned sw_lpm_support:1; + /* support xHCI 1.0 spec USB2 hardware LPM */ + unsigned hw_lpm_support:1; ++ /* cached usb2 extened protocol capabilites */ ++ u32 *ext_caps; ++ unsigned int num_ext_caps; + /* Compliance Mode Recovery Data */ + struct timer_list comp_mode_recovery_timer; + u32 port_status_u0; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0004-usb-xhci-define-port-register-names-and-use-them-ins.patch b/patches.baytrail/0004-usb-xhci-define-port-register-names-and-use-them-ins.patch new file mode 100644 index 000000000000..c996c1bd31f3 --- /dev/null +++ b/patches.baytrail/0004-usb-xhci-define-port-register-names-and-use-them-ins.patch @@ -0,0 +1,113 @@ +From d3690dac4e91a369c27937ac93dcf9a503ad2ada Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 23 May 2013 17:14:29 +0300 +Subject: usb: xhci: define port register names and use them instead of magic + numbers + +Signed-off-by: Mathias Nyman +Signed-off-by: Sarah Sharp +(cherry picked from commit b6e76371c888f5cb677f190a28444ac8875359ad) +Signed-off-by: Benson Leung + + +Reviewed-on: https://chromium-review.googlesource.com/169211 +Reviewed-by: Julius Werner +Commit-Queue: Benson Leung +Tested-by: Benson Leung +Signed-off-by: Darren Hart +--- + drivers/usb/host/xhci-hub.c | 16 +++++++--------- + drivers/usb/host/xhci.c | 4 ++-- + drivers/usb/host/xhci.h | 5 +++++ + 3 files changed, 14 insertions(+), 11 deletions(-) + +diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c +index 1f94d42bcc56..f6395dd6a8d6 100644 +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -920,18 +920,18 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + case USB_PORT_FEAT_U1_TIMEOUT: + if (hcd->speed != HCD_USB3) + goto error; +- temp = xhci_readl(xhci, port_array[wIndex] + 1); ++ temp = xhci_readl(xhci, port_array[wIndex] + PORTPMSC); + temp &= ~PORT_U1_TIMEOUT_MASK; + temp |= PORT_U1_TIMEOUT(timeout); +- xhci_writel(xhci, temp, port_array[wIndex] + 1); ++ xhci_writel(xhci, temp, port_array[wIndex] + PORTPMSC); + break; + case USB_PORT_FEAT_U2_TIMEOUT: + if (hcd->speed != HCD_USB3) + goto error; +- temp = xhci_readl(xhci, port_array[wIndex] + 1); ++ temp = xhci_readl(xhci, port_array[wIndex] + PORTPMSC); + temp &= ~PORT_U2_TIMEOUT_MASK; + temp |= PORT_U2_TIMEOUT(timeout); +- xhci_writel(xhci, temp, port_array[wIndex] + 1); ++ xhci_writel(xhci, temp, port_array[wIndex] + PORTPMSC); + break; + default: + goto error; +@@ -1151,10 +1151,8 @@ int xhci_bus_suspend(struct usb_hcd *hcd) + __le32 __iomem *addr; + u32 tmp; + +- /* Add one to the port status register address to get +- * the port power control register address. +- */ +- addr = port_array[port_index] + 1; ++ /* Get the port power control register address. */ ++ addr = port_array[port_index] + PORTPMSC; + tmp = xhci_readl(xhci, addr); + tmp |= PORT_RWE; + xhci_writel(xhci, tmp, addr); +@@ -1246,7 +1244,7 @@ int xhci_bus_resume(struct usb_hcd *hcd) + /* Add one to the port status register address to get + * the port power control register address. + */ +- addr = port_array[port_index] + 1; ++ addr = port_array[port_index] + PORTPMSC; + tmp = xhci_readl(xhci, addr); + tmp &= ~PORT_RWE; + xhci_writel(xhci, tmp, addr); +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index ae20252e22aa..1bd8ddb12d36 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -3923,7 +3923,7 @@ static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd, + * Check device's USB 2.0 extension descriptor to determine whether + * HIRD or BESL shoule be used. See USB2.0 LPM errata. + */ +- pm_addr = port_array[port_num] + 1; ++ pm_addr = port_array[port_num] + PORTPMSC; + hird = xhci_calculate_hird_besl(xhci, udev); + temp = PORT_L1DS(udev->slot_id) | PORT_HIRD(hird); + xhci_writel(xhci, temp, pm_addr); +@@ -4021,7 +4021,7 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, + + port_array = xhci->usb2_ports; + port_num = udev->portnum - 1; +- pm_addr = port_array[port_num] + 1; ++ pm_addr = port_array[port_num] + PORTPMSC; + temp = xhci_readl(xhci, pm_addr); + + xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n", +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 140b2edebde4..9d3766be3a64 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -132,6 +132,11 @@ struct xhci_cap_regs { + /* Number of registers per port */ + #define NUM_PORT_REGS 4 + ++#define PORTSC 0 ++#define PORTPMSC 1 ++#define PORTLI 2 ++#define PORTHLPMC 3 ++ + /** + * struct xhci_op_regs - xHCI Host Controller Operational Registers. + * @command: USBCMD - xHC command register +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0005-usb-xhci-add-USB2-Link-power-management-BESL-support.patch b/patches.baytrail/0005-usb-xhci-add-USB2-Link-power-management-BESL-support.patch new file mode 100644 index 000000000000..8f7eaa995fc0 --- /dev/null +++ b/patches.baytrail/0005-usb-xhci-add-USB2-Link-power-management-BESL-support.patch @@ -0,0 +1,356 @@ +From 4294a2f541d0910fe8ce152c00b48ed021fe3e20 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 23 May 2013 17:14:30 +0300 +Subject: usb: xhci: add USB2 Link power management BESL support + +usb 2.0 devices with link power managment (LPM) can describe their idle link +timeouts either in BESL or HIRD format, so far xHCI has only supported HIRD but +later xHCI errata add BESL support as well + +BESL timeouts need to inform exit latency changes with an evaluate +context command the same way USB 3.0 link PM code does. +The same xhci_change_max_exit_latency() function is used as with USB3 +but code is pulled out from #ifdef CONFIG_PM as USB2.0 BESL LPM +funcionality does not depend on CONFIG_PM. + +Signed-off-by: Mathias Nyman +Signed-off-by: Sarah Sharp +(cherry picked from commit a558ccdcc71c7770c5e80c926a31cfe8a3892a09) +Signed-off-by: Benson Leung + + +[bleung : 3.10 rebase. Remove BACKPORT version of this patch for + UPSTREAM] +Signed-off-by: Darren Hart +--- + drivers/usb/host/xhci-ext-caps.h | 1 + + drivers/usb/host/xhci.c | 204 +++++++++++++++++++++++++++------------ + drivers/usb/host/xhci.h | 21 ++++ + include/linux/usb.h | 2 + + 4 files changed, 164 insertions(+), 64 deletions(-) + +diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h +index 377f4242dabb..8d7a1324e2f3 100644 +--- a/drivers/usb/host/xhci-ext-caps.h ++++ b/drivers/usb/host/xhci-ext-caps.h +@@ -71,6 +71,7 @@ + + /* USB 2.0 xHCI 1.0 hardware LMP capability - section 7.2.2.1.3.2 */ + #define XHCI_HLC (1 << 19) ++#define XHCI_BLC (1 << 19) + + /* command register values to disable interrupts and halt the HC */ + /* start/stop HC execution - do not write unless HC is halted*/ +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 1bd8ddb12d36..0ea9df4df4b4 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -3827,6 +3827,56 @@ int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1) + return raw_port; + } + ++/* ++ * Issue an Evaluate Context command to change the Maximum Exit Latency in the ++ * slot context. If that succeeds, store the new MEL in the xhci_virt_device. ++ */ ++static int xhci_change_max_exit_latency(struct xhci_hcd *xhci, ++ struct usb_device *udev, u16 max_exit_latency) ++{ ++ struct xhci_virt_device *virt_dev; ++ struct xhci_command *command; ++ struct xhci_input_control_ctx *ctrl_ctx; ++ struct xhci_slot_ctx *slot_ctx; ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&xhci->lock, flags); ++ if (max_exit_latency == xhci->devs[udev->slot_id]->current_mel) { ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ return 0; ++ } ++ ++ /* Attempt to issue an Evaluate Context command to change the MEL. */ ++ virt_dev = xhci->devs[udev->slot_id]; ++ command = xhci->lpm_command; ++ xhci_slot_copy(xhci, command->in_ctx, virt_dev->out_ctx); ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ ++ ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); ++ ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG); ++ slot_ctx = xhci_get_slot_ctx(xhci, command->in_ctx); ++ slot_ctx->dev_info2 &= cpu_to_le32(~((u32) MAX_EXIT)); ++ slot_ctx->dev_info2 |= cpu_to_le32(max_exit_latency); ++ ++ xhci_dbg(xhci, "Set up evaluate context for LPM MEL change.\n"); ++ xhci_dbg(xhci, "Slot %u Input Context:\n", udev->slot_id); ++ xhci_dbg_ctx(xhci, command->in_ctx, 0); ++ ++ /* Issue and wait for the evaluate context command. */ ++ ret = xhci_configure_endpoint(xhci, udev, command, ++ true, true); ++ xhci_dbg(xhci, "Slot %u Output Context:\n", udev->slot_id); ++ xhci_dbg_ctx(xhci, virt_dev->out_ctx, 0); ++ ++ if (!ret) { ++ spin_lock_irqsave(&xhci->lock, flags); ++ virt_dev->current_mel = max_exit_latency; ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ } ++ return ret; ++} ++ + #ifdef CONFIG_PM_RUNTIME + + /* BESL to HIRD Encoding array for USB2 LPM */ +@@ -3868,6 +3918,28 @@ static int xhci_calculate_hird_besl(struct xhci_hcd *xhci, + return besl; + } + ++/* Calculate BESLD, L1 timeout and HIRDM for USB2 PORTHLPMC */ ++static int xhci_calculate_usb2_hw_lpm_params(struct usb_device *udev) ++{ ++ u32 field; ++ int l1; ++ int besld = 0; ++ int hirdm = 0; ++ ++ field = le32_to_cpu(udev->bos->ext_cap->bmAttributes); ++ ++ /* xHCI l1 is set in steps of 256us, xHCI 1.0 section 5.4.11.2 */ ++ l1 = XHCI_L1_TIMEOUT / 256; ++ ++ /* device has preferred BESLD */ ++ if (field & USB_BESL_DEEP_VALID) { ++ besld = USB_GET_BESL_DEEP(field); ++ hirdm = 1; ++ } ++ ++ return PORT_BESLD(besld) | PORT_L1_TIMEOUT(l1) | PORT_HIRDM(hirdm); ++} ++ + static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd, + struct usb_device *udev) + { +@@ -4000,11 +4072,12 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, + { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + __le32 __iomem **port_array; +- __le32 __iomem *pm_addr; +- u32 temp; ++ __le32 __iomem *pm_addr, *hlpm_addr; ++ u32 pm_val, hlpm_val, field; + unsigned int port_num; + unsigned long flags; +- int hird; ++ int hird, exit_latency; ++ int ret; + + if (hcd->speed == HCD_USB3 || !xhci->hw_lpm_support || + !udev->lpm_capable) +@@ -4022,23 +4095,73 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, + port_array = xhci->usb2_ports; + port_num = udev->portnum - 1; + pm_addr = port_array[port_num] + PORTPMSC; +- temp = xhci_readl(xhci, pm_addr); ++ pm_val = xhci_readl(xhci, pm_addr); ++ hlpm_addr = port_array[port_num] + PORTHLPMC; ++ field = le32_to_cpu(udev->bos->ext_cap->bmAttributes); + + xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n", + enable ? "enable" : "disable", port_num); + +- hird = xhci_calculate_hird_besl(xhci, udev); +- + if (enable) { +- temp &= ~PORT_HIRD_MASK; +- temp |= PORT_HIRD(hird) | PORT_RWE; +- xhci_writel(xhci, temp, pm_addr); +- temp = xhci_readl(xhci, pm_addr); +- temp |= PORT_HLE; +- xhci_writel(xhci, temp, pm_addr); ++ /* Host supports BESL timeout instead of HIRD */ ++ if (udev->usb2_hw_lpm_besl_capable) { ++ /* if device doesn't have a preferred BESL value use a ++ * default one which works with mixed HIRD and BESL ++ * systems. See XHCI_DEFAULT_BESL definition in xhci.h ++ */ ++ if ((field & USB_BESL_SUPPORT) && ++ (field & USB_BESL_BASELINE_VALID)) ++ hird = USB_GET_BESL_BASELINE(field); ++ else ++ hird = XHCI_DEFAULT_BESL; ++ ++ exit_latency = xhci_besl_encoding[hird]; ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ ++ /* USB 3.0 code dedicate one xhci->lpm_command->in_ctx ++ * input context for link powermanagement evaluate ++ * context commands. It is protected by hcd->bandwidth ++ * mutex and is shared by all devices. We need to set ++ * the max ext latency in USB 2 BESL LPM as well, so ++ * use the same mutex and xhci_change_max_exit_latency() ++ */ ++ mutex_lock(hcd->bandwidth_mutex); ++ ret = xhci_change_max_exit_latency(xhci, udev, ++ exit_latency); ++ mutex_unlock(hcd->bandwidth_mutex); ++ ++ if (ret < 0) ++ return ret; ++ spin_lock_irqsave(&xhci->lock, flags); ++ ++ hlpm_val = xhci_calculate_usb2_hw_lpm_params(udev); ++ xhci_writel(xhci, hlpm_val, hlpm_addr); ++ /* flush write */ ++ xhci_readl(xhci, hlpm_addr); ++ } else { ++ hird = xhci_calculate_hird_besl(xhci, udev); ++ } ++ ++ pm_val &= ~PORT_HIRD_MASK; ++ pm_val |= PORT_HIRD(hird) | PORT_RWE; ++ xhci_writel(xhci, pm_val, pm_addr); ++ pm_val = xhci_readl(xhci, pm_addr); ++ pm_val |= PORT_HLE; ++ xhci_writel(xhci, pm_val, pm_addr); ++ /* flush write */ ++ xhci_readl(xhci, pm_addr); + } else { +- temp &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK); +- xhci_writel(xhci, temp, pm_addr); ++ pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK); ++ xhci_writel(xhci, pm_val, pm_addr); ++ /* flush write */ ++ xhci_readl(xhci, pm_addr); ++ if (udev->usb2_hw_lpm_besl_capable) { ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ mutex_lock(hcd->bandwidth_mutex); ++ xhci_change_max_exit_latency(xhci, udev, 0); ++ mutex_unlock(hcd->bandwidth_mutex); ++ return 0; ++ } + } + + spin_unlock_irqrestore(&xhci->lock, flags); +@@ -4080,6 +4203,9 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) + if (xhci->hw_lpm_support == 1 && + xhci_check_usb2_port_capability(xhci, portnum, XHCI_HLC)) { + udev->usb2_hw_lpm_capable = 1; ++ if (xhci_check_usb2_port_capability(xhci, portnum, ++ XHCI_BLC)) ++ udev->usb2_hw_lpm_besl_capable = 1; + ret = xhci_set_usb2_hardware_lpm(hcd, udev, 1); + if (!ret) + udev->usb2_hw_lpm_enabled = 1; +@@ -4410,56 +4536,6 @@ static u16 xhci_calculate_lpm_timeout(struct usb_hcd *hcd, + return timeout; + } + +-/* +- * Issue an Evaluate Context command to change the Maximum Exit Latency in the +- * slot context. If that succeeds, store the new MEL in the xhci_virt_device. +- */ +-static int xhci_change_max_exit_latency(struct xhci_hcd *xhci, +- struct usb_device *udev, u16 max_exit_latency) +-{ +- struct xhci_virt_device *virt_dev; +- struct xhci_command *command; +- struct xhci_input_control_ctx *ctrl_ctx; +- struct xhci_slot_ctx *slot_ctx; +- unsigned long flags; +- int ret; +- +- spin_lock_irqsave(&xhci->lock, flags); +- if (max_exit_latency == xhci->devs[udev->slot_id]->current_mel) { +- spin_unlock_irqrestore(&xhci->lock, flags); +- return 0; +- } +- +- /* Attempt to issue an Evaluate Context command to change the MEL. */ +- virt_dev = xhci->devs[udev->slot_id]; +- command = xhci->lpm_command; +- xhci_slot_copy(xhci, command->in_ctx, virt_dev->out_ctx); +- spin_unlock_irqrestore(&xhci->lock, flags); +- +- ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); +- ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG); +- slot_ctx = xhci_get_slot_ctx(xhci, command->in_ctx); +- slot_ctx->dev_info2 &= cpu_to_le32(~((u32) MAX_EXIT)); +- slot_ctx->dev_info2 |= cpu_to_le32(max_exit_latency); +- +- xhci_dbg(xhci, "Set up evaluate context for LPM MEL change.\n"); +- xhci_dbg(xhci, "Slot %u Input Context:\n", udev->slot_id); +- xhci_dbg_ctx(xhci, command->in_ctx, 0); +- +- /* Issue and wait for the evaluate context command. */ +- ret = xhci_configure_endpoint(xhci, udev, command, +- true, true); +- xhci_dbg(xhci, "Slot %u Output Context:\n", udev->slot_id); +- xhci_dbg_ctx(xhci, virt_dev->out_ctx, 0); +- +- if (!ret) { +- spin_lock_irqsave(&xhci->lock, flags); +- virt_dev->current_mel = max_exit_latency; +- spin_unlock_irqrestore(&xhci->lock, flags); +- } +- return ret; +-} +- + static int calculate_max_exit_latency(struct usb_device *udev, + enum usb3_link_state state_changed, + u16 hub_encoded_timeout) +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 9d3766be3a64..65aef567ad34 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -386,6 +386,27 @@ struct xhci_op_regs { + #define PORT_L1DS(p) (((p) & 0xff) << 8) + #define PORT_HLE (1 << 16) + ++ ++/* USB2 Protocol PORTHLPMC */ ++#define PORT_HIRDM(p)((p) & 3) ++#define PORT_L1_TIMEOUT(p)(((p) & 0xff) << 2) ++#define PORT_BESLD(p)(((p) & 0xf) << 10) ++ ++/* use 512 microseconds as USB2 LPM L1 default timeout. */ ++#define XHCI_L1_TIMEOUT 512 ++ ++/* Set default HIRD/BESL value to 4 (350/400us) for USB2 L1 LPM resume latency. ++ * Safe to use with mixed HIRD and BESL systems (host and device) and is used ++ * by other operating systems. ++ * ++ * XHCI 1.0 errata 8/14/12 Table 13 notes: ++ * "Software should choose xHC BESL/BESLD field values that do not violate a ++ * device's resume latency requirements, ++ * e.g. not program values > '4' if BLC = '1' and a HIRD device is attached, ++ * or not program values < '4' if BLC = '0' and a BESL device is attached. ++ */ ++#define XHCI_DEFAULT_BESL 4 ++ + /** + * struct xhci_intr_reg - Interrupt Register Set + * @irq_pending: IMAN - Interrupt Management Register. Used to enable +diff --git a/include/linux/usb.h b/include/linux/usb.h +index a0bee5a28d1a..3a1b864ad541 100644 +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -468,6 +468,7 @@ struct usb3_lpm_parameters { + * @wusb: device is Wireless USB + * @lpm_capable: device supports LPM + * @usb2_hw_lpm_capable: device can perform USB2 hardware LPM ++ * @usb2_hw_lpm_besl_capable: device can perform USB2 hardware BESL LPM + * @usb2_hw_lpm_enabled: USB2 hardware LPM enabled + * @usb3_lpm_enabled: USB3 hardware LPM enabled + * @string_langid: language ID for strings +@@ -538,6 +539,7 @@ struct usb_device { + unsigned wusb:1; + unsigned lpm_capable:1; + unsigned usb2_hw_lpm_capable:1; ++ unsigned usb2_hw_lpm_besl_capable:1; + unsigned usb2_hw_lpm_enabled:1; + unsigned usb3_lpm_enabled:1; + int string_langid; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0006-usb-add-usb2-Link-PM-variables-to-sysfs-and-usb_devi.patch b/patches.baytrail/0006-usb-add-usb2-Link-PM-variables-to-sysfs-and-usb_devi.patch new file mode 100644 index 000000000000..2188d406b07e --- /dev/null +++ b/patches.baytrail/0006-usb-add-usb2-Link-PM-variables-to-sysfs-and-usb_devi.patch @@ -0,0 +1,208 @@ +From d9bcaf6868ca8f304dd76246251154cfd2bd0b50 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 23 May 2013 17:14:31 +0300 +Subject: usb: add usb2 Link PM variables to sysfs and usb_device + +Adds abitilty to tune L1 timeout (inactivity timer for usb2 link sleep) +and BESL (best effort service latency)via sysfs. + +This also adds a new usb2_lpm_parameters structure with those variables to +struct usb_device. + +Signed-off-by: Mathias Nyman +Signed-off-by: Sarah Sharp +(cherry picked from commit 17f34867e98d2fb0c03918faab79efb989fa134b) +Signed-off-by: Benson Leung + + +Reviewed-on: https://chromium-review.googlesource.com/169213 +Reviewed-by: Julius Werner +Commit-Queue: Benson Leung +Tested-by: Benson Leung +Signed-off-by: Darren Hart +--- + Documentation/ABI/testing/sysfs-bus-usb | 27 +++++++++++++++++ + drivers/usb/core/sysfs.c | 54 +++++++++++++++++++++++++++++++++ + drivers/usb/host/xhci.c | 6 ++-- + include/linux/usb.h | 18 +++++++++++ + 4 files changed, 103 insertions(+), 2 deletions(-) + +diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb +index f093e59cbe5f..9759b8c91332 100644 +--- a/Documentation/ABI/testing/sysfs-bus-usb ++++ b/Documentation/ABI/testing/sysfs-bus-usb +@@ -236,3 +236,30 @@ Description: + This attribute is to expose these information to user space. + The file will read "hotplug", "wired" and "not used" if the + information is available, and "unknown" otherwise. ++ ++What: /sys/bus/usb/devices/.../power/usb2_lpm_l1_timeout ++Date: May 2013 ++Contact: Mathias Nyman ++Description: ++ USB 2.0 devices may support hardware link power management (LPM) ++ L1 sleep state. The usb2_lpm_l1_timeout attribute allows ++ tuning the timeout for L1 inactivity timer (LPM timer), e.g. ++ needed inactivity time before host requests the device to go to L1 sleep. ++ Useful for power management tuning. ++ Supported values are 0 - 65535 microseconds. ++ ++What: /sys/bus/usb/devices/.../power/usb2_lpm_besl ++Date: May 2013 ++Contact: Mathias Nyman ++Description: ++ USB 2.0 devices that support hardware link power management (LPM) ++ L1 sleep state now use a best effort service latency value (BESL) to ++ indicate the best effort to resumption of service to the device after the ++ initiation of the resume event. ++ If the device does not have a preferred besl value then the host can select ++ one instead. This usb2_lpm_besl attribute allows to tune the host selected besl ++ value in order to tune power saving and service latency. ++ ++ Supported values are 0 - 15. ++ More information on how besl values map to microseconds can be found in ++ USB 2.0 ECN Errata for Link Power Management, section 4.10) +diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c +index aa38db44818a..d9284b998bd7 100644 +--- a/drivers/usb/core/sysfs.c ++++ b/drivers/usb/core/sysfs.c +@@ -497,8 +497,62 @@ set_usb2_hardware_lpm(struct device *dev, struct device_attribute *attr, + static DEVICE_ATTR(usb2_hardware_lpm, S_IRUGO | S_IWUSR, show_usb2_hardware_lpm, + set_usb2_hardware_lpm); + ++static ssize_t ++show_usb2_lpm_l1_timeout(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct usb_device *udev = to_usb_device(dev); ++ return sprintf(buf, "%d\n", udev->l1_params.timeout); ++} ++ ++static ssize_t ++set_usb2_lpm_l1_timeout(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct usb_device *udev = to_usb_device(dev); ++ u16 timeout; ++ ++ if (kstrtou16(buf, 0, &timeout)) ++ return -EINVAL; ++ ++ udev->l1_params.timeout = timeout; ++ ++ return count; ++} ++ ++static DEVICE_ATTR(usb2_lpm_l1_timeout, S_IRUGO | S_IWUSR, ++ show_usb2_lpm_l1_timeout, set_usb2_lpm_l1_timeout); ++ ++static ssize_t ++show_usb2_lpm_besl(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct usb_device *udev = to_usb_device(dev); ++ return sprintf(buf, "%d\n", udev->l1_params.besl); ++} ++ ++static ssize_t ++set_usb2_lpm_besl(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct usb_device *udev = to_usb_device(dev); ++ u8 besl; ++ ++ if (kstrtou8(buf, 0, &besl) || besl > 15) ++ return -EINVAL; ++ ++ udev->l1_params.besl = besl; ++ ++ return count; ++} ++ ++static DEVICE_ATTR(usb2_lpm_besl, S_IRUGO | S_IWUSR, ++ show_usb2_lpm_besl, set_usb2_lpm_besl); ++ + static struct attribute *usb2_hardware_lpm_attr[] = { + &dev_attr_usb2_hardware_lpm.attr, ++ &dev_attr_usb2_lpm_l1_timeout.attr, ++ &dev_attr_usb2_lpm_besl.attr, + NULL, + }; + static struct attribute_group usb2_hardware_lpm_attr_group = { +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 0ea9df4df4b4..a228b796c300 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -3929,7 +3929,7 @@ static int xhci_calculate_usb2_hw_lpm_params(struct usb_device *udev) + field = le32_to_cpu(udev->bos->ext_cap->bmAttributes); + + /* xHCI l1 is set in steps of 256us, xHCI 1.0 section 5.4.11.2 */ +- l1 = XHCI_L1_TIMEOUT / 256; ++ l1 = udev->l1_params.timeout / 256; + + /* device has preferred BESLD */ + if (field & USB_BESL_DEEP_VALID) { +@@ -4113,7 +4113,7 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, + (field & USB_BESL_BASELINE_VALID)) + hird = USB_GET_BESL_BASELINE(field); + else +- hird = XHCI_DEFAULT_BESL; ++ hird = udev->l1_params.besl; + + exit_latency = xhci_besl_encoding[hird]; + spin_unlock_irqrestore(&xhci->lock, flags); +@@ -4203,6 +4203,8 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) + if (xhci->hw_lpm_support == 1 && + xhci_check_usb2_port_capability(xhci, portnum, XHCI_HLC)) { + udev->usb2_hw_lpm_capable = 1; ++ udev->l1_params.timeout = XHCI_L1_TIMEOUT; ++ udev->l1_params.besl = XHCI_DEFAULT_BESL; + if (xhci_check_usb2_port_capability(xhci, portnum, + XHCI_BLC)) + udev->usb2_hw_lpm_besl_capable = 1; +diff --git a/include/linux/usb.h b/include/linux/usb.h +index 3a1b864ad541..1f7d63f3ab8b 100644 +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -394,6 +394,22 @@ enum usb_port_connect_type { + }; + + /* ++ * USB 2.0 Link Power Management (LPM) parameters. ++ */ ++struct usb2_lpm_parameters { ++ /* Best effort service latency indicate how long the host will drive ++ * resume on an exit from L1. ++ */ ++ unsigned int besl; ++ ++ /* Timeout value in microseconds for the L1 inactivity (LPM) timer. ++ * When the timer counts to zero, the parent hub will initiate a LPM ++ * transition to L1. ++ */ ++ int timeout; ++}; ++ ++/* + * USB 3.0 Link Power Management (LPM) parameters. + * + * PEL and SEL are USB 3.0 Link PM latencies for device-initiated LPM exit. +@@ -488,6 +504,7 @@ struct usb3_lpm_parameters { + * specific data for the device. + * @slot_id: Slot ID assigned by xHCI + * @removable: Device can be physically removed from this port ++ * @l1_params: best effor service latency for USB2 L1 LPM state, and L1 timeout. + * @u1_params: exit latencies for USB3 U1 LPM state, and hub-initiated timeout. + * @u2_params: exit latencies for USB3 U2 LPM state, and hub-initiated timeout. + * @lpm_disable_count: Ref count used by usb_disable_lpm() and usb_enable_lpm() +@@ -568,6 +585,7 @@ struct usb_device { + struct wusb_dev *wusb_dev; + int slot_id; + enum usb_device_removable removable; ++ struct usb2_lpm_parameters l1_params; + struct usb3_lpm_parameters u1_params; + struct usb3_lpm_parameters u2_params; + unsigned lpm_disable_count; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0007-xhci-fix-port-BESL-LPM-capability-checking.patch b/patches.baytrail/0007-xhci-fix-port-BESL-LPM-capability-checking.patch new file mode 100644 index 000000000000..1f02bb81f0e6 --- /dev/null +++ b/patches.baytrail/0007-xhci-fix-port-BESL-LPM-capability-checking.patch @@ -0,0 +1,46 @@ +From dcddb19f8ddd55b8709f90a7a92e9f39bdbdf825 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Wed, 21 Aug 2013 18:50:09 +0300 +Subject: xhci: fix port BESL LPM capability checking + +Wrong capability bit was checked for best effort service latency. +bit 20 indicate port is BESL LPM capable (BLC), +bit 19 is hardware LPM capable (HLC) + +This patch should be backported to kernels as old as 3.11, that +contain the commit a558ccdcc71c7770c5e80c926a31cfe8a3892a09 "usb: xhci: +add USB2 Link power management BESL support" + +Signed-off-by: Mathias Nyman +Signed-off-by: Sarah Sharp +Reported-by: Steve Cotton +Cc: stable@vger.kernel.org +(cherry picked from commit dcf06a036848b4e8e6c8220f2e00b9adf6f84918) +Signed-off-by: Benson Leung + + +Reviewed-on: https://chromium-review.googlesource.com/169214 +Reviewed-by: Julius Werner +Commit-Queue: Benson Leung +Tested-by: Benson Leung +Signed-off-by: Darren Hart +--- + drivers/usb/host/xhci-ext-caps.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h +index 8d7a1324e2f3..9fe3225e6c61 100644 +--- a/drivers/usb/host/xhci-ext-caps.h ++++ b/drivers/usb/host/xhci-ext-caps.h +@@ -71,7 +71,7 @@ + + /* USB 2.0 xHCI 1.0 hardware LMP capability - section 7.2.2.1.3.2 */ + #define XHCI_HLC (1 << 19) +-#define XHCI_BLC (1 << 19) ++#define XHCI_BLC (1 << 20) + + /* command register values to disable interrupts and halt the HC */ + /* start/stop HC execution - do not write unless HC is halted*/ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0008-usb-Don-t-enable-USB-2.0-Link-PM-by-default.patch b/patches.baytrail/0008-usb-Don-t-enable-USB-2.0-Link-PM-by-default.patch new file mode 100644 index 000000000000..e4084d6d7d29 --- /dev/null +++ b/patches.baytrail/0008-usb-Don-t-enable-USB-2.0-Link-PM-by-default.patch @@ -0,0 +1,378 @@ +From be4fc525ec62681a711552af31af72eddac487d8 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Mon, 30 Sep 2013 17:26:28 +0300 +Subject: usb: Don't enable USB 2.0 Link PM by default. + +How it's supposed to work: +-------------------------- + +USB 2.0 Link PM is a lower power state that some newer USB 2.0 devices +support. USB 3.0 devices certified by the USB-IF are required to +support it if they are plugged into a USB 2.0 only port, or a USB 2.0 +cable is used. USB 2.0 Link PM requires both a USB device and a host +controller that supports USB 2.0 hardware-enabled LPM. + +USB 2.0 Link PM is designed to be enabled once by software, and the host +hardware handles transitions to the L1 state automatically. The premise +of USB 2.0 Link PM is to be able to put the device into a lower power +link state when the bus is idle or the device NAKs USB IN transfers for +a specified amount of time. + +...but hardware is broken: +-------------------------- + +It turns out many USB 3.0 devices claim to support USB 2.0 Link PM (by +setting the LPM bit in their USB 2.0 BOS descriptor), but they don't +actually implement it correctly. This manifests as the USB device +refusing to respond to transfers when it is plugged into a USB 2.0 only +port under the Haswell-ULT/Lynx Point LP xHCI host. + +These devices pass the xHCI driver's simple test to enable USB 2.0 Link +PM, wait for the port to enter L1, and then bring it back into L0. They +only start to break when L1 entry is interleaved with transfers. + +Some devices then fail to respond to the next control transfer (usually +a Set Configuration). This results in devices never enumerating. + +Other mass storage devices (such as a later model Western Digital My +Passport USB 3.0 hard drive) respond fine to going into L1 between +control transfers. They ACK the entry, come out of L1 when the host +needs to send a control transfer, and respond properly to those control +transfers. However, when the first READ10 SCSI command is sent, the +device NAKs the data phase while it's reading from the spinning disk. +Eventually, the host requests to put the link into L1, and the device +ACKs that request. Then it never responds to the data phase of the +READ10 command. This results in not being able to read from the drive. + +Some mass storage devices (like the Corsair Survivor USB 3.0 flash +drive) are well behaved. They ACK the entry into L1 during control +transfers, and when SCSI commands start coming in, they NAK the requests +to go into L1, because they need to be at full power. + +Not all USB 3.0 devices advertise USB 2.0 link PM support. My Point +Grey USB 3.0 webcam advertises itself as a USB 2.1 device, but doesn't +have a USB 2.0 BOS descriptor, so we don't enable USB 2.0 Link PM. I +suspect that means the device isn't certified. + +What do we do about it? +----------------------- + +There's really no good way for the kernel to test these devices. +Therefore, the kernel needs to disable USB 2.0 Link PM by default, and +distros will have to enable it by writing 1 to the sysfs file +/sys/bus/usb/devices/../power/usb2_hardware_lpm. Rip out the xHCI Link +PM test, since it's not sufficient to detect these buggy devices, and +don't automatically enable LPM after the device is addressed. + +This patch should be backported to kernels as old as 3.11, that +contain the commit a558ccdcc71c7770c5e80c926a31cfe8a3892a09 "usb: xhci: +add USB2 Link power management BESL support". Without this fix, some +USB 3.0 devices will not enumerate or work properly under USB 2.0 ports +on Haswell-ULT systems. + +Signed-off-by: Sarah Sharp +Cc: stable@vger.kernel.org +(cherry picked from commit de68bab4fa96014cfaa6fcbcdb9750e32969fb86) +Signed-off-by: Darren Hart +--- + drivers/usb/core/driver.c | 3 + + drivers/usb/core/hub.c | 1 + + drivers/usb/core/sysfs.c | 6 +- + drivers/usb/host/xhci-mem.c | 10 --- + drivers/usb/host/xhci.c | 161 +++++--------------------------------------- + include/linux/usb.h | 4 +- + 6 files changed, 29 insertions(+), 156 deletions(-) + +diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c +index 6eab440e1542..bed14edd8ef5 100644 +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -1773,6 +1773,9 @@ int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + int ret = -EPERM; + ++ if (enable && !udev->usb2_hw_lpm_allowed) ++ return 0; ++ + if (hcd->driver->set_usb2_hw_lpm) { + ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, enable); + if (!ret) +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 1424a8988849..a5a1fcc09e9d 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -5186,6 +5186,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) + + done: + /* Now that the alt settings are re-installed, enable LTM and LPM. */ ++ usb_set_usb2_hardware_lpm(udev, 1); + usb_unlocked_enable_lpm(udev); + usb_enable_ltm(udev); + return 0; +diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c +index d9284b998bd7..9e6f9a945026 100644 +--- a/drivers/usb/core/sysfs.c ++++ b/drivers/usb/core/sysfs.c +@@ -463,7 +463,7 @@ show_usb2_hardware_lpm(struct device *dev, struct device_attribute *attr, + struct usb_device *udev = to_usb_device(dev); + const char *p; + +- if (udev->usb2_hw_lpm_enabled == 1) ++ if (udev->usb2_hw_lpm_allowed == 1) + p = "enabled"; + else + p = "disabled"; +@@ -483,8 +483,10 @@ set_usb2_hardware_lpm(struct device *dev, struct device_attribute *attr, + + ret = strtobool(buf, &value); + +- if (!ret) ++ if (!ret) { ++ udev->usb2_hw_lpm_allowed = value; + ret = usb_set_usb2_hardware_lpm(udev, value); ++ } + + usb_unlock_device(udev); + +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index 0fc539dc1cb8..27062e6010c2 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1763,9 +1763,7 @@ void xhci_free_command(struct xhci_hcd *xhci, + void xhci_mem_cleanup(struct xhci_hcd *xhci) + { + struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); +- struct dev_info *dev_info, *next; + struct xhci_cd *cur_cd, *next_cd; +- unsigned long flags; + int size; + int i, j, num_ports; + +@@ -1824,13 +1822,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) + + scratchpad_free(xhci); + +- spin_lock_irqsave(&xhci->lock, flags); +- list_for_each_entry_safe(dev_info, next, &xhci->lpm_failed_devs, list) { +- list_del(&dev_info->list); +- kfree(dev_info); +- } +- spin_unlock_irqrestore(&xhci->lock, flags); +- + if (!xhci->rh_bw) + goto no_bw; + +@@ -2289,7 +2280,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) + u32 page_size, temp; + int i; + +- INIT_LIST_HEAD(&xhci->lpm_failed_devs); + INIT_LIST_HEAD(&xhci->cancel_cmd_list); + + page_size = xhci_readl(xhci, &xhci->op_regs->page_size); +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index a228b796c300..10b15d3aa117 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -3940,133 +3940,6 @@ static int xhci_calculate_usb2_hw_lpm_params(struct usb_device *udev) + return PORT_BESLD(besld) | PORT_L1_TIMEOUT(l1) | PORT_HIRDM(hirdm); + } + +-static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd, +- struct usb_device *udev) +-{ +- struct xhci_hcd *xhci = hcd_to_xhci(hcd); +- struct dev_info *dev_info; +- __le32 __iomem **port_array; +- __le32 __iomem *addr, *pm_addr; +- u32 temp, dev_id; +- unsigned int port_num; +- unsigned long flags; +- int hird; +- int ret; +- +- if (hcd->speed == HCD_USB3 || !xhci->sw_lpm_support || +- !udev->lpm_capable) +- return -EINVAL; +- +- /* we only support lpm for non-hub device connected to root hub yet */ +- if (!udev->parent || udev->parent->parent || +- udev->descriptor.bDeviceClass == USB_CLASS_HUB) +- return -EINVAL; +- +- spin_lock_irqsave(&xhci->lock, flags); +- +- /* Look for devices in lpm_failed_devs list */ +- dev_id = le16_to_cpu(udev->descriptor.idVendor) << 16 | +- le16_to_cpu(udev->descriptor.idProduct); +- list_for_each_entry(dev_info, &xhci->lpm_failed_devs, list) { +- if (dev_info->dev_id == dev_id) { +- ret = -EINVAL; +- goto finish; +- } +- } +- +- port_array = xhci->usb2_ports; +- port_num = udev->portnum - 1; +- +- if (port_num > HCS_MAX_PORTS(xhci->hcs_params1)) { +- xhci_dbg(xhci, "invalid port number %d\n", udev->portnum); +- ret = -EINVAL; +- goto finish; +- } +- +- /* +- * Test USB 2.0 software LPM. +- * FIXME: some xHCI 1.0 hosts may implement a new register to set up +- * hardware-controlled USB 2.0 LPM. See section 5.4.11 and 4.23.5.1.1.1 +- * in the June 2011 errata release. +- */ +- xhci_dbg(xhci, "test port %d software LPM\n", port_num); +- /* +- * Set L1 Device Slot and HIRD/BESL. +- * Check device's USB 2.0 extension descriptor to determine whether +- * HIRD or BESL shoule be used. See USB2.0 LPM errata. +- */ +- pm_addr = port_array[port_num] + PORTPMSC; +- hird = xhci_calculate_hird_besl(xhci, udev); +- temp = PORT_L1DS(udev->slot_id) | PORT_HIRD(hird); +- xhci_writel(xhci, temp, pm_addr); +- +- /* Set port link state to U2(L1) */ +- addr = port_array[port_num]; +- xhci_set_link_state(xhci, port_array, port_num, XDEV_U2); +- +- /* wait for ACK */ +- spin_unlock_irqrestore(&xhci->lock, flags); +- msleep(10); +- spin_lock_irqsave(&xhci->lock, flags); +- +- /* Check L1 Status */ +- ret = xhci_handshake(xhci, pm_addr, +- PORT_L1S_MASK, PORT_L1S_SUCCESS, 125); +- if (ret != -ETIMEDOUT) { +- /* enter L1 successfully */ +- temp = xhci_readl(xhci, addr); +- xhci_dbg(xhci, "port %d entered L1 state, port status 0x%x\n", +- port_num, temp); +- ret = 0; +- } else { +- temp = xhci_readl(xhci, pm_addr); +- xhci_dbg(xhci, "port %d software lpm failed, L1 status %d\n", +- port_num, temp & PORT_L1S_MASK); +- ret = -EINVAL; +- } +- +- /* Resume the port */ +- xhci_set_link_state(xhci, port_array, port_num, XDEV_U0); +- +- spin_unlock_irqrestore(&xhci->lock, flags); +- msleep(10); +- spin_lock_irqsave(&xhci->lock, flags); +- +- /* Clear PLC */ +- xhci_test_and_clear_bit(xhci, port_array, port_num, PORT_PLC); +- +- /* Check PORTSC to make sure the device is in the right state */ +- if (!ret) { +- temp = xhci_readl(xhci, addr); +- xhci_dbg(xhci, "resumed port %d status 0x%x\n", port_num, temp); +- if (!(temp & PORT_CONNECT) || !(temp & PORT_PE) || +- (temp & PORT_PLS_MASK) != XDEV_U0) { +- xhci_dbg(xhci, "port L1 resume fail\n"); +- ret = -EINVAL; +- } +- } +- +- if (ret) { +- /* Insert dev to lpm_failed_devs list */ +- xhci_warn(xhci, "device LPM test failed, may disconnect and " +- "re-enumerate\n"); +- dev_info = kzalloc(sizeof(struct dev_info), GFP_ATOMIC); +- if (!dev_info) { +- ret = -ENOMEM; +- goto finish; +- } +- dev_info->dev_id = dev_id; +- INIT_LIST_HEAD(&dev_info->list); +- list_add(&dev_info->list, &xhci->lpm_failed_devs); +- } else { +- xhci_ring_device(xhci, udev->slot_id); +- } +- +-finish: +- spin_unlock_irqrestore(&xhci->lock, flags); +- return ret; +-} +- + int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, + struct usb_device *udev, int enable) + { +@@ -4194,24 +4067,26 @@ static int xhci_check_usb2_port_capability(struct xhci_hcd *xhci, int port, + int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) + { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); +- int ret; + int portnum = udev->portnum - 1; + +- ret = xhci_usb2_software_lpm_test(hcd, udev); +- if (!ret) { +- xhci_dbg(xhci, "software LPM test succeed\n"); +- if (xhci->hw_lpm_support == 1 && +- xhci_check_usb2_port_capability(xhci, portnum, XHCI_HLC)) { +- udev->usb2_hw_lpm_capable = 1; +- udev->l1_params.timeout = XHCI_L1_TIMEOUT; +- udev->l1_params.besl = XHCI_DEFAULT_BESL; +- if (xhci_check_usb2_port_capability(xhci, portnum, +- XHCI_BLC)) +- udev->usb2_hw_lpm_besl_capable = 1; +- ret = xhci_set_usb2_hardware_lpm(hcd, udev, 1); +- if (!ret) +- udev->usb2_hw_lpm_enabled = 1; +- } ++ if (hcd->speed == HCD_USB3 || !xhci->sw_lpm_support || ++ !udev->lpm_capable) ++ return 0; ++ ++ /* we only support lpm for non-hub device connected to root hub yet */ ++ if (!udev->parent || udev->parent->parent || ++ udev->descriptor.bDeviceClass == USB_CLASS_HUB) ++ return 0; ++ ++ if (xhci->hw_lpm_support == 1 && ++ xhci_check_usb2_port_capability( ++ xhci, portnum, XHCI_HLC)) { ++ udev->usb2_hw_lpm_capable = 1; ++ udev->l1_params.timeout = XHCI_L1_TIMEOUT; ++ udev->l1_params.besl = XHCI_DEFAULT_BESL; ++ if (xhci_check_usb2_port_capability(xhci, portnum, ++ XHCI_BLC)) ++ udev->usb2_hw_lpm_besl_capable = 1; + } + + return 0; +diff --git a/include/linux/usb.h b/include/linux/usb.h +index 1f7d63f3ab8b..0ffae80ab1e5 100644 +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -485,7 +485,8 @@ struct usb3_lpm_parameters { + * @lpm_capable: device supports LPM + * @usb2_hw_lpm_capable: device can perform USB2 hardware LPM + * @usb2_hw_lpm_besl_capable: device can perform USB2 hardware BESL LPM +- * @usb2_hw_lpm_enabled: USB2 hardware LPM enabled ++ * @usb2_hw_lpm_enabled: USB2 hardware LPM is enabled ++ * @usb2_hw_lpm_allowed: Userspace allows USB 2.0 LPM to be enabled + * @usb3_lpm_enabled: USB3 hardware LPM enabled + * @string_langid: language ID for strings + * @product: iProduct string, if present (static) +@@ -558,6 +559,7 @@ struct usb_device { + unsigned usb2_hw_lpm_capable:1; + unsigned usb2_hw_lpm_besl_capable:1; + unsigned usb2_hw_lpm_enabled:1; ++ unsigned usb2_hw_lpm_allowed:1; + unsigned usb3_lpm_enabled:1; + int string_langid; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0009-drm-i915-quirk-away-phantom-LVDS-on-Intel-s-D525MW-m.patch b/patches.baytrail/0009-drm-i915-quirk-away-phantom-LVDS-on-Intel-s-D525MW-m.patch new file mode 100644 index 000000000000..377bc9ad5628 --- /dev/null +++ b/patches.baytrail/0009-drm-i915-quirk-away-phantom-LVDS-on-Intel-s-D525MW-m.patch @@ -0,0 +1,46 @@ +From 2bac0d1c1ad07da04531d4fb59c0677fd7bd8db3 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Wed, 3 Jul 2013 15:05:05 -0700 +Subject: drm/i915: quirk away phantom LVDS on Intel's D525MW mainboard + +This replaceable mainboard only has a VGA-out, yet it claims to also have +a connected LVDS header. + +Addresses https://bugs.freedesktop.org/show_bug.cgi?id=65256 + +Signed-off-by: Jani Nikula +Reported-by: Cornel Panceac +Cc: Chris Wilson +Cc: +Acked-by: Daniel Vetter +Cc: Greg KH +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +(cherry picked from commit dcf6d294830d46b0e6901477fb4bf455281d90c8) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_lvds.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index f77d42f74427..b52f5cc7610b 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -893,6 +893,14 @@ static const struct dmi_system_id intel_no_lvds[] = { + DMI_EXACT_MATCH(DMI_BOARD_NAME, "D510MO"), + }, + }, ++ { ++ .callback = intel_no_lvds_dmi_callback, ++ .ident = "Intel D525MW", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Intel"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"), ++ }, ++ }, + + { } /* terminating entry */ + }; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0010-drm-i915-don-t-enable-the-plane-too-early-in-i9xx_cr.patch b/patches.baytrail/0010-drm-i915-don-t-enable-the-plane-too-early-in-i9xx_cr.patch new file mode 100644 index 000000000000..5b0ab6ab1fe9 --- /dev/null +++ b/patches.baytrail/0010-drm-i915-don-t-enable-the-plane-too-early-in-i9xx_cr.patch @@ -0,0 +1,32 @@ +From e00ba0d23f5dd0bd4535c4e72c75391346bb9a55 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 11 Apr 2013 16:29:07 +0200 +Subject: drm/i915: don't enable the plane too early in i9xx_crtc_mode_set + +This is horrible lore and we should be able to get rid of it now +that the lvds/pfit handling code actually does the right thing. + +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit d59f9f4d68ca82985a3b4578caa0485a9cb2b71b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index c714d4d5bedb..4edf527f1899 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4745,8 +4745,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + + i9xx_set_pipeconf(intel_crtc); + +- intel_enable_pipe(dev_priv, pipe, false); +- + intel_wait_for_vblank(dev, pipe); + + I915_WRITE(DSPCNTR(plane), dspcntr); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0011-drm-i915-drop-redundant-vblank-waits.patch b/patches.baytrail/0011-drm-i915-drop-redundant-vblank-waits.patch new file mode 100644 index 000000000000..b96d529cce7d --- /dev/null +++ b/patches.baytrail/0011-drm-i915-drop-redundant-vblank-waits.patch @@ -0,0 +1,40 @@ +From 162cd921a7f0108629be8c9bd045e49fc72b5ac2 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 11 Apr 2013 16:29:08 +0200 +Subject: drm/i915: drop redundant vblank waits + +Just blows through 50ms for naught, since the pipe is off. + +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 4667730163a6d0afb04cefae9805ca1cdad1df46) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 4edf527f1899..29675a78034e 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4745,8 +4745,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + + i9xx_set_pipeconf(intel_crtc); + +- intel_wait_for_vblank(dev, pipe); +- + I915_WRITE(DSPCNTR(plane), dspcntr); + POSTING_READ(DSPCNTR(plane)); + +@@ -5716,8 +5714,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + + ironlake_set_pipeconf(crtc, adjusted_mode, dither); + +- intel_wait_for_vblank(dev, pipe); +- + /* Set up the display plane register */ + I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE); + POSTING_READ(DSPCNTR(plane)); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0012-drm-i915-add-pipe-asserts-for-the-crtc-enable-sequen.patch b/patches.baytrail/0012-drm-i915-add-pipe-asserts-for-the-crtc-enable-sequen.patch new file mode 100644 index 000000000000..d1203b80de82 --- /dev/null +++ b/patches.baytrail/0012-drm-i915-add-pipe-asserts-for-the-crtc-enable-sequen.patch @@ -0,0 +1,45 @@ +From 51e43bae1aca2e0d51c5d71d7a5cf87e6896930c Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 11 Apr 2013 16:29:09 +0200 +Subject: drm/i915: add pipe asserts for the crtc enable sequence + +The i9xx modeset sequence is currently pretty fishy, so tight it all +up with some good assert-sprinkling. + +We already have good coverage on the disable side, but the enable side +is spotty (since until recently it was wrong). + +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 58c6eaa24dbd8c97ef5f643324f087271aa79d64) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 29675a78034e..4575e6ebfb07 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1474,6 +1474,8 @@ static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) + int reg; + u32 val; + ++ assert_pipe_disabled(dev_priv, pipe); ++ + /* No really, not for ILK+ */ + BUG_ON(!IS_VALLEYVIEW(dev_priv->dev) && dev_priv->info->gen >= 5); + +@@ -1835,6 +1837,9 @@ static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, + int reg; + u32 val; + ++ assert_planes_disabled(dev_priv, pipe); ++ assert_sprites_disabled(dev_priv, pipe); ++ + if (HAS_PCH_LPT(dev_priv->dev)) + pch_transcoder = TRANSCODER_A; + else +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0013-drm-i915-add-i9xx-pfit-pipe-asserts.patch b/patches.baytrail/0013-drm-i915-add-i9xx-pfit-pipe-asserts.patch new file mode 100644 index 000000000000..e97dfab25af4 --- /dev/null +++ b/patches.baytrail/0013-drm-i915-add-i9xx-pfit-pipe-asserts.patch @@ -0,0 +1,39 @@ +From 09b415087bed853d41d688aa6e946468140314aa Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 11 Apr 2013 16:29:10 +0200 +Subject: drm/i915: add i9xx pfit pipe asserts + +We can only enable the pfit if the pipe is disabled. Ensure that this +is obeyed with a neat assert. + +Also check whether the pfit is off before enabling it - if not we've +lost track of things somewhere since the pfit is only ever used by the +lvds output. + +v2: Fix spell fail in the commit message pointed out by Ville&Jani. + +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit e29a18faaa18470f313b570fdf2d0f75c35e6cb2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_lvds.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index b52f5cc7610b..2379b5e404df 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -159,6 +159,9 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder) + if (HAS_PCH_SPLIT(dev) || !enc->pfit_control) + return; + ++ WARN_ON(I915_READ(PFIT_CONTROL) & PFIT_ENABLE); ++ assert_pipe_disabled(dev_priv, to_intel_crtc(encoder->base.crtc)->pipe); ++ + /* + * Enable automatic panel scaling so that non-native modes + * fill the screen. The panel fitter should only be +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0014-drm-i915-move-debug-output-back-to-the-right-place.patch b/patches.baytrail/0014-drm-i915-move-debug-output-back-to-the-right-place.patch new file mode 100644 index 000000000000..ee4c7e392d5d --- /dev/null +++ b/patches.baytrail/0014-drm-i915-move-debug-output-back-to-the-right-place.patch @@ -0,0 +1,50 @@ +From 404a76c54fbaf2ef4478a8aa880b8133f39fdf14 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 11 Apr 2013 19:49:07 +0200 +Subject: drm/i915: move debug output back to the right place + +When adding the pipe config computation step I've accidentally moved +this a bit away. Which momentarily confused me since the pipe config +step rejected some modesetting operations I expected and so left me +looking in vain for that debug output. + +v2: Move the debug output into the right function to prevent this from +happening again. + +v3: Make it compile (Ville). Also reorder the patch so that the two +bugfixes are first. + +Signed-off-by: Daniel Vetter +(cherry picked from commit e3641d3f77bb9aea8442dc25018d651d3a348d76) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 4575e6ebfb07..45ae32757212 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -7760,6 +7760,9 @@ intel_modeset_affected_pipes(struct drm_crtc *crtc, unsigned *modeset_pipes, + */ + *modeset_pipes &= 1 << intel_crtc->pipe; + *prepare_pipes &= 1 << intel_crtc->pipe; ++ ++ DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n", ++ *modeset_pipes, *prepare_pipes, *disable_pipes); + } + + static bool intel_crtc_in_use(struct drm_crtc *crtc) +@@ -7995,9 +7998,6 @@ static int __intel_set_mode(struct drm_crtc *crtc, + } + } + +- DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n", +- modeset_pipes, prepare_pipes, disable_pipes); +- + for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc) + intel_crtc_disable(&intel_crtc->base); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0015-drm-i915-Use-pipe_name-and-port_name-where-appropria.patch b/patches.baytrail/0015-drm-i915-Use-pipe_name-and-port_name-where-appropria.patch new file mode 100644 index 000000000000..2729eb1ce35e --- /dev/null +++ b/patches.baytrail/0015-drm-i915-Use-pipe_name-and-port_name-where-appropria.patch @@ -0,0 +1,44 @@ +From b4e0f9e940dfd6daff260cb0bcde58ef979acca4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 17 Apr 2013 17:48:47 +0300 +Subject: drm/i915: Use pipe_name() and port_name() where appropriate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Get rid of the few remaining open coded copies of +pipe_name() and port_name(). + +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 2582a8504dbdc80b6e16ac8dfd6a7f9d03bece73) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 45ae32757212..46697588377e 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4735,7 +4735,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + dspcntr |= DISPPLANE_SEL_PIPE_B; + } + +- DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); ++ DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe_name(pipe)); + drm_mode_debug_printmodeline(mode); + + intel_set_pipe_timings(intel_crtc, mode, adjusted_mode); +@@ -6121,7 +6121,7 @@ static void ironlake_write_eld(struct drm_connector *connector, + eldv |= IBX_ELD_VALIDB << 4; + eldv |= IBX_ELD_VALIDB << 8; + } else { +- DRM_DEBUG_DRIVER("ELD on port %c\n", 'A' + i); ++ DRM_DEBUG_DRIVER("ELD on port %c\n", port_name(i)); + eldv = IBX_ELD_VALIDB << ((i - 1) * 4); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0016-drm-i915-Use-port_name-in-PCH-port-audio-power-chang.patch b/patches.baytrail/0016-drm-i915-Use-port_name-in-PCH-port-audio-power-chang.patch new file mode 100644 index 000000000000..c9a79be5ead5 --- /dev/null +++ b/patches.baytrail/0016-drm-i915-Use-port_name-in-PCH-port-audio-power-chang.patch @@ -0,0 +1,56 @@ +From e1dfcd3d47c1413cea5c0f518ac2d4645a369c9f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 17 Apr 2013 17:48:48 +0300 +Subject: drm/i915: Use port_name() in PCH port audio power change message +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit cfc33bf75bfbf8f95bffe040ee1a5ab1cda8c34c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index c8d16a622f3c..c939df03b229 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -754,10 +754,12 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) + ibx_hpd_irq_setup(dev); + queue_work(dev_priv->wq, &dev_priv->hotplug_work); + } +- if (pch_iir & SDE_AUDIO_POWER_MASK) ++ if (pch_iir & SDE_AUDIO_POWER_MASK) { ++ int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK) >> ++ SDE_AUDIO_POWER_SHIFT); + DRM_DEBUG_DRIVER("PCH audio power change on port %d\n", +- (pch_iir & SDE_AUDIO_POWER_MASK) >> +- SDE_AUDIO_POWER_SHIFT); ++ port_name(port)); ++ } + + if (pch_iir & SDE_AUX_MASK) + dp_aux_irq_handler(dev); +@@ -803,10 +805,12 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) + ibx_hpd_irq_setup(dev); + queue_work(dev_priv->wq, &dev_priv->hotplug_work); + } +- if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) +- DRM_DEBUG_DRIVER("PCH audio power change on port %d\n", +- (pch_iir & SDE_AUDIO_POWER_MASK_CPT) >> +- SDE_AUDIO_POWER_SHIFT_CPT); ++ if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) { ++ int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >> ++ SDE_AUDIO_POWER_SHIFT_CPT); ++ DRM_DEBUG_DRIVER("PCH audio power change on port %c\n", ++ port_name(port)); ++ } + + if (pch_iir & SDE_AUX_MASK_CPT) + dp_aux_irq_handler(dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0017-drm-i915-Print-plane-pipe-port-names-as-alphabetical.patch b/patches.baytrail/0017-drm-i915-Print-plane-pipe-port-names-as-alphabetical.patch new file mode 100644 index 000000000000..6db8b1e954c2 --- /dev/null +++ b/patches.baytrail/0017-drm-i915-Print-plane-pipe-port-names-as-alphabetical.patch @@ -0,0 +1,276 @@ +From 7c11d755e2b99567be12f53a0fa45ec0a9ec6a4e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 17 Apr 2013 17:48:49 +0300 +Subject: drm/i915: Print plane, pipe, port names as alphabetical insted of + decimal +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Alway use the alphabetical names in debug/error messages for planes, +pipes and ports, instead of using decimal numbers occasionally. + +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 84f44ce795b3da9a08dc2041ecd60550d34c123e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 10 ++++----- + drivers/gpu/drm/i915/intel_display.c | 42 ++++++++++++++++++------------------ + drivers/gpu/drm/i915/intel_pm.c | 26 +++++++++++----------- + 3 files changed, 39 insertions(+), 39 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 16e674af4d57..3b798ae62075 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -748,8 +748,8 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc) + } + + if (num_encoders != 1) +- WARN(1, "%d encoders on crtc for pipe %d\n", num_encoders, +- intel_crtc->pipe); ++ WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders, ++ pipe_name(intel_crtc->pipe)); + + BUG_ON(ret == NULL); + return ret; +@@ -1047,8 +1047,8 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) + } + + } else { +- WARN(1, "Invalid encoder type %d for pipe %d\n", +- intel_encoder->type, pipe); ++ WARN(1, "Invalid encoder type %d for pipe %c\n", ++ intel_encoder->type, pipe_name(pipe)); + } + + I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp); +@@ -1148,7 +1148,7 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, + } + } + +- DRM_DEBUG_KMS("No pipe for ddi port %i found\n", port); ++ DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port)); + + return false; + } +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 46697588377e..8ce42fa31a55 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2101,7 +2101,7 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, + case 1: + break; + default: +- DRM_ERROR("Can't update plane %d in SAREA\n", plane); ++ DRM_ERROR("Can't update plane %c in SAREA\n", plane_name(plane)); + return -EINVAL; + } + +@@ -2198,7 +2198,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc, + case 2: + break; + default: +- DRM_ERROR("Can't update plane %d in SAREA\n", plane); ++ DRM_ERROR("Can't update plane %c in SAREA\n", plane_name(plane)); + return -EINVAL; + } + +@@ -2389,9 +2389,9 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, + } + + if (intel_crtc->plane > INTEL_INFO(dev)->num_pipes) { +- DRM_ERROR("no plane for crtc: plane %d, num_pipes %d\n", +- intel_crtc->plane, +- INTEL_INFO(dev)->num_pipes); ++ DRM_ERROR("no plane for crtc: plane %c, num_pipes %d\n", ++ plane_name(intel_crtc->plane), ++ INTEL_INFO(dev)->num_pipes); + return -EINVAL; + } + +@@ -3299,7 +3299,7 @@ static struct intel_pch_pll *intel_get_pch_pll(struct intel_crtc *intel_crtc, u3 + found: + intel_crtc->pch_pll = pll; + pll->refcount++; +- DRM_DEBUG_DRIVER("using pll %d for pipe %d\n", i, intel_crtc->pipe); ++ DRM_DEBUG_DRIVER("using pll %d for pipe %c\n", i, pipe_name(intel_crtc->pipe)); + prepare: /* separate function? */ + DRM_DEBUG_DRIVER("switching PLL %x off\n", pll->pll_reg); + +@@ -3324,7 +3324,7 @@ void intel_cpt_verify_modeset(struct drm_device *dev, int pipe) + udelay(500); + if (wait_for(I915_READ(dslreg) != temp, 5)) { + if (wait_for(I915_READ(dslreg) != temp, 5)) +- DRM_ERROR("mode set failed: pipe %d stuck\n", pipe); ++ DRM_ERROR("mode set failed: pipe %c stuck\n", pipe_name(pipe)); + } + } + +@@ -5356,11 +5356,11 @@ static bool ironlake_check_fdi_lanes(struct intel_crtc *intel_crtc) + struct intel_crtc *pipe_B_crtc = + to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_B]); + +- DRM_DEBUG_KMS("checking fdi config on pipe %i, lanes %i\n", +- intel_crtc->pipe, intel_crtc->fdi_lanes); ++ DRM_DEBUG_KMS("checking fdi config on pipe %c, lanes %i\n", ++ pipe_name(intel_crtc->pipe), intel_crtc->fdi_lanes); + if (intel_crtc->fdi_lanes > 4) { +- DRM_DEBUG_KMS("invalid fdi lane config on pipe %i: %i lanes\n", +- intel_crtc->pipe, intel_crtc->fdi_lanes); ++ DRM_DEBUG_KMS("invalid fdi lane config on pipe %c: %i lanes\n", ++ pipe_name(intel_crtc->pipe), intel_crtc->fdi_lanes); + /* Clamp lanes to avoid programming the hw with bogus values. */ + intel_crtc->fdi_lanes = 4; + +@@ -5376,8 +5376,8 @@ static bool ironlake_check_fdi_lanes(struct intel_crtc *intel_crtc) + case PIPE_B: + if (dev_priv->pipe_to_crtc_mapping[PIPE_C]->enabled && + intel_crtc->fdi_lanes > 2) { +- DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %i: %i lanes\n", +- intel_crtc->pipe, intel_crtc->fdi_lanes); ++ DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n", ++ pipe_name(intel_crtc->pipe), intel_crtc->fdi_lanes); + /* Clamp lanes to avoid programming the hw with bogus values. */ + intel_crtc->fdi_lanes = 2; + +@@ -5393,8 +5393,8 @@ static bool ironlake_check_fdi_lanes(struct intel_crtc *intel_crtc) + case PIPE_C: + if (!pipe_B_crtc->base.enabled || pipe_B_crtc->fdi_lanes <= 2) { + if (intel_crtc->fdi_lanes > 2) { +- DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %i: %i lanes\n", +- intel_crtc->pipe, intel_crtc->fdi_lanes); ++ DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n", ++ pipe_name(intel_crtc->pipe), intel_crtc->fdi_lanes); + /* Clamp lanes to avoid programming the hw with bogus values. */ + intel_crtc->fdi_lanes = 2; + +@@ -5659,7 +5659,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + dpll = ironlake_compute_dpll(intel_crtc, &clock, &fp, &reduced_clock, + has_reduced_clock ? &fp2 : NULL); + +- DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe); ++ DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe_name(pipe)); + drm_mode_debug_printmodeline(mode); + + /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ +@@ -5668,8 +5668,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + + pll = intel_get_pch_pll(intel_crtc, dpll, fp); + if (pll == NULL) { +- DRM_DEBUG_DRIVER("failed to find PLL for pipe %d\n", +- pipe); ++ DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", ++ pipe_name(pipe)); + return -EINVAL; + } + } else +@@ -5833,7 +5833,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + /* determine panel color depth */ + dither = intel_crtc->config.dither; + +- DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe); ++ DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe_name(pipe)); + drm_mode_debug_printmodeline(mode); + + if (intel_crtc->config.has_dp_encoder) +@@ -9106,8 +9106,8 @@ void intel_modeset_init(struct drm_device *dev) + for (j = 0; j < dev_priv->num_plane; j++) { + ret = intel_plane_init(dev, i, j); + if (ret) +- DRM_DEBUG_KMS("pipe %d plane %d init failed: %d\n", +- i, j, ret); ++ DRM_DEBUG_KMS("pipe %c plane %d init failed: %d\n", ++ pipe_name(i), j, ret); + } + } + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 94ad6bc08260..f10a9b6758cb 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -113,8 +113,8 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + fbc_ctl |= obj->fence_reg; + I915_WRITE(FBC_CONTROL, fbc_ctl); + +- DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %d, ", +- cfb_pitch, crtc->y, intel_crtc->plane); ++ DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %c, ", ++ cfb_pitch, crtc->y, plane_name(intel_crtc->plane)); + } + + static bool i8xx_fbc_enabled(struct drm_device *dev) +@@ -148,7 +148,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + /* enable it... */ + I915_WRITE(DPFC_CONTROL, I915_READ(DPFC_CONTROL) | DPFC_CTL_EN); + +- DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); ++ DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane)); + } + + static void g4x_disable_fbc(struct drm_device *dev) +@@ -228,7 +228,7 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + sandybridge_blit_fbc_update(dev); + } + +- DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); ++ DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane)); + } + + static void ironlake_disable_fbc(struct drm_device *dev) +@@ -2146,15 +2146,15 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, + &sandybridge_display_wm_info, + latency, &sprite_wm); + if (!ret) { +- DRM_DEBUG_KMS("failed to compute sprite wm for pipe %d\n", +- pipe); ++ DRM_DEBUG_KMS("failed to compute sprite wm for pipe %c\n", ++ pipe_name(pipe)); + return; + } + + val = I915_READ(reg); + val &= ~WM0_PIPE_SPRITE_MASK; + I915_WRITE(reg, val | (sprite_wm << WM0_PIPE_SPRITE_SHIFT)); +- DRM_DEBUG_KMS("sprite watermarks For pipe %d - %d\n", pipe, sprite_wm); ++ DRM_DEBUG_KMS("sprite watermarks For pipe %c - %d\n", pipe_name(pipe), sprite_wm); + + + ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, +@@ -2163,8 +2163,8 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, + SNB_READ_WM1_LATENCY() * 500, + &sprite_wm); + if (!ret) { +- DRM_DEBUG_KMS("failed to compute sprite lp1 wm on pipe %d\n", +- pipe); ++ DRM_DEBUG_KMS("failed to compute sprite lp1 wm on pipe %c\n", ++ pipe_name(pipe)); + return; + } + I915_WRITE(WM1S_LP_ILK, sprite_wm); +@@ -2179,8 +2179,8 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, + SNB_READ_WM2_LATENCY() * 500, + &sprite_wm); + if (!ret) { +- DRM_DEBUG_KMS("failed to compute sprite lp2 wm on pipe %d\n", +- pipe); ++ DRM_DEBUG_KMS("failed to compute sprite lp2 wm on pipe %c\n", ++ pipe_name(pipe)); + return; + } + I915_WRITE(WM2S_LP_IVB, sprite_wm); +@@ -2191,8 +2191,8 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, + SNB_READ_WM3_LATENCY() * 500, + &sprite_wm); + if (!ret) { +- DRM_DEBUG_KMS("failed to compute sprite lp3 wm on pipe %d\n", +- pipe); ++ DRM_DEBUG_KMS("failed to compute sprite lp3 wm on pipe %c\n", ++ pipe_name(pipe)); + return; + } + I915_WRITE(WM3S_LP_IVB, sprite_wm); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0018-drm-i915-Use-alphabetical-names-for-transcoders-too.patch b/patches.baytrail/0018-drm-i915-Use-alphabetical-names-for-transcoders-too.patch new file mode 100644 index 000000000000..b51b43c050a0 --- /dev/null +++ b/patches.baytrail/0018-drm-i915-Use-alphabetical-names-for-transcoders-too.patch @@ -0,0 +1,64 @@ +From eea78c3f9820f0933e8b2f325aeb5d4a8d075890 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 17 Apr 2013 17:48:50 +0300 +Subject: drm/i915: Use alphabetical names for transcoders too +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Print the alphabetical name for transcoders. The code already used the +pipe_name() macro for transcoders, so I did the same. But we do have the +(unused) transcoder_name() macro which could be used instead. + +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 4bb6f1f3270923cdcd57293ea736955d5c35db72) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 8ce42fa31a55..518c507998a6 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1097,14 +1097,14 @@ static void assert_pch_pll(struct drm_i915_private *dev_priv, + pch_dpll = I915_READ(PCH_DPLL_SEL); + cur_state = pll->pll_reg == _PCH_DPLL_B; + if (!WARN(((pch_dpll >> (4 * crtc->pipe)) & 1) != cur_state, +- "PLL[%d] not attached to this transcoder %d: %08x\n", +- cur_state, crtc->pipe, pch_dpll)) { ++ "PLL[%d] not attached to this transcoder %c: %08x\n", ++ cur_state, pipe_name(crtc->pipe), pch_dpll)) { + cur_state = !!(val >> (4*crtc->pipe + 3)); + WARN(cur_state != state, +- "PLL[%d] not %s on this transcoder %d: %08x\n", ++ "PLL[%d] not %s on this transcoder %c: %08x\n", + pll->pll_reg == _PCH_DPLL_B, + state_string(state), +- crtc->pipe, ++ pipe_name(crtc->pipe), + val); + } + } +@@ -1733,7 +1733,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, + + I915_WRITE(reg, val | TRANS_ENABLE); + if (wait_for(I915_READ(reg) & TRANS_STATE_ENABLE, 100)) +- DRM_ERROR("failed to enable transcoder %d\n", pipe); ++ DRM_ERROR("failed to enable transcoder %c\n", pipe_name(pipe)); + } + + static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv, +@@ -1786,7 +1786,7 @@ static void ironlake_disable_pch_transcoder(struct drm_i915_private *dev_priv, + I915_WRITE(reg, val); + /* wait for PCH transcoder off, transcoder state */ + if (wait_for((I915_READ(reg) & TRANS_STATE_ENABLE) == 0, 50)) +- DRM_ERROR("failed to disable transcoder %d\n", pipe); ++ DRM_ERROR("failed to disable transcoder %c\n", pipe_name(pipe)); + + if (!HAS_PCH_IBX(dev)) { + /* Workaround: Clear the timing override chicken bit again. */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0019-drm-i915-Use-alphabetical-names-for-sprites.patch b/patches.baytrail/0019-drm-i915-Use-alphabetical-names-for-sprites.patch new file mode 100644 index 000000000000..22567c0c9ac1 --- /dev/null +++ b/patches.baytrail/0019-drm-i915-Use-alphabetical-names-for-sprites.patch @@ -0,0 +1,66 @@ +From 9676fc9bb083f73bb2deefa3be3ef237b344a51e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 17 Apr 2013 17:48:51 +0300 +Subject: drm/i915: Use alphabetical names for sprites +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add sprite_name() macro which should be used with the kind of sprites +that are fixed to pipes (gen4.5+). + +Also use dev_priv->num_plane to calculate the sprite index insted +assuming two sprites per pipe. This should make it print the right +name. + +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 06da8da2b014d6cc98fa86e72b605e525e6d6884) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 ++ + drivers/gpu/drm/i915/intel_display.c | 8 ++++---- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 47d8b68c5004..989d9a2d8bff 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -76,6 +76,8 @@ enum plane { + }; + #define plane_name(p) ((p) + 'A') + ++#define sprite_name(p, s) ((p) * dev_priv->num_plane + (s) + 'A') ++ + enum port { + PORT_A = 0, + PORT_B, +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 518c507998a6..bda32c4ebf58 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1302,8 +1302,8 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv, + reg = SPCNTR(pipe, i); + val = I915_READ(reg); + WARN((val & SP_ENABLE), +- "sprite %d assertion failure, should be off on pipe %c but is still active\n", +- pipe * 2 + i, pipe_name(pipe)); ++ "sprite %c assertion failure, should be off on pipe %c but is still active\n", ++ sprite_name(pipe, i), pipe_name(pipe)); + } + } + +@@ -9106,8 +9106,8 @@ void intel_modeset_init(struct drm_device *dev) + for (j = 0; j < dev_priv->num_plane; j++) { + ret = intel_plane_init(dev, i, j); + if (ret) +- DRM_DEBUG_KMS("pipe %c plane %d init failed: %d\n", +- pipe_name(i), j, ret); ++ DRM_DEBUG_KMS("pipe %c sprite %c init failed: %d\n", ++ pipe_name(i), sprite_name(i, j), ret); + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0020-drm-i915-VLV-GPU-frequency-to-opcode-functions.patch b/patches.baytrail/0020-drm-i915-VLV-GPU-frequency-to-opcode-functions.patch new file mode 100644 index 000000000000..55af872df7a3 --- /dev/null +++ b/patches.baytrail/0020-drm-i915-VLV-GPU-frequency-to-opcode-functions.patch @@ -0,0 +1,99 @@ +From 635708d73aec306534b98f6cda53b8049c14fc08 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Wed, 17 Apr 2013 15:54:57 -0700 +Subject: drm/i915: VLV GPU frequency to opcode functions + +When requesting frequency changes or querying status from the Punit, we +need to use an opcode that corresponds to the frequency, taking into +account the memory frequency. + +Signed-off-by: Jesse Barnes +Acked-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 855ba3be12badf6228151ca3ccf54632cfdd463d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 ++ + drivers/gpu/drm/i915/intel_pm.c | 56 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 58 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 989d9a2d8bff..3be035a8a7b1 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1891,6 +1891,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) + int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val); + int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val); + int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val); ++int vlv_gpu_freq(int ddr_freq, int val); ++int vlv_freq_opcode(int ddr_freq, int val); + + #define __i915_read(x, y) \ + u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg); +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index f10a9b6758cb..746990fd1bd4 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4655,3 +4655,59 @@ int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) + { + return vlv_punit_rw(dev_priv, PUNIT_OPCODE_REG_WRITE, addr, &val); + } ++ ++int vlv_gpu_freq(int ddr_freq, int val) ++{ ++ int mult, base; ++ ++ switch (ddr_freq) { ++ case 800: ++ mult = 20; ++ base = 120; ++ break; ++ case 1066: ++ mult = 22; ++ base = 133; ++ break; ++ case 1333: ++ mult = 21; ++ base = 125; ++ break; ++ default: ++ return -1; ++ } ++ ++ return ((val - 0xbd) * mult) + base; ++} ++ ++int vlv_freq_opcode(int ddr_freq, int val) ++{ ++ int mult, base; ++ ++ switch (ddr_freq) { ++ case 800: ++ mult = 20; ++ base = 120; ++ break; ++ case 1066: ++ mult = 22; ++ base = 133; ++ break; ++ case 1333: ++ mult = 21; ++ base = 125; ++ break; ++ default: ++ return -1; ++ } ++ ++ val /= mult; ++ val -= base / mult; ++ val += 0xbd; ++ ++ if (val > 0xea) ++ val = 0xea; ++ ++ return val; ++} ++ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0021-drm-i915-turbo-RC6-support-for-VLV-v7.patch b/patches.baytrail/0021-drm-i915-turbo-RC6-support-for-VLV-v7.patch new file mode 100644 index 000000000000..37aba6da5356 --- /dev/null +++ b/patches.baytrail/0021-drm-i915-turbo-RC6-support-for-VLV-v7.patch @@ -0,0 +1,627 @@ +From e6eabe75b201ee1221b5004ac98a4c9f1a8bdbaf Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Wed, 17 Apr 2013 15:54:58 -0700 +Subject: drm/i915: turbo & RC6 support for VLV v7 + +Uses slightly different interfaces than other platforms. + +v2: track actual set freq, not requested (Rohit) + fix debug prints in init code (Jesse) +v3: don't write sleep reg (Jesse) + re-add RC6 wake limit write (Ben) + fixup thresholds to match other platforms (Ben) + clean up mem freq calculation (Ben) + clean up debug prints (Ben) +v4: move defines from punit patch (Ville) +v5: remove writes to nonexistent regs (Jesse) + put RP and RC regs together (Jesse) + fix RC6 enable (Jesse) +v6: use correct fuse reads from NC (Jesse) + split out min/max funcs for use in sysfs (Jesse) + add debugfs & sysfs freq controls (Jesse) +v7: update with Ben's hw_max changes (Jesse) + +Signed-off-by: Jesse Barnes +Reviewed-by: Ben Widawsky (v6) +[danvet: Follow checkpatch sugggestion to use min_t to avoid casting +fun.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 0a073b843bcd9a660f76e497182aac97cafddc4c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 58 +++++++++-- + drivers/gpu/drm/i915/i915_drv.h | 5 + + drivers/gpu/drm/i915/i915_irq.c | 5 +- + drivers/gpu/drm/i915/i915_reg.h | 21 ++++ + drivers/gpu/drm/i915/i915_sysfs.c | 71 +++++++++---- + drivers/gpu/drm/i915/intel_pm.c | 199 ++++++++++++++++++++++++++++++++++-- + 6 files changed, 320 insertions(+), 39 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index e913d325d5b8..367b534d2260 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -941,7 +941,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) + MEMSTAT_VID_SHIFT); + seq_printf(m, "Current P-state: %d\n", + (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); +- } else if (IS_GEN6(dev) || IS_GEN7(dev)) { ++ } else if ((IS_GEN6(dev) || IS_GEN7(dev)) && !IS_VALLEYVIEW(dev)) { + u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); + u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS); + u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); +@@ -1009,6 +1009,25 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) + + seq_printf(m, "Max overclocked frequency: %dMHz\n", + dev_priv->rps.hw_max * GT_FREQUENCY_MULTIPLIER); ++ } else if (IS_VALLEYVIEW(dev)) { ++ u32 freq_sts, val; ++ ++ valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, ++ &freq_sts); ++ seq_printf(m, "PUNIT_REG_GPU_FREQ_STS: 0x%08x\n", freq_sts); ++ seq_printf(m, "DDR freq: %d MHz\n", dev_priv->mem_freq); ++ ++ valleyview_punit_read(dev_priv, PUNIT_FUSE_BUS1, &val); ++ seq_printf(m, "max GPU freq: %d MHz\n", ++ vlv_gpu_freq(dev_priv->mem_freq, val)); ++ ++ valleyview_punit_read(dev_priv, PUNIT_REG_GPU_LFM, &val); ++ seq_printf(m, "min GPU freq: %d MHz\n", ++ vlv_gpu_freq(dev_priv->mem_freq, val)); ++ ++ seq_printf(m, "current GPU freq: %d MHz\n", ++ vlv_gpu_freq(dev_priv->mem_freq, ++ (freq_sts >> 8) & 0xff)); + } else { + seq_printf(m, "no P-state info available\n"); + } +@@ -1812,7 +1831,11 @@ i915_max_freq_get(void *data, u64 *val) + if (ret) + return ret; + +- *val = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER; ++ if (IS_VALLEYVIEW(dev)) ++ *val = vlv_gpu_freq(dev_priv->mem_freq, ++ dev_priv->rps.max_delay); ++ else ++ *val = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER; + mutex_unlock(&dev_priv->rps.hw_lock); + + return 0; +@@ -1837,9 +1860,16 @@ i915_max_freq_set(void *data, u64 val) + /* + * Turbo will still be enabled, but won't go above the set value. + */ +- do_div(val, GT_FREQUENCY_MULTIPLIER); +- dev_priv->rps.max_delay = val; +- gen6_set_rps(dev, val); ++ if (IS_VALLEYVIEW(dev)) { ++ val = vlv_freq_opcode(dev_priv->mem_freq, val); ++ dev_priv->rps.max_delay = val; ++ gen6_set_rps(dev, val); ++ } else { ++ do_div(val, GT_FREQUENCY_MULTIPLIER); ++ dev_priv->rps.max_delay = val; ++ gen6_set_rps(dev, val); ++ } ++ + mutex_unlock(&dev_priv->rps.hw_lock); + + return 0; +@@ -1863,7 +1893,11 @@ i915_min_freq_get(void *data, u64 *val) + if (ret) + return ret; + +- *val = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER; ++ if (IS_VALLEYVIEW(dev)) ++ *val = vlv_gpu_freq(dev_priv->mem_freq, ++ dev_priv->rps.min_delay); ++ else ++ *val = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER; + mutex_unlock(&dev_priv->rps.hw_lock); + + return 0; +@@ -1888,9 +1922,15 @@ i915_min_freq_set(void *data, u64 val) + /* + * Turbo will still be enabled, but won't go below the set value. + */ +- do_div(val, GT_FREQUENCY_MULTIPLIER); +- dev_priv->rps.min_delay = val; +- gen6_set_rps(dev, val); ++ if (IS_VALLEYVIEW(dev)) { ++ val = vlv_freq_opcode(dev_priv->mem_freq, val); ++ dev_priv->rps.min_delay = val; ++ valleyview_set_rps(dev, val); ++ } else { ++ do_div(val, GT_FREQUENCY_MULTIPLIER); ++ dev_priv->rps.min_delay = val; ++ gen6_set_rps(dev, val); ++ } + mutex_unlock(&dev_priv->rps.hw_lock); + + return 0; +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 3be035a8a7b1..b32a0b18f003 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1860,6 +1860,9 @@ extern void intel_disable_fbc(struct drm_device *dev); + extern bool ironlake_set_drps(struct drm_device *dev, u8 val); + extern void intel_init_pch_refclk(struct drm_device *dev); + extern void gen6_set_rps(struct drm_device *dev, u8 val); ++extern void valleyview_set_rps(struct drm_device *dev, u8 val); ++extern int valleyview_rps_max_freq(struct drm_i915_private *dev_priv); ++extern int valleyview_rps_min_freq(struct drm_i915_private *dev_priv); + extern void intel_detect_pch(struct drm_device *dev); + extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); + extern int intel_enable_rc6(const struct drm_device *dev); +@@ -1891,6 +1894,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) + int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val); + int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val); + int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val); ++int valleyview_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val); ++ + int vlv_gpu_freq(int ddr_freq, int val); + int vlv_freq_opcode(int ddr_freq, int val); + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index c939df03b229..11a8f81a7fd1 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -473,7 +473,10 @@ static void gen6_pm_rps_work(struct work_struct *work) + */ + if (!(new_delay > dev_priv->rps.max_delay || + new_delay < dev_priv->rps.min_delay)) { +- gen6_set_rps(dev_priv->dev, new_delay); ++ if (IS_VALLEYVIEW(dev_priv->dev)) ++ valleyview_set_rps(dev_priv->dev, new_delay); ++ else ++ gen6_set_rps(dev_priv->dev, new_delay); + } + + mutex_unlock(&dev_priv->rps.hw_lock); +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index b1a0cdba59e7..acf0608cc761 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -4315,6 +4315,7 @@ + #define GEN6_RC_CTL_RC6_ENABLE (1<<18) + #define GEN6_RC_CTL_RC1e_ENABLE (1<<20) + #define GEN6_RC_CTL_RC7_ENABLE (1<<22) ++#define GEN7_RC_CTL_TO_MODE (1<<28) + #define GEN6_RC_CTL_EI_MODE(x) ((x)<<27) + #define GEN6_RC_CTL_HW_ENABLE (1<<31) + #define GEN6_RP_DOWN_TIMEOUT 0xA010 +@@ -4406,12 +4407,32 @@ + #define IOSF_BAR_SHIFT 1 + #define IOSF_SB_BUSY (1<<0) + #define IOSF_PORT_PUNIT 0x4 ++#define IOSF_PORT_NC 0x11 + #define VLV_IOSF_DATA 0x182104 + #define VLV_IOSF_ADDR 0x182108 + + #define PUNIT_OPCODE_REG_READ 6 + #define PUNIT_OPCODE_REG_WRITE 7 + ++#define PUNIT_REG_GPU_LFM 0xd3 ++#define PUNIT_REG_GPU_FREQ_REQ 0xd4 ++#define PUNIT_REG_GPU_FREQ_STS 0xd8 ++#define PUNIT_REG_MEDIA_TURBO_FREQ_REQ 0xdc ++ ++#define PUNIT_FUSE_BUS2 0xf6 /* bits 47:40 */ ++#define PUNIT_FUSE_BUS1 0xf5 /* bits 55:48 */ ++ ++#define IOSF_NC_FB_GFX_FREQ_FUSE 0x1c ++#define FB_GFX_MAX_FREQ_FUSE_SHIFT 3 ++#define FB_GFX_MAX_FREQ_FUSE_MASK 0x000007f8 ++#define FB_GFX_FGUARANTEED_FREQ_FUSE_SHIFT 11 ++#define FB_GFX_FGUARANTEED_FREQ_FUSE_MASK 0x0007f800 ++#define IOSF_NC_FB_GFX_FMAX_FUSE_HI 0x34 ++#define FB_FMAX_VMIN_FREQ_HI_MASK 0x00000007 ++#define IOSF_NC_FB_GFX_FMAX_FUSE_LO 0x30 ++#define FB_FMAX_VMIN_FREQ_LO_SHIFT 27 ++#define FB_FMAX_VMIN_FREQ_LO_MASK 0xf8000000 ++ + #define GEN6_GT_CORE_STATUS 0x138060 + #define GEN6_CORE_CPD_STATE_MASK (7<<4) + #define GEN6_RCn_MASK 7 +diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c +index d5e1890678f9..ca00df2de07b 100644 +--- a/drivers/gpu/drm/i915/i915_sysfs.c ++++ b/drivers/gpu/drm/i915/i915_sysfs.c +@@ -212,7 +212,10 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev, + int ret; + + mutex_lock(&dev_priv->rps.hw_lock); +- ret = dev_priv->rps.cur_delay * GT_FREQUENCY_MULTIPLIER; ++ if (IS_VALLEYVIEW(dev_priv->dev)) ++ ret = vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.cur_delay); ++ else ++ ret = dev_priv->rps.cur_delay * GT_FREQUENCY_MULTIPLIER; + mutex_unlock(&dev_priv->rps.hw_lock); + + return snprintf(buf, PAGE_SIZE, "%d\n", ret); +@@ -226,7 +229,10 @@ static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute + int ret; + + mutex_lock(&dev_priv->rps.hw_lock); +- ret = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER; ++ if (IS_VALLEYVIEW(dev_priv->dev)) ++ ret = vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.max_delay); ++ else ++ ret = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER; + mutex_unlock(&dev_priv->rps.hw_lock); + + return snprintf(buf, PAGE_SIZE, "%d\n", ret); +@@ -246,16 +252,25 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, + if (ret) + return ret; + +- val /= GT_FREQUENCY_MULTIPLIER; +- + mutex_lock(&dev_priv->rps.hw_lock); + +- rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); +- hw_max = dev_priv->rps.hw_max; +- non_oc_max = (rp_state_cap & 0xff); +- hw_min = ((rp_state_cap & 0xff0000) >> 16); ++ if (IS_VALLEYVIEW(dev_priv->dev)) { ++ val = vlv_freq_opcode(dev_priv->mem_freq, val); ++ ++ hw_max = valleyview_rps_max_freq(dev_priv); ++ hw_min = valleyview_rps_min_freq(dev_priv); ++ non_oc_max = hw_max; ++ } else { ++ val /= GT_FREQUENCY_MULTIPLIER; + +- if (val < hw_min || val > hw_max || val < dev_priv->rps.min_delay) { ++ rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); ++ hw_max = dev_priv->rps.hw_max; ++ non_oc_max = (rp_state_cap & 0xff); ++ hw_min = ((rp_state_cap & 0xff0000) >> 16); ++ } ++ ++ if (val < hw_min || val > hw_max || ++ val < dev_priv->rps.min_delay) { + mutex_unlock(&dev_priv->rps.hw_lock); + return -EINVAL; + } +@@ -264,8 +279,12 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, + DRM_DEBUG("User requested overclocking to %d\n", + val * GT_FREQUENCY_MULTIPLIER); + +- if (dev_priv->rps.cur_delay > val) +- gen6_set_rps(dev_priv->dev, val); ++ if (dev_priv->rps.cur_delay > val) { ++ if (IS_VALLEYVIEW(dev_priv->dev)) ++ valleyview_set_rps(dev_priv->dev, val); ++ else ++ gen6_set_rps(dev_priv->dev, val); ++ } + + dev_priv->rps.max_delay = val; + +@@ -282,7 +301,10 @@ static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute + int ret; + + mutex_lock(&dev_priv->rps.hw_lock); +- ret = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER; ++ if (IS_VALLEYVIEW(dev_priv->dev)) ++ ret = vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.min_delay); ++ else ++ ret = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER; + mutex_unlock(&dev_priv->rps.hw_lock); + + return snprintf(buf, PAGE_SIZE, "%d\n", ret); +@@ -302,21 +324,32 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, + if (ret) + return ret; + +- val /= GT_FREQUENCY_MULTIPLIER; +- + mutex_lock(&dev_priv->rps.hw_lock); + +- rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); +- hw_max = dev_priv->rps.hw_max; +- hw_min = ((rp_state_cap & 0xff0000) >> 16); ++ if (IS_VALLEYVIEW(dev)) { ++ val = vlv_freq_opcode(dev_priv->mem_freq, val); ++ ++ hw_max = valleyview_rps_max_freq(dev_priv); ++ hw_min = valleyview_rps_min_freq(dev_priv); ++ } else { ++ val /= GT_FREQUENCY_MULTIPLIER; ++ ++ rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); ++ hw_max = dev_priv->rps.hw_max; ++ hw_min = ((rp_state_cap & 0xff0000) >> 16); ++ } + + if (val < hw_min || val > hw_max || val > dev_priv->rps.max_delay) { + mutex_unlock(&dev_priv->rps.hw_lock); + return -EINVAL; + } + +- if (dev_priv->rps.cur_delay < val) +- gen6_set_rps(dev_priv->dev, val); ++ if (dev_priv->rps.cur_delay < val) { ++ if (IS_VALLEYVIEW(dev)) ++ valleyview_set_rps(dev, val); ++ else ++ gen6_set_rps(dev_priv->dev, val); ++ } + + dev_priv->rps.min_delay = val; + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 746990fd1bd4..ca43c4e33c45 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2481,6 +2481,52 @@ void gen6_set_rps(struct drm_device *dev, u8 val) + trace_intel_gpu_freq_change(val * 50); + } + ++void valleyview_set_rps(struct drm_device *dev, u8 val) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ unsigned long timeout = jiffies + msecs_to_jiffies(10); ++ u32 limits = gen6_rps_limits(dev_priv, &val); ++ u32 pval; ++ ++ WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); ++ WARN_ON(val > dev_priv->rps.max_delay); ++ WARN_ON(val < dev_priv->rps.min_delay); ++ ++ DRM_DEBUG_DRIVER("gpu freq request from %d to %d\n", ++ vlv_gpu_freq(dev_priv->mem_freq, ++ dev_priv->rps.cur_delay), ++ vlv_gpu_freq(dev_priv->mem_freq, val)); ++ ++ if (val == dev_priv->rps.cur_delay) ++ return; ++ ++ valleyview_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); ++ ++ do { ++ valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &pval); ++ if (time_after(jiffies, timeout)) { ++ DRM_DEBUG_DRIVER("timed out waiting for Punit\n"); ++ break; ++ } ++ udelay(10); ++ } while (pval & 1); ++ ++ valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &pval); ++ if ((pval >> 8) != val) ++ DRM_DEBUG_DRIVER("punit overrode freq: %d requested, but got %d\n", ++ val, pval >> 8); ++ ++ /* Make sure we continue to get interrupts ++ * until we hit the minimum or maximum frequencies. ++ */ ++ I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits); ++ ++ dev_priv->rps.cur_delay = pval >> 8; ++ ++ trace_intel_gpu_freq_change(vlv_gpu_freq(dev_priv->mem_freq, val)); ++} ++ ++ + static void gen6_disable_rps(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -2742,6 +2788,127 @@ static void gen6_update_ring_freq(struct drm_device *dev) + } + } + ++int valleyview_rps_max_freq(struct drm_i915_private *dev_priv) ++{ ++ u32 val, rp0; ++ ++ valleyview_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE, &val); ++ ++ rp0 = (val & FB_GFX_MAX_FREQ_FUSE_MASK) >> FB_GFX_MAX_FREQ_FUSE_SHIFT; ++ /* Clamp to max */ ++ rp0 = min_t(u32, rp0, 0xea); ++ ++ return rp0; ++} ++ ++static int valleyview_rps_rpe_freq(struct drm_i915_private *dev_priv) ++{ ++ u32 val, rpe; ++ ++ valleyview_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_LO, &val); ++ rpe = (val & FB_FMAX_VMIN_FREQ_LO_MASK) >> FB_FMAX_VMIN_FREQ_LO_SHIFT; ++ valleyview_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_HI, &val); ++ rpe |= (val & FB_FMAX_VMIN_FREQ_HI_MASK) << 5; ++ ++ return rpe; ++} ++ ++int valleyview_rps_min_freq(struct drm_i915_private *dev_priv) ++{ ++ u32 val; ++ ++ valleyview_punit_read(dev_priv, PUNIT_REG_GPU_LFM, &val); ++ ++ return val & 0xff; ++} ++ ++static void valleyview_enable_rps(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct intel_ring_buffer *ring; ++ u32 gtfifodbg, val, rpe; ++ int i; ++ ++ WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); ++ ++ if ((gtfifodbg = I915_READ(GTFIFODBG))) { ++ DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg); ++ I915_WRITE(GTFIFODBG, gtfifodbg); ++ } ++ ++ gen6_gt_force_wake_get(dev_priv); ++ ++ I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); ++ I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); ++ I915_WRITE(GEN6_RP_UP_EI, 66000); ++ I915_WRITE(GEN6_RP_DOWN_EI, 350000); ++ ++ I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); ++ ++ I915_WRITE(GEN6_RP_CONTROL, ++ GEN6_RP_MEDIA_TURBO | ++ GEN6_RP_MEDIA_HW_NORMAL_MODE | ++ GEN6_RP_MEDIA_IS_GFX | ++ GEN6_RP_ENABLE | ++ GEN6_RP_UP_BUSY_AVG | ++ GEN6_RP_DOWN_IDLE_CONT); ++ ++ I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 0x00280000); ++ I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); ++ I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); ++ ++ for_each_ring(ring, dev_priv, i) ++ I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); ++ ++ I915_WRITE(GEN6_RC6_THRESHOLD, 0xc350); ++ ++ /* allows RC6 residency counter to work */ ++ I915_WRITE(0x138104, _MASKED_BIT_ENABLE(0x3)); ++ I915_WRITE(GEN6_RC_CONTROL, ++ GEN7_RC_CTL_TO_MODE); ++ ++ valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &val); ++ dev_priv->mem_freq = 800 + (266 * (val >> 6) & 3); ++ DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq); ++ ++ DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & 0x10 ? "yes" : "no"); ++ DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val); ++ ++ DRM_DEBUG_DRIVER("current GPU freq: %d\n", ++ vlv_gpu_freq(dev_priv->mem_freq, (val >> 8) & 0xff)); ++ dev_priv->rps.cur_delay = (val >> 8) & 0xff; ++ ++ dev_priv->rps.max_delay = valleyview_rps_max_freq(dev_priv); ++ dev_priv->rps.hw_max = dev_priv->rps.max_delay; ++ DRM_DEBUG_DRIVER("max GPU freq: %d\n", vlv_gpu_freq(dev_priv->mem_freq, ++ dev_priv->rps.max_delay)); ++ ++ rpe = valleyview_rps_rpe_freq(dev_priv); ++ DRM_DEBUG_DRIVER("RPe GPU freq: %d\n", ++ vlv_gpu_freq(dev_priv->mem_freq, rpe)); ++ ++ val = valleyview_rps_min_freq(dev_priv); ++ DRM_DEBUG_DRIVER("min GPU freq: %d\n", vlv_gpu_freq(dev_priv->mem_freq, ++ val)); ++ dev_priv->rps.min_delay = val; ++ ++ DRM_DEBUG_DRIVER("setting GPU freq to %d\n", ++ vlv_gpu_freq(dev_priv->mem_freq, rpe)); ++ ++ valleyview_set_rps(dev_priv->dev, rpe); ++ ++ /* requires MSI enabled */ ++ I915_WRITE(GEN6_PMIER, GEN6_PM_DEFERRED_EVENTS); ++ spin_lock_irq(&dev_priv->rps.lock); ++ WARN_ON(dev_priv->rps.pm_iir != 0); ++ I915_WRITE(GEN6_PMIMR, 0); ++ spin_unlock_irq(&dev_priv->rps.lock); ++ /* enable all PM interrupts */ ++ I915_WRITE(GEN6_PMINTRMSK, 0); ++ ++ gen6_gt_force_wake_put(dev_priv); ++} ++ + void ironlake_teardown_rc6(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -3468,7 +3635,7 @@ void intel_disable_gt_powersave(struct drm_device *dev) + if (IS_IRONLAKE_M(dev)) { + ironlake_disable_drps(dev); + ironlake_disable_rc6(dev); +- } else if (INTEL_INFO(dev)->gen >= 6 && !IS_VALLEYVIEW(dev)) { ++ } else if (INTEL_INFO(dev)->gen >= 6) { + cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work); + mutex_lock(&dev_priv->rps.hw_lock); + gen6_disable_rps(dev); +@@ -3484,8 +3651,13 @@ static void intel_gen6_powersave_work(struct work_struct *work) + struct drm_device *dev = dev_priv->dev; + + mutex_lock(&dev_priv->rps.hw_lock); +- gen6_enable_rps(dev); +- gen6_update_ring_freq(dev); ++ ++ if (IS_VALLEYVIEW(dev)) { ++ valleyview_enable_rps(dev); ++ } else { ++ gen6_enable_rps(dev); ++ gen6_update_ring_freq(dev); ++ } + mutex_unlock(&dev_priv->rps.hw_lock); + } + +@@ -3497,7 +3669,7 @@ void intel_enable_gt_powersave(struct drm_device *dev) + ironlake_enable_drps(dev); + ironlake_enable_rc6(dev); + intel_init_emon(dev); +- } else if ((IS_GEN6(dev) || IS_GEN7(dev)) && !IS_VALLEYVIEW(dev)) { ++ } else if (IS_GEN6(dev) || IS_GEN7(dev)) { + /* + * PCU communication is slow and this doesn't need to be + * done at any specific time, so do this out of our fast path +@@ -4603,14 +4775,13 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val) + return 0; + } + +-static int vlv_punit_rw(struct drm_i915_private *dev_priv, u8 opcode, ++static int vlv_punit_rw(struct drm_i915_private *dev_priv, u32 port, u8 opcode, + u8 addr, u32 *val) + { +- u32 cmd, devfn, port, be, bar; ++ u32 cmd, devfn, be, bar; + + bar = 0; + be = 0xf; +- port = IOSF_PORT_PUNIT; + devfn = PCI_DEVFN(2, 0); + + cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) | +@@ -4632,7 +4803,7 @@ static int vlv_punit_rw(struct drm_i915_private *dev_priv, u8 opcode, + I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd); + + if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, +- 500)) { ++ 5)) { + DRM_ERROR("timeout waiting for pcode %s (%d) to finish\n", + opcode == PUNIT_OPCODE_REG_READ ? "read" : "write", + addr); +@@ -4648,12 +4819,20 @@ static int vlv_punit_rw(struct drm_i915_private *dev_priv, u8 opcode, + + int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) + { +- return vlv_punit_rw(dev_priv, PUNIT_OPCODE_REG_READ, addr, val); ++ return vlv_punit_rw(dev_priv, IOSF_PORT_PUNIT, PUNIT_OPCODE_REG_READ, ++ addr, val); + } + + int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) + { +- return vlv_punit_rw(dev_priv, PUNIT_OPCODE_REG_WRITE, addr, &val); ++ return vlv_punit_rw(dev_priv, IOSF_PORT_PUNIT, PUNIT_OPCODE_REG_WRITE, ++ addr, &val); ++} ++ ++int valleyview_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) ++{ ++ return vlv_punit_rw(dev_priv, IOSF_PORT_NC, PUNIT_OPCODE_REG_READ, ++ addr, val); + } + + int vlv_gpu_freq(int ddr_freq, int val) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0022-drm-i915-fix-VLV-limits.patch b/patches.baytrail/0022-drm-i915-fix-VLV-limits.patch new file mode 100644 index 000000000000..8f1f3b4257a1 --- /dev/null +++ b/patches.baytrail/0022-drm-i915-fix-VLV-limits.patch @@ -0,0 +1,60 @@ +From d5658e86973e337eea1ac4c3c4eee2fec09023be Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 18 Apr 2013 21:10:43 +0200 +Subject: drm/i915: fix VLV limits + +Magic updates. + +v2: use 64 bit types and math (Ville) + +v3: Trim out all the m/n/p calculation changes since they are still +under discussion. Instead squash in a fixup for hdmi limits which +slipped into a different patch. + +Signed-off-by: Pallavi G +Signed-off-by: Vijay Purushothaman +Signed-off-by: Yogesh M +Signed-off-by: Gajanan Bhat +Signed-off-by: Jesse Barnes (v2) +Signed-off-by: Daniel Vetter +(cherry picked from commit 75e539864a133c4d8d6a4aac9f409e0a23d7bc3f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index bda32c4ebf58..717bc1ef7a89 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -396,15 +396,15 @@ static const intel_limit_t intel_limits_vlv_dac = { + .m1 = { .min = 2, .max = 3 }, + .m2 = { .min = 11, .max = 156 }, + .p = { .min = 10, .max = 30 }, +- .p1 = { .min = 2, .max = 3 }, ++ .p1 = { .min = 1, .max = 3 }, + .p2 = { .dot_limit = 270000, + .p2_slow = 2, .p2_fast = 20 }, + .find_pll = intel_vlv_find_best_pll, + }; + + static const intel_limit_t intel_limits_vlv_hdmi = { +- .dot = { .min = 20000, .max = 165000 }, +- .vco = { .min = 4000000, .max = 5994000}, ++ .dot = { .min = 25000, .max = 270000 }, ++ .vco = { .min = 4000000, .max = 6000000 }, + .n = { .min = 1, .max = 7 }, + .m = { .min = 60, .max = 300 }, /* guess */ + .m1 = { .min = 2, .max = 3 }, +@@ -424,7 +424,7 @@ static const intel_limit_t intel_limits_vlv_dp = { + .m1 = { .min = 2, .max = 3 }, + .m2 = { .min = 11, .max = 156 }, + .p = { .min = 10, .max = 30 }, +- .p1 = { .min = 2, .max = 3 }, ++ .p1 = { .min = 1, .max = 3 }, + .p2 = { .dot_limit = 270000, + .p2_slow = 2, .p2_fast = 20 }, + .find_pll = intel_vlv_find_best_pll, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0023-drm-i915-magic-VLV-PLL-registers-in-the-dpio-sideban.patch b/patches.baytrail/0023-drm-i915-magic-VLV-PLL-registers-in-the-dpio-sideban.patch new file mode 100644 index 000000000000..20b6062afb55 --- /dev/null +++ b/patches.baytrail/0023-drm-i915-magic-VLV-PLL-registers-in-the-dpio-sideban.patch @@ -0,0 +1,183 @@ +From 4079198c5f551c1fc4c3f5e986cbc6713f32e7dc Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 18 Apr 2013 22:01:46 +0200 +Subject: drm/i915: magic VLV PLL registers in the dpio sideband + +Stolen from a patch with the below impressive sob-section. + +Signed-off-by: Pallavi G +Signed-off-by: Vijay Purushothaman +Signed-off-by: Gajanan Bhat +Signed-off-by: Ben Widawsky +Signed-off-by: Jesse Barnes +[danvet: Drop everything but the header #defines.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 598fac6bf8299ed7ae1852426660be3c265047a4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 118 +++++++++++++++++++++++++++++++++++++++- + 1 file changed, 116 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index acf0608cc761..a5fe3ba7d00d 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -351,6 +351,8 @@ + * 0x8100: fast clock controls + * + * DPIO is VLV only. ++ * ++ * Note: digital port B is DDI0, digital pot C is DDI1 + */ + #define DPIO_PKT (VLV_DISPLAY_BASE + 0x2100) + #define DPIO_RID (0<<24) +@@ -367,8 +369,20 @@ + #define DPIO_SFR_BYPASS (1<<1) + #define DPIO_RESET (1<<0) + ++#define _DPIO_TX3_SWING_CTL4_A 0x690 ++#define _DPIO_TX3_SWING_CTL4_B 0x2a90 ++#define DPIO_TX3_SWING_CTL4(pipe) _PIPE(pipe, _DPIO_TX_SWING_CTL4_A, \ ++ _DPIO_TX3_SWING_CTL4_B) ++ ++/* ++ * Per pipe/PLL DPIO regs ++ */ + #define _DPIO_DIV_A 0x800c + #define DPIO_POST_DIV_SHIFT (28) /* 3 bits */ ++#define DPIO_POST_DIV_DAC 0 ++#define DPIO_POST_DIV_HDMIDP 1 /* DAC 225-400M rate */ ++#define DPIO_POST_DIV_LVDS1 2 ++#define DPIO_POST_DIV_LVDS2 3 + #define DPIO_K_SHIFT (24) /* 4 bits */ + #define DPIO_P1_SHIFT (21) /* 3 bits */ + #define DPIO_P2_SHIFT (16) /* 5 bits */ +@@ -394,14 +408,111 @@ + #define _DPIO_CORE_CLK_B 0x803c + #define DPIO_CORE_CLK(pipe) _PIPE(pipe, _DPIO_CORE_CLK_A, _DPIO_CORE_CLK_B) + ++#define _DPIO_IREF_CTL_A 0x8040 ++#define _DPIO_IREF_CTL_B 0x8060 ++#define DPIO_IREF_CTL(pipe) _PIPE(pipe, _DPIO_IREF_CTL_A, _DPIO_IREF_CTL_B) ++ ++#define DPIO_IREF_BCAST 0xc044 ++#define _DPIO_IREF_A 0x8044 ++#define _DPIO_IREF_B 0x8064 ++#define DPIO_IREF(pipe) _PIPE(pipe, _DPIO_IREF_A, _DPIO_IREF_B) ++ ++#define _DPIO_PLL_CML_A 0x804c ++#define _DPIO_PLL_CML_B 0x806c ++#define DPIO_PLL_CML(pipe) _PIPE(pipe, _DPIO_PLL_CML_A, _DPIO_PLL_CML_B) ++ + #define _DPIO_LFP_COEFF_A 0x8048 + #define _DPIO_LFP_COEFF_B 0x8068 + #define DPIO_LFP_COEFF(pipe) _PIPE(pipe, _DPIO_LFP_COEFF_A, _DPIO_LFP_COEFF_B) + ++#define DPIO_CALIBRATION 0x80ac ++ + #define DPIO_FASTCLK_DISABLE 0x8100 + +-#define DPIO_DATA_CHANNEL1 0x8220 +-#define DPIO_DATA_CHANNEL2 0x8420 ++/* ++ * Per DDI channel DPIO regs ++ */ ++ ++#define _DPIO_PCS_TX_0 0x8200 ++#define _DPIO_PCS_TX_1 0x8400 ++#define DPIO_PCS_TX_LANE2_RESET (1<<16) ++#define DPIO_PCS_TX_LANE1_RESET (1<<7) ++#define DPIO_PCS_TX(port) _PORT(port, _DPIO_PCS_TX_0, _DPIO_PCS_TX_1) ++ ++#define _DPIO_PCS_CLK_0 0x8204 ++#define _DPIO_PCS_CLK_1 0x8404 ++#define DPIO_PCS_CLK_CRI_RXEB_EIOS_EN (1<<22) ++#define DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN (1<<21) ++#define DPIO_PCS_CLK_DATAWIDTH_SHIFT (6) ++#define DPIO_PCS_CLK_SOFT_RESET (1<<5) ++#define DPIO_PCS_CLK(port) _PORT(port, _DPIO_PCS_CLK_0, _DPIO_PCS_CLK_1) ++ ++#define _DPIO_PCS_CTL_OVR1_A 0x8224 ++#define _DPIO_PCS_CTL_OVR1_B 0x8424 ++#define DPIO_PCS_CTL_OVER1(port) _PORT(port, _DPIO_PCS_CTL_OVR1_A, \ ++ _DPIO_PCS_CTL_OVR1_B) ++ ++#define _DPIO_PCS_STAGGER0_A 0x822c ++#define _DPIO_PCS_STAGGER0_B 0x842c ++#define DPIO_PCS_STAGGER0(port) _PORT(port, _DPIO_PCS_STAGGER0_A, \ ++ _DPIO_PCS_STAGGER0_B) ++ ++#define _DPIO_PCS_STAGGER1_A 0x8230 ++#define _DPIO_PCS_STAGGER1_B 0x8430 ++#define DPIO_PCS_STAGGER1(port) _PORT(port, _DPIO_PCS_STAGGER1_A, \ ++ _DPIO_PCS_STAGGER1_B) ++ ++#define _DPIO_PCS_CLOCKBUF0_A 0x8238 ++#define _DPIO_PCS_CLOCKBUF0_B 0x8438 ++#define DPIO_PCS_CLOCKBUF0(port) _PORT(port, _DPIO_PCS_CLOCKBUF0_A, \ ++ _DPIO_PCS_CLOCKBUF0_B) ++ ++#define _DPIO_PCS_CLOCKBUF8_A 0x825c ++#define _DPIO_PCS_CLOCKBUF8_B 0x845c ++#define DPIO_PCS_CLOCKBUF8(port) _PORT(port, _DPIO_PCS_CLOCKBUF8_A, \ ++ _DPIO_PCS_CLOCKBUF8_B) ++ ++#define _DPIO_TX_SWING_CTL2_A 0x8288 ++#define _DPIO_TX_SWING_CTL2_B 0x8488 ++#define DPIO_TX_SWING_CTL2(port) _PORT(port, _DPIO_TX_SWING_CTL2_A, \ ++ _DPIO_TX_SWING_CTL2_B) ++ ++#define _DPIO_TX_SWING_CTL3_A 0x828c ++#define _DPIO_TX_SWING_CTL3_B 0x848c ++#define DPIO_TX_SWING_CTL3(port) _PORT(port, _DPIO_TX_SWING_CTL3_A, \ ++ _DPIO_TX_SWING_CTL3_B) ++ ++#define _DPIO_TX_SWING_CTL4_A 0x8290 ++#define _DPIO_TX_SWING_CTL4_B 0x8490 ++#define DPIO_TX_SWING_CTL4(port) _PORT(port, _DPIO_TX_SWING_CTL4_A, \ ++ _DPIO_TX_SWING_CTL4_B) ++ ++#define _DPIO_TX_OCALINIT_0 0x8294 ++#define _DPIO_TX_OCALINIT_1 0x8494 ++#define DPIO_TX_OCALINIT_EN (1<<31) ++#define DPIO_TX_OCALINIT(port) _PORT(port, _DPIO_TX_OCALINIT_0, \ ++ _DPIO_TX_OCALINIT_1) ++ ++#define _DPIO_TX_CTL_0 0x82ac ++#define _DPIO_TX_CTL_1 0x84ac ++#define DPIO_TX_CTL(port) _PORT(port, _DPIO_TX_CTL_0, _DPIO_TX_CTL_1) ++ ++#define _DPIO_TX_LANE_0 0x82b8 ++#define _DPIO_TX_LANE_1 0x84b8 ++#define DPIO_TX_LANE(port) _PORT(port, _DPIO_TX_LANE_0, _DPIO_TX_LANE_1) ++ ++#define _DPIO_DATA_CHANNEL1 0x8220 ++#define _DPIO_DATA_CHANNEL2 0x8420 ++#define DPIO_DATA_CHANNEL(port) _PORT(port, _DPIO_DATA_CHANNEL1, _DPIO_DATA_CHANNEL2) ++ ++#define _DPIO_PORT0_PCS0 0x0220 ++#define _DPIO_PORT0_PCS1 0x0420 ++#define _DPIO_PORT1_PCS2 0x2620 ++#define _DPIO_PORT1_PCS3 0x2820 ++#define DPIO_DATA_LANE_A(port) _PORT(port, _DPIO_PORT0_PCS0, _DPIO_PORT1_PCS2) ++#define DPIO_DATA_LANE_B(port) _PORT(port, _DPIO_PORT0_PCS1, _DPIO_PORT1_PCS3) ++#define DPIO_DATA_CHANNEL1 0x8220 ++#define DPIO_DATA_CHANNEL2 0x8420 + + /* + * Fence registers +@@ -965,7 +1076,10 @@ + #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ + #define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */ + #define DPLL_LOCK_VLV (1<<15) ++#define DPLL_INTEGRATED_CRI_CLK_VLV (1<<14) + #define DPLL_INTEGRATED_CLOCK_VLV (1<<13) ++#define DPLL_PORTC_READY_MASK (0xf << 4) ++#define DPLL_PORTB_READY_MASK (0xf) + + #define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 + /* +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0024-drm-i915-dp-program-VSwing-and-Preemphasis-control-s.patch b/patches.baytrail/0024-drm-i915-dp-program-VSwing-and-Preemphasis-control-s.patch new file mode 100644 index 000000000000..ba279346bbcf --- /dev/null +++ b/patches.baytrail/0024-drm-i915-dp-program-VSwing-and-Preemphasis-control-s.patch @@ -0,0 +1,217 @@ +From 99fc35d67bde57ea86f8c197fde5614988008f8a Mon Sep 17 00:00:00 2001 +From: Pallavi G +Date: Thu, 18 Apr 2013 14:44:28 -0700 +Subject: drm/i915/dp: program VSwing and Preemphasis control settings on VLV + v2 + +Program few Tx buffer Swing control settings through DPIO. + +v2: fix up codingstyle (Daniel) + call from set_signal_levels (Ville, Daniel) + use proper port numbers (Jesse) + +Signed-off-by: Pallavi G +Signed-off-by: Yogesh M +Signed-off-by: Gajanan Bhat +Signed-off-by: Jesse Barnes (v2 changes) +[danvet: Reorder if-ladder to avoid two IS_VLV checks.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit e2fa6fba3d2fa03a5efdedf0b6f045fcc3428a80) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 3 +- + drivers/gpu/drm/i915/intel_dp.c | 128 ++++++++++++++++++++++++++++++++++- + drivers/gpu/drm/i915/intel_drv.h | 2 + + 3 files changed, 128 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 717bc1ef7a89..7b52c0f729d5 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -450,8 +450,7 @@ u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg) + return I915_READ(DPIO_DATA); + } + +-static void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, +- u32 val) ++void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val) + { + WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 80feaec88d2b..cd460c90e4aa 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1463,7 +1463,9 @@ intel_dp_voltage_max(struct intel_dp *intel_dp) + { + struct drm_device *dev = intel_dp_to_dev(intel_dp); + +- if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) ++ if (IS_VALLEYVIEW(dev)) ++ return DP_TRAIN_VOLTAGE_SWING_1200; ++ else if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) + return DP_TRAIN_VOLTAGE_SWING_800; + else if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) + return DP_TRAIN_VOLTAGE_SWING_1200; +@@ -1488,7 +1490,19 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing) + default: + return DP_TRAIN_PRE_EMPHASIS_0; + } +- } else if (IS_GEN7(dev) && is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) { ++ } else if (IS_VALLEYVIEW(dev)) { ++ switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { ++ case DP_TRAIN_VOLTAGE_SWING_400: ++ return DP_TRAIN_PRE_EMPHASIS_9_5; ++ case DP_TRAIN_VOLTAGE_SWING_600: ++ return DP_TRAIN_PRE_EMPHASIS_6; ++ case DP_TRAIN_VOLTAGE_SWING_800: ++ return DP_TRAIN_PRE_EMPHASIS_3_5; ++ case DP_TRAIN_VOLTAGE_SWING_1200: ++ default: ++ return DP_TRAIN_PRE_EMPHASIS_0; ++ } ++ } else if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) { + switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { + case DP_TRAIN_VOLTAGE_SWING_400: + return DP_TRAIN_PRE_EMPHASIS_6; +@@ -1513,6 +1527,111 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing) + } + } + ++static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp) ++{ ++ struct drm_device *dev = intel_dp_to_dev(intel_dp); ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct intel_digital_port *dport = dp_to_dig_port(intel_dp); ++ unsigned long demph_reg_value, preemph_reg_value, ++ uniqtranscale_reg_value; ++ uint8_t train_set = intel_dp->train_set[0]; ++ int port; ++ ++ if (dport->port == PORT_B) ++ port = 0; ++ else if (dport->port == PORT_C) ++ port = 1; ++ else ++ BUG(); ++ ++ switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { ++ case DP_TRAIN_PRE_EMPHASIS_0: ++ preemph_reg_value = 0x0004000; ++ switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { ++ case DP_TRAIN_VOLTAGE_SWING_400: ++ demph_reg_value = 0x2B405555; ++ uniqtranscale_reg_value = 0x552AB83A; ++ break; ++ case DP_TRAIN_VOLTAGE_SWING_600: ++ demph_reg_value = 0x2B404040; ++ uniqtranscale_reg_value = 0x5548B83A; ++ break; ++ case DP_TRAIN_VOLTAGE_SWING_800: ++ demph_reg_value = 0x2B245555; ++ uniqtranscale_reg_value = 0x5560B83A; ++ break; ++ case DP_TRAIN_VOLTAGE_SWING_1200: ++ demph_reg_value = 0x2B405555; ++ uniqtranscale_reg_value = 0x5598DA3A; ++ break; ++ default: ++ return 0; ++ } ++ break; ++ case DP_TRAIN_PRE_EMPHASIS_3_5: ++ preemph_reg_value = 0x0002000; ++ switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { ++ case DP_TRAIN_VOLTAGE_SWING_400: ++ demph_reg_value = 0x2B404040; ++ uniqtranscale_reg_value = 0x5552B83A; ++ break; ++ case DP_TRAIN_VOLTAGE_SWING_600: ++ demph_reg_value = 0x2B404848; ++ uniqtranscale_reg_value = 0x5580B83A; ++ break; ++ case DP_TRAIN_VOLTAGE_SWING_800: ++ demph_reg_value = 0x2B404040; ++ uniqtranscale_reg_value = 0x55ADDA3A; ++ break; ++ default: ++ return 0; ++ } ++ break; ++ case DP_TRAIN_PRE_EMPHASIS_6: ++ preemph_reg_value = 0x0000000; ++ switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { ++ case DP_TRAIN_VOLTAGE_SWING_400: ++ demph_reg_value = 0x2B305555; ++ uniqtranscale_reg_value = 0x5570B83A; ++ break; ++ case DP_TRAIN_VOLTAGE_SWING_600: ++ demph_reg_value = 0x2B2B4040; ++ uniqtranscale_reg_value = 0x55ADDA3A; ++ break; ++ default: ++ return 0; ++ } ++ break; ++ case DP_TRAIN_PRE_EMPHASIS_9_5: ++ preemph_reg_value = 0x0006000; ++ switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { ++ case DP_TRAIN_VOLTAGE_SWING_400: ++ demph_reg_value = 0x1B405555; ++ uniqtranscale_reg_value = 0x55ADDA3A; ++ break; ++ default: ++ return 0; ++ } ++ break; ++ default: ++ return 0; ++ } ++ ++ /* eDP is only on port C */ ++ mutex_lock(&dev_priv->dpio_lock); ++ intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x00000000); ++ intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(port), demph_reg_value); ++ intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(port), ++ uniqtranscale_reg_value); ++ intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL3(port), 0x0C782040); ++ intel_dpio_write(dev_priv, DPIO_PCS_STAGGER0(port), 0x00030000); ++ intel_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port), preemph_reg_value); ++ intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x80000000); ++ mutex_unlock(&dev_priv->dpio_lock); ++ ++ return 0; ++} ++ + static void + intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) + { +@@ -1687,7 +1806,10 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP) + if (HAS_DDI(dev)) { + signal_levels = intel_hsw_signal_levels(train_set); + mask = DDI_BUF_EMP_MASK; +- } else if (IS_GEN7(dev) && is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) { ++ } else if (IS_VALLEYVIEW(dev)) { ++ signal_levels = intel_vlv_signal_levels(intel_dp); ++ mask = 0; ++ } else if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) { + signal_levels = intel_gen7_edp_signal_levels(train_set); + mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB; + } else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 7cd55843e73e..4b8bec2ca2ab 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -690,6 +690,8 @@ extern int intel_sprite_get_colorkey(struct drm_device *dev, void *data, + struct drm_file *file_priv); + + extern u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg); ++extern void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, ++ u32 val); + + /* Power-related functions, located in intel_pm.c */ + extern void intel_init_pm(struct drm_device *dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0025-drm-i915-drop-init_dpio-shouldn-t-be-needed.patch b/patches.baytrail/0025-drm-i915-drop-init_dpio-shouldn-t-be-needed.patch new file mode 100644 index 000000000000..487f18df6af3 --- /dev/null +++ b/patches.baytrail/0025-drm-i915-drop-init_dpio-shouldn-t-be-needed.patch @@ -0,0 +1,52 @@ +From e7c5a2856cd2fc6f7ad6e5b71a23c741e8d77b5a Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Thu, 18 Apr 2013 14:44:29 -0700 +Subject: drm/i915: drop init_dpio, shouldn't be needed + +This is a reset feature we don't actually need. + +Signed-off-by: Jesse Barnes +[danvet: Make it compile.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 78c9b7e71d90f32ce19d4a575a1a206cfe7c6a00) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 14 -------------- + 1 file changed, 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 7b52c0f729d5..9a284ac81c34 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -467,17 +467,6 @@ void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val) + DRM_ERROR("DPIO write wait timed out\n"); + } + +-static void vlv_init_dpio(struct drm_device *dev) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- +- /* Reset the DPIO config */ +- I915_WRITE(DPIO_CTL, 0); +- POSTING_READ(DPIO_CTL); +- I915_WRITE(DPIO_CTL, 1); +- POSTING_READ(DPIO_CTL); +-} +- + static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, + int refclk) + { +@@ -9484,9 +9473,6 @@ void intel_modeset_cleanup(struct drm_device *dev) + + ironlake_teardown_rc6(dev); + +- if (IS_VALLEYVIEW(dev)) +- vlv_init_dpio(dev); +- + mutex_unlock(&dev->struct_mutex); + + /* Disable the irq before mode object teardown, for the irq might +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0026-drm-i915-update-VLV-PLL-and-DPIO-code-v11.patch b/patches.baytrail/0026-drm-i915-update-VLV-PLL-and-DPIO-code-v11.patch new file mode 100644 index 000000000000..416046abc41d --- /dev/null +++ b/patches.baytrail/0026-drm-i915-update-VLV-PLL-and-DPIO-code-v11.patch @@ -0,0 +1,663 @@ +From 8aba3a4c6aa58f5eccb37f3c27b4e4b2919e4252 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Thu, 18 Apr 2013 14:51:36 -0700 +Subject: drm/i915: update VLV PLL and DPIO code v11 + +In Valleyview voltage swing, pre-emphasis and lane control registers can +be programmed only through the h/w side band fabric. Update +vlv_update_pll, i9xx_crtc_enable, and intel_enable_pll with the +appropriate programming. + +We need to make sure that the tx lane reset occurs in both the full mode +set and DPMS paths, so factor things out to allow that. + +v2: use different DPIO_DIVISOR values for VGA and DisplayPort +v3: Fix update pll logic to use same DPIO_DIVISOR & DPIO_REFSFR values + for all display interfaces +v4: collapse with various updates +v5: squash with crtc enable/pll enable bits +v6: split out DP code (jbarnes) + put phyready check under IS_VALLEYVIEW (jbarnes) + remove unneeded check in 9xx pll div update (Jani) + wrap VLV pll update call in IS_VALLEYVIEW (Jani) + move port enable back to end of crtc enable (jbarnes) + put phyready check under IS_VALLEYVIEW (jbarnes) +v7: fix up conflicts against latest drm-intel-next-queued +v8: use DPIO reg names, fix pipes (Jani) + from mPhy_registers_VLV2_ww20p5 doc +v9: update to latest info from driver enabling notes doc + driver_vbios_notes_9 +v10: fixup a bit of pipe/port confusion to allow eDP and HDMI to work + simultaneously (Jesse) +v11: use pll/port callbacks for DPIO port activity (Daniel) + use separate VLV CRTC enable function (Daniel) + move around port ready checks (Jesse) + +Signed-off-by: Pallavi G +Signed-off-by: Vijay Purushothaman +Signed-off-by: Gajanan Bhat +Signed-off-by: Ben Widawsky +Signed-off-by: Jesse Barnes +[danvet: Drop pfit changes and add a little comment explaining that +vlv has a different enable sequence and so needs it's own crtc_enable +callback. Also apply a fixup patch from Wu Fengguang to shut up some +compiler warnings.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 89b667f86a62a99a7b484a7e1b3f8f7a108a7dee) +[dbasehore: Fixed Issue with number of arguments to function. 4th +argument should not be removed (yet)] +Signed-off-by: Derek Basehore + +Conflicts: + drivers/gpu/drm/i915/intel_display.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 235 +++++++++++++++++++++++++++-------- + drivers/gpu/drm/i915/intel_dp.c | 69 +++++++++- + drivers/gpu/drm/i915/intel_drv.h | 14 +++ + drivers/gpu/drm/i915/intel_hdmi.c | 108 ++++++++++++++++ + 4 files changed, 369 insertions(+), 57 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 9a284ac81c34..913860931245 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1576,6 +1576,20 @@ intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg, + return I915_READ(SBI_DATA); + } + ++void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port) ++{ ++ u32 port_mask; ++ ++ if (!port) ++ port_mask = DPLL_PORTB_READY_MASK; ++ else ++ port_mask = DPLL_PORTC_READY_MASK; ++ ++ if (wait_for((I915_READ(DPLL(0)) & port_mask) == 0, 1000)) ++ WARN(1, "timed out waiting for port %c ready: 0x%08x\n", ++ 'B' + port, I915_READ(DPLL(0))); ++} ++ + /** + * ironlake_enable_pch_pll - enable PCH PLL + * @dev_priv: i915 private structure +@@ -3678,6 +3692,52 @@ g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe) + } + } + ++static void valleyview_crtc_enable(struct drm_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ struct intel_encoder *encoder; ++ int pipe = intel_crtc->pipe; ++ int plane = intel_crtc->plane; ++ ++ WARN_ON(!crtc->enabled); ++ ++ if (intel_crtc->active) ++ return; ++ ++ intel_crtc->active = true; ++ intel_update_watermarks(dev); ++ ++ mutex_lock(&dev_priv->dpio_lock); ++ ++ for_each_encoder_on_crtc(dev, crtc, encoder) ++ if (encoder->pre_pll_enable) ++ encoder->pre_pll_enable(encoder); ++ ++ intel_enable_pll(dev_priv, pipe); ++ ++ for_each_encoder_on_crtc(dev, crtc, encoder) ++ if (encoder->pre_enable) ++ encoder->pre_enable(encoder); ++ ++ /* VLV wants encoder enabling _before_ the pipe is up. */ ++ for_each_encoder_on_crtc(dev, crtc, encoder) ++ encoder->enable(encoder); ++ ++ intel_enable_pipe(dev_priv, pipe, false); ++ intel_enable_plane(dev_priv, plane, pipe); ++ ++ intel_crtc_load_lut(crtc); ++ intel_update_fbc(dev); ++ ++ /* Give the overlay scaler a chance to enable if it's on this pipe */ ++ intel_crtc_dpms_overlay(intel_crtc, true); ++ intel_crtc_update_cursor(crtc, true); ++ ++ mutex_unlock(&dev_priv->dpio_lock); ++} ++ + static void i9xx_crtc_enable(struct drm_crtc *crtc) + { + struct drm_device *dev = crtc->dev; +@@ -3766,6 +3826,10 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) + + i9xx_pfit_disable(intel_crtc); + ++ for_each_encoder_on_crtc(dev, crtc, encoder) ++ if (encoder->post_disable) ++ encoder->post_disable(encoder); ++ + intel_disable_pll(dev_priv, pipe); + + intel_crtc->active = false; +@@ -4214,6 +4278,34 @@ static void i9xx_update_pll_dividers(struct intel_crtc *crtc, + } + } + ++static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv) ++{ ++ u32 reg_val; ++ ++ /* ++ * PLLB opamp always calibrates to max value of 0x3f, force enable it ++ * and set it to a reasonable value instead. ++ */ ++ reg_val = intel_dpio_read(dev_priv, DPIO_IREF(1)); ++ reg_val &= 0xffffff00; ++ reg_val |= 0x00000030; ++ intel_dpio_write(dev_priv, DPIO_IREF(1), reg_val); ++ ++ reg_val = intel_dpio_read(dev_priv, DPIO_CALIBRATION); ++ reg_val &= 0x8cffffff; ++ reg_val = 0x8c000000; ++ intel_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val); ++ ++ reg_val = intel_dpio_read(dev_priv, DPIO_IREF(1)); ++ reg_val &= 0xffffff00; ++ intel_dpio_write(dev_priv, DPIO_IREF(1), reg_val); ++ ++ reg_val = intel_dpio_read(dev_priv, DPIO_CALIBRATION); ++ reg_val &= 0x00ffffff; ++ reg_val |= 0xb0000000; ++ intel_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val); ++} ++ + static void intel_dp_set_m_n(struct intel_crtc *crtc) + { + if (crtc->config.has_pch_encoder) +@@ -4226,24 +4318,18 @@ static void vlv_update_pll(struct intel_crtc *crtc) + { + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_display_mode *adjusted_mode = ++ &crtc->config.adjusted_mode; ++ struct intel_encoder *encoder; + int pipe = crtc->pipe; +- u32 dpll, mdiv, pdiv; ++ u32 dpll, mdiv; + u32 bestn, bestm1, bestm2, bestp1, bestp2; +- bool is_sdvo; +- u32 temp; ++ bool is_hdmi; ++ u32 coreclk, reg_val, temp; + + mutex_lock(&dev_priv->dpio_lock); + +- is_sdvo = intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_SDVO) || +- intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI); +- +- dpll = DPLL_VGA_MODE_DIS; +- dpll |= DPLL_EXT_BUFFER_ENABLE_VLV; +- dpll |= DPLL_REFA_CLK_ENABLE_VLV; +- dpll |= DPLL_INTEGRATED_CLOCK_VLV; +- +- I915_WRITE(DPLL(pipe), dpll); +- POSTING_READ(DPLL(pipe)); ++ is_hdmi = intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI); + + bestn = crtc->config.dpll.n; + bestm1 = crtc->config.dpll.m1; +@@ -4251,71 +4337,105 @@ static void vlv_update_pll(struct intel_crtc *crtc) + bestp1 = crtc->config.dpll.p1; + bestp2 = crtc->config.dpll.p2; + +- /* +- * In Valleyview PLL and program lane counter registers are exposed +- * through DPIO interface +- */ ++ /* See eDP HDMI DPIO driver vbios notes doc */ ++ ++ /* PLL B needs special handling */ ++ if (pipe) ++ vlv_pllb_recal_opamp(dev_priv); ++ ++ /* Set up Tx target for periodic Rcomp update */ ++ intel_dpio_write(dev_priv, DPIO_IREF_BCAST, 0x0100000f); ++ ++ /* Disable target IRef on PLL */ ++ reg_val = intel_dpio_read(dev_priv, DPIO_IREF_CTL(pipe)); ++ reg_val &= 0x00ffffff; ++ intel_dpio_write(dev_priv, DPIO_IREF_CTL(pipe), reg_val); ++ ++ /* Disable fast lock */ ++ intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x610); ++ ++ /* Set idtafcrecal before PLL is enabled */ + mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK)); + mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT)); + mdiv |= ((bestn << DPIO_N_SHIFT)); +- mdiv |= (1 << DPIO_POST_DIV_SHIFT); + mdiv |= (1 << DPIO_K_SHIFT); +- mdiv |= DPIO_ENABLE_CALIBRATION; ++ if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI) || ++ intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) || ++ intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)) ++ mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT); + intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); + +- intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), 0x01000000); ++ mdiv |= DPIO_ENABLE_CALIBRATION; ++ intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); + +- pdiv = (1 << DPIO_REFSEL_OVERRIDE) | (5 << DPIO_PLL_MODESEL_SHIFT) | +- (3 << DPIO_BIAS_CURRENT_CTL_SHIFT) | (1<<20) | +- (7 << DPIO_PLL_REFCLK_SEL_SHIFT) | (8 << DPIO_DRIVER_CTL_SHIFT) | +- (5 << DPIO_CLK_BIAS_CTL_SHIFT); +- intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), pdiv); ++ /* Set HBR and RBR LPF coefficients */ ++ if (adjusted_mode->clock == 162000 || ++ intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI)) ++ intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), ++ 0x005f0021); ++ else ++ intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), ++ 0x00d0000f); ++ ++ if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) || ++ intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)) { ++ /* Use SSC source */ ++ if (!pipe) ++ intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), ++ 0x0df40000); ++ else ++ intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), ++ 0x0df70000); ++ } else { /* HDMI or VGA */ ++ /* Use bend source */ ++ if (!pipe) ++ intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), ++ 0x0df70000); ++ else ++ intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), ++ 0x0df40000); ++ } + +- intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), 0x005f003b); ++ coreclk = intel_dpio_read(dev_priv, DPIO_CORE_CLK(pipe)); ++ coreclk = (coreclk & 0x0000ff00) | 0x01c00000; ++ if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT) || ++ intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP)) ++ coreclk |= 0x01000000; ++ intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), coreclk); + +- dpll |= DPLL_VCO_ENABLE; +- I915_WRITE(DPLL(pipe), dpll); +- POSTING_READ(DPLL(pipe)); +- if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) +- DRM_ERROR("DPLL %d failed to lock\n", pipe); ++ intel_dpio_write(dev_priv, DPIO_PLL_CML(pipe), 0x87871000); + +- intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x620); ++ for_each_encoder_on_crtc(dev, &crtc->base, encoder) ++ if (encoder->pre_pll_enable) ++ encoder->pre_pll_enable(encoder); + +- if (crtc->config.has_dp_encoder) +- intel_dp_set_m_n(crtc); ++ /* Enable DPIO clock input */ ++ dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV | ++ DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV; ++ if (pipe) ++ dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; + ++ dpll |= DPLL_VCO_ENABLE; + I915_WRITE(DPLL(pipe), dpll); +- +- /* Wait for the clocks to stabilize. */ + POSTING_READ(DPLL(pipe)); + udelay(150); + +- temp = 0; +- if (is_sdvo) { ++ if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) ++ DRM_ERROR("DPLL %d failed to lock\n", pipe); ++ ++ if (is_hdmi) { + temp = 0; + if (crtc->config.pixel_multiplier > 1) { + temp = (crtc->config.pixel_multiplier - 1) + << DPLL_MD_UDI_MULTIPLIER_SHIFT; + } +- } +- I915_WRITE(DPLL_MD(pipe), temp); +- POSTING_READ(DPLL_MD(pipe)); + +- /* Now program lane control registers */ +- if(intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT) +- || intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI)) { +- temp = 0x1000C4; +- if(pipe == 1) +- temp |= (1 << 21); +- intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL1, temp); ++ I915_WRITE(DPLL_MD(pipe), temp); ++ POSTING_READ(DPLL_MD(pipe)); + } + +- if(intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP)) { +- temp = 0x1000C4; +- if(pipe == 1) +- temp |= (1 << 21); +- intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL2, temp); +- } ++ if (crtc->config.has_dp_encoder) ++ intel_dp_set_m_n(crtc); + + mutex_unlock(&dev_priv->dpio_lock); + } +@@ -8792,6 +8912,13 @@ static void intel_init_display(struct drm_device *dev) + dev_priv->display.crtc_disable = ironlake_crtc_disable; + dev_priv->display.off = ironlake_crtc_off; + dev_priv->display.update_plane = ironlake_update_plane; ++ } else if (IS_VALLEYVIEW(dev)) { ++ dev_priv->display.get_pipe_config = i9xx_get_pipe_config; ++ dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; ++ dev_priv->display.crtc_enable = valleyview_crtc_enable; ++ dev_priv->display.crtc_disable = i9xx_crtc_disable; ++ dev_priv->display.off = i9xx_crtc_off; ++ dev_priv->display.update_plane = i9xx_update_plane; + } else { + dev_priv->display.get_pipe_config = i9xx_get_pipe_config; + dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index cd460c90e4aa..415caad2b10f 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1392,15 +1392,77 @@ static void intel_enable_dp(struct intel_encoder *encoder) + intel_dp_complete_link_train(intel_dp); + intel_dp_stop_link_train(intel_dp); + ironlake_edp_backlight_on(intel_dp); ++ ++ if (IS_VALLEYVIEW(dev)) { ++ struct intel_digital_port *dport = ++ enc_to_dig_port(&encoder->base); ++ int channel = vlv_dport_to_channel(dport); ++ ++ vlv_wait_port_ready(dev_priv, channel); ++ } + } + + static void intel_pre_enable_dp(struct intel_encoder *encoder) + { + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + struct drm_device *dev = encoder->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; + + if (is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) + ironlake_edp_pll_on(intel_dp); ++ ++ if (IS_VALLEYVIEW(dev)) { ++ struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); ++ struct intel_crtc *intel_crtc = ++ to_intel_crtc(encoder->base.crtc); ++ int port = vlv_dport_to_channel(dport); ++ int pipe = intel_crtc->pipe; ++ u32 val; ++ ++ WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); ++ ++ val = intel_dpio_read(dev_priv, DPIO_DATA_LANE_A(port)); ++ val = 0; ++ if (pipe) ++ val |= (1<<21); ++ else ++ val &= ~(1<<21); ++ val |= 0x001000c4; ++ intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val); ++ ++ intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port), ++ 0x00760018); ++ intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port), ++ 0x00400888); ++ } ++} ++ ++static void intel_dp_pre_pll_enable(struct intel_encoder *encoder) ++{ ++ struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int port = vlv_dport_to_channel(dport); ++ ++ if (!IS_VALLEYVIEW(dev)) ++ return; ++ ++ WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); ++ ++ /* Program Tx lane resets to default */ ++ intel_dpio_write(dev_priv, DPIO_PCS_TX(port), ++ DPIO_PCS_TX_LANE2_RESET | ++ DPIO_PCS_TX_LANE1_RESET); ++ intel_dpio_write(dev_priv, DPIO_PCS_CLK(port), ++ DPIO_PCS_CLK_CRI_RXEB_EIOS_EN | ++ DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN | ++ (1<dpio_lock)); ++ + switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { + case DP_TRAIN_PRE_EMPHASIS_0: + preemph_reg_value = 0x0004000; +@@ -1617,8 +1681,6 @@ static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp) + return 0; + } + +- /* eDP is only on port C */ +- mutex_lock(&dev_priv->dpio_lock); + intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x00000000); + intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(port), demph_reg_value); + intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(port), +@@ -1627,7 +1689,6 @@ static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp) + intel_dpio_write(dev_priv, DPIO_PCS_STAGGER0(port), 0x00030000); + intel_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port), preemph_reg_value); + intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x80000000); +- mutex_unlock(&dev_priv->dpio_lock); + + return 0; + } +@@ -3119,6 +3180,8 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) + intel_encoder->disable = intel_disable_dp; + intel_encoder->post_disable = intel_post_disable_dp; + intel_encoder->get_hw_state = intel_dp_get_hw_state; ++ if (IS_VALLEYVIEW(dev)) ++ intel_encoder->pre_pll_enable = intel_dp_pre_pll_enable; + + intel_dig_port->port = port; + intel_dig_port->dp.output_reg = output_reg; +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 4b8bec2ca2ab..310899f4c3b5 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -431,6 +431,19 @@ struct intel_digital_port { + struct intel_hdmi hdmi; + }; + ++static inline int ++vlv_dport_to_channel(struct intel_digital_port *dport) ++{ ++ switch (dport->port) { ++ case PORT_B: ++ return 0; ++ case PORT_C: ++ return 1; ++ default: ++ BUG(); ++ } ++} ++ + static inline struct drm_crtc * + intel_get_crtc_for_pipe(struct drm_device *dev, int pipe) + { +@@ -607,6 +620,7 @@ intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, + extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); + extern void intel_wait_for_pipe_off(struct drm_device *dev, int pipe); + extern int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp); ++extern void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port); + + struct intel_load_detect_pipe { + struct drm_framebuffer *release_fb; +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index a9057930f2b2..075b7d83d9f5 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -697,6 +697,14 @@ static void intel_enable_hdmi(struct intel_encoder *encoder) + I915_WRITE(intel_hdmi->hdmi_reg, temp); + POSTING_READ(intel_hdmi->hdmi_reg); + } ++ ++ if (IS_VALLEYVIEW(dev)) { ++ struct intel_digital_port *dport = ++ enc_to_dig_port(&encoder->base); ++ int channel = vlv_dport_to_channel(dport); ++ ++ vlv_wait_port_ready(dev_priv, channel); ++ } + } + + static void intel_disable_hdmi(struct intel_encoder *encoder) +@@ -955,6 +963,101 @@ done: + return 0; + } + ++static void intel_hdmi_pre_enable(struct intel_encoder *encoder) ++{ ++ struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct intel_crtc *intel_crtc = ++ to_intel_crtc(encoder->base.crtc); ++ int port = vlv_dport_to_channel(dport); ++ int pipe = intel_crtc->pipe; ++ u32 val; ++ ++ if (!IS_VALLEYVIEW(dev)) ++ return; ++ ++ WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); ++ ++ /* Enable clock channels for this port */ ++ val = intel_dpio_read(dev_priv, DPIO_DATA_LANE_A(port)); ++ val = 0; ++ if (pipe) ++ val |= (1<<21); ++ else ++ val &= ~(1<<21); ++ val |= 0x001000c4; ++ intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val); ++ ++ /* HDMI 1.0V-2dB */ ++ intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0); ++ intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(port), ++ 0x2b245f5f); ++ intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(port), ++ 0x5578b83a); ++ intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL3(port), ++ 0x0c782040); ++ intel_dpio_write(dev_priv, DPIO_TX3_SWING_CTL4(port), ++ 0x2b247878); ++ intel_dpio_write(dev_priv, DPIO_PCS_STAGGER0(port), 0x00030000); ++ intel_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port), ++ 0x00002000); ++ intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), ++ DPIO_TX_OCALINIT_EN); ++ ++ /* Program lane clock */ ++ intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port), ++ 0x00760018); ++ intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port), ++ 0x00400888); ++} ++ ++static void intel_hdmi_pre_pll_enable(struct intel_encoder *encoder) ++{ ++ struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int port = vlv_dport_to_channel(dport); ++ ++ if (!IS_VALLEYVIEW(dev)) ++ return; ++ ++ WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); ++ ++ /* Program Tx lane resets to default */ ++ intel_dpio_write(dev_priv, DPIO_PCS_TX(port), ++ DPIO_PCS_TX_LANE2_RESET | ++ DPIO_PCS_TX_LANE1_RESET); ++ intel_dpio_write(dev_priv, DPIO_PCS_CLK(port), ++ DPIO_PCS_CLK_CRI_RXEB_EIOS_EN | ++ DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN | ++ (1<base); ++ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; ++ int port = vlv_dport_to_channel(dport); ++ ++ /* Reset lanes to avoid HDMI flicker (VLV w/a) */ ++ mutex_lock(&dev_priv->dpio_lock); ++ intel_dpio_write(dev_priv, DPIO_PCS_TX(port), 0x00000000); ++ intel_dpio_write(dev_priv, DPIO_PCS_CLK(port), 0x00e00060); ++ mutex_unlock(&dev_priv->dpio_lock); ++} ++ + static void intel_hdmi_destroy(struct drm_connector *connector) + { + drm_sysfs_connector_remove(connector); +@@ -1094,6 +1197,11 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) + intel_encoder->enable = intel_enable_hdmi; + intel_encoder->disable = intel_disable_hdmi; + intel_encoder->get_hw_state = intel_hdmi_get_hw_state; ++ if (IS_VALLEYVIEW(dev)) { ++ intel_encoder->pre_enable = intel_hdmi_pre_enable; ++ intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable; ++ intel_encoder->post_disable = intel_hdmi_post_disable; ++ } + + intel_encoder->type = INTEL_OUTPUT_HDMI; + intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0027-drm-i915-report-Gen5-CPU-and-PCH-FIFO-underruns.patch b/patches.baytrail/0027-drm-i915-report-Gen5-CPU-and-PCH-FIFO-underruns.patch new file mode 100644 index 000000000000..e3edcade2883 --- /dev/null +++ b/patches.baytrail/0027-drm-i915-report-Gen5-CPU-and-PCH-FIFO-underruns.patch @@ -0,0 +1,598 @@ +From e6e1de1d67ec43930bb3470ee5d89e58a882559f Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 12 Apr 2013 17:57:57 -0300 +Subject: drm/i915: report Gen5+ CPU and PCH FIFO underruns + +In this commit we enable both CPU and PCH FIFO underrun reporting and +start reporting them. We follow a few rules: + - after we receive one of these errors, we mask the interrupt, so + we won't get an "interrupt storm" and we also won't flood dmesg; + - at each mode set we enable the interrupts again, so we'll see each + message at most once per mode set; + - in the specific places where we need to ignore the errors, we + completely mask the interrupts. + +The downside of this patch is that since we're completely disabling +(masking) the interrupts instead of just not printing error messages, +we will mask more than just what we want on IVB/HSW CPU interrupts +(due to GEN7_ERR_INT) and on CPT/PPT/LPT PCHs (due to SERR_INT). So +when we decide to mask PCH FIFO underruns for pipe A on CPT, we'll +also be masking PCH FIFO underruns for pipe B, because both are +reported by SERR_INT, which has to be either completely enabled or +completely disabled (in othe words, there's no way to disable/enable +specific bits of GEN7_ERR_INT and SERR_INT). + +V2: Rename some functions and variables, downgrade messages to +DRM_DEBUG_DRIVER and rebase. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 8664281b64c457705db72fc60143d03827e75ca9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 315 ++++++++++++++++++++++++++++++++++- + drivers/gpu/drm/i915/i915_reg.h | 13 +- + drivers/gpu/drm/i915/intel_display.c | 14 ++ + drivers/gpu/drm/i915/intel_drv.h | 11 ++ + 4 files changed, 342 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 11a8f81a7fd1..859727d34c2c 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -103,6 +103,213 @@ ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) + } + } + ++static bool ivb_can_enable_err_int(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct intel_crtc *crtc; ++ enum pipe pipe; ++ ++ for_each_pipe(pipe) { ++ crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); ++ ++ if (crtc->cpu_fifo_underrun_disabled) ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool cpt_can_enable_serr_int(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ enum pipe pipe; ++ struct intel_crtc *crtc; ++ ++ for_each_pipe(pipe) { ++ crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); ++ ++ if (crtc->pch_fifo_underrun_disabled) ++ return false; ++ } ++ ++ return true; ++} ++ ++static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev, ++ enum pipe pipe, bool enable) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ uint32_t bit = (pipe == PIPE_A) ? DE_PIPEA_FIFO_UNDERRUN : ++ DE_PIPEB_FIFO_UNDERRUN; ++ ++ if (enable) ++ ironlake_enable_display_irq(dev_priv, bit); ++ else ++ ironlake_disable_display_irq(dev_priv, bit); ++} ++ ++static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, ++ bool enable) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (enable) { ++ if (!ivb_can_enable_err_int(dev)) ++ return; ++ ++ I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN_A | ++ ERR_INT_FIFO_UNDERRUN_B | ++ ERR_INT_FIFO_UNDERRUN_C); ++ ++ ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB); ++ } else { ++ ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); ++ } ++} ++ ++static void ibx_set_fifo_underrun_reporting(struct intel_crtc *crtc, ++ bool enable) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ uint32_t bit = (crtc->pipe == PIPE_A) ? SDE_TRANSA_FIFO_UNDER : ++ SDE_TRANSB_FIFO_UNDER; ++ ++ if (enable) ++ I915_WRITE(SDEIMR, I915_READ(SDEIMR) & ~bit); ++ else ++ I915_WRITE(SDEIMR, I915_READ(SDEIMR) | bit); ++ ++ POSTING_READ(SDEIMR); ++} ++ ++static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, ++ enum transcoder pch_transcoder, ++ bool enable) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (enable) { ++ if (!cpt_can_enable_serr_int(dev)) ++ return; ++ ++ I915_WRITE(SERR_INT, SERR_INT_TRANS_A_FIFO_UNDERRUN | ++ SERR_INT_TRANS_B_FIFO_UNDERRUN | ++ SERR_INT_TRANS_C_FIFO_UNDERRUN); ++ ++ I915_WRITE(SDEIMR, I915_READ(SDEIMR) & ~SDE_ERROR_CPT); ++ } else { ++ I915_WRITE(SDEIMR, I915_READ(SDEIMR) | SDE_ERROR_CPT); ++ } ++ ++ POSTING_READ(SDEIMR); ++} ++ ++/** ++ * intel_set_cpu_fifo_underrun_reporting - enable/disable FIFO underrun messages ++ * @dev: drm device ++ * @pipe: pipe ++ * @enable: true if we want to report FIFO underrun errors, false otherwise ++ * ++ * This function makes us disable or enable CPU fifo underruns for a specific ++ * pipe. Notice that on some Gens (e.g. IVB, HSW), disabling FIFO underrun ++ * reporting for one pipe may also disable all the other CPU error interruts for ++ * the other pipes, due to the fact that there's just one interrupt mask/enable ++ * bit for all the pipes. ++ * ++ * Returns the previous state of underrun reporting. ++ */ ++bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, ++ enum pipe pipe, bool enable) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ unsigned long flags; ++ bool ret; ++ ++ spin_lock_irqsave(&dev_priv->irq_lock, flags); ++ ++ ret = !intel_crtc->cpu_fifo_underrun_disabled; ++ ++ if (enable == ret) ++ goto done; ++ ++ intel_crtc->cpu_fifo_underrun_disabled = !enable; ++ ++ if (IS_GEN5(dev) || IS_GEN6(dev)) ++ ironlake_set_fifo_underrun_reporting(dev, pipe, enable); ++ else if (IS_GEN7(dev)) ++ ivybridge_set_fifo_underrun_reporting(dev, enable); ++ ++done: ++ spin_unlock_irqrestore(&dev_priv->irq_lock, flags); ++ return ret; ++} ++ ++/** ++ * intel_set_pch_fifo_underrun_reporting - enable/disable FIFO underrun messages ++ * @dev: drm device ++ * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older) ++ * @enable: true if we want to report FIFO underrun errors, false otherwise ++ * ++ * This function makes us disable or enable PCH fifo underruns for a specific ++ * PCH transcoder. Notice that on some PCHs (e.g. CPT/PPT), disabling FIFO ++ * underrun reporting for one transcoder may also disable all the other PCH ++ * error interruts for the other transcoders, due to the fact that there's just ++ * one interrupt mask/enable bit for all the transcoders. ++ * ++ * Returns the previous state of underrun reporting. ++ */ ++bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, ++ enum transcoder pch_transcoder, ++ bool enable) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ enum pipe p; ++ struct drm_crtc *crtc; ++ struct intel_crtc *intel_crtc; ++ unsigned long flags; ++ bool ret; ++ ++ if (HAS_PCH_LPT(dev)) { ++ crtc = NULL; ++ for_each_pipe(p) { ++ struct drm_crtc *c = dev_priv->pipe_to_crtc_mapping[p]; ++ if (intel_pipe_has_type(c, INTEL_OUTPUT_ANALOG)) { ++ crtc = c; ++ break; ++ } ++ } ++ if (!crtc) { ++ DRM_ERROR("PCH FIFO underrun, but no CRTC using the PCH found\n"); ++ return false; ++ } ++ } else { ++ crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder]; ++ } ++ intel_crtc = to_intel_crtc(crtc); ++ ++ spin_lock_irqsave(&dev_priv->irq_lock, flags); ++ ++ ret = !intel_crtc->pch_fifo_underrun_disabled; ++ ++ if (enable == ret) ++ goto done; ++ ++ intel_crtc->pch_fifo_underrun_disabled = !enable; ++ ++ if (HAS_PCH_IBX(dev)) ++ ibx_set_fifo_underrun_reporting(intel_crtc, enable); ++ else ++ cpt_set_fifo_underrun_reporting(dev, pch_transcoder, enable); ++ ++done: ++ spin_unlock_irqrestore(&dev_priv->irq_lock, flags); ++ return ret; ++} ++ ++ + void + i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) + { +@@ -791,10 +998,58 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) + if (pch_iir & (SDE_TRANSB_CRC_ERR | SDE_TRANSA_CRC_ERR)) + DRM_DEBUG_DRIVER("PCH transcoder CRC error interrupt\n"); + +- if (pch_iir & SDE_TRANSB_FIFO_UNDER) +- DRM_DEBUG_DRIVER("PCH transcoder B underrun interrupt\n"); + if (pch_iir & SDE_TRANSA_FIFO_UNDER) +- DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); ++ if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, ++ false)) ++ DRM_DEBUG_DRIVER("PCH transcoder A FIFO underrun\n"); ++ ++ if (pch_iir & SDE_TRANSB_FIFO_UNDER) ++ if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_B, ++ false)) ++ DRM_DEBUG_DRIVER("PCH transcoder B FIFO underrun\n"); ++} ++ ++static void ivb_err_int_handler(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ u32 err_int = I915_READ(GEN7_ERR_INT); ++ ++ if (err_int & ERR_INT_FIFO_UNDERRUN_A) ++ if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_A, false)) ++ DRM_DEBUG_DRIVER("Pipe A FIFO underrun\n"); ++ ++ if (err_int & ERR_INT_FIFO_UNDERRUN_B) ++ if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_B, false)) ++ DRM_DEBUG_DRIVER("Pipe B FIFO underrun\n"); ++ ++ if (err_int & ERR_INT_FIFO_UNDERRUN_C) ++ if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_C, false)) ++ DRM_DEBUG_DRIVER("Pipe C FIFO underrun\n"); ++ ++ I915_WRITE(GEN7_ERR_INT, err_int); ++} ++ ++static void cpt_serr_int_handler(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ u32 serr_int = I915_READ(SERR_INT); ++ ++ if (serr_int & SERR_INT_TRANS_A_FIFO_UNDERRUN) ++ if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, ++ false)) ++ DRM_DEBUG_DRIVER("PCH transcoder A FIFO underrun\n"); ++ ++ if (serr_int & SERR_INT_TRANS_B_FIFO_UNDERRUN) ++ if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_B, ++ false)) ++ DRM_DEBUG_DRIVER("PCH transcoder B FIFO underrun\n"); ++ ++ if (serr_int & SERR_INT_TRANS_C_FIFO_UNDERRUN) ++ if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_C, ++ false)) ++ DRM_DEBUG_DRIVER("PCH transcoder C FIFO underrun\n"); ++ ++ I915_WRITE(SERR_INT, serr_int); + } + + static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) +@@ -832,6 +1087,9 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) + DRM_DEBUG_DRIVER(" pipe %c FDI IIR: 0x%08x\n", + pipe_name(pipe), + I915_READ(FDI_RX_IIR(pipe))); ++ ++ if (pch_iir & SDE_ERROR_CPT) ++ cpt_serr_int_handler(dev); + } + + static irqreturn_t ivybridge_irq_handler(int irq, void *arg) +@@ -844,6 +1102,14 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + + atomic_inc(&dev_priv->irq_received); + ++ /* We get interrupts on unclaimed registers, so check for this before we ++ * do any I915_{READ,WRITE}. */ ++ if (IS_HASWELL(dev) && ++ (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { ++ DRM_ERROR("Unclaimed register before interrupt\n"); ++ I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); ++ } ++ + /* disable master interrupt before clearing iir */ + de_ier = I915_READ(DEIER); + I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); +@@ -859,6 +1125,12 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + POSTING_READ(SDEIER); + } + ++ /* On Haswell, also mask ERR_INT because we don't want to risk ++ * generating "unclaimed register" interrupts from inside the interrupt ++ * handler. */ ++ if (IS_HASWELL(dev)) ++ ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); ++ + gt_iir = I915_READ(GTIIR); + if (gt_iir) { + snb_gt_irq_handler(dev, dev_priv, gt_iir); +@@ -868,6 +1140,9 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + + de_iir = I915_READ(DEIIR); + if (de_iir) { ++ if (de_iir & DE_ERR_INT_IVB) ++ ivb_err_int_handler(dev); ++ + if (de_iir & DE_AUX_CHANNEL_A_IVB) + dp_aux_irq_handler(dev); + +@@ -905,6 +1180,9 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + ret = IRQ_HANDLED; + } + ++ if (IS_HASWELL(dev) && ivb_can_enable_err_int(dev)) ++ ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB); ++ + I915_WRITE(DEIER, de_ier); + POSTING_READ(DEIER); + if (!HAS_PCH_NOP(dev)) { +@@ -974,6 +1252,14 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + if (de_iir & DE_PIPEB_VBLANK) + drm_handle_vblank(dev, 1); + ++ if (de_iir & DE_PIPEA_FIFO_UNDERRUN) ++ if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_A, false)) ++ DRM_DEBUG_DRIVER("Pipe A FIFO underrun\n"); ++ ++ if (de_iir & DE_PIPEB_FIFO_UNDERRUN) ++ if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_B, false)) ++ DRM_DEBUG_DRIVER("Pipe B FIFO underrun\n"); ++ + if (de_iir & DE_PLANEA_FLIP_DONE) { + intel_prepare_page_flip(dev, 0); + intel_finish_page_flip_plane(dev, 0); +@@ -2245,10 +2531,14 @@ static void ibx_irq_postinstall(struct drm_device *dev) + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u32 mask; + +- if (HAS_PCH_IBX(dev)) +- mask = SDE_GMBUS | SDE_AUX_MASK; +- else +- mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT; ++ if (HAS_PCH_IBX(dev)) { ++ mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER | ++ SDE_TRANSA_FIFO_UNDER; ++ } else { ++ mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT; ++ ++ I915_WRITE(SERR_INT, I915_READ(SERR_INT)); ++ } + + if (HAS_PCH_NOP(dev)) + return; +@@ -2263,7 +2553,8 @@ static int ironlake_irq_postinstall(struct drm_device *dev) + /* enable kind of interrupts always enabled */ + u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | + DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | +- DE_AUX_CHANNEL_A; ++ DE_AUX_CHANNEL_A | DE_PIPEB_FIFO_UNDERRUN | ++ DE_PIPEA_FIFO_UNDERRUN; + u32 render_irqs; + + dev_priv->irq_mask = ~display_mask; +@@ -2313,12 +2604,14 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) + DE_PLANEC_FLIP_DONE_IVB | + DE_PLANEB_FLIP_DONE_IVB | + DE_PLANEA_FLIP_DONE_IVB | +- DE_AUX_CHANNEL_A_IVB; ++ DE_AUX_CHANNEL_A_IVB | ++ DE_ERR_INT_IVB; + u32 render_irqs; + + dev_priv->irq_mask = ~display_mask; + + /* should always can generate irq */ ++ I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); + I915_WRITE(DEIIR, I915_READ(DEIIR)); + I915_WRITE(DEIMR, dev_priv->irq_mask); + I915_WRITE(DEIER, +@@ -2446,6 +2739,8 @@ static void ironlake_irq_uninstall(struct drm_device *dev) + I915_WRITE(DEIMR, 0xffffffff); + I915_WRITE(DEIER, 0x0); + I915_WRITE(DEIIR, I915_READ(DEIIR)); ++ if (IS_GEN7(dev)) ++ I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); + + I915_WRITE(GTIMR, 0xffffffff); + I915_WRITE(GTIER, 0x0); +@@ -2457,6 +2752,8 @@ static void ironlake_irq_uninstall(struct drm_device *dev) + I915_WRITE(SDEIMR, 0xffffffff); + I915_WRITE(SDEIER, 0x0); + I915_WRITE(SDEIIR, I915_READ(SDEIIR)); ++ if (HAS_PCH_CPT(dev) || HAS_PCH_LPT(dev)) ++ I915_WRITE(SERR_INT, I915_READ(SERR_INT)); + } + + static void i8xx_irq_preinstall(struct drm_device * dev) +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index a5fe3ba7d00d..b76679e401d2 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -638,7 +638,10 @@ + + #define ERROR_GEN6 0x040a0 + #define GEN7_ERR_INT 0x44040 +-#define ERR_INT_MMIO_UNCLAIMED (1<<13) ++#define ERR_INT_MMIO_UNCLAIMED (1<<13) ++#define ERR_INT_FIFO_UNDERRUN_C (1<<6) ++#define ERR_INT_FIFO_UNDERRUN_B (1<<3) ++#define ERR_INT_FIFO_UNDERRUN_A (1<<0) + + #define FPGA_DBG 0x42300 + #define FPGA_DBG_RM_NOCLAIM (1<<31) +@@ -3622,7 +3625,7 @@ + #define DE_PIPEA_FIFO_UNDERRUN (1 << 0) + + /* More Ivybridge lolz */ +-#define DE_ERR_DEBUG_IVB (1<<30) ++#define DE_ERR_INT_IVB (1<<30) + #define DE_GSE_IVB (1<<29) + #define DE_PCH_EVENT_IVB (1<<28) + #define DE_DP_A_HOTPLUG_IVB (1<<27) +@@ -3781,6 +3784,7 @@ + SDE_PORTC_HOTPLUG_CPT | \ + SDE_PORTB_HOTPLUG_CPT) + #define SDE_GMBUS_CPT (1 << 17) ++#define SDE_ERROR_CPT (1 << 16) + #define SDE_AUDIO_CP_REQ_C_CPT (1 << 10) + #define SDE_AUDIO_CP_CHG_C_CPT (1 << 9) + #define SDE_FDI_RXC_CPT (1 << 8) +@@ -3805,6 +3809,11 @@ + #define SDEIIR 0xc4008 + #define SDEIER 0xc400c + ++#define SERR_INT 0xc4040 ++#define SERR_INT_TRANS_C_FIFO_UNDERRUN (1<<6) ++#define SERR_INT_TRANS_B_FIFO_UNDERRUN (1<<3) ++#define SERR_INT_TRANS_A_FIFO_UNDERRUN (1<<0) ++ + /* digital port hotplug */ + #define PCH_PORT_HOTPLUG 0xc4030 /* SHOTPLUG_CTL */ + #define PORTD_HOTPLUG_ENABLE (1 << 20) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 913860931245..212fb82e0f31 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3346,6 +3346,10 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + return; + + intel_crtc->active = true; ++ ++ intel_set_cpu_fifo_underrun_reporting(dev, pipe, true); ++ intel_set_pch_fifo_underrun_reporting(dev, pipe, true); ++ + intel_update_watermarks(dev); + + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { +@@ -3437,6 +3441,11 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) + return; + + intel_crtc->active = true; ++ ++ intel_set_cpu_fifo_underrun_reporting(dev, pipe, true); ++ if (intel_crtc->config.has_pch_encoder) ++ intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true); ++ + intel_update_watermarks(dev); + + if (intel_crtc->config.has_pch_encoder) +@@ -3523,6 +3532,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) + if (dev_priv->cfb_plane == plane) + intel_disable_fbc(dev); + ++ intel_set_pch_fifo_underrun_reporting(dev, pipe, false); + intel_disable_pipe(dev_priv, pipe); + + /* Disable PF */ +@@ -3536,6 +3546,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) + ironlake_fdi_disable(crtc); + + ironlake_disable_pch_transcoder(dev_priv, pipe); ++ intel_set_pch_fifo_underrun_reporting(dev, pipe, true); + + if (HAS_PCH_CPT(dev)) { + /* disable TRANS_DP_CTL */ +@@ -3602,6 +3613,8 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) + if (dev_priv->cfb_plane == plane) + intel_disable_fbc(dev); + ++ if (intel_crtc->config.has_pch_encoder) ++ intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false); + intel_disable_pipe(dev_priv, pipe); + + intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); +@@ -3622,6 +3635,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) + + if (intel_crtc->config.has_pch_encoder) { + lpt_disable_pch_transcoder(dev_priv); ++ intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true); + intel_ddi_fdi_disable(crtc); + } + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 310899f4c3b5..3976eadbb4b6 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -265,6 +265,10 @@ struct intel_crtc { + + /* reset counter value when the last flip was submitted */ + unsigned int reset_counter; ++ ++ /* Access to these should be protected by dev_priv->irq_lock. */ ++ bool cpu_fifo_underrun_disabled; ++ bool pch_fifo_underrun_disabled; + }; + + struct intel_plane { +@@ -487,6 +491,7 @@ int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); + extern void intel_attach_force_audio_property(struct drm_connector *connector); + extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector); + ++extern bool intel_pipe_has_type(struct drm_crtc *crtc, int type); + extern void intel_crt_init(struct drm_device *dev); + extern void intel_hdmi_init(struct drm_device *dev, + int hdmi_reg, enum port port); +@@ -744,5 +749,11 @@ intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector); + extern void intel_ddi_fdi_disable(struct drm_crtc *crtc); + + extern void intel_display_handle_reset(struct drm_device *dev); ++extern bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, ++ enum pipe pipe, ++ bool enable); ++extern bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, ++ enum transcoder pch_transcoder, ++ bool enable); + + #endif /* __INTEL_DRV_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0028-drm-i915-print-Gen5-CPU-PCH-poison-interrupts.patch b/patches.baytrail/0028-drm-i915-print-Gen5-CPU-PCH-poison-interrupts.patch new file mode 100644 index 000000000000..219286d5ba6e --- /dev/null +++ b/patches.baytrail/0028-drm-i915-print-Gen5-CPU-PCH-poison-interrupts.patch @@ -0,0 +1,94 @@ +From b8e93abe1d9a7e71c40997d861fa216ff96a0082 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 12 Apr 2013 17:57:58 -0300 +Subject: drm/i915: print Gen5+ CPU/PCH poison interrupts + +This is bad news and shouldn't be happening. + +V2: Rebase. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit de032bf40a52dbbada11e071d150d2c062b5527e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 13 +++++++++++-- + drivers/gpu/drm/i915/i915_reg.h | 2 ++ + 2 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 859727d34c2c..450a03c6f945 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1014,6 +1014,9 @@ static void ivb_err_int_handler(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + u32 err_int = I915_READ(GEN7_ERR_INT); + ++ if (err_int & ERR_INT_POISON) ++ DRM_ERROR("Poison interrupt\n"); ++ + if (err_int & ERR_INT_FIFO_UNDERRUN_A) + if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_A, false)) + DRM_DEBUG_DRIVER("Pipe A FIFO underrun\n"); +@@ -1034,6 +1037,9 @@ static void cpt_serr_int_handler(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + u32 serr_int = I915_READ(SERR_INT); + ++ if (serr_int & SERR_INT_POISON) ++ DRM_ERROR("PCH poison interrupt\n"); ++ + if (serr_int & SERR_INT_TRANS_A_FIFO_UNDERRUN) + if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, + false)) +@@ -1252,6 +1258,9 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + if (de_iir & DE_PIPEB_VBLANK) + drm_handle_vblank(dev, 1); + ++ if (de_iir & DE_POISON) ++ DRM_ERROR("Poison interrupt\n"); ++ + if (de_iir & DE_PIPEA_FIFO_UNDERRUN) + if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_A, false)) + DRM_DEBUG_DRIVER("Pipe A FIFO underrun\n"); +@@ -2533,7 +2542,7 @@ static void ibx_irq_postinstall(struct drm_device *dev) + + if (HAS_PCH_IBX(dev)) { + mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER | +- SDE_TRANSA_FIFO_UNDER; ++ SDE_TRANSA_FIFO_UNDER | SDE_POISON; + } else { + mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT; + +@@ -2554,7 +2563,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) + u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | + DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | + DE_AUX_CHANNEL_A | DE_PIPEB_FIFO_UNDERRUN | +- DE_PIPEA_FIFO_UNDERRUN; ++ DE_PIPEA_FIFO_UNDERRUN | DE_POISON; + u32 render_irqs; + + dev_priv->irq_mask = ~display_mask; +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index b76679e401d2..5a7a694121ec 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -638,6 +638,7 @@ + + #define ERROR_GEN6 0x040a0 + #define GEN7_ERR_INT 0x44040 ++#define ERR_INT_POISON (1<<31) + #define ERR_INT_MMIO_UNCLAIMED (1<<13) + #define ERR_INT_FIFO_UNDERRUN_C (1<<6) + #define ERR_INT_FIFO_UNDERRUN_B (1<<3) +@@ -3810,6 +3811,7 @@ + #define SDEIER 0xc400c + + #define SERR_INT 0xc4040 ++#define SERR_INT_POISON (1<<31) + #define SERR_INT_TRANS_C_FIFO_UNDERRUN (1<<6) + #define SERR_INT_TRANS_B_FIFO_UNDERRUN (1<<3) + #define SERR_INT_TRANS_A_FIFO_UNDERRUN (1<<0) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0029-drm-i915-check-the-power-well-inside-haswell_get_pip.patch b/patches.baytrail/0029-drm-i915-check-the-power-well-inside-haswell_get_pip.patch new file mode 100644 index 000000000000..3c313ea85bee --- /dev/null +++ b/patches.baytrail/0029-drm-i915-check-the-power-well-inside-haswell_get_pip.patch @@ -0,0 +1,47 @@ +From 53aa484893afe71e12b9e73cf75389cfc74ae314 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 18 Apr 2013 16:35:40 -0300 +Subject: drm/i915: check the power well inside haswell_get_pipe_config + +This fixes "unclaimed register" messages when booting with eDP only +and i915.disable_power_well=1. + +The error messages were caused by: + + commit 0e8ffe1bf81b0780cc6229cb38664754dffe8776 + Author: Daniel Vetter + Date: Thu Mar 28 10:42:00 2013 +0100 + drm/i915: add hw state readout/checking for pipe_config + +Signed-off-by: Paulo Zanoni +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 2bfce95075fa58eaf2ead5b0863c50a3f6098bc2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 212fb82e0f31..f81c1fce9621 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5990,9 +5990,14 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + { + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; ++ enum transcoder cpu_transcoder = crtc->config.cpu_transcoder; + uint32_t tmp; + +- tmp = I915_READ(PIPECONF(crtc->config.cpu_transcoder)); ++ if (!intel_using_power_well(dev_priv->dev) && ++ cpu_transcoder != TRANSCODER_EDP) ++ return false; ++ ++ tmp = I915_READ(PIPECONF(cpu_transcoder)); + if (!(tmp & PIPECONF_ENABLE)) + return false; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0030-drm-i915-use-cpu_transcoder-for-TRANS_DDI_FUNC_CTL.patch b/patches.baytrail/0030-drm-i915-use-cpu_transcoder-for-TRANS_DDI_FUNC_CTL.patch new file mode 100644 index 000000000000..d819ac722257 --- /dev/null +++ b/patches.baytrail/0030-drm-i915-use-cpu_transcoder-for-TRANS_DDI_FUNC_CTL.patch @@ -0,0 +1,53 @@ +From 89cda7e13d3f55c52ccf0f9e4ecb76b9a4ec96d1 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 18 Apr 2013 16:35:41 -0300 +Subject: drm/i915: use cpu_transcoder for TRANS_DDI_FUNC_CTL + +... inside haswell_get_pipe_config. Because there's one TRANS_DDI_FUNC_CTL +register per CPU transcoder, not per pipe. This solves "unclaimed register" +messages when booting with eDP only and using the i915.disable_power_well=1. + +Also fix a comment and remove an useless empty line. + +The error messages were caused by: + + commit 88adfff1ad5019f65b9d0b4e1a4ac900fb065183 + Author: Daniel Vetter + Date: Thu Mar 28 10:42:01 2013 +0100 + drm/i915: hw readout support for ->has_pch_encoders + +Signed-off-by: Paulo Zanoni +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit f196e6bedb1b8a76f8526798e0feeb7a213e7505) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index f81c1fce9621..ea83011e454e 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -6002,16 +6002,15 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + return false; + + /* +- * aswell has only FDI/PCH transcoder A. It is which is connected to ++ * Haswell has only FDI/PCH transcoder A. It is which is connected to + * DDI E. So just check whether this pipe is wired to DDI E and whether + * the PCH transcoder is on. + */ +- tmp = I915_READ(TRANS_DDI_FUNC_CTL(crtc->pipe)); ++ tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); + if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(PORT_E) && + I915_READ(TRANSCONF(PIPE_A)) & TRANS_ENABLE) + pipe_config->has_pch_encoder = true; + +- + return true; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0031-drm-i915-Move-the-CSC_MODE-bits-next-to-the-register.patch b/patches.baytrail/0031-drm-i915-Move-the-CSC_MODE-bits-next-to-the-register.patch new file mode 100644 index 000000000000..b2462ad5e1ad --- /dev/null +++ b/patches.baytrail/0031-drm-i915-Move-the-CSC_MODE-bits-next-to-the-register.patch @@ -0,0 +1,47 @@ +From 4ac68de94caec9322808b63579589d08a543414f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 19 Apr 2013 12:23:02 +0300 +Subject: drm/i915: Move the CSC_MODE bits next to the register +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Shame on me for not putting the bit definitions next to the register +definition in the first place. + +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 29a397ba7a4bded235c79f050753637cad3409ff) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 5a7a694121ec..14cd707265b9 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -4939,6 +4939,9 @@ + #define _PIPE_A_CSC_COEFF_RV_GV 0x49020 + #define _PIPE_A_CSC_COEFF_BV 0x49024 + #define _PIPE_A_CSC_MODE 0x49028 ++#define CSC_BLACK_SCREEN_OFFSET (1 << 2) ++#define CSC_POSITION_BEFORE_GAMMA (1 << 1) ++#define CSC_MODE_YUV_TO_RGB (1 << 0) + #define _PIPE_A_CSC_PREOFF_HI 0x49030 + #define _PIPE_A_CSC_PREOFF_ME 0x49034 + #define _PIPE_A_CSC_PREOFF_LO 0x49038 +@@ -4960,10 +4963,6 @@ + #define _PIPE_B_CSC_POSTOFF_ME 0x49144 + #define _PIPE_B_CSC_POSTOFF_LO 0x49148 + +-#define CSC_BLACK_SCREEN_OFFSET (1 << 2) +-#define CSC_POSITION_BEFORE_GAMMA (1 << 1) +-#define CSC_MODE_YUV_TO_RGB (1 << 0) +- + #define PIPE_CSC_COEFF_RY_GY(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RY_GY, _PIPE_B_CSC_COEFF_RY_GY) + #define PIPE_CSC_COEFF_BY(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BY, _PIPE_B_CSC_COEFF_BY) + #define PIPE_CSC_COEFF_RU_GU(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RU_GU, _PIPE_B_CSC_COEFF_RU_GU) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0032-drm-i915-Remove-mention-of-Haswell-in-DDI-code.patch b/patches.baytrail/0032-drm-i915-Remove-mention-of-Haswell-in-DDI-code.patch new file mode 100644 index 000000000000..1096e6701bbc --- /dev/null +++ b/patches.baytrail/0032-drm-i915-Remove-mention-of-Haswell-in-DDI-code.patch @@ -0,0 +1,34 @@ +From d60584171f5c15809251cecefe553680bd758d28 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Fri, 19 Apr 2013 14:27:31 +0100 +Subject: drm/i915: Remove mention of Haswell in DDI code + +We are trying to have more platform-orthogonal pieces of code. The DDI +code shouldn't mention Haswell. + +v2: Fix the email address + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit bf98a72650c9272e70e7f0e904f85c025c0bb421) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 3b798ae62075..cfaf6bead217 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -675,7 +675,7 @@ static void intel_ddi_mode_set(struct drm_encoder *encoder, + int pipe = intel_crtc->pipe; + int type = intel_encoder->type; + +- DRM_DEBUG_KMS("Preparing DDI mode for Haswell on port %c, pipe %c\n", ++ DRM_DEBUG_KMS("Preparing DDI mode on port %c, pipe %c\n", + port_name(port), pipe_name(pipe)); + + intel_crtc->eld_vld = false; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0033-drm-i915-use-vlv_dport_to_channel-in-vlv_signal_leve.patch b/patches.baytrail/0033-drm-i915-use-vlv_dport_to_channel-in-vlv_signal_leve.patch new file mode 100644 index 000000000000..b4a41a756338 --- /dev/null +++ b/patches.baytrail/0033-drm-i915-use-vlv_dport_to_channel-in-vlv_signal_leve.patch @@ -0,0 +1,40 @@ +From 39c407ed1c6b7da0c806c98c21964cc1bd4f8230 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Fri, 19 Apr 2013 08:46:35 -0700 +Subject: drm/i915: use vlv_dport_to_channel in vlv_signal_levels + +Minor cleanup. Would be nice to use an enum for channel in the DPIO +macros so we don't mix up pipes and channels, but that's for another +patch. + +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit cece5d58d5568e4a7986e43981d21a80ea189a82) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 415caad2b10f..d8407c9b0504 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1597,14 +1597,7 @@ static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp) + unsigned long demph_reg_value, preemph_reg_value, + uniqtranscale_reg_value; + uint8_t train_set = intel_dp->train_set[0]; +- int port; +- +- if (dport->port == PORT_B) +- port = 0; +- else if (dport->port == PORT_C) +- port = 1; +- else +- BUG(); ++ int port = vlv_dport_to_channel(dport); + + WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0034-drm-i915-Make-struct-dpll-intel_clock_t.patch b/patches.baytrail/0034-drm-i915-Make-struct-dpll-intel_clock_t.patch new file mode 100644 index 000000000000..f390b3dcb88d --- /dev/null +++ b/patches.baytrail/0034-drm-i915-Make-struct-dpll-intel_clock_t.patch @@ -0,0 +1,81 @@ +From 2bde9fef869ee4b50c60e74e71e5a34806176038 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 19 Apr 2013 14:36:51 +0300 +Subject: drm/i915: Make struct dpll == intel_clock_t +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This allows unifying a bunch of the PLL calculations and whatnot. + +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 80ad9206c0d863832bc5f6008c4d1868d1df8e70) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 12 ------------ + drivers/gpu/drm/i915/intel_drv.h | 18 +++++++++++++----- + 2 files changed, 13 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index ea83011e454e..0db840241690 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -46,18 +46,6 @@ static void intel_increase_pllclock(struct drm_crtc *crtc); + static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); + + typedef struct { +- /* given values */ +- int n; +- int m1, m2; +- int p1, p2; +- /* derived values */ +- int dot; +- int vco; +- int m; +- int p; +-} intel_clock_t; +- +-typedef struct { + int min, max; + } intel_range_t; + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 3976eadbb4b6..a8e180732452 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -177,6 +177,18 @@ struct intel_connector { + u8 polled; + }; + ++typedef struct dpll { ++ /* given values */ ++ int n; ++ int m1, m2; ++ int p1, p2; ++ /* derived values */ ++ int dot; ++ int vco; ++ int m; ++ int p; ++} intel_clock_t; ++ + struct intel_crtc_config { + struct drm_display_mode requested_mode; + struct drm_display_mode adjusted_mode; +@@ -208,11 +220,7 @@ struct intel_crtc_config { + + /* Settings for the intel dpll used on pretty much everything but + * haswell. */ +- struct dpll { +- unsigned n; +- unsigned m1, m2; +- unsigned p1, p2; +- } dpll; ++ struct dpll dpll; + + int pipe_bpp; + struct intel_link_m_n dp_m_n; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0035-drm-i915-Add-PTE-encoding-function-to-the-gtt-ppgtt-.patch b/patches.baytrail/0035-drm-i915-Add-PTE-encoding-function-to-the-gtt-ppgtt-.patch new file mode 100644 index 000000000000..36e0cb695030 --- /dev/null +++ b/patches.baytrail/0035-drm-i915-Add-PTE-encoding-function-to-the-gtt-ppgtt-.patch @@ -0,0 +1,158 @@ +From 951c1081a166a1a0f58a7a310c3c72057d097631 Mon Sep 17 00:00:00 2001 +From: Kenneth Graunke +Date: Mon, 22 Apr 2013 00:53:49 -0700 +Subject: drm/i915: Add PTE encoding function to the gtt/ppgtt vtables. + +Sandybridge/Ivybridge, Bay Trail, and Haswell all have slightly +different page table entry formats. Rather than polluting one function +with generation checks, simply use a function pointer and set up the +correct PTE encoding function at startup. + +v2: Move the gen6_gtt_pte_t typedef to i915_drv.h so that the function + pointers and implementations have identical signatures. Also remove + inline keyword on gen6_pte_encode. Both suggested by Jani Nikula. + +Signed-off-by: Kenneth Graunke +Reviewed-by: Jani Nikula +Tested-by: Daniel Leung [v1] +Signed-off-by: Daniel Vetter +(cherry picked from commit 2d04befb949744998284d8551ae7cd47059b8a53) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 8 ++++++++ + drivers/gpu/drm/i915/i915_gem_gtt.c | 30 ++++++++++++++++-------------- + 2 files changed, 24 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index b32a0b18f003..0ede85bcb45b 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -395,6 +395,8 @@ enum i915_cache_level { + I915_CACHE_LLC_MLC, /* gen6+, in docs at least! */ + }; + ++typedef uint32_t gen6_gtt_pte_t; ++ + /* The Graphics Translation Table is the way in which GEN hardware translates a + * Graphics Virtual Address into a Physical Address. In addition to the normal + * collateral associated with any va->pa translations GEN hardware also has a +@@ -430,6 +432,9 @@ struct i915_gtt { + struct sg_table *st, + unsigned int pg_start, + enum i915_cache_level cache_level); ++ gen6_gtt_pte_t (*pte_encode)(struct drm_device *dev, ++ dma_addr_t addr, ++ enum i915_cache_level level); + }; + #define gtt_total_entries(gtt) ((gtt).total >> PAGE_SHIFT) + +@@ -451,6 +456,9 @@ struct i915_hw_ppgtt { + struct sg_table *st, + unsigned int pg_start, + enum i915_cache_level cache_level); ++ gen6_gtt_pte_t (*pte_encode)(struct drm_device *dev, ++ dma_addr_t addr, ++ enum i915_cache_level level); + int (*enable)(struct drm_device *dev); + void (*cleanup)(struct i915_hw_ppgtt *ppgtt); + }; +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index bdb0d7717bc7..a6b4af7b425a 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -28,8 +28,6 @@ + #include "i915_trace.h" + #include "intel_drv.h" + +-typedef uint32_t gen6_gtt_pte_t; +- + /* PPGTT stuff */ + #define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) + +@@ -44,9 +42,9 @@ typedef uint32_t gen6_gtt_pte_t; + #define GEN6_PTE_CACHE_LLC_MLC (3 << 1) + #define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) + +-static inline gen6_gtt_pte_t gen6_pte_encode(struct drm_device *dev, +- dma_addr_t addr, +- enum i915_cache_level level) ++static gen6_gtt_pte_t gen6_pte_encode(struct drm_device *dev, ++ dma_addr_t addr, ++ enum i915_cache_level level) + { + gen6_gtt_pte_t pte = GEN6_PTE_VALID; + pte |= GEN6_PTE_ADDR_ENCODE(addr); +@@ -154,9 +152,9 @@ static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, + unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; + unsigned last_pte, i; + +- scratch_pte = gen6_pte_encode(ppgtt->dev, +- ppgtt->scratch_page_dma_addr, +- I915_CACHE_LLC); ++ scratch_pte = ppgtt->pte_encode(ppgtt->dev, ++ ppgtt->scratch_page_dma_addr, ++ I915_CACHE_LLC); + + while (num_entries) { + last_pte = first_pte + num_entries; +@@ -191,8 +189,8 @@ static void gen6_ppgtt_insert_entries(struct i915_hw_ppgtt *ppgtt, + dma_addr_t page_addr; + + page_addr = sg_page_iter_dma_address(&sg_iter); +- pt_vaddr[act_pte] = gen6_pte_encode(ppgtt->dev, page_addr, +- cache_level); ++ pt_vaddr[act_pte] = ppgtt->pte_encode(ppgtt->dev, page_addr, ++ cache_level); + if (++act_pte == I915_PPGTT_PT_ENTRIES) { + kunmap_atomic(pt_vaddr); + act_pt++; +@@ -235,6 +233,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) + * now. */ + first_pd_entry_in_global_pt = gtt_total_entries(dev_priv->gtt); + ++ ppgtt->pte_encode = gen6_pte_encode; + ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES; + ppgtt->enable = gen6_ppgtt_enable; + ppgtt->clear_range = gen6_ppgtt_clear_range; +@@ -437,7 +436,8 @@ static void gen6_ggtt_insert_entries(struct drm_device *dev, + + for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) { + addr = sg_page_iter_dma_address(&sg_iter); +- iowrite32(gen6_pte_encode(dev, addr, level), >t_entries[i]); ++ iowrite32(dev_priv->gtt.pte_encode(dev, addr, level), ++ >t_entries[i]); + i++; + } + +@@ -449,7 +449,7 @@ static void gen6_ggtt_insert_entries(struct drm_device *dev, + */ + if (i != 0) + WARN_ON(readl(>t_entries[i-1]) +- != gen6_pte_encode(dev, addr, level)); ++ != dev_priv->gtt.pte_encode(dev, addr, level)); + + /* This next bit makes the above posting read even more important. We + * want to flush the TLBs only after we're certain all the PTE updates +@@ -474,8 +474,9 @@ static void gen6_ggtt_clear_range(struct drm_device *dev, + first_entry, num_entries, max_entries)) + num_entries = max_entries; + +- scratch_pte = gen6_pte_encode(dev, dev_priv->gtt.scratch_page_dma, +- I915_CACHE_LLC); ++ scratch_pte = dev_priv->gtt.pte_encode(dev, ++ dev_priv->gtt.scratch_page_dma, ++ I915_CACHE_LLC); + for (i = 0; i < num_entries; i++) + iowrite32(scratch_pte, >t_base[i]); + readl(gtt_base); +@@ -809,6 +810,7 @@ int i915_gem_gtt_init(struct drm_device *dev) + } else { + dev_priv->gtt.gtt_probe = gen6_gmch_probe; + dev_priv->gtt.gtt_remove = gen6_gmch_remove; ++ dev_priv->gtt.pte_encode = gen6_pte_encode; + } + + ret = dev_priv->gtt.gtt_probe(dev, &dev_priv->gtt.total, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0036-drm-i915-Fix-page-table-entries-for-Bay-Trail.patch b/patches.baytrail/0036-drm-i915-Fix-page-table-entries-for-Bay-Trail.patch new file mode 100644 index 000000000000..230dc592ee3f --- /dev/null +++ b/patches.baytrail/0036-drm-i915-Fix-page-table-entries-for-Bay-Trail.patch @@ -0,0 +1,81 @@ +From 91990be7a31b091032b9ab5964ef3999f7d83fac Mon Sep 17 00:00:00 2001 +From: Kenneth Graunke +Date: Mon, 22 Apr 2013 00:53:50 -0700 +Subject: drm/i915: Fix page table entries for Bay Trail. + +On Bay Trail, bit 1 means "writeable by the GPU." Failing to set that +means basically anything using the GPU will cause hangs. + +v2: Drop accidental inline keyword on byt_pte_encode. + +Signed-off-by: Kenneth Graunke +Reviewed-by: Jani Nikula +Tested-by: Daniel Leung [v1] +Signed-off-by: Daniel Vetter +(cherry picked from commit 93c34e70ebf464a9ee142d93b681c5df094ec654) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_gtt.c | 33 +++++++++++++++++++++++++++++++-- + 1 file changed, 31 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index a6b4af7b425a..4241c9697fe3 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -73,6 +73,27 @@ static gen6_gtt_pte_t gen6_pte_encode(struct drm_device *dev, + return pte; + } + ++#define BYT_PTE_WRITEABLE (1 << 1) ++#define BYT_PTE_SNOOPED_BY_CPU_CACHES (1 << 2) ++ ++static gen6_gtt_pte_t byt_pte_encode(struct drm_device *dev, ++ dma_addr_t addr, ++ enum i915_cache_level level) ++{ ++ gen6_gtt_pte_t pte = GEN6_PTE_VALID; ++ pte |= GEN6_PTE_ADDR_ENCODE(addr); ++ ++ /* Mark the page as writeable. Other platforms don't have a ++ * setting for read-only/writable, so this matches that behavior. ++ */ ++ pte |= BYT_PTE_WRITEABLE; ++ ++ if (level != I915_CACHE_NONE) ++ pte |= BYT_PTE_SNOOPED_BY_CPU_CACHES; ++ ++ return pte; ++} ++ + static int gen6_ppgtt_enable(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; +@@ -233,7 +254,11 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) + * now. */ + first_pd_entry_in_global_pt = gtt_total_entries(dev_priv->gtt); + +- ppgtt->pte_encode = gen6_pte_encode; ++ if (IS_VALLEYVIEW(dev)) { ++ ppgtt->pte_encode = byt_pte_encode; ++ } else { ++ ppgtt->pte_encode = gen6_pte_encode; ++ } + ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES; + ppgtt->enable = gen6_ppgtt_enable; + ppgtt->clear_range = gen6_ppgtt_clear_range; +@@ -810,7 +835,11 @@ int i915_gem_gtt_init(struct drm_device *dev) + } else { + dev_priv->gtt.gtt_probe = gen6_gmch_probe; + dev_priv->gtt.gtt_remove = gen6_gmch_remove; +- dev_priv->gtt.pte_encode = gen6_pte_encode; ++ if (IS_VALLEYVIEW(dev)) { ++ dev_priv->gtt.pte_encode = byt_pte_encode; ++ } else { ++ dev_priv->gtt.pte_encode = gen6_pte_encode; ++ } + } + + ret = dev_priv->gtt.gtt_probe(dev, &dev_priv->gtt.total, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0037-drm-i915-Split-out-Haswell-code-from-gen6_pte_encode.patch b/patches.baytrail/0037-drm-i915-Split-out-Haswell-code-from-gen6_pte_encode.patch new file mode 100644 index 000000000000..7d2b22d18c67 --- /dev/null +++ b/patches.baytrail/0037-drm-i915-Split-out-Haswell-code-from-gen6_pte_encode.patch @@ -0,0 +1,94 @@ +From 76889de98ca867d2bb10c1296e802290889658fd Mon Sep 17 00:00:00 2001 +From: Kenneth Graunke +Date: Mon, 22 Apr 2013 00:53:51 -0700 +Subject: drm/i915: Split out Haswell code from gen6_pte_encode. + +Now that we have function pointers, it's cleaner to just create a new +per-platform PTE encoding function. + +This should be identical in behavior to the previous code. + +v2: Drop accidental inline keyword on hsw_pte_encode. + +Signed-off-by: Kenneth Graunke +Reviewed-by: Jani Nikula +Tested-by: Daniel Leung [v1] +Signed-off-by: Daniel Vetter +(cherry picked from commit 9119708cd484923bbc45fa60740bff58b358b848) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_gtt.c | 32 +++++++++++++++++++++----------- + 1 file changed, 21 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 4241c9697fe3..de6e7c54ea56 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -51,20 +51,13 @@ static gen6_gtt_pte_t gen6_pte_encode(struct drm_device *dev, + + switch (level) { + case I915_CACHE_LLC_MLC: +- /* Haswell doesn't set L3 this way */ +- if (IS_HASWELL(dev)) +- pte |= GEN6_PTE_CACHE_LLC; +- else +- pte |= GEN6_PTE_CACHE_LLC_MLC; ++ pte |= GEN6_PTE_CACHE_LLC_MLC; + break; + case I915_CACHE_LLC: + pte |= GEN6_PTE_CACHE_LLC; + break; + case I915_CACHE_NONE: +- if (IS_HASWELL(dev)) +- pte |= HSW_PTE_UNCACHED; +- else +- pte |= GEN6_PTE_UNCACHED; ++ pte |= GEN6_PTE_UNCACHED; + break; + default: + BUG(); +@@ -94,6 +87,19 @@ static gen6_gtt_pte_t byt_pte_encode(struct drm_device *dev, + return pte; + } + ++static gen6_gtt_pte_t hsw_pte_encode(struct drm_device *dev, ++ dma_addr_t addr, ++ enum i915_cache_level level) ++{ ++ gen6_gtt_pte_t pte = GEN6_PTE_VALID; ++ pte |= GEN6_PTE_ADDR_ENCODE(addr); ++ ++ if (level != I915_CACHE_NONE) ++ pte |= GEN6_PTE_CACHE_LLC; ++ ++ return pte; ++} ++ + static int gen6_ppgtt_enable(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; +@@ -254,7 +260,9 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) + * now. */ + first_pd_entry_in_global_pt = gtt_total_entries(dev_priv->gtt); + +- if (IS_VALLEYVIEW(dev)) { ++ if (IS_HASWELL(dev)) { ++ ppgtt->pte_encode = hsw_pte_encode; ++ } else if (IS_VALLEYVIEW(dev)) { + ppgtt->pte_encode = byt_pte_encode; + } else { + ppgtt->pte_encode = gen6_pte_encode; +@@ -835,7 +843,9 @@ int i915_gem_gtt_init(struct drm_device *dev) + } else { + dev_priv->gtt.gtt_probe = gen6_gmch_probe; + dev_priv->gtt.gtt_remove = gen6_gmch_remove; +- if (IS_VALLEYVIEW(dev)) { ++ if (IS_HASWELL(dev)) { ++ dev_priv->gtt.pte_encode = hsw_pte_encode; ++ } else if (IS_VALLEYVIEW(dev)) { + dev_priv->gtt.pte_encode = byt_pte_encode; + } else { + dev_priv->gtt.pte_encode = gen6_pte_encode; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0038-drm-i915-fix-locking-around-punit-access-in-cur_dela.patch b/patches.baytrail/0038-drm-i915-fix-locking-around-punit-access-in-cur_dela.patch new file mode 100644 index 000000000000..d707c4610fbd --- /dev/null +++ b/patches.baytrail/0038-drm-i915-fix-locking-around-punit-access-in-cur_dela.patch @@ -0,0 +1,40 @@ +From d74b92dd977d6eac6daa8be6c7a2f91d85a8240d Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Mon, 22 Apr 2013 15:59:30 -0700 +Subject: drm/i915: fix locking around punit access in cur_delayinfo for VLV + +We need to hold the rps lock around punit access. + +Reported-by: Kenneth Graunke +Signed-off-by: Jesse Barnes +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 259bd5d4e909a6c07e0da8d6f623d2ab89b7a042) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 367b534d2260..d195d097cbb7 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1012,6 +1012,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) + } else if (IS_VALLEYVIEW(dev)) { + u32 freq_sts, val; + ++ mutex_lock(&dev_priv->rps.hw_lock); + valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, + &freq_sts); + seq_printf(m, "PUNIT_REG_GPU_FREQ_STS: 0x%08x\n", freq_sts); +@@ -1028,6 +1029,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) + seq_printf(m, "current GPU freq: %d MHz\n", + vlv_gpu_freq(dev_priv->mem_freq, + (freq_sts >> 8) & 0xff)); ++ mutex_unlock(&dev_priv->rps.hw_lock); + } else { + seq_printf(m, "no P-state info available\n"); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0039-drm-i915-Add-bit-field-to-record-which-pins-have-rec.patch b/patches.baytrail/0039-drm-i915-Add-bit-field-to-record-which-pins-have-rec.patch new file mode 100644 index 000000000000..852a77bf5d29 --- /dev/null +++ b/patches.baytrail/0039-drm-i915-Add-bit-field-to-record-which-pins-have-rec.patch @@ -0,0 +1,86 @@ +From 5404c5055fc3af2bb06fbac43e34387f4dd501dc Mon Sep 17 00:00:00 2001 +From: Egbert Eich +Date: Thu, 11 Apr 2013 15:57:57 +0200 +Subject: drm/i915: Add bit field to record which pins have received HPD events + (v3) + +This way it is possible to limit 're'-detect() of displays to connectors +which have received an HPD event. + +v2: Reordered drm_i915_private: Move hpd_event_bits to hpd state tracking. +v3: Fixed merge conflicts with previous patches. + +Signed-off-by: Egbert Eich +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 142e239849c800f9dc23f828762873073f612d3f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/i915_irq.c | 10 ++++++++++ + 2 files changed, 11 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 0ede85bcb45b..698da6dbdb32 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -952,6 +952,7 @@ typedef struct drm_i915_private { + HPD_MARK_DISABLED = 2 + } hpd_mark; + } hpd_stats[HPD_NUM_PINS]; ++ u32 hpd_event_bits; + struct timer_list hotplug_reenable_timer; + + int num_pch_pll; +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 450a03c6f945..66aa4dacd83f 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -548,6 +548,7 @@ static void i915_hotplug_work_func(struct work_struct *work) + struct drm_connector *connector; + unsigned long irqflags; + bool hpd_disabled = false; ++ u32 hpd_event_bits; + + /* HPD irq before everything is fully set up. */ + if (!dev_priv->enable_hotplug_processing) +@@ -557,6 +558,9 @@ static void i915_hotplug_work_func(struct work_struct *work) + DRM_DEBUG_KMS("running encoder hotplug functions\n"); + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); ++ ++ hpd_event_bits = dev_priv->hpd_event_bits; ++ dev_priv->hpd_event_bits = 0; + list_for_each_entry(connector, &mode_config->connector_list, head) { + intel_connector = to_intel_connector(connector); + intel_encoder = intel_connector->encoder; +@@ -571,6 +575,10 @@ static void i915_hotplug_work_func(struct work_struct *work) + | DRM_CONNECTOR_POLL_DISCONNECT; + hpd_disabled = true; + } ++ if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) { ++ DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug event.\n", ++ drm_get_connector_name(connector), intel_encoder->hpd_pin); ++ } + } + /* if there were no outputs to poll, poll was disabled, + * therefore make sure it's enabled when disabling HPD on +@@ -835,6 +843,7 @@ static inline bool hotplug_irq_storm_detect(struct drm_device *dev, + + if (!(hpd[i] & hotplug_trigger) || + dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) ++ dev_priv->hpd_event_bits |= (1 << i); + continue; + + if (!time_in_range(jiffies, dev_priv->hpd_stats[i].hpd_last_jiffies, +@@ -844,6 +853,7 @@ static inline bool hotplug_irq_storm_detect(struct drm_device *dev, + dev_priv->hpd_stats[i].hpd_cnt = 0; + } else if (dev_priv->hpd_stats[i].hpd_cnt > HPD_STORM_THRESHOLD) { + dev_priv->hpd_stats[i].hpd_mark = HPD_MARK_DISABLED; ++ dev_priv->hpd_event_bits &= ~(1 << i); + DRM_DEBUG_KMS("HPD interrupt storm detected on PIN %d\n", i); + ret = true; + } else { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0040-drm-i915-Only-reprobe-display-on-encoder-which-has-r.patch b/patches.baytrail/0040-drm-i915-Only-reprobe-display-on-encoder-which-has-r.patch new file mode 100644 index 000000000000..ed67dfa1b453 --- /dev/null +++ b/patches.baytrail/0040-drm-i915-Only-reprobe-display-on-encoder-which-has-r.patch @@ -0,0 +1,88 @@ +From 8a85a19825edd287c64c597e0b1c51292cd2ceeb Mon Sep 17 00:00:00 2001 +From: Egbert Eich +Date: Thu, 11 Apr 2013 16:00:26 +0200 +Subject: drm/i915: Only reprobe display on encoder which has received an HPD + event (v2) + +Instead of calling into the DRM helper layer to poll all connectors for +changes in connected displays probe only those connectors which have +received a hotplug event. + +v2: Resolved conflicts with changes in previous commits. + Renamed function and and added a WARN_ON() to warn of + intel_hpd_irq_event() from being called without + mode_config.mutex held - suggested by Jani Nikula. + +Signed-off-by: Egbert Eich +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 321a1b3026ea194dd084cf3bda1e235b2986b0af) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 34 ++++++++++++++++++++++++++++------ + 1 file changed, 28 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 66aa4dacd83f..1d42446e287c 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -532,6 +532,21 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, + crtc); + } + ++static int intel_hpd_irq_event(struct drm_device *dev, struct drm_connector *connector) ++{ ++ enum drm_connector_status old_status; ++ ++ WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); ++ old_status = connector->status; ++ ++ connector->status = connector->funcs->detect(connector, false); ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n", ++ connector->base.id, ++ drm_get_connector_name(connector), ++ old_status, connector->status); ++ return (old_status != connector->status); ++} ++ + /* + * Handle hotplug events outside the interrupt handler proper. + */ +@@ -548,6 +563,7 @@ static void i915_hotplug_work_func(struct work_struct *work) + struct drm_connector *connector; + unsigned long irqflags; + bool hpd_disabled = false; ++ bool changed = false; + u32 hpd_event_bits; + + /* HPD irq before everything is fully set up. */ +@@ -591,14 +607,20 @@ static void i915_hotplug_work_func(struct work_struct *work) + + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + +- list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) +- if (intel_encoder->hot_plug) +- intel_encoder->hot_plug(intel_encoder); +- ++ list_for_each_entry(connector, &mode_config->connector_list, head) { ++ intel_connector = to_intel_connector(connector); ++ intel_encoder = intel_connector->encoder; ++ if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) { ++ if (intel_encoder->hot_plug) ++ intel_encoder->hot_plug(intel_encoder); ++ if (intel_hpd_irq_event(dev, connector)) ++ changed = true; ++ } ++ } + mutex_unlock(&mode_config->mutex); + +- /* Just fire off a uevent and let userspace tell us what to do */ +- drm_helper_hpd_irq_event(dev); ++ if (changed) ++ drm_kms_helper_hotplug_event(dev); + } + + static void ironlake_handle_rps_change(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0041-drm-i915-Turn-DEV_INFO_FLAGS-into-a-foreach-style-ma.patch b/patches.baytrail/0041-drm-i915-Turn-DEV_INFO_FLAGS-into-a-foreach-style-ma.patch new file mode 100644 index 000000000000..5b8f97b36398 --- /dev/null +++ b/patches.baytrail/0041-drm-i915-Turn-DEV_INFO_FLAGS-into-a-foreach-style-ma.patch @@ -0,0 +1,139 @@ +From cca87d75baaf99e9c071ca47b9d7fdd70129f9fc Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Tue, 23 Apr 2013 16:37:17 +0100 +Subject: drm/i915: Turn DEV_INFO_FLAGS into a foreach style macro +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +DEV_INFO_FOR_FLAG() now takes 2 parameters: + • A function to apply to the flag + • A separator + +This will allow us to use the macro twice in the DRM_DEBUG_DRIVER() call +of i915_dump_device_info(). + +v2: Fix a typo in the subject (Jani Nikula) +v3: Undef the helper macros (Jani Nikula, Daniel vetter) + +Reviewed-by: Jani Nikula +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 79fc46dfd0c7cc68442554a428e03a3b7e0d44aa) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 10 ++++---- + drivers/gpu/drm/i915/i915_dma.c | 10 ++++---- + drivers/gpu/drm/i915/i915_drv.h | 50 ++++++++++++++++++------------------- + 3 files changed, 35 insertions(+), 35 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index d195d097cbb7..a55630a80f83 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -61,11 +61,11 @@ static int i915_capabilities(struct seq_file *m, void *data) + + seq_printf(m, "gen: %d\n", info->gen); + seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(dev)); +-#define DEV_INFO_FLAG(x) seq_printf(m, #x ": %s\n", yesno(info->x)) +-#define DEV_INFO_SEP ; +- DEV_INFO_FLAGS; +-#undef DEV_INFO_FLAG +-#undef DEV_INFO_SEP ++#define PRINT_FLAG(x) seq_printf(m, #x ": %s\n", yesno(info->x)) ++#define SEP_SEMICOLON ; ++ DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_SEMICOLON); ++#undef PRINT_FLAG ++#undef SEP_SEMICOLON + + return 0; + } +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 17d9b0b6afc5..120e1fc4890f 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1445,15 +1445,15 @@ static void i915_dump_device_info(struct drm_i915_private *dev_priv) + { + const struct intel_device_info *info = dev_priv->info; + +-#define DEV_INFO_FLAG(name) info->name ? #name "," : "" +-#define DEV_INFO_SEP , ++#define PRINT_FLAG(name) info->name ? #name "," : "" ++#define SEP_COMMA , + DRM_DEBUG_DRIVER("i915 device info: gen=%i, pciid=0x%04x flags=" + "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + info->gen, + dev_priv->dev->pdev->device, +- DEV_INFO_FLAGS); +-#undef DEV_INFO_FLAG +-#undef DEV_INFO_SEP ++ DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_COMMA)); ++#undef PRINT_FLAG ++#undef SEP_COMMA + } + + /** +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 698da6dbdb32..c6179c8bea21 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -333,31 +333,31 @@ struct drm_i915_gt_funcs { + void (*force_wake_put)(struct drm_i915_private *dev_priv); + }; + +-#define DEV_INFO_FLAGS \ +- DEV_INFO_FLAG(is_mobile) DEV_INFO_SEP \ +- DEV_INFO_FLAG(is_i85x) DEV_INFO_SEP \ +- DEV_INFO_FLAG(is_i915g) DEV_INFO_SEP \ +- DEV_INFO_FLAG(is_i945gm) DEV_INFO_SEP \ +- DEV_INFO_FLAG(is_g33) DEV_INFO_SEP \ +- DEV_INFO_FLAG(need_gfx_hws) DEV_INFO_SEP \ +- DEV_INFO_FLAG(is_g4x) DEV_INFO_SEP \ +- DEV_INFO_FLAG(is_pineview) DEV_INFO_SEP \ +- DEV_INFO_FLAG(is_broadwater) DEV_INFO_SEP \ +- DEV_INFO_FLAG(is_crestline) DEV_INFO_SEP \ +- DEV_INFO_FLAG(is_ivybridge) DEV_INFO_SEP \ +- DEV_INFO_FLAG(is_valleyview) DEV_INFO_SEP \ +- DEV_INFO_FLAG(is_haswell) DEV_INFO_SEP \ +- DEV_INFO_FLAG(has_force_wake) DEV_INFO_SEP \ +- DEV_INFO_FLAG(has_fbc) DEV_INFO_SEP \ +- DEV_INFO_FLAG(has_pipe_cxsr) DEV_INFO_SEP \ +- DEV_INFO_FLAG(has_hotplug) DEV_INFO_SEP \ +- DEV_INFO_FLAG(cursor_needs_physical) DEV_INFO_SEP \ +- DEV_INFO_FLAG(has_overlay) DEV_INFO_SEP \ +- DEV_INFO_FLAG(overlay_needs_physical) DEV_INFO_SEP \ +- DEV_INFO_FLAG(supports_tv) DEV_INFO_SEP \ +- DEV_INFO_FLAG(has_bsd_ring) DEV_INFO_SEP \ +- DEV_INFO_FLAG(has_blt_ring) DEV_INFO_SEP \ +- DEV_INFO_FLAG(has_llc) ++#define DEV_INFO_FOR_EACH_FLAG(func, sep) \ ++ func(is_mobile) sep \ ++ func(is_i85x) sep \ ++ func(is_i915g) sep \ ++ func(is_i945gm) sep \ ++ func(is_g33) sep \ ++ func(need_gfx_hws) sep \ ++ func(is_g4x) sep \ ++ func(is_pineview) sep \ ++ func(is_broadwater) sep \ ++ func(is_crestline) sep \ ++ func(is_ivybridge) sep \ ++ func(is_valleyview) sep \ ++ func(is_haswell) sep \ ++ func(has_force_wake) sep \ ++ func(has_fbc) sep \ ++ func(has_pipe_cxsr) sep \ ++ func(has_hotplug) sep \ ++ func(cursor_needs_physical) sep \ ++ func(has_overlay) sep \ ++ func(overlay_needs_physical) sep \ ++ func(supports_tv) sep \ ++ func(has_bsd_ring) sep \ ++ func(has_blt_ring) sep \ ++ func(has_llc) + + struct intel_device_info { + u32 display_mmio_offset; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0042-drm-i915-Replace-the-line-of-s-by-a-DEV_INFO_FOR_EAC.patch b/patches.baytrail/0042-drm-i915-Replace-the-line-of-s-by-a-DEV_INFO_FOR_EAC.patch new file mode 100644 index 000000000000..3d436f63006e --- /dev/null +++ b/patches.baytrail/0042-drm-i915-Replace-the-line-of-s-by-a-DEV_INFO_FOR_EAC.patch @@ -0,0 +1,46 @@ +From 5f76c57898760f9ed1205180faec47afa81a3f0c Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Tue, 23 Apr 2013 16:38:34 +0100 +Subject: drm/i915: Replace the line of %s by a DEV_INFO_FOR_EACH_FLAG() + invocation + +This way, when adding a device flag we don't have to manually maintain +that list. + +v2: undefine the helper macros (Jani Nikula, Daniel Vetter) + +Signed-off-by: Damien Lespiau +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit e2a5800a14abcf861b9d6565de2a22bd6e9ae0ef) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 120e1fc4890f..579654d89ac3 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1445,13 +1445,17 @@ static void i915_dump_device_info(struct drm_i915_private *dev_priv) + { + const struct intel_device_info *info = dev_priv->info; + ++#define PRINT_S(name) "%s" ++#define SEP_EMPTY + #define PRINT_FLAG(name) info->name ? #name "," : "" + #define SEP_COMMA , + DRM_DEBUG_DRIVER("i915 device info: gen=%i, pciid=0x%04x flags=" +- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", ++ DEV_INFO_FOR_EACH_FLAG(PRINT_S, SEP_EMPTY), + info->gen, + dev_priv->dev->pdev->device, + DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_COMMA)); ++#undef PRINT_S ++#undef SEP_EMPTY + #undef PRINT_FLAG + #undef SEP_COMMA + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0043-drm-i915-Use-DEV_INFO_FOR_EACH_FLAG-to-declare-flags.patch b/patches.baytrail/0043-drm-i915-Use-DEV_INFO_FOR_EACH_FLAG-to-declare-flags.patch new file mode 100644 index 000000000000..b168869469ab --- /dev/null +++ b/patches.baytrail/0043-drm-i915-Use-DEV_INFO_FOR_EACH_FLAG-to-declare-flags.patch @@ -0,0 +1,65 @@ +From c51766e44eec61bd31f53b3299f743e56d5754a9 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 22 Apr 2013 18:40:38 +0100 +Subject: drm/i915: Use DEV_INFO_FOR_EACH_FLAG() to declare flags as well + +Signed-off-by: Damien Lespiau +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit a587f77987295ddec59afb653cea5335b4d1e191) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 31 +++++++------------------------ + 1 file changed, 7 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index c6179c8bea21..cd1144e68d3c 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -359,36 +359,19 @@ struct drm_i915_gt_funcs { + func(has_blt_ring) sep \ + func(has_llc) + ++#define DEFINE_FLAG(name) u8 name:1 ++#define SEP_SEMICOLON ; ++ + struct intel_device_info { + u32 display_mmio_offset; + u8 num_pipes:3; + u8 gen; +- u8 is_mobile:1; +- u8 is_i85x:1; +- u8 is_i915g:1; +- u8 is_i945gm:1; +- u8 is_g33:1; +- u8 need_gfx_hws:1; +- u8 is_g4x:1; +- u8 is_pineview:1; +- u8 is_broadwater:1; +- u8 is_crestline:1; +- u8 is_ivybridge:1; +- u8 is_valleyview:1; +- u8 has_force_wake:1; +- u8 is_haswell:1; +- u8 has_fbc:1; +- u8 has_pipe_cxsr:1; +- u8 has_hotplug:1; +- u8 cursor_needs_physical:1; +- u8 has_overlay:1; +- u8 overlay_needs_physical:1; +- u8 supports_tv:1; +- u8 has_bsd_ring:1; +- u8 has_blt_ring:1; +- u8 has_llc:1; ++ DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON); + }; + ++#undef DEFINE_FLAG ++#undef SEP_SEMICOLON ++ + enum i915_cache_level { + I915_CACHE_NONE = 0, + I915_CACHE_LLC, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0044-drm-i915-Turn-HAS_DDI-into-a-device_info-flag.patch b/patches.baytrail/0044-drm-i915-Turn-HAS_DDI-into-a-device_info-flag.patch new file mode 100644 index 000000000000..9c55c21a19e9 --- /dev/null +++ b/patches.baytrail/0044-drm-i915-Turn-HAS_DDI-into-a-device_info-flag.patch @@ -0,0 +1,60 @@ +From 727bb9225198092ea1906c6484ffbb737aba5efd Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 22 Apr 2013 18:40:39 +0100 +Subject: drm/i915: Turn HAS_DDI() into a device_info flag + +Signed-off-by: Damien Lespiau +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit dd93be584099b157039c43c7b48eac56223ac94d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 2 ++ + drivers/gpu/drm/i915/i915_drv.h | 5 +++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index bc6cd3117ac3..7d4a284487ee 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -308,12 +308,14 @@ static const struct intel_device_info intel_valleyview_d_info = { + static const struct intel_device_info intel_haswell_d_info = { + GEN7_FEATURES, + .is_haswell = 1, ++ .has_ddi = 1, + }; + + static const struct intel_device_info intel_haswell_m_info = { + GEN7_FEATURES, + .is_haswell = 1, + .is_mobile = 1, ++ .has_ddi = 1, + }; + + static const struct pci_device_id pciidlist[] = { /* aka */ +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index cd1144e68d3c..15951914a65b 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -357,7 +357,8 @@ struct drm_i915_gt_funcs { + func(supports_tv) sep \ + func(has_bsd_ring) sep \ + func(has_blt_ring) sep \ +- func(has_llc) ++ func(has_llc) sep \ ++ func(has_ddi) + + #define DEFINE_FLAG(name) u8 name:1 + #define SEP_SEMICOLON ; +@@ -1368,7 +1369,7 @@ struct drm_i915_file_private { + + #define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5) + +-#define HAS_DDI(dev) (IS_HASWELL(dev)) ++#define HAS_DDI(dev) (INTEL_INFO(dev)->has_ddi) + #define HAS_POWER_WELL(dev) (IS_HASWELL(dev)) + + #define INTEL_PCH_DEVICE_ID_MASK 0xff00 +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0045-drm-i915-Introduce-HAS_FPGA_DBG_UNCLAIMED.patch b/patches.baytrail/0045-drm-i915-Introduce-HAS_FPGA_DBG_UNCLAIMED.patch new file mode 100644 index 000000000000..514a96396d6f --- /dev/null +++ b/patches.baytrail/0045-drm-i915-Introduce-HAS_FPGA_DBG_UNCLAIMED.patch @@ -0,0 +1,73 @@ +From 903f857985d8452458e365ba7f8c87dff7104e0c Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 22 Apr 2013 18:40:40 +0100 +Subject: drm/i915: Introduce HAS_FPGA_DBG_UNCLAIMED() + +Let's introduce one more of those orthogonal feature macros. This should +hopefully make the code more readable and make things easier for new platform +enabling. + +This time, HAS_FPGA_DBG_UNCLAIMED() is true for platforms that have bit +31 of FPGA_DBG able to signal unclaimed writes. + +Signed-off-by: Damien Lespiau +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit e76ebff887e9cc4a8448a0fc6abbb1925291f38b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 2 +- + drivers/gpu/drm/i915/i915_drv.c | 4 ++-- + drivers/gpu/drm/i915/i915_drv.h | 1 + + 3 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 579654d89ac3..f7b85e1a1ba7 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1472,7 +1472,7 @@ static void intel_early_sanitize_regs(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + +- if (IS_HASWELL(dev)) ++ if (HAS_FPGA_DBG_UNCLAIMED(dev)) + I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); + } + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 7d4a284487ee..97858c71b3f7 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -1229,7 +1229,7 @@ ilk_dummy_write(struct drm_i915_private *dev_priv) + static void + hsw_unclaimed_reg_clear(struct drm_i915_private *dev_priv, u32 reg) + { +- if (IS_HASWELL(dev_priv->dev) && ++ if (HAS_FPGA_DBG_UNCLAIMED(dev_priv->dev) && + (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { + DRM_ERROR("Unknown unclaimed register before writing to %x\n", + reg); +@@ -1240,7 +1240,7 @@ hsw_unclaimed_reg_clear(struct drm_i915_private *dev_priv, u32 reg) + static void + hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) + { +- if (IS_HASWELL(dev_priv->dev) && ++ if (HAS_FPGA_DBG_UNCLAIMED(dev_priv->dev) && + (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { + DRM_ERROR("Unclaimed write to %x\n", reg); + I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 15951914a65b..99d744441ad6 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1371,6 +1371,7 @@ struct drm_i915_file_private { + + #define HAS_DDI(dev) (INTEL_INFO(dev)->has_ddi) + #define HAS_POWER_WELL(dev) (IS_HASWELL(dev)) ++#define HAS_FPGA_DBG_UNCLAIMED(dev) (IS_HASWELL(dev)) + + #define INTEL_PCH_DEVICE_ID_MASK 0xff00 + #define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0046-drm-i915-Turn-HAS_FPGA_DBG_UNCLAIMED-into-a-device_i.patch b/patches.baytrail/0046-drm-i915-Turn-HAS_FPGA_DBG_UNCLAIMED-into-a-device_i.patch new file mode 100644 index 000000000000..c370c9e83d7c --- /dev/null +++ b/patches.baytrail/0046-drm-i915-Turn-HAS_FPGA_DBG_UNCLAIMED-into-a-device_i.patch @@ -0,0 +1,61 @@ +From 0c726f443a73bacd42656de8c2456f17768fc1b1 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 22 Apr 2013 18:40:41 +0100 +Subject: drm/i915: Turn HAS_FPGA_DBG_UNCLAIMED into a device_info flag + +Signed-off-by: Damien Lespiau +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 30568c45d9fc4ee0bb9e1da90e185692fcd67e38) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 2 ++ + drivers/gpu/drm/i915/i915_drv.h | 5 +++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 97858c71b3f7..b7fdafdb496e 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -309,6 +309,7 @@ static const struct intel_device_info intel_haswell_d_info = { + GEN7_FEATURES, + .is_haswell = 1, + .has_ddi = 1, ++ .has_fpga_dbg = 1, + }; + + static const struct intel_device_info intel_haswell_m_info = { +@@ -316,6 +317,7 @@ static const struct intel_device_info intel_haswell_m_info = { + .is_haswell = 1, + .is_mobile = 1, + .has_ddi = 1, ++ .has_fpga_dbg = 1, + }; + + static const struct pci_device_id pciidlist[] = { /* aka */ +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 99d744441ad6..4060621e76e3 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -358,7 +358,8 @@ struct drm_i915_gt_funcs { + func(has_bsd_ring) sep \ + func(has_blt_ring) sep \ + func(has_llc) sep \ +- func(has_ddi) ++ func(has_ddi) sep \ ++ func(has_fpga_dbg) + + #define DEFINE_FLAG(name) u8 name:1 + #define SEP_SEMICOLON ; +@@ -1371,7 +1372,7 @@ struct drm_i915_file_private { + + #define HAS_DDI(dev) (INTEL_INFO(dev)->has_ddi) + #define HAS_POWER_WELL(dev) (IS_HASWELL(dev)) +-#define HAS_FPGA_DBG_UNCLAIMED(dev) (IS_HASWELL(dev)) ++#define HAS_FPGA_DBG_UNCLAIMED(dev) (INTEL_INFO(dev)->has_fpga_dbg) + + #define INTEL_PCH_DEVICE_ID_MASK 0xff00 + #define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0047-drm-i915-make-sure-GPU-freq-drops-to-minimum-after-e.patch b/patches.baytrail/0047-drm-i915-make-sure-GPU-freq-drops-to-minimum-after-e.patch new file mode 100644 index 000000000000..0c912490ad87 --- /dev/null +++ b/patches.baytrail/0047-drm-i915-make-sure-GPU-freq-drops-to-minimum-after-e.patch @@ -0,0 +1,128 @@ +From 89a1433aebda51050c4569740746560616c9f816 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Tue, 23 Apr 2013 10:09:26 -0700 +Subject: drm/i915: make sure GPU freq drops to minimum after entering RC6 v4 + +On VLV, the Punit doesn't automatically drop the GPU to it's minimum +voltage level when entering RC6, so we arm a timer to do it for us from +the RPS interrupt handler. It'll generally only fire when we go idle +(or if for some reason there's a long delay between RPS interrupts), but +won't be re-armed again until the next RPS event, so shouldn't affect +power consumption after we go idle and it triggers. + +v2: use delayed work instead of timer + work queue combo (Ville) +v3: fix up delayed work cancel (must be outside lock) (Daniel) + fix up delayed work handling func for delayed work (Jesse) +v4: cancel delayed work before RPS shutdown (Jani) + pass delay not absolute time to mod_delayed_work (Jani) + +Signed-off-by: Jesse Barnes +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 52ceb908018d3ac3c19cea85d5e407705f0a79c3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 ++ + drivers/gpu/drm/i915/i915_irq.c | 11 +++++++++++ + drivers/gpu/drm/i915/intel_pm.c | 22 ++++++++++++++++++++++ + 3 files changed, 35 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 4060621e76e3..c123e9e0cd12 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -654,6 +654,7 @@ struct i915_suspend_saved_registers { + + struct intel_gen6_power_mgmt { + struct work_struct work; ++ struct delayed_work vlv_work; + u32 pm_iir; + /* lock - irqsave spinlock that protectects the work_struct and + * pm_iir. */ +@@ -664,6 +665,7 @@ struct intel_gen6_power_mgmt { + u8 cur_delay; + u8 min_delay; + u8 max_delay; ++ u8 rpe_delay; + u8 hw_max; + + struct delayed_work delayed_resume_work; +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 1d42446e287c..4fe62a65a87a 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -716,6 +716,17 @@ static void gen6_pm_rps_work(struct work_struct *work) + gen6_set_rps(dev_priv->dev, new_delay); + } + ++ if (IS_VALLEYVIEW(dev_priv->dev)) { ++ /* ++ * On VLV, when we enter RC6 we may not be at the minimum ++ * voltage level, so arm a timer to check. It should only ++ * fire when there's activity or once after we've entered ++ * RC6, and then won't be re-armed until the next RPS interrupt. ++ */ ++ mod_delayed_work(dev_priv->wq, &dev_priv->rps.vlv_work, ++ msecs_to_jiffies(100)); ++ } ++ + mutex_unlock(&dev_priv->rps.hw_lock); + } + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index ca43c4e33c45..d5946860ce5b 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2822,6 +2822,23 @@ int valleyview_rps_min_freq(struct drm_i915_private *dev_priv) + return val & 0xff; + } + ++static void vlv_rps_timer_work(struct work_struct *work) ++{ ++ drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, ++ rps.vlv_work.work); ++ ++ /* ++ * Timer fired, we must be idle. Drop to min voltage state. ++ * Note: we use RPe here since it should match the ++ * Vmin we were shooting for. That should give us better ++ * perf when we come back out of RC6 than if we used the ++ * min freq available. ++ */ ++ mutex_lock(&dev_priv->rps.hw_lock); ++ valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay); ++ mutex_unlock(&dev_priv->rps.hw_lock); ++} ++ + static void valleyview_enable_rps(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -2886,6 +2903,7 @@ static void valleyview_enable_rps(struct drm_device *dev) + rpe = valleyview_rps_rpe_freq(dev_priv); + DRM_DEBUG_DRIVER("RPe GPU freq: %d\n", + vlv_gpu_freq(dev_priv->mem_freq, rpe)); ++ dev_priv->rps.rpe_delay = rpe; + + val = valleyview_rps_min_freq(dev_priv); + DRM_DEBUG_DRIVER("min GPU freq: %d\n", vlv_gpu_freq(dev_priv->mem_freq, +@@ -2895,6 +2913,8 @@ static void valleyview_enable_rps(struct drm_device *dev) + DRM_DEBUG_DRIVER("setting GPU freq to %d\n", + vlv_gpu_freq(dev_priv->mem_freq, rpe)); + ++ INIT_DELAYED_WORK(&dev_priv->rps.vlv_work, vlv_rps_timer_work); ++ + valleyview_set_rps(dev_priv->dev, rpe); + + /* requires MSI enabled */ +@@ -3637,6 +3657,8 @@ void intel_disable_gt_powersave(struct drm_device *dev) + ironlake_disable_rc6(dev); + } else if (INTEL_INFO(dev)->gen >= 6) { + cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work); ++ if (IS_VALLEYVIEW(dev)) ++ cancel_delayed_work_sync(&dev_priv->rps.vlv_work); + mutex_lock(&dev_priv->rps.hw_lock); + gen6_disable_rps(dev); + mutex_unlock(&dev_priv->rps.hw_lock); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0048-drm-i915-cancel-RPS-work-before-disabling-RPS.patch b/patches.baytrail/0048-drm-i915-cancel-RPS-work-before-disabling-RPS.patch new file mode 100644 index 000000000000..ee5f752a190e --- /dev/null +++ b/patches.baytrail/0048-drm-i915-cancel-RPS-work-before-disabling-RPS.patch @@ -0,0 +1,37 @@ +From 44b5c33aaebfcf8b56a78705ec366289e6b581ed Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Tue, 23 Apr 2013 10:09:27 -0700 +Subject: drm/i915: cancel RPS work before disabling RPS +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Ville noticed this while doing another review; we may as well cancel +this work just to make sure we don't try anything fancy after disabling +the RPS interfaces. + +Reported-by: Ville Syrjälä +Signed-off-by: Jesse Barnes +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 250848ca04b734c91f491b7c9b6045d2198a208c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index d5946860ce5b..69f19de204e2 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3657,6 +3657,7 @@ void intel_disable_gt_powersave(struct drm_device *dev) + ironlake_disable_rc6(dev); + } else if (INTEL_INFO(dev)->gen >= 6) { + cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work); ++ cancel_work_sync(&dev_priv->rps.work); + if (IS_VALLEYVIEW(dev)) + cancel_delayed_work_sync(&dev_priv->rps.vlv_work); + mutex_lock(&dev_priv->rps.hw_lock); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0049-drm-i915-create-spearate-VLV-disable_rps-function.patch b/patches.baytrail/0049-drm-i915-create-spearate-VLV-disable_rps-function.patch new file mode 100644 index 000000000000..c8a8f3c3b886 --- /dev/null +++ b/patches.baytrail/0049-drm-i915-create-spearate-VLV-disable_rps-function.patch @@ -0,0 +1,66 @@ +From a0b6a29fce66d2d98e7dfd1d26f42ac345e5eab2 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Tue, 23 Apr 2013 10:09:28 -0700 +Subject: drm/i915: create spearate VLV disable_rps function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We don't want to write reserved regs here, and may want to do other bits +in the future, so split it out. + +Reported-by: Ville Syrjälä +Signed-off-by: Jesse Barnes +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit d20d4f0ca343c0b76567d46fcc343c165e8d7c43) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 69f19de204e2..789710624d75 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2547,6 +2547,25 @@ static void gen6_disable_rps(struct drm_device *dev) + I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); + } + ++static void valleyview_disable_rps(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ I915_WRITE(GEN6_RC_CONTROL, 0); ++ I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); ++ I915_WRITE(GEN6_PMIER, 0); ++ /* Complete PM interrupt masking here doesn't race with the rps work ++ * item again unmasking PM interrupts because that is using a different ++ * register (PMIMR) to mask PM interrupts. The only risk is in leaving ++ * stale bits in PMIIR and PMIMR which gen6_enable_rps will clean up. */ ++ ++ spin_lock_irq(&dev_priv->rps.lock); ++ dev_priv->rps.pm_iir = 0; ++ spin_unlock_irq(&dev_priv->rps.lock); ++ ++ I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); ++} ++ + int intel_enable_rc6(const struct drm_device *dev) + { + /* Respect the kernel parameter if it is set */ +@@ -3661,7 +3680,10 @@ void intel_disable_gt_powersave(struct drm_device *dev) + if (IS_VALLEYVIEW(dev)) + cancel_delayed_work_sync(&dev_priv->rps.vlv_work); + mutex_lock(&dev_priv->rps.hw_lock); +- gen6_disable_rps(dev); ++ if (IS_VALLEYVIEW(dev)) ++ valleyview_disable_rps(dev); ++ else ++ gen6_disable_rps(dev); + mutex_unlock(&dev_priv->rps.hw_lock); + } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0050-drm-i915-disable-interrupts-earlier-in-the-driver-un.patch b/patches.baytrail/0050-drm-i915-disable-interrupts-earlier-in-the-driver-un.patch new file mode 100644 index 000000000000..196d56902db7 --- /dev/null +++ b/patches.baytrail/0050-drm-i915-disable-interrupts-earlier-in-the-driver-un.patch @@ -0,0 +1,90 @@ +From 6ddefd3caa8401123586c7cec07c1dac9f0cb4e2 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 24 Apr 2013 11:13:35 +0200 +Subject: drm/i915: disable interrupts earlier in the driver unload code + +Our rps code relies on the interrupts being off to prevent re-arming +of the work items at inopportune moments. + +Also drop the redundant cancel_work for the main rps work, +disable_gt_powersave already takes care of that. + +Finally add a WARN_ON to ensure we obey that piece of ordering +constraint. Long term I want to lock down the setup/teardown code in a +similar way to how we painstakingly check modeset sequence constraints +already. + +v2: Disable polling after hpd handling is shut down - since Egbert's +hpd irq storm handling the hotplug work can re-arm the polling +handler. Spotted by Jani Nikula. + +Cc: Jesse Barnes +Cc: Jani Nikula +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit fd0c06420d39958032655a04cfd194d5a7b38f83) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 19 ++++++++++++------- + drivers/gpu/drm/i915/intel_pm.c | 3 +++ + 2 files changed, 15 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 0db840241690..df0d00df3532 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -9585,12 +9585,23 @@ void intel_modeset_cleanup(struct drm_device *dev) + struct drm_crtc *crtc; + struct intel_crtc *intel_crtc; + ++ /* ++ * Interrupts and polling as the first thing to avoid creating havoc. ++ * Too much stuff here (turning of rps, connectors, ...) would ++ * experience fancy races otherwise. ++ */ ++ drm_irq_uninstall(dev); ++ cancel_work_sync(&dev_priv->hotplug_work); ++ /* ++ * Due to the hpd irq storm handling the hotplug work can re-arm the ++ * poll handlers. Hence disable polling after hpd handling is shut down. ++ */ + drm_kms_helper_poll_fini(dev); ++ + mutex_lock(&dev->struct_mutex); + + intel_unregister_dsm_handler(); + +- + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + /* Skip inactive CRTCs */ + if (!crtc->fb) +@@ -9608,12 +9619,6 @@ void intel_modeset_cleanup(struct drm_device *dev) + + mutex_unlock(&dev->struct_mutex); + +- /* Disable the irq before mode object teardown, for the irq might +- * enqueue unpin/hotplug work. */ +- drm_irq_uninstall(dev); +- cancel_work_sync(&dev_priv->hotplug_work); +- cancel_work_sync(&dev_priv->rps.work); +- + /* flush any delayed tasks or pending work */ + flush_scheduled_work(); + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 789710624d75..ad9d622c55af 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3671,6 +3671,9 @@ void intel_disable_gt_powersave(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + ++ /* Interrupts should be disabled already to avoid re-arming. */ ++ WARN_ON(dev->irq_enabled); ++ + if (IS_IRONLAKE_M(dev)) { + ironlake_disable_drps(dev); + ironlake_disable_rc6(dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0051-drm-i915-Disable-high-bpc-on-pre-1.4-EDID-screens.patch b/patches.baytrail/0051-drm-i915-Disable-high-bpc-on-pre-1.4-EDID-screens.patch new file mode 100644 index 000000000000..16ac4efe6553 --- /dev/null +++ b/patches.baytrail/0051-drm-i915-Disable-high-bpc-on-pre-1.4-EDID-screens.patch @@ -0,0 +1,43 @@ +From dec37ba36f6a4b611381a5b575a19565b48dfd1f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 19 Apr 2013 11:24:34 +0200 +Subject: drm/i915: Disable high-bpc on pre-1.4 EDID screens +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Prevents black screens when using 30bpp framebuffers on my +HDMI screens here. The DP input on the same screen though reports a +1.4 EDID with the correct 8bpc limit set. + +v2: Actually check for the right thing! + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 996a2239f93b03c5972923f04b097f65565c5bed) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index df0d00df3532..f8d54036bcf3 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -7710,6 +7710,13 @@ pipe_config_set_bpp(struct drm_crtc *crtc, + bpp, connector->display_info.bpc*3); + pipe_config->pipe_bpp = connector->display_info.bpc*3; + } ++ ++ /* Clamp bpp to 8 on screens without EDID 1.4 */ ++ if (connector->display_info.bpc == 0 && bpp > 24) { ++ DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of 24\n", ++ bpp); ++ pipe_config->pipe_bpp = 24; ++ } + } + + return bpp; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0052-drm-i915-Fixup-non-24bpp-support-for-VGA-screens-on-.patch b/patches.baytrail/0052-drm-i915-Fixup-non-24bpp-support-for-VGA-screens-on-.patch new file mode 100644 index 000000000000..c3da46aa8f33 --- /dev/null +++ b/patches.baytrail/0052-drm-i915-Fixup-non-24bpp-support-for-VGA-screens-on-.patch @@ -0,0 +1,37 @@ +From 5ac0a9430796e59ed945dd045d500f9d0c0f8e0f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 19 Apr 2013 11:24:39 +0200 +Subject: drm/i915: Fixup non-24bpp support for VGA screens on Haswell +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The LPT PCH only supports 8bpc, so we need to force the pipe bpp +to the right value. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 2a7aceecf15a463ba6bfa83b6579e75bb4703cd9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_crt.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c +index 58b4a53715cd..1b9ebf4b77fc 100644 +--- a/drivers/gpu/drm/i915/intel_crt.c ++++ b/drivers/gpu/drm/i915/intel_crt.c +@@ -207,6 +207,10 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder, + if (HAS_PCH_SPLIT(dev)) + pipe_config->has_pch_encoder = true; + ++ /* LPT FDI RX only supports 8bpc. */ ++ if (HAS_PCH_LPT(dev)) ++ pipe_config->pipe_bpp = 24; ++ + return true; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0053-drm-i915-keep-max-backlight-internal-to-intel_panel..patch b/patches.baytrail/0053-drm-i915-keep-max-backlight-internal-to-intel_panel..patch new file mode 100644 index 000000000000..ddfa714cccec --- /dev/null +++ b/patches.baytrail/0053-drm-i915-keep-max-backlight-internal-to-intel_panel..patch @@ -0,0 +1,179 @@ +From 0ee62d6476d1467b84498d1165a447394e135859 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Fri, 12 Apr 2013 15:18:36 +0300 +Subject: drm/i915: keep max backlight internal to intel_panel.c + +In preparation of adding locking to backlight, make max backlight value +(the modulation frequency the PWM duty cycle value must not exceed) +internal to intel_panel.c. + +Have intel_panel_set_backlight() accept a caller defined range for level, +and scale input to max backlight value internally. + +Clean up intel_panel_get_max_backlight() and usage internally. + +Signed-off-by: Jani Nikula +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit d65406327345e5a5e0f697a3ffe3e53bc9b5d7c6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_drv.h | 4 +-- + drivers/gpu/drm/i915/intel_opregion.c | 4 +-- + drivers/gpu/drm/i915/intel_panel.c | 51 ++++++++++++++++++++--------------- + 3 files changed, 32 insertions(+), 27 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index a8e180732452..86a26ae1615f 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -554,8 +554,8 @@ extern void intel_pch_panel_fitting(struct drm_device *dev, + int fitting_mode, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); +-extern u32 intel_panel_get_max_backlight(struct drm_device *dev); +-extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); ++extern void intel_panel_set_backlight(struct drm_device *dev, ++ u32 level, u32 max); + extern int intel_panel_setup_backlight(struct drm_connector *connector); + extern void intel_panel_enable_backlight(struct drm_device *dev, + enum pipe pipe); +diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c +index a8117e614009..b9b2694be80f 100644 +--- a/drivers/gpu/drm/i915/intel_opregion.c ++++ b/drivers/gpu/drm/i915/intel_opregion.c +@@ -152,7 +152,6 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct opregion_asle __iomem *asle = dev_priv->opregion.asle; +- u32 max; + + DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); + +@@ -163,8 +162,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) + if (bclp > 255) + return ASLE_BACKLIGHT_FAILED; + +- max = intel_panel_get_max_backlight(dev); +- intel_panel_set_backlight(dev, bclp * max / 255); ++ intel_panel_set_backlight(dev, bclp, 255); + iowrite32((bclp*0x64)/0xff | ASLE_CBLV_VALID, &asle->cblv); + + return 0; +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index 33cb87f7983e..3df5931e638f 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -130,6 +130,9 @@ static int is_backlight_combination_mode(struct drm_device *dev) + return 0; + } + ++/* XXX: query mode clock or hardware clock and program max PWM appropriately ++ * when it's 0. ++ */ + static u32 i915_read_blc_pwm_ctl(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -164,7 +167,7 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev) + return val; + } + +-static u32 _intel_panel_get_max_backlight(struct drm_device *dev) ++static u32 intel_panel_get_max_backlight(struct drm_device *dev) + { + u32 max; + +@@ -182,23 +185,8 @@ static u32 _intel_panel_get_max_backlight(struct drm_device *dev) + max *= 0xff; + } + +- return max; +-} +- +-u32 intel_panel_get_max_backlight(struct drm_device *dev) +-{ +- u32 max; +- +- max = _intel_panel_get_max_backlight(dev); +- if (max == 0) { +- /* XXX add code here to query mode clock or hardware clock +- * and program max PWM appropriately. +- */ +- pr_warn_once("fixme: max PWM is zero\n"); +- return 1; +- } +- + DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); ++ + return max; + } + +@@ -217,8 +205,11 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val) + return val; + + if (i915_panel_invert_brightness > 0 || +- dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) +- return intel_panel_get_max_backlight(dev) - val; ++ dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) { ++ u32 max = intel_panel_get_max_backlight(dev); ++ if (max) ++ return max - val; ++ } + + return val; + } +@@ -270,6 +261,10 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level + u32 max = intel_panel_get_max_backlight(dev); + u8 lbpc; + ++ /* we're screwed, but keep behaviour backwards compatible */ ++ if (!max) ++ max = 1; ++ + lbpc = level * 0xfe / max + 1; + level /= lbpc; + pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc); +@@ -282,9 +277,20 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level + I915_WRITE(BLC_PWM_CTL, tmp | level); + } + +-void intel_panel_set_backlight(struct drm_device *dev, u32 level) ++/* set backlight brightness to level in range [0..max] */ ++void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max) + { + struct drm_i915_private *dev_priv = dev->dev_private; ++ u32 freq; ++ ++ freq = intel_panel_get_max_backlight(dev); ++ if (!freq) { ++ /* we are screwed, bail out */ ++ return; ++ } ++ ++ /* scale to hardware */ ++ level = level * freq / max; + + dev_priv->backlight.level = level; + if (dev_priv->backlight.device) +@@ -406,7 +412,8 @@ intel_panel_detect(struct drm_device *dev) + static int intel_panel_update_status(struct backlight_device *bd) + { + struct drm_device *dev = bl_get_data(bd); +- intel_panel_set_backlight(dev, bd->props.brightness); ++ intel_panel_set_backlight(dev, bd->props.brightness, ++ bd->props.max_brightness); + return 0; + } + +@@ -435,7 +442,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector) + memset(&props, 0, sizeof(props)); + props.type = BACKLIGHT_RAW; + props.brightness = dev_priv->backlight.level; +- props.max_brightness = _intel_panel_get_max_backlight(dev); ++ props.max_brightness = intel_panel_get_max_backlight(dev); + if (props.max_brightness == 0) { + DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n"); + return -ENODEV; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0054-drm-i915-protect-backlight-registers-and-data-with-a.patch b/patches.baytrail/0054-drm-i915-protect-backlight-registers-and-data-with-a.patch new file mode 100644 index 000000000000..c8a1bd3911c0 --- /dev/null +++ b/patches.baytrail/0054-drm-i915-protect-backlight-registers-and-data-with-a.patch @@ -0,0 +1,228 @@ +From f6675adc2421c21c8060e4f1ff1eb720ca61b66a Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Fri, 12 Apr 2013 15:18:37 +0300 +Subject: drm/i915: protect backlight registers and data with a spinlock + +Backlight data and registers are fiddled through LVDS/eDP modeset +enable/disable hooks, backlight sysfs files, asle interrupts, and register +save/restore. Protect the backlight related registers and driver private +fields using a spinlock. + +The locking in register save/restore covers a little more than is strictly +necessary, including non-modeset case, for simplicity. + +v2: Cover register access, save/restore, i915_read_blc_pwm_ctl() and code + paths leading there. + +Signed-off-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 8ba2d18520ce380cf572e9902d9b3b91ece6c2c0) +[dbasehore: Fixed simple conflict] +Signed-off-by: Derek Basehore + +Conflicts: + drivers/gpu/drm/i915/i915_dma.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 1 + + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/i915_suspend.c | 10 ++++++++++ + drivers/gpu/drm/i915/intel_panel.c | 30 +++++++++++++++++++++++++++++- + 4 files changed, 41 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index f7b85e1a1ba7..68a57031db2c 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1519,6 +1519,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + spin_lock_init(&dev_priv->gpu_error.lock); + spin_lock_init(&dev_priv->rps.lock); + spin_lock_init(&dev_priv->gt_lock); ++ spin_lock_init(&dev_priv->backlight.lock); + mutex_init(&dev_priv->dpio_lock); + mutex_init(&dev_priv->rps.hw_lock); + mutex_init(&dev_priv->modeset_restore_lock); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index c123e9e0cd12..8a8e8dc5c2e1 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -961,6 +961,7 @@ typedef struct drm_i915_private { + struct { + int level; + bool enabled; ++ spinlock_t lock; /* bl registers and the above bl fields */ + struct backlight_device *device; + } backlight; + +diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c +index 369b3d8776ab..70db618989c4 100644 +--- a/drivers/gpu/drm/i915/i915_suspend.c ++++ b/drivers/gpu/drm/i915/i915_suspend.c +@@ -192,6 +192,7 @@ static void i915_restore_vga(struct drm_device *dev) + static void i915_save_display(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; ++ unsigned long flags; + + /* Display arbitration control */ + if (INTEL_INFO(dev)->gen <= 4) +@@ -202,6 +203,8 @@ static void i915_save_display(struct drm_device *dev) + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + i915_save_display_reg(dev); + ++ spin_lock_irqsave(&dev_priv->backlight.lock, flags); ++ + /* LVDS state */ + if (HAS_PCH_SPLIT(dev)) { + dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL); +@@ -222,6 +225,8 @@ static void i915_save_display(struct drm_device *dev) + dev_priv->regfile.saveLVDS = I915_READ(LVDS); + } + ++ spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); ++ + if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) + dev_priv->regfile.savePFIT_CONTROL = I915_READ(PFIT_CONTROL); + +@@ -257,6 +262,7 @@ static void i915_restore_display(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + u32 mask = 0xffffffff; ++ unsigned long flags; + + /* Display arbitration */ + if (INTEL_INFO(dev)->gen <= 4) +@@ -265,6 +271,8 @@ static void i915_restore_display(struct drm_device *dev) + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + i915_restore_display_reg(dev); + ++ spin_lock_irqsave(&dev_priv->backlight.lock, flags); ++ + /* LVDS state */ + if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) + I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2); +@@ -304,6 +312,8 @@ static void i915_restore_display(struct drm_device *dev) + I915_WRITE(PP_CONTROL, dev_priv->regfile.savePP_CONTROL); + } + ++ spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); ++ + /* only restore FBC info on the platform that supports FBC*/ + intel_disable_fbc(dev); + if (I915_HAS_FBC(dev)) { +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index 3df5931e638f..4c49b3f77455 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -138,6 +138,8 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val; + ++ WARN_ON(!spin_is_locked(&dev_priv->backlight.lock)); ++ + /* Restore the CTL value if it lost, e.g. GPU reset */ + + if (HAS_PCH_SPLIT(dev_priv->dev)) { +@@ -218,6 +220,9 @@ static u32 intel_panel_get_backlight(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev_priv->backlight.lock, flags); + + if (HAS_PCH_SPLIT(dev)) { + val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; +@@ -235,6 +240,9 @@ static u32 intel_panel_get_backlight(struct drm_device *dev) + } + + val = intel_panel_compute_brightness(dev, val); ++ ++ spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); ++ + DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val); + return val; + } +@@ -282,11 +290,14 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max) + { + struct drm_i915_private *dev_priv = dev->dev_private; + u32 freq; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev_priv->backlight.lock, flags); + + freq = intel_panel_get_max_backlight(dev); + if (!freq) { + /* we are screwed, bail out */ +- return; ++ goto out; + } + + /* scale to hardware */ +@@ -298,11 +309,16 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max) + + if (dev_priv->backlight.enabled) + intel_panel_actually_set_backlight(dev, level); ++out: ++ spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); + } + + void intel_panel_disable_backlight(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev_priv->backlight.lock, flags); + + dev_priv->backlight.enabled = false; + intel_panel_actually_set_backlight(dev, 0); +@@ -320,12 +336,17 @@ void intel_panel_disable_backlight(struct drm_device *dev) + I915_WRITE(BLC_PWM_PCH_CTL1, tmp); + } + } ++ ++ spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); + } + + void intel_panel_enable_backlight(struct drm_device *dev, + enum pipe pipe) + { + struct drm_i915_private *dev_priv = dev->dev_private; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev_priv->backlight.lock, flags); + + if (dev_priv->backlight.level == 0) { + dev_priv->backlight.level = intel_panel_get_max_backlight(dev); +@@ -376,6 +397,8 @@ set_level: + */ + dev_priv->backlight.enabled = true; + intel_panel_actually_set_backlight(dev, dev_priv->backlight.level); ++ ++ spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); + } + + static void intel_panel_init_backlight(struct drm_device *dev) +@@ -433,6 +456,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector) + struct drm_device *dev = connector->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct backlight_properties props; ++ unsigned long flags; + + intel_panel_init_backlight(dev); + +@@ -442,7 +466,11 @@ int intel_panel_setup_backlight(struct drm_connector *connector) + memset(&props, 0, sizeof(props)); + props.type = BACKLIGHT_RAW; + props.brightness = dev_priv->backlight.level; ++ ++ spin_lock_irqsave(&dev_priv->backlight.lock, flags); + props.max_brightness = intel_panel_get_max_backlight(dev); ++ spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); ++ + if (props.max_brightness == 0) { + DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n"); + return -ENODEV; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0055-drm-i915-don-t-pretend-we-support-ASLE-ALS-PFIT-or-P.patch b/patches.baytrail/0055-drm-i915-don-t-pretend-we-support-ASLE-ALS-PFIT-or-P.patch new file mode 100644 index 000000000000..2f9602b858de --- /dev/null +++ b/patches.baytrail/0055-drm-i915-don-t-pretend-we-support-ASLE-ALS-PFIT-or-P.patch @@ -0,0 +1,37 @@ +From f398c5cc0afdad3aae3f5cfa203343ff8dd34299 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Fri, 12 Apr 2013 15:20:56 +0300 +Subject: drm/i915: don't pretend we support ASLE ALS, PFIT, or PFMB + +In theory, this should prevent the BIOS from requesting them from us, and +this should be the right thing. + +In practice, this is not always the case, and might surprise the BIOS. + +Signed-off-by: Jani Nikula +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 1767afa4d0a6409e24fd9421a7c2df0490a0da4a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_opregion.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c +index b9b2694be80f..772fbf344c33 100644 +--- a/drivers/gpu/drm/i915/intel_opregion.c ++++ b/drivers/gpu/drm/i915/intel_opregion.c +@@ -280,9 +280,7 @@ void intel_opregion_enable_asle(struct drm_device *dev) + if (IS_MOBILE(dev)) + intel_enable_asle(dev); + +- iowrite32(ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | +- ASLE_PFMB_EN, +- &asle->tche); ++ iowrite32(ASLE_BLC_EN, &asle->tche); + iowrite32(1, &asle->ardy); + } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0056-drm-i915-opregion-don-t-pretend-we-did-something-whe.patch b/patches.baytrail/0056-drm-i915-opregion-don-t-pretend-we-did-something-whe.patch new file mode 100644 index 000000000000..821be6e4a491 --- /dev/null +++ b/patches.baytrail/0056-drm-i915-opregion-don-t-pretend-we-did-something-whe.patch @@ -0,0 +1,61 @@ +From 25c2f460fe47244f7753c9cbb6b9f997748c46cd Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Fri, 12 Apr 2013 15:20:57 +0300 +Subject: drm/i915/opregion: don't pretend we did something when we didn't + +In theory, the BIOS should not even request these from us now that we +aren't claiming we support these, but when it does anyway, don't pretend it +succeeded. It should be the right thing to do, but might confuse the BIOS. + +Signed-off-by: Jani Nikula +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit e93d440b352a1ba9e99cc17f3d46b1841caef3cd) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_opregion.c | 19 ++++++------------- + 1 file changed, 6 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c +index 772fbf344c33..34586410743b 100644 +--- a/drivers/gpu/drm/i915/intel_opregion.c ++++ b/drivers/gpu/drm/i915/intel_opregion.c +@@ -172,29 +172,22 @@ static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi) + { + /* alsi is the current ALS reading in lux. 0 indicates below sensor + range, 0xffff indicates above sensor range. 1-0xfffe are valid */ +- return 0; ++ DRM_DEBUG_DRIVER("Illum is not supported\n"); ++ return ASLE_ALS_ILLUM_FAILED; + } + + static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb) + { +- struct drm_i915_private *dev_priv = dev->dev_private; +- if (pfmb & ASLE_PFMB_PWM_VALID) { +- u32 blc_pwm_ctl = I915_READ(BLC_PWM_CTL); +- u32 pwm = pfmb & ASLE_PFMB_PWM_MASK; +- blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK; +- pwm = pwm >> 9; +- /* FIXME - what do we do with the PWM? */ +- } +- return 0; ++ DRM_DEBUG_DRIVER("PWM freq is not supported\n"); ++ return ASLE_PWM_FREQ_FAILED; + } + + static u32 asle_set_pfit(struct drm_device *dev, u32 pfit) + { + /* Panel fitting is currently controlled by the X code, so this is a + noop until modesetting support works fully */ +- if (!(pfit & ASLE_PFIT_VALID)) +- return ASLE_PFIT_FAILED; +- return 0; ++ DRM_DEBUG_DRIVER("Pfit is not supported\n"); ++ return ASLE_PFIT_FAILED; + } + + void intel_opregion_asle_intr(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0057-drm-i915-drop-code-duplication-in-favor-of-asle-inte.patch b/patches.baytrail/0057-drm-i915-drop-code-duplication-in-favor-of-asle-inte.patch new file mode 100644 index 000000000000..3c25caaf9c63 --- /dev/null +++ b/patches.baytrail/0057-drm-i915-drop-code-duplication-in-favor-of-asle-inte.patch @@ -0,0 +1,112 @@ +From 75b6465485ee76c8432d06059734f7bab1b227c7 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Wed, 24 Apr 2013 22:18:44 +0300 +Subject: drm/i915: drop code duplication in favor of asle interrupt handler + +With the previous work asle and gse interrupt handlers should now be +functionally the same. Drop the duplicated code. + +v2: Drop intel_opregion_gse_intr() also in the !CONFIG_ACPI path. (Damien) + +Signed-off-by: Jani Nikula +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 81a078092ed25b1017d1351c68837b750a09933a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 -- + drivers/gpu/drm/i915/i915_irq.c | 4 ++-- + drivers/gpu/drm/i915/intel_opregion.c | 37 ----------------------------------- + 3 files changed, 2 insertions(+), 41 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 8a8e8dc5c2e1..afc6977303c6 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1825,13 +1825,11 @@ extern int intel_opregion_setup(struct drm_device *dev); + extern void intel_opregion_init(struct drm_device *dev); + extern void intel_opregion_fini(struct drm_device *dev); + extern void intel_opregion_asle_intr(struct drm_device *dev); +-extern void intel_opregion_gse_intr(struct drm_device *dev); + extern void intel_opregion_enable_asle(struct drm_device *dev); + #else + static inline void intel_opregion_init(struct drm_device *dev) { return; } + static inline void intel_opregion_fini(struct drm_device *dev) { return; } + static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; } +-static inline void intel_opregion_gse_intr(struct drm_device *dev) { return; } + static inline void intel_opregion_enable_asle(struct drm_device *dev) { return; } + #endif + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 4fe62a65a87a..ebb0c7c3836e 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1196,7 +1196,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + dp_aux_irq_handler(dev); + + if (de_iir & DE_GSE_IVB) +- intel_opregion_gse_intr(dev); ++ intel_opregion_asle_intr(dev); + + for (i = 0; i < 3; i++) { + if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i))) +@@ -1293,7 +1293,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + dp_aux_irq_handler(dev); + + if (de_iir & DE_GSE) +- intel_opregion_gse_intr(dev); ++ intel_opregion_asle_intr(dev); + + if (de_iir & DE_PIPEA_VBLANK) + drm_handle_vblank(dev, 0); +diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c +index 34586410743b..8f4989476a6f 100644 +--- a/drivers/gpu/drm/i915/intel_opregion.c ++++ b/drivers/gpu/drm/i915/intel_opregion.c +@@ -222,43 +222,6 @@ void intel_opregion_asle_intr(struct drm_device *dev) + iowrite32(asle_stat, &asle->aslc); + } + +-void intel_opregion_gse_intr(struct drm_device *dev) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- struct opregion_asle __iomem *asle = dev_priv->opregion.asle; +- u32 asle_stat = 0; +- u32 asle_req; +- +- if (!asle) +- return; +- +- asle_req = ioread32(&asle->aslc) & ASLE_REQ_MSK; +- +- if (!asle_req) { +- DRM_DEBUG_DRIVER("non asle set request??\n"); +- return; +- } +- +- if (asle_req & ASLE_SET_ALS_ILLUM) { +- DRM_DEBUG_DRIVER("Illum is not supported\n"); +- asle_stat |= ASLE_ALS_ILLUM_FAILED; +- } +- +- if (asle_req & ASLE_SET_BACKLIGHT) +- asle_stat |= asle_set_backlight(dev, ioread32(&asle->bclp)); +- +- if (asle_req & ASLE_SET_PFIT) { +- DRM_DEBUG_DRIVER("Pfit is not supported\n"); +- asle_stat |= ASLE_PFIT_FAILED; +- } +- +- if (asle_req & ASLE_SET_PWM_FREQ) { +- DRM_DEBUG_DRIVER("PWM freq is not supported\n"); +- asle_stat |= ASLE_PWM_FREQ_FAILED; +- } +- +- iowrite32(asle_stat, &asle->aslc); +-} + #define ASLE_ALS_EN (1<<0) + #define ASLE_BLC_EN (1<<1) + #define ASLE_PFIT_EN (1<<2) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0058-drm-i915-hsw-backlight-registers-need-transcoder-ins.patch b/patches.baytrail/0058-drm-i915-hsw-backlight-registers-need-transcoder-ins.patch new file mode 100644 index 000000000000..ee89afa63921 --- /dev/null +++ b/patches.baytrail/0058-drm-i915-hsw-backlight-registers-need-transcoder-ins.patch @@ -0,0 +1,60 @@ +From 069a4e64a35dc46ffd6b5b89f1d3ee18ed919ddf Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Thu, 25 Apr 2013 16:49:25 +0300 +Subject: drm/i915: hsw backlight registers need transcoder instead of pipe + +v2: Make TRANSCODER_EDP handling more explicit. (Imre) + +Signed-off-by: Jani Nikula +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 35ffda4883a8d3f75632d7389dc96a25640033f0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 4 ++++ + drivers/gpu/drm/i915/intel_panel.c | 7 ++++++- + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 14cd707265b9..8fff456c1c87 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -2091,6 +2091,10 @@ + #define BLM_PIPE_A (0 << 29) + #define BLM_PIPE_B (1 << 29) + #define BLM_PIPE_C (2 << 29) /* ivb + */ ++#define BLM_TRANSCODER_A BLM_PIPE_A /* hsw */ ++#define BLM_TRANSCODER_B BLM_PIPE_B ++#define BLM_TRANSCODER_C BLM_PIPE_C ++#define BLM_TRANSCODER_EDP (3 << 29) + #define BLM_PIPE(pipe) ((pipe) << 29) + #define BLM_POLARITY_I965 (1 << 28) /* gen4 only */ + #define BLM_PHASE_IN_INTERUPT_STATUS (1 << 26) +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index 4c49b3f77455..317d2bc15049 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -344,6 +344,8 @@ void intel_panel_enable_backlight(struct drm_device *dev, + enum pipe pipe) + { + struct drm_i915_private *dev_priv = dev->dev_private; ++ enum transcoder cpu_transcoder = ++ intel_pipe_to_cpu_transcoder(dev_priv, pipe); + unsigned long flags; + + spin_lock_irqsave(&dev_priv->backlight.lock, flags); +@@ -374,7 +376,10 @@ void intel_panel_enable_backlight(struct drm_device *dev, + else + tmp &= ~BLM_PIPE_SELECT; + +- tmp |= BLM_PIPE(pipe); ++ if (cpu_transcoder == TRANSCODER_EDP) ++ tmp |= BLM_TRANSCODER_EDP; ++ else ++ tmp |= BLM_PIPE(cpu_transcoder); + tmp &= ~BLM_PWM_ENABLE; + + I915_WRITE(reg, tmp); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0059-drm-i915-Ivybridge-is-the-odd-one-when-it-comes-to-p.patch b/patches.baytrail/0059-drm-i915-Ivybridge-is-the-odd-one-when-it-comes-to-p.patch new file mode 100644 index 000000000000..2bb92995fcab --- /dev/null +++ b/patches.baytrail/0059-drm-i915-Ivybridge-is-the-odd-one-when-it-comes-to-p.patch @@ -0,0 +1,59 @@ +From ca90df43636d314d7febd1d7533dcb6c728bbd68 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Thu, 25 Apr 2013 15:15:00 +0100 +Subject: drm/i915: Ivybridge is the odd one when it comes to pipe scalers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Between ivb, hsw and vlv, only Ivybridge has sprites with scaling +capabilities. + +Also make max_downscale coherent with that. + +v2: Rebase on top of the recent ivb/vlv/hsw sprite scaling fixes. + +Signed-off-by: Damien Lespiau (v1) +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit d49f70915c07c1a313e459d23fad61ddbeeb1bae) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sprite.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index c7d25c5dd4e6..18993ad93540 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -918,13 +918,15 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) + break; + + case 7: +- if (IS_HASWELL(dev) || IS_VALLEYVIEW(dev)) +- intel_plane->can_scale = false; +- else ++ if (IS_IVYBRIDGE(dev)) { + intel_plane->can_scale = true; ++ intel_plane->max_downscale = 2; ++ } else { ++ intel_plane->can_scale = false; ++ intel_plane->max_downscale = 1; ++ } + + if (IS_VALLEYVIEW(dev)) { +- intel_plane->max_downscale = 1; + intel_plane->update_plane = vlv_update_plane; + intel_plane->disable_plane = vlv_disable_plane; + intel_plane->update_colorkey = vlv_update_colorkey; +@@ -933,7 +935,6 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) + plane_formats = vlv_plane_formats; + num_plane_formats = ARRAY_SIZE(vlv_plane_formats); + } else { +- intel_plane->max_downscale = 2; + intel_plane->update_plane = ivb_update_plane; + intel_plane->disable_plane = ivb_disable_plane; + intel_plane->update_colorkey = ivb_update_colorkey; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0060-drm-i915-consolidate-pch-pll-computations-a-bit.patch b/patches.baytrail/0060-drm-i915-consolidate-pch-pll-computations-a-bit.patch new file mode 100644 index 000000000000..24b31d13b921 --- /dev/null +++ b/patches.baytrail/0060-drm-i915-consolidate-pch-pll-computations-a-bit.patch @@ -0,0 +1,66 @@ +From 96c7053090b00d033164a2b794fa8efda5fda38f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 19 Apr 2013 11:14:31 +0200 +Subject: drm/i915: consolidate pch pll computations a bit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We need the dpll/fp/fp2 values only when we need a pch pll. So move +them together with the code to acquire such a pll. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit cbbab5bdea0df4e85ac7fbc0b3e1d7dee71cb708) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index f8d54036bcf3..1afc053c39cc 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5716,7 +5716,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + int plane = intel_crtc->plane; + int num_connectors = 0; + intel_clock_t clock, reduced_clock; +- u32 dpll, fp = 0, fp2 = 0; ++ u32 dpll = 0, fp = 0, fp2 = 0; + bool ok, has_reduced_clock = false; + bool is_lvds = false; + struct intel_encoder *encoder; +@@ -5761,14 +5761,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + if (is_lvds && dev_priv->lvds_dither) + dither = true; + +- fp = clock.n << 16 | clock.m1 << 8 | clock.m2; +- if (has_reduced_clock) +- fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | +- reduced_clock.m2; +- +- dpll = ironlake_compute_dpll(intel_crtc, &clock, &fp, &reduced_clock, +- has_reduced_clock ? &fp2 : NULL); +- + DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe_name(pipe)); + drm_mode_debug_printmodeline(mode); + +@@ -5776,6 +5768,15 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + if (intel_crtc->config.has_pch_encoder) { + struct intel_pch_pll *pll; + ++ fp = clock.n << 16 | clock.m1 << 8 | clock.m2; ++ if (has_reduced_clock) ++ fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | ++ reduced_clock.m2; ++ ++ dpll = ironlake_compute_dpll(intel_crtc, &clock, ++ &fp, &reduced_clock, ++ has_reduced_clock ? &fp2 : NULL); ++ + pll = intel_get_pch_pll(intel_crtc, dpll, fp); + if (pll == NULL) { + DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0061-drm-i915-shovel-compute-clock-into-crtc-config.dpll-.patch b/patches.baytrail/0061-drm-i915-shovel-compute-clock-into-crtc-config.dpll-.patch new file mode 100644 index 000000000000..50370ed120dd --- /dev/null +++ b/patches.baytrail/0061-drm-i915-shovel-compute-clock-into-crtc-config.dpll-.patch @@ -0,0 +1,152 @@ +From 9b72e6a45a1bd7a34003f4081443639cfd075dac Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sat, 20 Apr 2013 17:19:46 +0200 +Subject: drm/i915: shovel compute clock into crtc->config.dpll on ilk +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This was somehow lost in the pipe_config->dpll introduction in + +commit f47709a9502f3715cc488b788ca91cf0c142b1b1 +Author: Daniel Vetter +Date: Thu Mar 28 10:42:02 2013 +0100 + + drm/i915: create pipe_config->dpll for clock state + +While at it, extract a few small helpers for common computations. + +v2: Use the newly added helpers more thanks to Ville's trick to +typedef the legacy intel_clock_t as the new-world struct dpll. + +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 7429e9d4bfcfd08a00ed7b760386bd81a60e91d6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 50 ++++++++++++++++++++++++------------ + 1 file changed, 33 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 1afc053c39cc..eefc8e2ebe94 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -549,13 +549,18 @@ static void pineview_clock(int refclk, intel_clock_t *clock) + clock->dot = clock->vco / clock->p; + } + ++static uint32_t i9xx_dpll_compute_m(struct dpll *dpll) ++{ ++ return 5 * (dpll->m1 + 2) + (dpll->m2 + 2); ++} ++ + static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock) + { + if (IS_PINEVIEW(dev)) { + pineview_clock(refclk, clock); + return; + } +- clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); ++ clock->m = i9xx_dpll_compute_m(clock); + clock->p = clock->p1 * clock->p2; + clock->vco = refclk * clock->m / (clock->n + 2); + clock->dot = clock->vco / clock->p; +@@ -4247,6 +4252,16 @@ static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc *crtc) + crtc->config.clock_set = true; + } + ++static uint32_t pnv_dpll_compute_fp(struct dpll *dpll) ++{ ++ return (1 << dpll->n) << 16 | dpll->m1 << 8 | dpll->m2; ++} ++ ++static uint32_t i9xx_dpll_compute_fp(struct dpll *dpll) ++{ ++ return dpll->n << 16 | dpll->m1 << 8 | dpll->m2; ++} ++ + static void i9xx_update_pll_dividers(struct intel_crtc *crtc, + intel_clock_t *reduced_clock) + { +@@ -4254,18 +4269,15 @@ static void i9xx_update_pll_dividers(struct intel_crtc *crtc, + struct drm_i915_private *dev_priv = dev->dev_private; + int pipe = crtc->pipe; + u32 fp, fp2 = 0; +- struct dpll *clock = &crtc->config.dpll; + + if (IS_PINEVIEW(dev)) { +- fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2; ++ fp = pnv_dpll_compute_fp(&crtc->config.dpll); + if (reduced_clock) +- fp2 = (1 << reduced_clock->n) << 16 | +- reduced_clock->m1 << 8 | reduced_clock->m2; ++ fp2 = pnv_dpll_compute_fp(reduced_clock); + } else { +- fp = clock->n << 16 | clock->m1 << 8 | clock->m2; ++ fp = i9xx_dpll_compute_fp(&crtc->config.dpll); + if (reduced_clock) +- fp2 = reduced_clock->n << 16 | reduced_clock->m1 << 8 | +- reduced_clock->m2; ++ fp2 = i9xx_dpll_compute_fp(reduced_clock); + } + + I915_WRITE(FP0(pipe), fp); +@@ -5604,8 +5616,13 @@ static void ironlake_fdi_set_m_n(struct drm_crtc *crtc) + intel_cpu_transcoder_set_m_n(intel_crtc, &m_n); + } + ++static bool ironlake_needs_fb_cb_tune(struct dpll *dpll, int factor) ++{ ++ return i9xx_dpll_compute_m(dpll) < factor * dpll->n; ++} ++ + static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, +- intel_clock_t *clock, u32 *fp, ++ u32 *fp, + intel_clock_t *reduced_clock, u32 *fp2) + { + struct drm_crtc *crtc = &intel_crtc->base; +@@ -5645,7 +5662,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, + } else if (is_sdvo && is_tv) + factor = 20; + +- if (clock->m < factor * clock->n) ++ if (ironlake_needs_fb_cb_tune(&intel_crtc->config.dpll, factor)) + *fp |= FP_CB_TUNE; + + if (fp2 && (reduced_clock->m < factor * reduced_clock->n)) +@@ -5669,11 +5686,11 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, + dpll |= DPLL_DVO_HIGH_SPEED; + + /* compute bitmask from p1 value */ +- dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; ++ dpll |= (1 << (intel_crtc->config.dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; + /* also FPA1 */ +- dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; ++ dpll |= (1 << (intel_crtc->config.dpll.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; + +- switch (clock->p2) { ++ switch (intel_crtc->config.dpll.p2) { + case 5: + dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; + break; +@@ -5768,12 +5785,11 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + if (intel_crtc->config.has_pch_encoder) { + struct intel_pch_pll *pll; + +- fp = clock.n << 16 | clock.m1 << 8 | clock.m2; ++ fp = i9xx_dpll_compute_fp(&intel_crtc->config.dpll); + if (has_reduced_clock) +- fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | +- reduced_clock.m2; ++ fp2 = i9xx_dpll_compute_fp(&reduced_clock); + +- dpll = ironlake_compute_dpll(intel_crtc, &clock, ++ dpll = ironlake_compute_dpll(intel_crtc, + &fp, &reduced_clock, + has_reduced_clock ? &fp2 : NULL); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0062-drm-i915-move-dp-clock-computations-to-encoder-compu.patch b/patches.baytrail/0062-drm-i915-move-dp-clock-computations-to-encoder-compu.patch new file mode 100644 index 000000000000..70931eb13c61 --- /dev/null +++ b/patches.baytrail/0062-drm-i915-move-dp-clock-computations-to-encoder-compu.patch @@ -0,0 +1,252 @@ +From 92ad83df80e58305d098ae4d83206d0ca57f39d0 Mon Sep 17 00:00:00 2001 +From: James Ausmus +Date: Mon, 23 Sep 2013 16:48:59 -0700 +Subject: drm/i915: move dp clock computations to encoder->compute_config +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With the exception of hsw, which has dedicated DP clocks which run at +the fixed frequency already, and vlv, which doesn't have optmized +pre-defined dp clock parameters (yet). + +v2: Ville asked me to elaborate a bit more on the longer-term goals +wrt dpll settings computation: + +So ultimately my idea is that in the compute config stage first the crtc +code puts the default platform pll limits into the pipe_config. Then +encoders can either overwrite that limit structure with their own special +stuff (mostly for lvds madness). Or they can pick some or all of the +parameters (e.g. just the p2 switchover on hdmi, or all the clock +parameters for dp/sdvo tv). + +Once that's done then the generic crtc code can fill out any missing bits +(using the find_best_pll code) and then try to assign which pll to use (if +it's a platform with shared plls). In the end the modeset could should +simply write the computed stuff into registers and never be able to fail. + +Of course there's still a lot of data to be moved into pipe_config to make +this all happen, hence some of the temporary ugliness. + +Reviewed-by: Jesse Barnes (v1) +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit c6bb353815c30c3f8a33b436314926706f4b6360) + +Conflicts: + drivers/gpu/drm/i915/intel_dp.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 97 +----------------------------------- + drivers/gpu/drm/i915/intel_dp.c | 45 +++++++++++++++++ + 2 files changed, 46 insertions(+), 96 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index eefc8e2ebe94..32e3fea86606 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -102,15 +102,6 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, + intel_clock_t *best_clock); + + static bool +-intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, +- int target, int refclk, intel_clock_t *match_clock, +- intel_clock_t *best_clock); +-static bool +-intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, +- int target, int refclk, intel_clock_t *match_clock, +- intel_clock_t *best_clock); +- +-static bool + intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock); +@@ -242,20 +233,6 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { + .find_pll = intel_g4x_find_best_PLL, + }; + +-static const intel_limit_t intel_limits_g4x_display_port = { +- .dot = { .min = 161670, .max = 227000 }, +- .vco = { .min = 1750000, .max = 3500000}, +- .n = { .min = 1, .max = 2 }, +- .m = { .min = 97, .max = 108 }, +- .m1 = { .min = 0x10, .max = 0x12 }, +- .m2 = { .min = 0x05, .max = 0x06 }, +- .p = { .min = 10, .max = 20 }, +- .p1 = { .min = 1, .max = 2}, +- .p2 = { .dot_limit = 0, +- .p2_slow = 10, .p2_fast = 10 }, +- .find_pll = intel_find_pll_g4x_dp, +-}; +- + static const intel_limit_t intel_limits_pineview_sdvo = { + .dot = { .min = 20000, .max = 400000}, + .vco = { .min = 1700000, .max = 3500000 }, +@@ -362,20 +339,6 @@ static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = { + .find_pll = intel_g4x_find_best_PLL, + }; + +-static const intel_limit_t intel_limits_ironlake_display_port = { +- .dot = { .min = 25000, .max = 350000 }, +- .vco = { .min = 1760000, .max = 3510000}, +- .n = { .min = 1, .max = 2 }, +- .m = { .min = 81, .max = 90 }, +- .m1 = { .min = 12, .max = 22 }, +- .m2 = { .min = 5, .max = 9 }, +- .p = { .min = 10, .max = 20 }, +- .p1 = { .min = 1, .max = 2}, +- .p2 = { .dot_limit = 0, +- .p2_slow = 10, .p2_fast = 10 }, +- .find_pll = intel_find_pll_ironlake_dp, +-}; +- + static const intel_limit_t intel_limits_vlv_dac = { + .dot = { .min = 25000, .max = 270000 }, + .vco = { .min = 4000000, .max = 6000000 }, +@@ -473,10 +436,7 @@ static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, + else + limit = &intel_limits_ironlake_single_lvds; + } +- } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || +- intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) +- limit = &intel_limits_ironlake_display_port; +- else ++ } else + limit = &intel_limits_ironlake_dac; + + return limit; +@@ -497,8 +457,6 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) + limit = &intel_limits_g4x_hdmi; + } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { + limit = &intel_limits_g4x_sdvo; +- } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { +- limit = &intel_limits_g4x_display_port; + } else /* The option is for other outputs */ + limit = &intel_limits_i9xx_sdvo; + +@@ -746,59 +704,6 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, + } + + static bool +-intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, +- int target, int refclk, intel_clock_t *match_clock, +- intel_clock_t *best_clock) +-{ +- struct drm_device *dev = crtc->dev; +- intel_clock_t clock; +- +- if (target < 200000) { +- clock.n = 1; +- clock.p1 = 2; +- clock.p2 = 10; +- clock.m1 = 12; +- clock.m2 = 9; +- } else { +- clock.n = 2; +- clock.p1 = 1; +- clock.p2 = 10; +- clock.m1 = 14; +- clock.m2 = 8; +- } +- intel_clock(dev, refclk, &clock); +- memcpy(best_clock, &clock, sizeof(intel_clock_t)); +- return true; +-} +- +-/* DisplayPort has only two frequencies, 162MHz and 270MHz */ +-static bool +-intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, +- int target, int refclk, intel_clock_t *match_clock, +- intel_clock_t *best_clock) +-{ +- intel_clock_t clock; +- if (target < 200000) { +- clock.p1 = 2; +- clock.p2 = 10; +- clock.n = 2; +- clock.m1 = 23; +- clock.m2 = 8; +- } else { +- clock.p1 = 1; +- clock.p2 = 10; +- clock.n = 1; +- clock.m1 = 14; +- clock.m2 = 2; +- } +- clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2); +- clock.p = (clock.p1 * clock.p2); +- clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; +- clock.vco = 0; +- memcpy(best_clock, &clock, sizeof(intel_clock_t)); +- return true; +-} +-static bool + intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock) +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index d8407c9b0504..fbae5092b1f6 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -671,6 +671,49 @@ intel_dp_i2c_init(struct intel_dp *intel_dp, + return ret; + } + ++static void ++intel_dp_set_clock(struct intel_encoder *encoder, ++ struct intel_crtc_config *pipe_config, int link_bw) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ ++ if (IS_G4X(dev)) { ++ if (link_bw == DP_LINK_BW_1_62) { ++ pipe_config->dpll.p1 = 2; ++ pipe_config->dpll.p2 = 10; ++ pipe_config->dpll.n = 2; ++ pipe_config->dpll.m1 = 23; ++ pipe_config->dpll.m2 = 8; ++ } else { ++ pipe_config->dpll.p1 = 1; ++ pipe_config->dpll.p2 = 10; ++ pipe_config->dpll.n = 1; ++ pipe_config->dpll.m1 = 14; ++ pipe_config->dpll.m2 = 2; ++ } ++ pipe_config->clock_set = true; ++ } else if (IS_HASWELL(dev)) { ++ /* Haswell has special-purpose DP DDI clocks. */ ++ } else if (HAS_PCH_SPLIT(dev)) { ++ if (link_bw == DP_LINK_BW_1_62) { ++ pipe_config->dpll.n = 1; ++ pipe_config->dpll.p1 = 2; ++ pipe_config->dpll.p2 = 10; ++ pipe_config->dpll.m1 = 12; ++ pipe_config->dpll.m2 = 9; ++ } else { ++ pipe_config->dpll.n = 2; ++ pipe_config->dpll.p1 = 1; ++ pipe_config->dpll.p2 = 10; ++ pipe_config->dpll.m1 = 14; ++ pipe_config->dpll.m2 = 8; ++ } ++ pipe_config->clock_set = true; ++ } else if (IS_VALLEYVIEW(dev)) { ++ /* FIXME: Need to figure out optimized DP clocks for vlv. */ ++ } ++} ++ + bool + intel_dp_compute_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) +@@ -766,6 +809,8 @@ found: + target_clock, adjusted_mode->clock, + &pipe_config->dp_m_n); + ++ intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw); ++ + return true; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0063-drm-i915-use-pipe_config-for-lvds-dithering.patch b/patches.baytrail/0063-drm-i915-use-pipe_config-for-lvds-dithering.patch new file mode 100644 index 000000000000..5e61df4326df --- /dev/null +++ b/patches.baytrail/0063-drm-i915-use-pipe_config-for-lvds-dithering.patch @@ -0,0 +1,203 @@ +From 0af02f1028efb594bf9a6efacc6c8884eac1628f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 25 Apr 2013 17:54:44 +0200 +Subject: drm/i915: use pipe_config for lvds dithering +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Up to now we've relied on the bios to get this right for us. Let's try +out whether our code has improved a bit, since we should dither +always when the output bpp doesn't match the plane bpp. +- gen5+ should be fine, since we only use the bios hint as an upgrade. +- gen4 changes, since here dithering is still controlled in the lvds + register. +- gen2/3 has implicit dithering depeding upon whether you use 2 or 3 + lvds pairs (which makes sense, since it only supports 8bpc pipe + outpu configurations). +- hsw doesn't support lvds. + +v2: Remove redudant dither setting. + +v3: Completly drop reliance on dev_priv->lvds_dither. + +v4: Enable dithering on gen2/3 only when we have a 18bpp panel, since +up-dithering to a 24bpp panel is not supported by the hw. Spotted by +Ville. + +v5: Also only enable lvds port dithering on gen4 for 18bpp modes. In +practice this only excludes dithering a 10bpc plane down for a 24bpp +lvds panel. Not something we truly care about. Again noticed by Ville. + +v6: Actually git add. + +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit d8b322474941fa565ba5c58292ccc54be92cca41) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 25 +++++++------------------ + drivers/gpu/drm/i915/intel_drv.h | 5 +++++ + drivers/gpu/drm/i915/intel_lvds.c | 15 ++++++++++----- + 3 files changed, 22 insertions(+), 23 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 32e3fea86606..07f526ff5557 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5158,8 +5158,7 @@ static int ironlake_get_refclk(struct drm_crtc *crtc) + } + + static void ironlake_set_pipeconf(struct drm_crtc *crtc, +- struct drm_display_mode *adjusted_mode, +- bool dither) ++ struct drm_display_mode *adjusted_mode) + { + struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +@@ -5188,7 +5187,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc, + } + + val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK); +- if (dither) ++ if (intel_crtc->config.dither) + val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP); + + val &= ~PIPECONF_INTERLACE_MASK; +@@ -5271,8 +5270,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc) + } + + static void haswell_set_pipeconf(struct drm_crtc *crtc, +- struct drm_display_mode *adjusted_mode, +- bool dither) ++ struct drm_display_mode *adjusted_mode) + { + struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +@@ -5282,7 +5280,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc, + val = I915_READ(PIPECONF(cpu_transcoder)); + + val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK); +- if (dither) ++ if (intel_crtc->config.dither) + val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP); + + val &= ~PIPECONF_INTERLACE_MASK_HSW; +@@ -5643,7 +5641,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + bool is_lvds = false; + struct intel_encoder *encoder; + int ret; +- bool dither, fdi_config_ok; ++ bool fdi_config_ok; + + for_each_encoder_on_crtc(dev, crtc, encoder) { + switch (encoder->type) { +@@ -5678,11 +5676,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + /* Ensure that the cursor is valid for the new mode before changing... */ + intel_crtc_update_cursor(crtc, true); + +- /* determine panel color depth */ +- dither = intel_crtc->config.dither; +- if (is_lvds && dev_priv->lvds_dither) +- dither = true; +- + DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe_name(pipe)); + drm_mode_debug_printmodeline(mode); + +@@ -5749,7 +5742,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + + fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc); + +- ironlake_set_pipeconf(crtc, adjusted_mode, dither); ++ ironlake_set_pipeconf(crtc, adjusted_mode); + + /* Set up the display plane register */ + I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE); +@@ -5826,7 +5819,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + bool is_cpu_edp = false; + struct intel_encoder *encoder; + int ret; +- bool dither; + + for_each_encoder_on_crtc(dev, crtc, encoder) { + switch (encoder->type) { +@@ -5862,9 +5854,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + /* Ensure that the cursor is valid for the new mode before changing... */ + intel_crtc_update_cursor(crtc, true); + +- /* determine panel color depth */ +- dither = intel_crtc->config.dither; +- + DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe_name(pipe)); + drm_mode_debug_printmodeline(mode); + +@@ -5878,7 +5867,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + if (intel_crtc->config.has_pch_encoder) + ironlake_fdi_set_m_n(crtc); + +- haswell_set_pipeconf(crtc, adjusted_mode, dither); ++ haswell_set_pipeconf(crtc, adjusted_mode); + + intel_set_pipe_csc(crtc); + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 86a26ae1615f..52b2505f1823 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -213,6 +213,11 @@ struct intel_crtc_config { + /* DP has a bunch of special case unfortunately, so mark the pipe + * accordingly. */ + bool has_dp_encoder; ++ ++ /* ++ * Enable dithering, used when the selected pipe bpp doesn't match the ++ * plane bpp. ++ */ + bool dither; + + /* Controls for the clock computation, to override various stages. */ +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 2379b5e404df..855c0850f030 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -136,7 +136,10 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder) + * special lvds dither control bit on pch-split platforms, dithering is + * only controlled through the PIPECONF reg. */ + if (INTEL_INFO(dev)->gen == 4) { +- if (dev_priv->lvds_dither) ++ /* Bspec wording suggests that LVDS port dithering only exists ++ * for 18bpp panels. */ ++ if (intel_crtc->config.dither && ++ intel_crtc->config.pipe_bpp == 18) + temp |= LVDS_ENABLE_DITHER; + else + temp &= ~LVDS_ENABLE_DITHER; +@@ -335,7 +338,13 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + DRM_DEBUG_KMS("forcing display bpp (was %d) to LVDS (%d)\n", + pipe_config->pipe_bpp, lvds_bpp); + pipe_config->pipe_bpp = lvds_bpp; ++ ++ /* Make sure pre-965 set dither correctly for 18bpp panels. */ ++ if (INTEL_INFO(dev)->gen < 4 && lvds_bpp == 18) ++ pfit_control |= PANEL_8TO6_DITHER_ENABLE; ++ + } ++ + /* + * We have timings from the BIOS for the panel, put them in + * to the adjusted mode. The CRTC will be set up for this mode, +@@ -470,10 +479,6 @@ out: + pfit_pgm_ratios = 0; + } + +- /* Make sure pre-965 set dither correctly */ +- if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither) +- pfit_control |= PANEL_8TO6_DITHER_ENABLE; +- + if (pfit_control != lvds_encoder->pfit_control || + pfit_pgm_ratios != lvds_encoder->pfit_pgm_ratios) { + lvds_encoder->pfit_control = pfit_control; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0064-drm-i915-don-t-force-matching-p1-for-g4x-ilk-reduced.patch b/patches.baytrail/0064-drm-i915-don-t-force-matching-p1-for-g4x-ilk-reduced.patch new file mode 100644 index 000000000000..8fa445cafbcc --- /dev/null +++ b/patches.baytrail/0064-drm-i915-don-t-force-matching-p1-for-g4x-ilk-reduced.patch @@ -0,0 +1,47 @@ +From 7a4b736b75ae8af323ae98892804544622892b3a Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 19 Apr 2013 11:14:35 +0200 +Subject: drm/i915: don't force matching p1 for g4x/ilk+ reduced pll settings + +g4x dplls and ilk+ pch plls have a separate field for the reduced p1 +setting, so this restriction does not apply. Only older platforms have +the restriction that the p1 divisors must match. + +This unnecessary restriction has been introduced in + +commit cec2f356d59d9e070413e5966a3c5a1af136d948 +Author: Sean Paul +Date: Tue Jan 10 15:09:36 2012 -0800 + + drm/i915: Only look for matching clocks for LVDS downcloc + +Note that with lvds the p2 divisors _always_ match for LVDS, and we +don't support auto-downclocking anywhere else. On eDP downclocking +works with separate data m/n settings, using the same link clock. + +Cc: Sean Paul +Reviewed-by: Sean Paul +Signed-off-by: Daniel Vetter +(cherry picked from commit 4f4134ace04fd5b0e8734b65f4046e7aa2e39393) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 07f526ff5557..a22bcf576ea9 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -685,9 +685,6 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, + if (!intel_PLL_is_valid(dev, limit, + &clock)) + continue; +- if (match_clock && +- clock.p != match_clock->p) +- continue; + + this_err = abs(clock.dot - target); + if (this_err < err_most) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0065-drm-i915-remove-redundant-has_pch_encoder-check.patch b/patches.baytrail/0065-drm-i915-remove-redundant-has_pch_encoder-check.patch new file mode 100644 index 000000000000..aa2c6965942c --- /dev/null +++ b/patches.baytrail/0065-drm-i915-remove-redundant-has_pch_encoder-check.patch @@ -0,0 +1,35 @@ +From 2997db2589af9a5081fa13a94fea9c69dd66e549 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 19 Apr 2013 11:14:36 +0200 +Subject: drm/i915: remove redundant has_pch_encoder check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If we compute the pch pll state, we _have_ a pch encoder. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 9566e9af524856a27f3c6b00821e74ff9ae04732) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index a22bcf576ea9..2a951781074d 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5581,8 +5581,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, + } + dpll |= DPLL_DVO_HIGH_SPEED; + } +- if (intel_crtc->config.has_dp_encoder && +- intel_crtc->config.has_pch_encoder) ++ if (intel_crtc->config.has_dp_encoder) + dpll |= DPLL_DVO_HIGH_SPEED; + + /* compute bitmask from p1 value */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0066-drm-i915-simplify-config-pixel_multiplier-handling.patch b/patches.baytrail/0066-drm-i915-simplify-config-pixel_multiplier-handling.patch new file mode 100644 index 000000000000..d90e9eb9c9fc --- /dev/null +++ b/patches.baytrail/0066-drm-i915-simplify-config-pixel_multiplier-handling.patch @@ -0,0 +1,125 @@ +From 9ffc79890b374125f8c047c25b067e19f2d3512b Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 19 Apr 2013 11:14:37 +0200 +Subject: drm/i915: simplify config->pixel_multiplier handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We only ever check whether it's strictly bigger than one, so all the +is_sdvo/is_hdmi checks are redundant. Flatten the code a bit. + +Also, s/temp/dpll_md/ + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 198a037f02666eeaab5ba07974fa37467b1f6bd8) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 58 +++++++++++++++++------------------- + 1 file changed, 27 insertions(+), 31 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 2a951781074d..c3da1726a027 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4241,7 +4241,7 @@ static void vlv_update_pll(struct intel_crtc *crtc) + u32 dpll, mdiv; + u32 bestn, bestm1, bestm2, bestp1, bestp2; + bool is_hdmi; +- u32 coreclk, reg_val, temp; ++ u32 coreclk, reg_val, dpll_md; + + mutex_lock(&dev_priv->dpio_lock); + +@@ -4339,16 +4339,13 @@ static void vlv_update_pll(struct intel_crtc *crtc) + if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) + DRM_ERROR("DPLL %d failed to lock\n", pipe); + +- if (is_hdmi) { +- temp = 0; +- if (crtc->config.pixel_multiplier > 1) { +- temp = (crtc->config.pixel_multiplier - 1) +- << DPLL_MD_UDI_MULTIPLIER_SHIFT; +- } +- +- I915_WRITE(DPLL_MD(pipe), temp); +- POSTING_READ(DPLL_MD(pipe)); ++ dpll_md = 0; ++ if (crtc->config.pixel_multiplier > 1) { ++ dpll_md = (crtc->config.pixel_multiplier - 1) ++ << DPLL_MD_UDI_MULTIPLIER_SHIFT; + } ++ I915_WRITE(DPLL_MD(pipe), dpll_md); ++ POSTING_READ(DPLL_MD(pipe)); + + if (crtc->config.has_dp_encoder) + intel_dp_set_m_n(crtc); +@@ -4381,14 +4378,15 @@ static void i9xx_update_pll(struct intel_crtc *crtc, + else + dpll |= DPLLB_MODE_DAC_SERIAL; + +- if (is_sdvo) { +- if ((crtc->config.pixel_multiplier > 1) && +- (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))) { +- dpll |= (crtc->config.pixel_multiplier - 1) +- << SDVO_MULTIPLIER_SHIFT_HIRES; +- } +- dpll |= DPLL_DVO_HIGH_SPEED; ++ if ((crtc->config.pixel_multiplier > 1) && ++ (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))) { ++ dpll |= (crtc->config.pixel_multiplier - 1) ++ << SDVO_MULTIPLIER_SHIFT_HIRES; + } ++ ++ if (is_sdvo) ++ dpll |= DPLL_DVO_HIGH_SPEED; ++ + if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)) + dpll |= DPLL_DVO_HIGH_SPEED; + +@@ -4448,15 +4446,12 @@ static void i9xx_update_pll(struct intel_crtc *crtc, + udelay(150); + + if (INTEL_INFO(dev)->gen >= 4) { +- u32 temp = 0; +- if (is_sdvo) { +- temp = 0; +- if (crtc->config.pixel_multiplier > 1) { +- temp = (crtc->config.pixel_multiplier - 1) +- << DPLL_MD_UDI_MULTIPLIER_SHIFT; +- } ++ u32 dpll_md = 0; ++ if (crtc->config.pixel_multiplier > 1) { ++ dpll_md = (crtc->config.pixel_multiplier - 1) ++ << DPLL_MD_UDI_MULTIPLIER_SHIFT; + } +- I915_WRITE(DPLL_MD(pipe), temp); ++ I915_WRITE(DPLL_MD(pipe), dpll_md); + } else { + /* The pixel multiplier can only be updated once the + * DPLL is enabled and the clocks are stable. +@@ -5574,13 +5569,14 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, + dpll |= DPLLB_MODE_LVDS; + else + dpll |= DPLLB_MODE_DAC_SERIAL; +- if (is_sdvo) { +- if (intel_crtc->config.pixel_multiplier > 1) { +- dpll |= (intel_crtc->config.pixel_multiplier - 1) +- << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; +- } +- dpll |= DPLL_DVO_HIGH_SPEED; ++ ++ if (intel_crtc->config.pixel_multiplier > 1) { ++ dpll |= (intel_crtc->config.pixel_multiplier - 1) ++ << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; + } ++ ++ if (is_sdvo) ++ dpll |= DPLL_DVO_HIGH_SPEED; + if (intel_crtc->config.has_dp_encoder) + dpll |= DPLL_DVO_HIGH_SPEED; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0067-drm-i915-factor-out-GMCH-panel-fitting-code-and-use-.patch b/patches.baytrail/0067-drm-i915-factor-out-GMCH-panel-fitting-code-and-use-.patch new file mode 100644 index 000000000000..36e69076a5ee --- /dev/null +++ b/patches.baytrail/0067-drm-i915-factor-out-GMCH-panel-fitting-code-and-use-.patch @@ -0,0 +1,632 @@ +From 30af340d1b2fb5434c36e9f3ee4c4b01c815fa95 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Thu, 25 Apr 2013 12:55:01 -0700 +Subject: drm/i915: factor out GMCH panel fitting code and use for eDP v3 + +This gets the panel fitter working on eDP on VLV, and should also apply +to eDP panels on G4x chipsets (if we ever detect and mark an all-in-one +panel as eDP anyway). + +A few cleanups are still possible on top of this, for example the LVDS +border control could be placed in the LVDS encoder structure and updated +based on the result of the panel fitter calculation. + +Multi-pipe fitting isn't handled correctly either if we ever get a config +that wants to try the panel fitter on more than one output at a time. + +v2: use pipe_config for storing pfit values (Daniel) + add i9xx_pfit_enable function for use by 9xx and VLV (Daniel) +v3: fixup conflicts and lvds_dither check + +Reviewed-by: Mika Kuoppala +Signed-off-by: Jesse Barnes +[danvet: fix up botched conflict resolution from Jesse: +- border = LVDS_BORDER_ENABLE was lost for CENTER scaling +- comment about gen2/3 panel fitter scaling was lost +- dev_priv->lvds_dither reintroduced.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 2dd24552cab40ea829ba3fda890eeafd2c4816d8) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 33 ++++++ + drivers/gpu/drm/i915/intel_dp.c | 11 +- + drivers/gpu/drm/i915/intel_drv.h | 6 + + drivers/gpu/drm/i915/intel_lvds.c | 209 +---------------------------------- + drivers/gpu/drm/i915/intel_panel.c | 191 ++++++++++++++++++++++++++++++++ + 5 files changed, 241 insertions(+), 209 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index c3da1726a027..ab5758374f8d 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3601,6 +3601,33 @@ g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe) + } + } + ++static void i9xx_pfit_enable(struct intel_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct intel_crtc_config *pipe_config = &crtc->config; ++ ++ if (!(intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) || ++ intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS))) ++ return; ++ ++ WARN_ON(I915_READ(PFIT_CONTROL) & PFIT_ENABLE); ++ assert_pipe_disabled(dev_priv, crtc->pipe); ++ ++ /* ++ * Enable automatic panel scaling so that non-native modes ++ * fill the screen. The panel fitter should only be ++ * adjusted whilst the pipe is disabled, according to ++ * register description and PRM. ++ */ ++ DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", ++ pipe_config->pfit_control, ++ pipe_config->pfit_pgm_ratios); ++ ++ I915_WRITE(PFIT_PGM_RATIOS, pipe_config->pfit_pgm_ratios); ++ I915_WRITE(PFIT_CONTROL, pipe_config->pfit_control); ++} ++ + static void valleyview_crtc_enable(struct drm_crtc *crtc) + { + struct drm_device *dev = crtc->dev; +@@ -3634,6 +3661,9 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) + for_each_encoder_on_crtc(dev, crtc, encoder) + encoder->enable(encoder); + ++ /* Enable panel fitting for eDP */ ++ i9xx_pfit_enable(intel_crtc); ++ + intel_enable_pipe(dev_priv, pipe, false); + intel_enable_plane(dev_priv, plane, pipe); + +@@ -3670,6 +3700,9 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) + if (encoder->pre_enable) + encoder->pre_enable(encoder); + ++ /* Enable panel fitting for LVDS */ ++ i9xx_pfit_enable(intel_crtc); ++ + intel_enable_pipe(dev_priv, pipe, false); + intel_enable_plane(dev_priv, plane, pipe); + if (IS_G4X(dev)) +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index fbae5092b1f6..38b3fb549bac 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -723,6 +723,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; + struct drm_display_mode *mode = &pipe_config->requested_mode; + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); ++ struct intel_crtc *intel_crtc = encoder->new_crtc; + struct intel_connector *intel_connector = intel_dp->attached_connector; + int lane_count, clock; + int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd); +@@ -739,9 +740,13 @@ intel_dp_compute_config(struct intel_encoder *encoder, + if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) { + intel_fixed_panel_mode(intel_connector->panel.fixed_mode, + adjusted_mode); +- intel_pch_panel_fitting(dev, +- intel_connector->panel.fitting_mode, +- mode, adjusted_mode); ++ if (!HAS_PCH_SPLIT(dev)) ++ intel_gmch_panel_fitting(intel_crtc, pipe_config, ++ intel_connector->panel.fitting_mode); ++ else ++ intel_pch_panel_fitting(dev, ++ intel_connector->panel.fitting_mode, ++ mode, adjusted_mode); + } + /* We need to take the panel's fixed mode into account. */ + target_clock = adjusted_mode->clock; +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 52b2505f1823..1780f79e1a89 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -237,6 +237,9 @@ struct intel_crtc_config { + int pixel_target_clock; + /* Used by SDVO (and if we ever fix it, HDMI). */ + unsigned pixel_multiplier; ++ ++ /* Panel fitter controls for gen2-gen4 + VLV */ ++ u32 pfit_control, pfit_pgm_ratios; + }; + + struct intel_crtc { +@@ -559,6 +562,9 @@ extern void intel_pch_panel_fitting(struct drm_device *dev, + int fitting_mode, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); ++extern void intel_gmch_panel_fitting(struct intel_crtc *crtc, ++ struct intel_crtc_config *pipe_config, ++ int fitting_mode); + extern void intel_panel_set_backlight(struct drm_device *dev, + u32 level, u32 max); + extern int intel_panel_setup_backlight(struct drm_connector *connector); +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 855c0850f030..2a2180410cbd 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -49,8 +49,6 @@ struct intel_lvds_connector { + struct intel_lvds_encoder { + struct intel_encoder base; + +- u32 pfit_control; +- u32 pfit_pgm_ratios; + bool is_dual_link; + u32 reg; + +@@ -153,32 +151,6 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder) + I915_WRITE(lvds_encoder->reg, temp); + } + +-static void intel_pre_enable_lvds(struct intel_encoder *encoder) +-{ +- struct drm_device *dev = encoder->base.dev; +- struct intel_lvds_encoder *enc = to_lvds_encoder(&encoder->base); +- struct drm_i915_private *dev_priv = dev->dev_private; +- +- if (HAS_PCH_SPLIT(dev) || !enc->pfit_control) +- return; +- +- WARN_ON(I915_READ(PFIT_CONTROL) & PFIT_ENABLE); +- assert_pipe_disabled(dev_priv, to_intel_crtc(encoder->base.crtc)->pipe); +- +- /* +- * Enable automatic panel scaling so that non-native modes +- * fill the screen. The panel fitter should only be +- * adjusted whilst the pipe is disabled, according to +- * register description and PRM. +- */ +- DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", +- enc->pfit_control, +- enc->pfit_pgm_ratios); +- +- I915_WRITE(PFIT_PGM_RATIOS, enc->pfit_pgm_ratios); +- I915_WRITE(PFIT_CONTROL, enc->pfit_control); +-} +- + /** + * Sets the power state for the panel. + */ +@@ -247,62 +219,6 @@ static int intel_lvds_mode_valid(struct drm_connector *connector, + return MODE_OK; + } + +-static void +-centre_horizontally(struct drm_display_mode *mode, +- int width) +-{ +- u32 border, sync_pos, blank_width, sync_width; +- +- /* keep the hsync and hblank widths constant */ +- sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start; +- blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start; +- sync_pos = (blank_width - sync_width + 1) / 2; +- +- border = (mode->hdisplay - width + 1) / 2; +- border += border & 1; /* make the border even */ +- +- mode->crtc_hdisplay = width; +- mode->crtc_hblank_start = width + border; +- mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width; +- +- mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; +- mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; +-} +- +-static void +-centre_vertically(struct drm_display_mode *mode, +- int height) +-{ +- u32 border, sync_pos, blank_width, sync_width; +- +- /* keep the vsync and vblank widths constant */ +- sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start; +- blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start; +- sync_pos = (blank_width - sync_width + 1) / 2; +- +- border = (mode->vdisplay - height + 1) / 2; +- +- mode->crtc_vdisplay = height; +- mode->crtc_vblank_start = height + border; +- mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width; +- +- mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; +- mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; +-} +- +-static inline u32 panel_fitter_scaling(u32 source, u32 target) +-{ +- /* +- * Floating point operation is not supported. So the FACTOR +- * is defined, which can avoid the floating point computation +- * when calculating the panel ratio. +- */ +-#define ACCURACY 12 +-#define FACTOR (1 << ACCURACY) +- u32 ratio = source * FACTOR / target; +- return (FACTOR * ratio + FACTOR/2) / FACTOR; +-} +- + static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + struct intel_crtc_config *pipe_config) + { +@@ -315,7 +231,6 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; + struct drm_display_mode *mode = &pipe_config->requested_mode; + struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc; +- u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; + unsigned int lvds_bpp; + int pipe; + +@@ -338,11 +253,6 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + DRM_DEBUG_KMS("forcing display bpp (was %d) to LVDS (%d)\n", + pipe_config->pipe_bpp, lvds_bpp); + pipe_config->pipe_bpp = lvds_bpp; +- +- /* Make sure pre-965 set dither correctly for 18bpp panels. */ +- if (INTEL_INFO(dev)->gen < 4 && lvds_bpp == 18) +- pfit_control |= PANEL_8TO6_DITHER_ENABLE; +- + } + + /* +@@ -361,18 +271,11 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + intel_connector->panel.fitting_mode, + mode, adjusted_mode); + return true; ++ } else { ++ intel_gmch_panel_fitting(intel_crtc, pipe_config, ++ intel_connector->panel.fitting_mode); + } + +- /* Native modes don't need fitting */ +- if (adjusted_mode->hdisplay == mode->hdisplay && +- adjusted_mode->vdisplay == mode->vdisplay) +- goto out; +- +- /* 965+ wants fuzzy fitting */ +- if (INTEL_INFO(dev)->gen >= 4) +- pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | +- PFIT_FILTER_FUZZY); +- + /* + * Enable automatic panel scaling for non-native modes so that they fill + * the screen. Should be enabled before the pipe is enabled, according +@@ -385,107 +288,6 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + drm_mode_set_crtcinfo(adjusted_mode, 0); + pipe_config->timings_set = true; + +- switch (intel_connector->panel.fitting_mode) { +- case DRM_MODE_SCALE_CENTER: +- /* +- * For centered modes, we have to calculate border widths & +- * heights and modify the values programmed into the CRTC. +- */ +- centre_horizontally(adjusted_mode, mode->hdisplay); +- centre_vertically(adjusted_mode, mode->vdisplay); +- border = LVDS_BORDER_ENABLE; +- break; +- +- case DRM_MODE_SCALE_ASPECT: +- /* Scale but preserve the aspect ratio */ +- if (INTEL_INFO(dev)->gen >= 4) { +- u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; +- u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; +- +- /* 965+ is easy, it does everything in hw */ +- if (scaled_width > scaled_height) +- pfit_control |= PFIT_ENABLE | PFIT_SCALING_PILLAR; +- else if (scaled_width < scaled_height) +- pfit_control |= PFIT_ENABLE | PFIT_SCALING_LETTER; +- else if (adjusted_mode->hdisplay != mode->hdisplay) +- pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; +- } else { +- u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; +- u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; +- /* +- * For earlier chips we have to calculate the scaling +- * ratio by hand and program it into the +- * PFIT_PGM_RATIO register +- */ +- if (scaled_width > scaled_height) { /* pillar */ +- centre_horizontally(adjusted_mode, scaled_height / mode->vdisplay); +- +- border = LVDS_BORDER_ENABLE; +- if (mode->vdisplay != adjusted_mode->vdisplay) { +- u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay); +- pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | +- bits << PFIT_VERT_SCALE_SHIFT); +- pfit_control |= (PFIT_ENABLE | +- VERT_INTERP_BILINEAR | +- HORIZ_INTERP_BILINEAR); +- } +- } else if (scaled_width < scaled_height) { /* letter */ +- centre_vertically(adjusted_mode, scaled_width / mode->hdisplay); +- +- border = LVDS_BORDER_ENABLE; +- if (mode->hdisplay != adjusted_mode->hdisplay) { +- u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay); +- pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | +- bits << PFIT_VERT_SCALE_SHIFT); +- pfit_control |= (PFIT_ENABLE | +- VERT_INTERP_BILINEAR | +- HORIZ_INTERP_BILINEAR); +- } +- } else +- /* Aspects match, Let hw scale both directions */ +- pfit_control |= (PFIT_ENABLE | +- VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | +- VERT_INTERP_BILINEAR | +- HORIZ_INTERP_BILINEAR); +- } +- break; +- +- case DRM_MODE_SCALE_FULLSCREEN: +- /* +- * Full scaling, even if it changes the aspect ratio. +- * Fortunately this is all done for us in hw. +- */ +- if (mode->vdisplay != adjusted_mode->vdisplay || +- mode->hdisplay != adjusted_mode->hdisplay) { +- pfit_control |= PFIT_ENABLE; +- if (INTEL_INFO(dev)->gen >= 4) +- pfit_control |= PFIT_SCALING_AUTO; +- else +- pfit_control |= (VERT_AUTO_SCALE | +- VERT_INTERP_BILINEAR | +- HORIZ_AUTO_SCALE | +- HORIZ_INTERP_BILINEAR); +- } +- break; +- +- default: +- break; +- } +- +-out: +- /* If not enabling scaling, be consistent and always use 0. */ +- if ((pfit_control & PFIT_ENABLE) == 0) { +- pfit_control = 0; +- pfit_pgm_ratios = 0; +- } +- +- if (pfit_control != lvds_encoder->pfit_control || +- pfit_pgm_ratios != lvds_encoder->pfit_pgm_ratios) { +- lvds_encoder->pfit_control = pfit_control; +- lvds_encoder->pfit_pgm_ratios = pfit_pgm_ratios; +- } +- dev_priv->lvds_border_bits = border; +- + /* + * XXX: It would be nice to support lower refresh rates on the + * panels to reduce power consumption, and perhaps match the +@@ -1147,10 +949,6 @@ bool intel_lvds_init(struct drm_device *dev) + + lvds_encoder->attached_connector = lvds_connector; + +- if (!HAS_PCH_SPLIT(dev)) { +- lvds_encoder->pfit_control = I915_READ(PFIT_CONTROL); +- } +- + intel_encoder = &lvds_encoder->base; + encoder = &intel_encoder->base; + intel_connector = &lvds_connector->base; +@@ -1162,7 +960,6 @@ bool intel_lvds_init(struct drm_device *dev) + DRM_MODE_ENCODER_LVDS); + + intel_encoder->enable = intel_enable_lvds; +- intel_encoder->pre_enable = intel_pre_enable_lvds; + intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds; + intel_encoder->compute_config = intel_lvds_compute_config; + intel_encoder->disable = intel_disable_lvds; +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index 317d2bc15049..b775dd5f8dd9 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -117,6 +117,197 @@ done: + dev_priv->pch_pf_size = (width << 16) | height; + } + ++static void ++centre_horizontally(struct drm_display_mode *mode, ++ int width) ++{ ++ u32 border, sync_pos, blank_width, sync_width; ++ ++ /* keep the hsync and hblank widths constant */ ++ sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start; ++ blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start; ++ sync_pos = (blank_width - sync_width + 1) / 2; ++ ++ border = (mode->hdisplay - width + 1) / 2; ++ border += border & 1; /* make the border even */ ++ ++ mode->crtc_hdisplay = width; ++ mode->crtc_hblank_start = width + border; ++ mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width; ++ ++ mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; ++ mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; ++} ++ ++static void ++centre_vertically(struct drm_display_mode *mode, ++ int height) ++{ ++ u32 border, sync_pos, blank_width, sync_width; ++ ++ /* keep the vsync and vblank widths constant */ ++ sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start; ++ blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start; ++ sync_pos = (blank_width - sync_width + 1) / 2; ++ ++ border = (mode->vdisplay - height + 1) / 2; ++ ++ mode->crtc_vdisplay = height; ++ mode->crtc_vblank_start = height + border; ++ mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width; ++ ++ mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; ++ mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; ++} ++ ++static inline u32 panel_fitter_scaling(u32 source, u32 target) ++{ ++ /* ++ * Floating point operation is not supported. So the FACTOR ++ * is defined, which can avoid the floating point computation ++ * when calculating the panel ratio. ++ */ ++#define ACCURACY 12 ++#define FACTOR (1 << ACCURACY) ++ u32 ratio = source * FACTOR / target; ++ return (FACTOR * ratio + FACTOR/2) / FACTOR; ++} ++ ++void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, ++ struct intel_crtc_config *pipe_config, ++ int fitting_mode) ++{ ++ struct drm_device *dev = intel_crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; ++ struct drm_display_mode *mode, *adjusted_mode; ++ ++ mode = &pipe_config->requested_mode; ++ adjusted_mode = &pipe_config->adjusted_mode; ++ ++ /* Native modes don't need fitting */ ++ if (adjusted_mode->hdisplay == mode->hdisplay && ++ adjusted_mode->vdisplay == mode->vdisplay) ++ goto out; ++ ++ switch (fitting_mode) { ++ case DRM_MODE_SCALE_CENTER: ++ /* ++ * For centered modes, we have to calculate border widths & ++ * heights and modify the values programmed into the CRTC. ++ */ ++ centre_horizontally(adjusted_mode, mode->hdisplay); ++ centre_vertically(adjusted_mode, mode->vdisplay); ++ border = LVDS_BORDER_ENABLE; ++ break; ++ case DRM_MODE_SCALE_ASPECT: ++ /* Scale but preserve the aspect ratio */ ++ if (INTEL_INFO(dev)->gen >= 4) { ++ u32 scaled_width = adjusted_mode->hdisplay * ++ mode->vdisplay; ++ u32 scaled_height = mode->hdisplay * ++ adjusted_mode->vdisplay; ++ ++ /* 965+ is easy, it does everything in hw */ ++ if (scaled_width > scaled_height) ++ pfit_control |= PFIT_ENABLE | ++ PFIT_SCALING_PILLAR; ++ else if (scaled_width < scaled_height) ++ pfit_control |= PFIT_ENABLE | ++ PFIT_SCALING_LETTER; ++ else if (adjusted_mode->hdisplay != mode->hdisplay) ++ pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; ++ } else { ++ u32 scaled_width = adjusted_mode->hdisplay * ++ mode->vdisplay; ++ u32 scaled_height = mode->hdisplay * ++ adjusted_mode->vdisplay; ++ /* ++ * For earlier chips we have to calculate the scaling ++ * ratio by hand and program it into the ++ * PFIT_PGM_RATIO register ++ */ ++ if (scaled_width > scaled_height) { /* pillar */ ++ centre_horizontally(adjusted_mode, ++ scaled_height / ++ mode->vdisplay); ++ ++ border = LVDS_BORDER_ENABLE; ++ if (mode->vdisplay != adjusted_mode->vdisplay) { ++ u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay); ++ pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | ++ bits << PFIT_VERT_SCALE_SHIFT); ++ pfit_control |= (PFIT_ENABLE | ++ VERT_INTERP_BILINEAR | ++ HORIZ_INTERP_BILINEAR); ++ } ++ } else if (scaled_width < scaled_height) { /* letter */ ++ centre_vertically(adjusted_mode, ++ scaled_width / ++ mode->hdisplay); ++ ++ border = LVDS_BORDER_ENABLE; ++ if (mode->hdisplay != adjusted_mode->hdisplay) { ++ u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay); ++ pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | ++ bits << PFIT_VERT_SCALE_SHIFT); ++ pfit_control |= (PFIT_ENABLE | ++ VERT_INTERP_BILINEAR | ++ HORIZ_INTERP_BILINEAR); ++ } ++ } else { ++ /* Aspects match, Let hw scale both directions */ ++ pfit_control |= (PFIT_ENABLE | ++ VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | ++ VERT_INTERP_BILINEAR | ++ HORIZ_INTERP_BILINEAR); ++ } ++ } ++ break; ++ default: ++ case DRM_MODE_SCALE_FULLSCREEN: ++ /* ++ * Full scaling, even if it changes the aspect ratio. ++ * Fortunately this is all done for us in hw. ++ */ ++ if (mode->vdisplay != adjusted_mode->vdisplay || ++ mode->hdisplay != adjusted_mode->hdisplay) { ++ pfit_control |= PFIT_ENABLE; ++ if (INTEL_INFO(dev)->gen >= 4) ++ pfit_control |= PFIT_SCALING_AUTO; ++ else ++ pfit_control |= (VERT_AUTO_SCALE | ++ VERT_INTERP_BILINEAR | ++ HORIZ_AUTO_SCALE | ++ HORIZ_INTERP_BILINEAR); ++ } ++ break; ++ } ++ ++ /* 965+ wants fuzzy fitting */ ++ /* FIXME: handle multiple panels by failing gracefully */ ++ if (INTEL_INFO(dev)->gen >= 4) ++ pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | ++ PFIT_FILTER_FUZZY); ++ ++out: ++ if ((pfit_control & PFIT_ENABLE) == 0) { ++ pfit_control = 0; ++ pfit_pgm_ratios = 0; ++ } ++ ++ /* Make sure pre-965 set dither correctly for 18bpp panels. */ ++ if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18) ++ pfit_control |= PANEL_8TO6_DITHER_ENABLE; ++ ++ if (pfit_control != pipe_config->pfit_control || ++ pfit_pgm_ratios != pipe_config->pfit_pgm_ratios) { ++ pipe_config->pfit_control = pfit_control; ++ pipe_config->pfit_pgm_ratios = pfit_pgm_ratios; ++ } ++ dev_priv->lvds_border_bits = border; ++} ++ + static int is_backlight_combination_mode(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0068-drm-i915-move-PCH-pfit-controls-into-pipe_config.patch b/patches.baytrail/0068-drm-i915-move-PCH-pfit-controls-into-pipe_config.patch new file mode 100644 index 000000000000..ac129d35a0c9 --- /dev/null +++ b/patches.baytrail/0068-drm-i915-move-PCH-pfit-controls-into-pipe_config.patch @@ -0,0 +1,300 @@ +From a2e5bc8abb3c38173c900dd9737f8a565c1d5357 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Thu, 25 Apr 2013 12:55:02 -0700 +Subject: drm/i915: move PCH pfit controls into pipe_config + +And put the pfit stuff into substructs while we're at it. + +Signed-off-by: Jesse Barnes +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit b074cec8c652f2d273907a4b35239b4766c894ac) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 -- + drivers/gpu/drm/i915/intel_ddi.c | 2 +- + drivers/gpu/drm/i915/intel_display.c | 65 +++++++++++++++++------------------- + drivers/gpu/drm/i915/intel_dp.c | 6 ++-- + drivers/gpu/drm/i915/intel_drv.h | 18 +++++++--- + drivers/gpu/drm/i915/intel_lvds.c | 6 ++-- + drivers/gpu/drm/i915/intel_panel.c | 25 ++++++++------ + 7 files changed, 63 insertions(+), 61 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index afc6977303c6..a540b1f2354e 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1022,8 +1022,6 @@ typedef struct drm_i915_private { + struct sdvo_device_mapping sdvo_mappings[2]; + /* indicate whether the LVDS_BORDER should be enabled or not */ + unsigned int lvds_border_bits; +- /* Panel fitter placement and size for Ironlake+ */ +- u32 pch_pf_pos, pch_pf_size; + + struct drm_crtc *plane_to_crtc_mapping[3]; + struct drm_crtc *pipe_to_crtc_mapping[3]; +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index cfaf6bead217..70a1e9ca87d3 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -995,7 +995,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) + /* Can only use the always-on power well for eDP when + * not using the panel fitter, and when not using motion + * blur mitigation (which we don't support). */ +- if (dev_priv->pch_pf_size) ++ if (intel_crtc->config.pch_pfit.size) + temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; + else + temp |= TRANS_DDI_EDP_INPUT_A_ON; +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index ab5758374f8d..0af841ebc505 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3225,6 +3225,28 @@ void intel_cpt_verify_modeset(struct drm_device *dev, int pipe) + } + } + ++static void ironlake_pfit_enable(struct intel_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int pipe = crtc->pipe; ++ ++ if (crtc->config.pch_pfit.size && ++ intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP)) { ++ /* Force use of hard-coded filter coefficients ++ * as some pre-programmed values are broken, ++ * e.g. x201. ++ */ ++ if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) ++ I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3 | ++ PF_PIPE_SEL_IVB(pipe)); ++ else ++ I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3); ++ I915_WRITE(PF_WIN_POS(pipe), crtc->config.pch_pfit.pos); ++ I915_WRITE(PF_WIN_SZ(pipe), crtc->config.pch_pfit.size); ++ } ++} ++ + static void ironlake_crtc_enable(struct drm_crtc *crtc) + { + struct drm_device *dev = crtc->dev; +@@ -3269,21 +3291,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + encoder->pre_enable(encoder); + + /* Enable panel fitting for LVDS */ +- if (dev_priv->pch_pf_size && +- (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || +- intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { +- /* Force use of hard-coded filter coefficients +- * as some pre-programmed values are broken, +- * e.g. x201. +- */ +- if (IS_IVYBRIDGE(dev)) +- I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3 | +- PF_PIPE_SEL_IVB(pipe)); +- else +- I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3); +- I915_WRITE(PF_WIN_POS(pipe), dev_priv->pch_pf_pos); +- I915_WRITE(PF_WIN_SZ(pipe), dev_priv->pch_pf_size); +- } ++ ironlake_pfit_enable(intel_crtc); + + /* + * On ILK+ LUT must be loaded before the pipe is running but with +@@ -3353,17 +3361,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) + intel_ddi_enable_pipe_clock(intel_crtc); + + /* Enable panel fitting for eDP */ +- if (dev_priv->pch_pf_size && +- intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) { +- /* Force use of hard-coded filter coefficients +- * as some pre-programmed values are broken, +- * e.g. x201. +- */ +- I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3 | +- PF_PIPE_SEL_IVB(pipe)); +- I915_WRITE(PF_WIN_POS(pipe), dev_priv->pch_pf_pos); +- I915_WRITE(PF_WIN_SZ(pipe), dev_priv->pch_pf_size); +- } ++ ironlake_pfit_enable(intel_crtc); + + /* + * On ILK+ LUT must be loaded before the pipe is running but with +@@ -3621,11 +3619,11 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc) + * register description and PRM. + */ + DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", +- pipe_config->pfit_control, +- pipe_config->pfit_pgm_ratios); ++ pipe_config->gmch_pfit.control, ++ pipe_config->gmch_pfit.pgm_ratios); + +- I915_WRITE(PFIT_PGM_RATIOS, pipe_config->pfit_pgm_ratios); +- I915_WRITE(PFIT_CONTROL, pipe_config->pfit_control); ++ I915_WRITE(PFIT_PGM_RATIOS, pipe_config->gmch_pfit.pgm_ratios); ++ I915_WRITE(PFIT_CONTROL, pipe_config->gmch_pfit.control); + } + + static void valleyview_crtc_enable(struct drm_crtc *crtc) +@@ -5812,6 +5810,9 @@ static void haswell_modeset_global_resources(struct drm_device *dev) + /* XXX: Should check for edp transcoder here, but thanks to init + * sequence that's not yet available. Just in case desktop eDP + * on PORT D is possible on haswell, too. */ ++ /* Even the eDP panel fitter is outside the always-on well. */ ++ if (I915_READ(PF_WIN_SZ(crtc->pipe))) ++ enable = true; + } + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, +@@ -5821,10 +5822,6 @@ static void haswell_modeset_global_resources(struct drm_device *dev) + enable = true; + } + +- /* Even the eDP panel fitter is outside the always-on well. */ +- if (dev_priv->pch_pf_size) +- enable = true; +- + intel_set_power_well(dev, enable); + } + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 38b3fb549bac..83d2241176d8 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -721,7 +721,6 @@ intel_dp_compute_config(struct intel_encoder *encoder, + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; +- struct drm_display_mode *mode = &pipe_config->requested_mode; + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + struct intel_crtc *intel_crtc = encoder->new_crtc; + struct intel_connector *intel_connector = intel_dp->attached_connector; +@@ -744,9 +743,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, + intel_gmch_panel_fitting(intel_crtc, pipe_config, + intel_connector->panel.fitting_mode); + else +- intel_pch_panel_fitting(dev, +- intel_connector->panel.fitting_mode, +- mode, adjusted_mode); ++ intel_pch_panel_fitting(intel_crtc, pipe_config, ++ intel_connector->panel.fitting_mode); + } + /* We need to take the panel's fixed mode into account. */ + target_clock = adjusted_mode->clock; +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 1780f79e1a89..6edab480f6b4 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -239,7 +239,16 @@ struct intel_crtc_config { + unsigned pixel_multiplier; + + /* Panel fitter controls for gen2-gen4 + VLV */ +- u32 pfit_control, pfit_pgm_ratios; ++ struct { ++ u32 control; ++ u32 pgm_ratios; ++ } gmch_pfit; ++ ++ /* Panel fitter placement and size for Ironlake+ */ ++ struct { ++ u32 pos; ++ u32 size; ++ } pch_pfit; + }; + + struct intel_crtc { +@@ -558,10 +567,9 @@ extern void intel_panel_fini(struct intel_panel *panel); + + extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, + struct drm_display_mode *adjusted_mode); +-extern void intel_pch_panel_fitting(struct drm_device *dev, +- int fitting_mode, +- const struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode); ++extern void intel_pch_panel_fitting(struct intel_crtc *crtc, ++ struct intel_crtc_config *pipe_config, ++ int fitting_mode); + extern void intel_gmch_panel_fitting(struct intel_crtc *crtc, + struct intel_crtc_config *pipe_config, + int fitting_mode); +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 2a2180410cbd..d125756a2665 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -229,7 +229,6 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + struct intel_connector *intel_connector = + &lvds_encoder->attached_connector->base; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; +- struct drm_display_mode *mode = &pipe_config->requested_mode; + struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc; + unsigned int lvds_bpp; + int pipe; +@@ -267,9 +266,8 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + if (HAS_PCH_SPLIT(dev)) { + pipe_config->has_pch_encoder = true; + +- intel_pch_panel_fitting(dev, +- intel_connector->panel.fitting_mode, +- mode, adjusted_mode); ++ intel_pch_panel_fitting(intel_crtc, pipe_config, ++ intel_connector->panel.fitting_mode); + return true; + } else { + intel_gmch_panel_fitting(intel_crtc, pipe_config, +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index b775dd5f8dd9..5cd82a5ce907 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -54,14 +54,17 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, + + /* adjusted_mode has been preset to be the panel's fixed mode */ + void +-intel_pch_panel_fitting(struct drm_device *dev, +- int fitting_mode, +- const struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) ++intel_pch_panel_fitting(struct intel_crtc *intel_crtc, ++ struct intel_crtc_config *pipe_config, ++ int fitting_mode) + { +- struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; ++ struct drm_display_mode *mode, *adjusted_mode; + int x, y, width, height; + ++ mode = &pipe_config->requested_mode; ++ adjusted_mode = &pipe_config->adjusted_mode; ++ + x = y = width = height = 0; + + /* Native modes don't need fitting */ +@@ -113,8 +116,8 @@ intel_pch_panel_fitting(struct drm_device *dev, + } + + done: +- dev_priv->pch_pf_pos = (x << 16) | y; +- dev_priv->pch_pf_size = (width << 16) | height; ++ pipe_config->pch_pfit.pos = (x << 16) | y; ++ pipe_config->pch_pfit.size = (width << 16) | height; + } + + static void +@@ -300,10 +303,10 @@ out: + if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18) + pfit_control |= PANEL_8TO6_DITHER_ENABLE; + +- if (pfit_control != pipe_config->pfit_control || +- pfit_pgm_ratios != pipe_config->pfit_pgm_ratios) { +- pipe_config->pfit_control = pfit_control; +- pipe_config->pfit_pgm_ratios = pfit_pgm_ratios; ++ if (pfit_control != pipe_config->gmch_pfit.control || ++ pfit_pgm_ratios != pipe_config->gmch_pfit.pgm_ratios) { ++ pipe_config->gmch_pfit.control = pfit_control; ++ pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios; + } + dev_priv->lvds_border_bits = border; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0069-drm-i915-warn-about-invalid-pfit-modes.patch b/patches.baytrail/0069-drm-i915-warn-about-invalid-pfit-modes.patch new file mode 100644 index 000000000000..fab908ec4d36 --- /dev/null +++ b/patches.baytrail/0069-drm-i915-warn-about-invalid-pfit-modes.patch @@ -0,0 +1,66 @@ +From 2c06dd310db8286f4a44bc4a92655335499f1bec Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Thu, 25 Apr 2013 12:55:03 -0700 +Subject: drm/i915: warn about invalid pfit modes + +We prevent invalid ones from getting here in the first place, but it +doesn't hurt to have an extra sanity check. + +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit ab3e67f43a299b064ccd8cd230d4a006a05c8a4c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_panel.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index 5cd82a5ce907..140f60d40105 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -58,7 +58,6 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc, + struct intel_crtc_config *pipe_config, + int fitting_mode) + { +- struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; + struct drm_display_mode *mode, *adjusted_mode; + int x, y, width, height; + +@@ -107,12 +106,15 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc, + } + break; + +- default: + case DRM_MODE_SCALE_FULLSCREEN: + x = y = 0; + width = adjusted_mode->hdisplay; + height = adjusted_mode->vdisplay; + break; ++ ++ default: ++ WARN(1, "bad panel fit mode: %d\n", fitting_mode); ++ return; + } + + done: +@@ -267,7 +269,6 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, + } + } + break; +- default: + case DRM_MODE_SCALE_FULLSCREEN: + /* + * Full scaling, even if it changes the aspect ratio. +@@ -285,6 +286,9 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, + HORIZ_INTERP_BILINEAR); + } + break; ++ default: ++ WARN(1, "bad panel fit mode: %d\n", fitting_mode); ++ return; + } + + /* 965+ wants fuzzy fitting */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0070-drm-i915-remove-VLV-MSI-IRQ-hack.patch b/patches.baytrail/0070-drm-i915-remove-VLV-MSI-IRQ-hack.patch new file mode 100644 index 000000000000..275dc2fc9dcb --- /dev/null +++ b/patches.baytrail/0070-drm-i915-remove-VLV-MSI-IRQ-hack.patch @@ -0,0 +1,42 @@ +From c224c6efd49aaca8d56f1f5f5079ad29f4ebbd1b Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Fri, 1 Mar 2013 14:08:33 -0800 +Subject: drm/i915: remove VLV MSI IRQ hack + +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 2ce12e3dffe005f96e3b3ff1f761bbb0bf570fda) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index ebb0c7c3836e..3587ea7fa1fb 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2694,7 +2694,6 @@ static int valleyview_irq_postinstall(struct drm_device *dev) + u32 enable_mask; + u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV; + u32 render_irqs; +- u16 msid; + + enable_mask = I915_DISPLAY_PORT_INTERRUPT; + enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | +@@ -2710,13 +2709,6 @@ static int valleyview_irq_postinstall(struct drm_device *dev) + I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | + I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; + +- /* Hack for broken MSIs on VLV */ +- pci_write_config_dword(dev_priv->dev->pdev, 0x94, 0xfee00000); +- pci_read_config_word(dev->pdev, 0x98, &msid); +- msid &= 0xff; /* mask out delivery bits */ +- msid |= (1<<14); +- pci_write_config_word(dev_priv->dev->pdev, 0x98, msid); +- + I915_WRITE(PORT_HOTPLUG_EN, 0); + POSTING_READ(PORT_HOTPLUG_EN); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0071-drm-i915-Only-print-the-info-message-about-incresing.patch b/patches.baytrail/0071-drm-i915-Only-print-the-info-message-about-incresing.patch new file mode 100644 index 000000000000..4699011bd941 --- /dev/null +++ b/patches.baytrail/0071-drm-i915-Only-print-the-info-message-about-incresing.patch @@ -0,0 +1,53 @@ +From 825a350fccaeba4d96212e8db10a45cc9a746e5f Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Sat, 27 Apr 2013 12:44:16 +0100 +Subject: drm/i915: Only print the info message about incresing stolen size for + FBC once + +Instead of repeatedly bombarding the user with a request to reboot and +increase the stolen size with every fb refresh, just inform them the +first time only. + +v2: Rearrange code so the hint to increase the amount of memory stolen +by the BIOS is only emitted if we fail to find sufficient stolen memory +for FBC. + +Signed-off-by: Chris Wilson +[danvet: Fixup formatting code mismatch that gcc spotted.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit d8241785c24d4508ecc26fb91b28b39a0dd26070) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_stolen.c | 1 + + drivers/gpu/drm/i915/intel_pm.c | 2 -- + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 130d1db27e28..67d3510cafed 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -136,6 +136,7 @@ static int i915_setup_compression(struct drm_device *dev, int size) + err_fb: + drm_mm_put_block(compressed_fb); + err: ++ pr_info_once("drm: not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size); + return -ENOSPC; + } + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index ad9d622c55af..5977599bde42 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -481,8 +481,6 @@ void intel_update_fbc(struct drm_device *dev) + goto out_disable; + + if (i915_gem_stolen_setup_compression(dev, intel_fb->obj->base.size)) { +- DRM_INFO("not enough stolen space for compressed buffer (need %zd bytes), disabling\n", intel_fb->obj->base.size); +- DRM_INFO("hint: you may be able to increase stolen memory size in the BIOS to avoid this\n"); + DRM_DEBUG_KMS("framebuffer too large, disabling compression\n"); + dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; + goto out_disable; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0072-drm-i915-put-the-right-cpu_transcoder-into-pipe_conf.patch b/patches.baytrail/0072-drm-i915-put-the-right-cpu_transcoder-into-pipe_conf.patch new file mode 100644 index 000000000000..2c3cafb0fc26 --- /dev/null +++ b/patches.baytrail/0072-drm-i915-put-the-right-cpu_transcoder-into-pipe_conf.patch @@ -0,0 +1,32 @@ +From ddf29ee753771fa4977b5af0afe24c4bd59593f4 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 29 Apr 2013 18:29:19 +0200 +Subject: drm/i915: put the right cpu_transcoder into pipe_config for hw state + readout + +This hack is getting a bit messy, but this plugs the leak for now +until we have the cpu_transcoder properly pipe_config'ed. + +Cc: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 60c4ae101fdebdd1451e93f08161af3d78725cff) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 0af841ebc505..e5735287ff8c 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -7997,6 +7997,7 @@ intel_modeset_check_state(struct drm_device *dev) + "(expected %i, found %i)\n", enabled, crtc->base.enabled); + + memset(&pipe_config, 0, sizeof(pipe_config)); ++ pipe_config.cpu_transcoder = crtc->config.cpu_transcoder; + active = dev_priv->display.get_pipe_config(crtc, + &pipe_config); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0073-drm-i915-force-bpp-for-eDP-panels.patch b/patches.baytrail/0073-drm-i915-force-bpp-for-eDP-panels.patch new file mode 100644 index 000000000000..f6abf57bee7e --- /dev/null +++ b/patches.baytrail/0073-drm-i915-force-bpp-for-eDP-panels.patch @@ -0,0 +1,87 @@ +From df2f0819d9be05d3ae1148122c0666946f7bc6c0 Mon Sep 17 00:00:00 2001 +From: James Ausmus +Date: Mon, 23 Sep 2013 16:49:14 -0700 +Subject: drm/i915: force bpp for eDP panels + +We've had our fair share of woes already which showed that we can't +rely on the bpc limits in the EDID for eDP panels without risking +black screens. So now we limit the depth by what the BIOS recommends +in the VBT: + +commit 2f4f649a69a9eb51f6e98130e19dd90a260a4145 +Author: Jani Nikula +Date: Mon Nov 12 14:33:44 2012 +0200 + + drm/i915: do not ignore eDP bpc settings from vbt + +But that's not enough, since at least the panel on my ASUS Zenbook +Prime here is also unhappy if the bpc is too low. Hence just take the +firmware value and dither to get what flimsy panels want. + +Like before we ensure that we don't change the bpp if the firmware +doesn't provide a value, see + +commit 9a30a61f3516871c5c638fd7c025fbaa11ddf7fe +Author: Jani Nikula +Date: Mon Nov 12 14:33:45 2012 +0200 + + drm/i915: do not default to 18 bpp for eDP if missing from VBT + +v2: Apparently there are some horribly broken eDP panels around which +only work if the DP link is set up as if we want to driver a 24bpp +mode, but still only work if the data is feed at 18bpp. See + +commit 57c219633275c7e7413f8bc7be250dc092887458 +Author: Daniel Vetter +Date: Thu Apr 4 17:19:37 2013 +0200 + + drm/i915: revert eDP bpp clamping code changes + +for the gory details. + +Adjust the patch accordingly and update all the relevant comments. + +v3: Give up on the cargo-culting v2 attempt and just enfore the edp +bpp value if it's there. Broken panels be damned! + +Cc: Jani Nikula +Cc: Paulo Zanoni +Reviewed-by: Jani Nikula +Tested-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit af13188a1a6623fc8b4b6c42178046fb80f8b1d0) + +Conflicts: + drivers/gpu/drm/i915/intel_dp.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 83d2241176d8..993d80eab510 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -759,8 +759,17 @@ intel_dp_compute_config(struct intel_encoder *encoder, + /* Walk through all bpp values. Luckily they're all nicely spaced with 2 + * bpc in between. */ + bpp = min_t(int, 8*3, pipe_config->pipe_bpp); +- if (is_edp(intel_dp) && dev_priv->edp.bpp) +- bpp = min_t(int, bpp, dev_priv->edp.bpp); ++ ++ /* ++ * eDP panels are really fickle, try to enfore the bpp the firmware ++ * recomments. This means we'll up-dither 16bpp framebuffers on ++ * high-depth panels. ++ */ ++ if (is_edp(intel_dp) && dev_priv->edp.bpp) { ++ DRM_DEBUG_KMS("forcing bpp for eDP panel to BIOS-provided %i\n", ++ dev_priv->edp.bpp); ++ bpp = dev_priv->edp.bpp; ++ } + + for (; bpp >= 6*3; bpp -= 2*3) { + mode_rate = intel_dp_link_required(target_clock, bpp); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0074-drm-i915-drop-adjusted_mode-from-_set_pipeconf-funct.patch b/patches.baytrail/0074-drm-i915-drop-adjusted_mode-from-_set_pipeconf-funct.patch new file mode 100644 index 000000000000..e39f2f70eb59 --- /dev/null +++ b/patches.baytrail/0074-drm-i915-drop-adjusted_mode-from-_set_pipeconf-funct.patch @@ -0,0 +1,81 @@ +From 9728e06f73e44dc01dbcec5d61d16cbd0e21d315 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 19 Apr 2013 11:24:36 +0200 +Subject: drm/i915: drop adjusted_mode from *_set_pipeconf functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +They can get at the adjusted mode through intel_crtc->config. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 6ff93609b1cf77121ec61e8fe197d683b1702cd9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index e5735287ff8c..45c2e32d65c7 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5180,8 +5180,7 @@ static int ironlake_get_refclk(struct drm_crtc *crtc) + return 120000; + } + +-static void ironlake_set_pipeconf(struct drm_crtc *crtc, +- struct drm_display_mode *adjusted_mode) ++static void ironlake_set_pipeconf(struct drm_crtc *crtc) + { + struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +@@ -5214,7 +5213,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc, + val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP); + + val &= ~PIPECONF_INTERLACE_MASK; +- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ++ if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) + val |= PIPECONF_INTERLACED_ILK; + else + val |= PIPECONF_PROGRESSIVE; +@@ -5292,8 +5291,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc) + } + } + +-static void haswell_set_pipeconf(struct drm_crtc *crtc, +- struct drm_display_mode *adjusted_mode) ++static void haswell_set_pipeconf(struct drm_crtc *crtc) + { + struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +@@ -5307,7 +5305,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc, + val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP); + + val &= ~PIPECONF_INTERLACE_MASK_HSW; +- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ++ if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) + val |= PIPECONF_INTERLACED_ILK; + else + val |= PIPECONF_PROGRESSIVE; +@@ -5765,7 +5763,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + + fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc); + +- ironlake_set_pipeconf(crtc, adjusted_mode); ++ ironlake_set_pipeconf(crtc); + + /* Set up the display plane register */ + I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE); +@@ -5889,7 +5887,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + if (intel_crtc->config.has_pch_encoder) + ironlake_fdi_set_m_n(crtc); + +- haswell_set_pipeconf(crtc, adjusted_mode); ++ haswell_set_pipeconf(crtc); + + intel_set_pipe_csc(crtc); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0075-drm-i915-implement-high-bpc-pipeconf-dither-support-.patch b/patches.baytrail/0075-drm-i915-implement-high-bpc-pipeconf-dither-support-.patch new file mode 100644 index 000000000000..eae608bff49c --- /dev/null +++ b/patches.baytrail/0075-drm-i915-implement-high-bpc-pipeconf-dither-support-.patch @@ -0,0 +1,101 @@ +From 0f6b2b45fe4a5b27dcc7b76f15c8859a01f36182 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 24 Apr 2013 14:57:17 +0200 +Subject: drm/i915: implement high-bpc + pipeconf-dither support for g4x/vlv +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The current code is rather ... ugly. The only thing it managed to pull +off is getting 6bpc on DP working on g4x. Then someone added another +custom hack for 6bpc eDP on vlv. Fix up this entire mess by properly +implementing the PIPECONF-based dither/bpc controls on g4x/vlv. + +Note that compared to pch based platforms g4x/vlv don't support 12bpc +modes. g4x is already caught, extend the check for vlv. + +The other fixup is to restrict the lvds-specific dithering to early +gen4 devices - g4x should use the pipeconf dither controls. Note that +on gen2/3 the dither control is in the panel fitter even. + +v2: Don't enable dithering when the pipe is in 10 bpc mode. Quoting +from Bspec "PIPEACONF - Pipe A Configuration Register, bit 4": + +"Programming note: Dithering should only be enabled for 8 bpc or 6 +bpc." + +v3: Actually drop the old ugly dither code. + +v4: Explain in a short comment why g4x/vlv shouldn't dither for 30 bpp +pipes (Jesse). + +v5: Also clear the dither type correctly as spotted by Ville. + +v6: As Ville pointed out we need to indeed set the dithering both in +the pipeconf register (for DP outputs) and in the LVDS port register +(for LVDS ouputs). Otherwise LVDS panel will not get properly +dithered. The old patch got away with this since it forgot to clear +the LVDS dither bit ... + +v7: Remove redundant BPC_MASK clearing, spotted by Ville. + +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit ff9ce46ed6878d6be08660f7d75897d500a4fe9e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 35 +++++++++++++++++++++-------------- + 1 file changed, 21 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 45c2e32d65c7..f3dc36f87760 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4633,22 +4633,29 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) + pipeconf &= ~PIPECONF_DOUBLE_WIDE; + } + +- /* default to 8bpc */ +- pipeconf &= ~(PIPECONF_BPC_MASK | PIPECONF_DITHER_EN); +- if (intel_crtc->config.has_dp_encoder) { +- if (intel_crtc->config.dither) { +- pipeconf |= PIPECONF_6BPC | +- PIPECONF_DITHER_EN | ++ /* only g4x and later have fancy bpc/dither controls */ ++ if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) { ++ pipeconf &= ~(PIPECONF_BPC_MASK | ++ PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK); ++ ++ /* Bspec claims that we can't use dithering for 30bpp pipes. */ ++ if (intel_crtc->config.dither && intel_crtc->config.pipe_bpp != 30) ++ pipeconf |= PIPECONF_DITHER_EN | + PIPECONF_DITHER_TYPE_SP; +- } +- } + +- if (IS_VALLEYVIEW(dev) && intel_pipe_has_type(&intel_crtc->base, +- INTEL_OUTPUT_EDP)) { +- if (intel_crtc->config.dither) { +- pipeconf |= PIPECONF_6BPC | +- PIPECONF_ENABLE | +- I965_PIPECONF_ACTIVE; ++ switch (intel_crtc->config.pipe_bpp) { ++ case 18: ++ pipeconf |= PIPECONF_6BPC; ++ break; ++ case 24: ++ pipeconf |= PIPECONF_8BPC; ++ break; ++ case 30: ++ pipeconf |= PIPECONF_10BPC; ++ break; ++ default: ++ /* Case prevented by intel_choose_pipe_bpp_dither. */ ++ BUG(); + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0076-drm-i915-allow-high-bpc-modes-on-DP.patch b/patches.baytrail/0076-drm-i915-allow-high-bpc-modes-on-DP.patch new file mode 100644 index 000000000000..e33d85d256d5 --- /dev/null +++ b/patches.baytrail/0076-drm-i915-allow-high-bpc-modes-on-DP.patch @@ -0,0 +1,36 @@ +From 31012139f3e381dc4a006b11036a6af349a80971 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 19 Apr 2013 11:24:38 +0200 +Subject: drm/i915: allow high-bpc modes on DP + +Totally untested due to lack of screens supporting more than 8bpc. But +now we should have closed all holes in our bpp handling, so this +should be safe. The last missing piece was 10bpc support for g4x/vlv, +since we directly use the pipe bpp to feed the display link (and +anyway, only the cpt has any means to have a pipe bpp != the display +link bpp). + +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 52541e30339d932382ab9c0c1d1bacc8dacc541e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 993d80eab510..98c871d1084c 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -758,7 +758,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, + + /* Walk through all bpp values. Luckily they're all nicely spaced with 2 + * bpc in between. */ +- bpp = min_t(int, 8*3, pipe_config->pipe_bpp); ++ bpp = pipe_config->pipe_bpp; + + /* + * eDP panels are really fickle, try to enfore the bpp the firmware +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0077-drm-i915-move-intel_crtc-fdi_lanes-to-pipe_config.patch b/patches.baytrail/0077-drm-i915-move-intel_crtc-fdi_lanes-to-pipe_config.patch new file mode 100644 index 000000000000..a4294159253f --- /dev/null +++ b/patches.baytrail/0077-drm-i915-move-intel_crtc-fdi_lanes-to-pipe_config.patch @@ -0,0 +1,191 @@ +From 51cd1b72fc26b4f7beefbbe434239745efa6321a Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 13 Feb 2013 18:04:45 +0100 +Subject: drm/i915: move intel_crtc->fdi_lanes to pipe_config + +We need this for two reasons: +- Correct handling of shared fdi lanes on ivb with fastboot. +- Handling fdi link bw limits when we only have two fdi lanes by + dithering down a bit. + +Just search&replace in this patch, no functional change at all. + +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 33d29b145305641f2c693b759cac468e0c87ab4d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 7 ++++--- + drivers/gpu/drm/i915/intel_display.c | 36 ++++++++++++++++++------------------ + drivers/gpu/drm/i915/intel_drv.h | 4 +++- + 3 files changed, 25 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 70a1e9ca87d3..79c2af486dbb 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -181,7 +181,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) + + /* Enable the PCH Receiver FDI PLL */ + rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE | +- FDI_RX_PLL_ENABLE | ((intel_crtc->fdi_lanes - 1) << 19); ++ FDI_RX_PLL_ENABLE | ++ ((intel_crtc->config.fdi_lanes - 1) << 19); + I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); + POSTING_READ(_FDI_RXA_CTL); + udelay(220); +@@ -209,7 +210,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) + * port reversal bit */ + I915_WRITE(DDI_BUF_CTL(PORT_E), + DDI_BUF_CTL_ENABLE | +- ((intel_crtc->fdi_lanes - 1) << 1) | ++ ((intel_crtc->config.fdi_lanes - 1) << 1) | + hsw_ddi_buf_ctl_values[i / 2]); + POSTING_READ(DDI_BUF_CTL(PORT_E)); + +@@ -1022,7 +1023,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) + + } else if (type == INTEL_OUTPUT_ANALOG) { + temp |= TRANS_DDI_MODE_SELECT_FDI; +- temp |= (intel_crtc->fdi_lanes - 1) << 1; ++ temp |= (intel_crtc->config.fdi_lanes - 1) << 1; + + } else if (type == INTEL_OUTPUT_DISPLAYPORT || + type == INTEL_OUTPUT_EDP) { +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index f3dc36f87760..1a257d5bc8a9 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2420,7 +2420,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); + temp &= ~(7 << 19); +- temp |= (intel_crtc->fdi_lanes - 1) << 19; ++ temp |= (intel_crtc->config.fdi_lanes - 1) << 19; + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_PATTERN_1; + I915_WRITE(reg, temp | FDI_TX_ENABLE); +@@ -2518,7 +2518,7 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); + temp &= ~(7 << 19); +- temp |= (intel_crtc->fdi_lanes - 1) << 19; ++ temp |= (intel_crtc->config.fdi_lanes - 1) << 19; + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_PATTERN_1; + temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; +@@ -2653,7 +2653,7 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc) + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); + temp &= ~(7 << 19); +- temp |= (intel_crtc->fdi_lanes - 1) << 19; ++ temp |= (intel_crtc->config.fdi_lanes - 1) << 19; + temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB); + temp |= FDI_LINK_TRAIN_PATTERN_1_IVB; + temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; +@@ -2755,7 +2755,7 @@ static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc) + reg = FDI_RX_CTL(pipe); + temp = I915_READ(reg); + temp &= ~((0x7 << 19) | (0x7 << 16)); +- temp |= (intel_crtc->fdi_lanes - 1) << 19; ++ temp |= (intel_crtc->config.fdi_lanes - 1) << 19; + temp |= (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11; + I915_WRITE(reg, temp | FDI_RX_PLL_ENABLE); + +@@ -5410,12 +5410,12 @@ static bool ironlake_check_fdi_lanes(struct intel_crtc *intel_crtc) + to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_B]); + + DRM_DEBUG_KMS("checking fdi config on pipe %c, lanes %i\n", +- pipe_name(intel_crtc->pipe), intel_crtc->fdi_lanes); +- if (intel_crtc->fdi_lanes > 4) { ++ pipe_name(intel_crtc->pipe), intel_crtc->config.fdi_lanes); ++ if (intel_crtc->config.fdi_lanes > 4) { + DRM_DEBUG_KMS("invalid fdi lane config on pipe %c: %i lanes\n", +- pipe_name(intel_crtc->pipe), intel_crtc->fdi_lanes); ++ pipe_name(intel_crtc->pipe), intel_crtc->config.fdi_lanes); + /* Clamp lanes to avoid programming the hw with bogus values. */ +- intel_crtc->fdi_lanes = 4; ++ intel_crtc->config.fdi_lanes = 4; + + return false; + } +@@ -5428,28 +5428,28 @@ static bool ironlake_check_fdi_lanes(struct intel_crtc *intel_crtc) + return true; + case PIPE_B: + if (dev_priv->pipe_to_crtc_mapping[PIPE_C]->enabled && +- intel_crtc->fdi_lanes > 2) { ++ intel_crtc->config.fdi_lanes > 2) { + DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n", +- pipe_name(intel_crtc->pipe), intel_crtc->fdi_lanes); ++ pipe_name(intel_crtc->pipe), intel_crtc->config.fdi_lanes); + /* Clamp lanes to avoid programming the hw with bogus values. */ +- intel_crtc->fdi_lanes = 2; ++ intel_crtc->config.fdi_lanes = 2; + + return false; + } + +- if (intel_crtc->fdi_lanes > 2) ++ if (intel_crtc->config.fdi_lanes > 2) + WARN_ON(I915_READ(SOUTH_CHICKEN1) & FDI_BC_BIFURCATION_SELECT); + else + cpt_enable_fdi_bc_bifurcation(dev); + + return true; + case PIPE_C: +- if (!pipe_B_crtc->base.enabled || pipe_B_crtc->fdi_lanes <= 2) { +- if (intel_crtc->fdi_lanes > 2) { ++ if (!pipe_B_crtc->base.enabled || pipe_B_crtc->config.fdi_lanes <= 2) { ++ if (intel_crtc->config.fdi_lanes > 2) { + DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n", +- pipe_name(intel_crtc->pipe), intel_crtc->fdi_lanes); ++ pipe_name(intel_crtc->pipe), intel_crtc->config.fdi_lanes); + /* Clamp lanes to avoid programming the hw with bogus values. */ +- intel_crtc->fdi_lanes = 2; ++ intel_crtc->config.fdi_lanes = 2; + + return false; + } +@@ -5537,7 +5537,7 @@ static void ironlake_fdi_set_m_n(struct drm_crtc *crtc) + lane = ironlake_get_lanes_required(target_clock, link_bw, + intel_crtc->config.pipe_bpp); + +- intel_crtc->fdi_lanes = lane; ++ intel_crtc->config.fdi_lanes = lane; + + if (intel_crtc->config.pixel_multiplier > 1) + link_bw *= intel_crtc->config.pixel_multiplier; +@@ -5764,7 +5764,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + + /* Note, this also computes intel_crtc->fdi_lanes which is used below in + * ironlake_check_fdi_lanes. */ +- intel_crtc->fdi_lanes = 0; ++ intel_crtc->config.fdi_lanes = 0; + if (intel_crtc->config.has_pch_encoder) + ironlake_fdi_set_m_n(crtc); + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 6edab480f6b4..b078b1d51070 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -249,6 +249,9 @@ struct intel_crtc_config { + u32 pos; + u32 size; + } pch_pfit; ++ ++ /* FDI lanes used, only valid if has_pch_encoder is set. */ ++ int fdi_lanes; + }; + + struct intel_crtc { +@@ -267,7 +270,6 @@ struct intel_crtc { + bool lowfreq_avail; + struct intel_overlay *overlay; + struct intel_unpin_work *unpin_work; +- int fdi_lanes; + + atomic_t unpin_work_count; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0078-drm-i915-hw-state-readout-support-for-pipe_config-fd.patch b/patches.baytrail/0078-drm-i915-hw-state-readout-support-for-pipe_config-fd.patch new file mode 100644 index 000000000000..c65d3b933820 --- /dev/null +++ b/patches.baytrail/0078-drm-i915-hw-state-readout-support-for-pipe_config-fd.patch @@ -0,0 +1,173 @@ +From 223fcef7636ee4341fb610ebf6773f37c94172a4 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 29 Apr 2013 19:33:42 +0200 +Subject: drm/i915: hw state readout support for pipe_config->fdi_lanes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +v2: Introduce some nice #defines for the FDI lane width fields and put +them to good use. Suggested by Ville. + +v3: Fixup the mask vs. shift copy&pasta fail Imre Deak spotted, and +use the shift #define also in the mask. + +Cc: Imre Deak +Cc: Ville Syrjälä +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 627eb5a318a6caca2145d3c7195b084c59b291d9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 11 +++-------- + drivers/gpu/drm/i915/intel_ddi.c | 2 +- + drivers/gpu/drm/i915/intel_display.c | 38 ++++++++++++++++++++++++++---------- + 3 files changed, 32 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 8fff456c1c87..efdc01b17c5c 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -4146,10 +4146,9 @@ + #define FDI_LINK_TRAIN_600MV_3_5DB_SNB_B (0x39<<22) + #define FDI_LINK_TRAIN_800MV_0DB_SNB_B (0x38<<22) + #define FDI_LINK_TRAIN_VOL_EMP_MASK (0x3f<<22) +-#define FDI_DP_PORT_WIDTH_X1 (0<<19) +-#define FDI_DP_PORT_WIDTH_X2 (1<<19) +-#define FDI_DP_PORT_WIDTH_X3 (2<<19) +-#define FDI_DP_PORT_WIDTH_X4 (3<<19) ++#define FDI_DP_PORT_WIDTH_SHIFT 19 ++#define FDI_DP_PORT_WIDTH_MASK (7 << FDI_DP_PORT_WIDTH_SHIFT) ++#define FDI_DP_PORT_WIDTH(width) (((width) - 1) << FDI_DP_PORT_WIDTH_SHIFT) + #define FDI_TX_ENHANCE_FRAME_ENABLE (1<<18) + /* Ironlake: hardwired to 1 */ + #define FDI_TX_PLL_ENABLE (1<<14) +@@ -4174,7 +4173,6 @@ + /* train, dp width same as FDI_TX */ + #define FDI_FS_ERRC_ENABLE (1<<27) + #define FDI_FE_ERRC_ENABLE (1<<26) +-#define FDI_DP_PORT_WIDTH_X8 (7<<19) + #define FDI_RX_POLARITY_REVERSED_LPT (1<<16) + #define FDI_8BPC (0<<16) + #define FDI_10BPC (1<<16) +@@ -4196,9 +4194,6 @@ + #define FDI_LINK_TRAIN_PATTERN_IDLE_CPT (2<<8) + #define FDI_LINK_TRAIN_NORMAL_CPT (3<<8) + #define FDI_LINK_TRAIN_PATTERN_MASK_CPT (3<<8) +-/* LPT */ +-#define FDI_PORT_WIDTH_2X_LPT (1<<19) +-#define FDI_PORT_WIDTH_1X_LPT (0<<19) + + #define _FDI_RXA_MISC 0xf0010 + #define _FDI_RXB_MISC 0xf1010 +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 79c2af486dbb..2a84a5edbf45 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -182,7 +182,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) + /* Enable the PCH Receiver FDI PLL */ + rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE | + FDI_RX_PLL_ENABLE | +- ((intel_crtc->config.fdi_lanes - 1) << 19); ++ FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes); + I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); + POSTING_READ(_FDI_RXA_CTL); + udelay(220); +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 1a257d5bc8a9..d3c2d5c1e72a 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2419,8 +2419,8 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) + /* enable CPU FDI TX and PCH FDI RX */ + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); +- temp &= ~(7 << 19); +- temp |= (intel_crtc->config.fdi_lanes - 1) << 19; ++ temp &= ~FDI_DP_PORT_WIDTH_MASK; ++ temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes); + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_PATTERN_1; + I915_WRITE(reg, temp | FDI_TX_ENABLE); +@@ -2517,8 +2517,8 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) + /* enable CPU FDI TX and PCH FDI RX */ + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); +- temp &= ~(7 << 19); +- temp |= (intel_crtc->config.fdi_lanes - 1) << 19; ++ temp &= ~FDI_DP_PORT_WIDTH_MASK; ++ temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes); + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_PATTERN_1; + temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; +@@ -2652,8 +2652,8 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc) + /* enable CPU FDI TX and PCH FDI RX */ + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); +- temp &= ~(7 << 19); +- temp |= (intel_crtc->config.fdi_lanes - 1) << 19; ++ temp &= ~FDI_DP_PORT_WIDTH_MASK; ++ temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes); + temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB); + temp |= FDI_LINK_TRAIN_PATTERN_1_IVB; + temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; +@@ -2754,8 +2754,8 @@ static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc) + /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ + reg = FDI_RX_CTL(pipe); + temp = I915_READ(reg); +- temp &= ~((0x7 << 19) | (0x7 << 16)); +- temp |= (intel_crtc->config.fdi_lanes - 1) << 19; ++ temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16)); ++ temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes); + temp |= (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11; + I915_WRITE(reg, temp | FDI_RX_PLL_ENABLE); + +@@ -5796,9 +5796,14 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + if (!(tmp & PIPECONF_ENABLE)) + return false; + +- if (I915_READ(TRANSCONF(crtc->pipe)) & TRANS_ENABLE) ++ if (I915_READ(TRANSCONF(crtc->pipe)) & TRANS_ENABLE) { + pipe_config->has_pch_encoder = true; + ++ tmp = I915_READ(FDI_RX_CTL(crtc->pipe)); ++ pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >> ++ FDI_DP_PORT_WIDTH_SHIFT) + 1; ++ } ++ + return true; + } + +@@ -5934,9 +5939,14 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + */ + tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); + if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(PORT_E) && +- I915_READ(TRANSCONF(PIPE_A)) & TRANS_ENABLE) ++ I915_READ(TRANSCONF(PIPE_A)) & TRANS_ENABLE) { + pipe_config->has_pch_encoder = true; + ++ tmp = I915_READ(FDI_RX_CTL(PIPE_A)); ++ pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >> ++ FDI_DP_PORT_WIDTH_SHIFT) + 1; ++ } ++ + return true; + } + +@@ -7902,6 +7912,14 @@ intel_pipe_config_compare(struct intel_crtc_config *current_config, + return false; + } + ++ if (current_config->fdi_lanes != pipe_config->fdi_lanes) { ++ DRM_ERROR("mismatch in fdi_lanes " ++ "(expected %i, found %i)\n", ++ current_config->fdi_lanes, ++ pipe_config->fdi_lanes); ++ return false; ++ } ++ + return true; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0079-drm-i915-split-up-fdi_set_m_n-into-computation-and-h.patch b/patches.baytrail/0079-drm-i915-split-up-fdi_set_m_n-into-computation-and-h.patch new file mode 100644 index 000000000000..9ea37ec60291 --- /dev/null +++ b/patches.baytrail/0079-drm-i915-split-up-fdi_set_m_n-into-computation-and-h.patch @@ -0,0 +1,101 @@ +From 28f0597efe29a1f7221cfe017479c531e3408739 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 14 Feb 2013 16:54:22 +0100 +Subject: drm/i915: split up fdi_set_m_n into computation and hw setup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +And also move the computed m_n values into the pipe_config. This is a +prep step to move the fdi state computation completely into the +prepare phase of the modeset sequence. Which will allow us to handle +fdi link bw constraints in a better way. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit ca3a0ff80faa7ee043fd615c9d9394757e2acb09) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 26 +++++++++++++++----------- + drivers/gpu/drm/i915/intel_drv.h | 3 ++- + 2 files changed, 17 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index d3c2d5c1e72a..0d8ff30e62a2 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5511,13 +5511,11 @@ void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, + } + } + +-static void ironlake_fdi_set_m_n(struct drm_crtc *crtc) ++static void ironlake_fdi_compute_config(struct intel_crtc *intel_crtc) + { +- struct drm_device *dev = crtc->dev; +- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ struct drm_device *dev = intel_crtc->base.dev; + struct drm_display_mode *adjusted_mode = + &intel_crtc->config.adjusted_mode; +- struct intel_link_m_n m_n = {0}; + int target_clock, lane, link_bw; + + /* FDI is a binary signal running at ~2.7GHz, encoding +@@ -5542,9 +5540,7 @@ static void ironlake_fdi_set_m_n(struct drm_crtc *crtc) + if (intel_crtc->config.pixel_multiplier > 1) + link_bw *= intel_crtc->config.pixel_multiplier; + intel_link_compute_m_n(intel_crtc->config.pipe_bpp, lane, target_clock, +- link_bw, &m_n); +- +- intel_cpu_transcoder_set_m_n(intel_crtc, &m_n); ++ link_bw, &intel_crtc->config.fdi_m_n); + } + + static bool ironlake_needs_fb_cb_tune(struct dpll *dpll, int factor) +@@ -5765,8 +5761,12 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + /* Note, this also computes intel_crtc->fdi_lanes which is used below in + * ironlake_check_fdi_lanes. */ + intel_crtc->config.fdi_lanes = 0; +- if (intel_crtc->config.has_pch_encoder) +- ironlake_fdi_set_m_n(crtc); ++ if (intel_crtc->config.has_pch_encoder) { ++ ironlake_fdi_compute_config(intel_crtc); ++ ++ intel_cpu_transcoder_set_m_n(intel_crtc, ++ &intel_crtc->config.fdi_m_n); ++ } + + fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc); + +@@ -5896,8 +5896,12 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + + intel_set_pipe_timings(intel_crtc, mode, adjusted_mode); + +- if (intel_crtc->config.has_pch_encoder) +- ironlake_fdi_set_m_n(crtc); ++ if (intel_crtc->config.has_pch_encoder) { ++ ironlake_fdi_compute_config(intel_crtc); ++ ++ intel_cpu_transcoder_set_m_n(intel_crtc, ++ &intel_crtc->config.fdi_m_n); ++ } + + haswell_set_pipeconf(crtc); + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index b078b1d51070..cee65ee5745c 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -250,8 +250,9 @@ struct intel_crtc_config { + u32 size; + } pch_pfit; + +- /* FDI lanes used, only valid if has_pch_encoder is set. */ ++ /* FDI configuration, only valid if has_pch_encoder is set. */ + int fdi_lanes; ++ struct intel_link_m_n fdi_m_n; + }; + + struct intel_crtc { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0080-drm-i915-compute-fdi-lane-config-earlier.patch b/patches.baytrail/0080-drm-i915-compute-fdi-lane-config-earlier.patch new file mode 100644 index 000000000000..a059c9488c6f --- /dev/null +++ b/patches.baytrail/0080-drm-i915-compute-fdi-lane-config-earlier.patch @@ -0,0 +1,130 @@ +From 77bfcf37950c6657b7ecc3cc051504899c305d9f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 19 Apr 2013 11:24:43 +0200 +Subject: drm/i915: compute fdi lane config earlier + +Now that it's split up, we can easily move it around and precompute +the fdi lane configuration. + +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 877d48d5f7d4f90d3bd5fb5422e1a88d39e1d3b3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 71 +++++++++++++++++------------------- + 1 file changed, 34 insertions(+), 37 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 0d8ff30e62a2..d1b3e54e02d1 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3970,6 +3970,37 @@ bool intel_connector_get_hw_state(struct intel_connector *connector) + return encoder->get_hw_state(encoder, &pipe); + } + ++static void ironlake_fdi_compute_config(struct drm_device *dev, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; ++ int target_clock, lane, link_bw; ++ ++ /* FDI is a binary signal running at ~2.7GHz, encoding ++ * each output octet as 10 bits. The actual frequency ++ * is stored as a divider into a 100MHz clock, and the ++ * mode pixel clock is stored in units of 1KHz. ++ * Hence the bw of each lane in terms of the mode signal ++ * is: ++ */ ++ link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; ++ ++ if (pipe_config->pixel_target_clock) ++ target_clock = pipe_config->pixel_target_clock; ++ else ++ target_clock = adjusted_mode->clock; ++ ++ lane = ironlake_get_lanes_required(target_clock, link_bw, ++ pipe_config->pipe_bpp); ++ ++ pipe_config->fdi_lanes = lane; ++ ++ if (pipe_config->pixel_multiplier > 1) ++ link_bw *= pipe_config->pixel_multiplier; ++ intel_link_compute_m_n(pipe_config->pipe_bpp, lane, target_clock, ++ link_bw, &pipe_config->fdi_m_n); ++} ++ + static bool intel_crtc_compute_config(struct drm_crtc *crtc, + struct intel_crtc_config *pipe_config) + { +@@ -4004,6 +4035,9 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc, + pipe_config->pipe_bpp = 8*3; + } + ++ if (pipe_config->has_pch_encoder) ++ ironlake_fdi_compute_config(dev, pipe_config); ++ + return true; + } + +@@ -5511,38 +5545,6 @@ void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, + } + } + +-static void ironlake_fdi_compute_config(struct intel_crtc *intel_crtc) +-{ +- struct drm_device *dev = intel_crtc->base.dev; +- struct drm_display_mode *adjusted_mode = +- &intel_crtc->config.adjusted_mode; +- int target_clock, lane, link_bw; +- +- /* FDI is a binary signal running at ~2.7GHz, encoding +- * each output octet as 10 bits. The actual frequency +- * is stored as a divider into a 100MHz clock, and the +- * mode pixel clock is stored in units of 1KHz. +- * Hence the bw of each lane in terms of the mode signal +- * is: +- */ +- link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; +- +- if (intel_crtc->config.pixel_target_clock) +- target_clock = intel_crtc->config.pixel_target_clock; +- else +- target_clock = adjusted_mode->clock; +- +- lane = ironlake_get_lanes_required(target_clock, link_bw, +- intel_crtc->config.pipe_bpp); +- +- intel_crtc->config.fdi_lanes = lane; +- +- if (intel_crtc->config.pixel_multiplier > 1) +- link_bw *= intel_crtc->config.pixel_multiplier; +- intel_link_compute_m_n(intel_crtc->config.pipe_bpp, lane, target_clock, +- link_bw, &intel_crtc->config.fdi_m_n); +-} +- + static bool ironlake_needs_fb_cb_tune(struct dpll *dpll, int factor) + { + return i9xx_dpll_compute_m(dpll) < factor * dpll->n; +@@ -5760,10 +5762,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + + /* Note, this also computes intel_crtc->fdi_lanes which is used below in + * ironlake_check_fdi_lanes. */ +- intel_crtc->config.fdi_lanes = 0; + if (intel_crtc->config.has_pch_encoder) { +- ironlake_fdi_compute_config(intel_crtc); +- + intel_cpu_transcoder_set_m_n(intel_crtc, + &intel_crtc->config.fdi_m_n); + } +@@ -5897,8 +5896,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + intel_set_pipe_timings(intel_crtc, mode, adjusted_mode); + + if (intel_crtc->config.has_pch_encoder) { +- ironlake_fdi_compute_config(intel_crtc); +- + intel_cpu_transcoder_set_m_n(intel_crtc, + &intel_crtc->config.fdi_m_n); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0081-drm-i915-Split-up-ironlake_check_fdi_lanes.patch b/patches.baytrail/0081-drm-i915-Split-up-ironlake_check_fdi_lanes.patch new file mode 100644 index 000000000000..750d89ba25c6 --- /dev/null +++ b/patches.baytrail/0081-drm-i915-Split-up-ironlake_check_fdi_lanes.patch @@ -0,0 +1,77 @@ +From 8d1b67f6cf1b27dca06f2049622357dbe8ef0a24 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 19 Apr 2013 11:24:44 +0200 +Subject: drm/i915: Split up ironlake_check_fdi_lanes + +Again in preparation to move the configuration checks into the +pipe_config computation stage of the modeset sequence. + +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit ebfd86fda69bbe4d7b15e0c31e86a3069cf69085) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 31 +++++++++++++++++++++++++------ + 1 file changed, 25 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index d1b3e54e02d1..4dc01e9b59f7 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5471,11 +5471,6 @@ static bool ironlake_check_fdi_lanes(struct intel_crtc *intel_crtc) + return false; + } + +- if (intel_crtc->config.fdi_lanes > 2) +- WARN_ON(I915_READ(SOUTH_CHICKEN1) & FDI_BC_BIFURCATION_SELECT); +- else +- cpt_enable_fdi_bc_bifurcation(dev); +- + return true; + case PIPE_C: + if (!pipe_B_crtc->base.enabled || pipe_B_crtc->config.fdi_lanes <= 2) { +@@ -5492,9 +5487,31 @@ static bool ironlake_check_fdi_lanes(struct intel_crtc *intel_crtc) + return false; + } + ++ return true; ++ default: ++ BUG(); ++ } ++} ++ ++static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc) ++{ ++ struct drm_device *dev = intel_crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ switch (intel_crtc->pipe) { ++ case PIPE_A: ++ break; ++ case PIPE_B: ++ if (intel_crtc->config.fdi_lanes > 2) ++ WARN_ON(I915_READ(SOUTH_CHICKEN1) & FDI_BC_BIFURCATION_SELECT); ++ else ++ cpt_enable_fdi_bc_bifurcation(dev); ++ ++ break; ++ case PIPE_C: + cpt_enable_fdi_bc_bifurcation(dev); + +- return true; ++ break; + default: + BUG(); + } +@@ -5768,6 +5785,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + } + + fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc); ++ if (IS_IVYBRIDGE(dev)) ++ ivybridge_update_fdi_bc_bifurcation(intel_crtc); + + ironlake_set_pipeconf(crtc); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0082-drm-i915-move-fdi-lane-configuration-checks-ahead.patch b/patches.baytrail/0082-drm-i915-move-fdi-lane-configuration-checks-ahead.patch new file mode 100644 index 000000000000..b8314f475aa0 --- /dev/null +++ b/patches.baytrail/0082-drm-i915-move-fdi-lane-configuration-checks-ahead.patch @@ -0,0 +1,227 @@ +From 5c7f57e276f8e6bc4a3a7b53221e751c76b7e181 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 29 Apr 2013 19:34:16 +0200 +Subject: drm/i915: move fdi lane configuration checks ahead +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This nicely allows us to drop some hacks which have only been used +to work around modeset failures due to lack of fdi lanes. + +v2: Implement proper checking for Haswell platforms - the fdi link to +the LPT PCH has only 2 lanes. Note that we already filter out +impossible modes in intel_crt_mode_valid. Unfortunately LPT does not +support 6bpc on the fdi rx, so we can't pull clever tricks to squeeze +in a few more modes. + +v2: Rebased on top of Ben Widawsky's num_pipes reorg. + +v3: Rebase on top of Ville's pipe debug output ocd rampage. + +v4: Fixup rebase fail spotted by Ville. + +v5: Fixup rebase fail spotted by Imre Deak. I suck. + +Cc: Imre Deak +Cc: Ville Syrjälä +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 1857e1daa0695d45b2639ac9e3cfcdaede4a7f8a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 129 ++++++++++++++++++----------------- + 1 file changed, 65 insertions(+), 64 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 4dc01e9b59f7..1b4af98f416a 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3970,9 +3970,68 @@ bool intel_connector_get_hw_state(struct intel_connector *connector) + return encoder->get_hw_state(encoder, &pipe); + } + +-static void ironlake_fdi_compute_config(struct drm_device *dev, ++static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct intel_crtc *pipe_B_crtc = ++ to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_B]); ++ ++ DRM_DEBUG_KMS("checking fdi config on pipe %c, lanes %i\n", ++ pipe_name(pipe), pipe_config->fdi_lanes); ++ if (pipe_config->fdi_lanes > 4) { ++ DRM_DEBUG_KMS("invalid fdi lane config on pipe %c: %i lanes\n", ++ pipe_name(pipe), pipe_config->fdi_lanes); ++ return false; ++ } ++ ++ if (IS_HASWELL(dev)) { ++ if (pipe_config->fdi_lanes > 2) { ++ DRM_DEBUG_KMS("only 2 lanes on haswell, required: %i lanes\n", ++ pipe_config->fdi_lanes); ++ return false; ++ } else { ++ return true; ++ } ++ } ++ ++ if (INTEL_INFO(dev)->num_pipes == 2) ++ return true; ++ ++ /* Ivybridge 3 pipe is really complicated */ ++ switch (pipe) { ++ case PIPE_A: ++ return true; ++ case PIPE_B: ++ if (dev_priv->pipe_to_crtc_mapping[PIPE_C]->enabled && ++ pipe_config->fdi_lanes > 2) { ++ DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n", ++ pipe_name(pipe), pipe_config->fdi_lanes); ++ return false; ++ } ++ return true; ++ case PIPE_C: ++ if (!pipe_B_crtc->base.enabled || ++ pipe_B_crtc->config.fdi_lanes <= 2) { ++ if (pipe_config->fdi_lanes > 2) { ++ DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n", ++ pipe_name(pipe), pipe_config->fdi_lanes); ++ return false; ++ } ++ } else { ++ DRM_DEBUG_KMS("fdi link B uses too many lanes to enable link C\n"); ++ return false; ++ } ++ return true; ++ default: ++ BUG(); ++ } ++} ++ ++static bool ironlake_fdi_compute_config(struct intel_crtc *intel_crtc, + struct intel_crtc_config *pipe_config) + { ++ struct drm_device *dev = intel_crtc->base.dev; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; + int target_clock, lane, link_bw; + +@@ -3999,6 +4058,9 @@ static void ironlake_fdi_compute_config(struct drm_device *dev, + link_bw *= pipe_config->pixel_multiplier; + intel_link_compute_m_n(pipe_config->pipe_bpp, lane, target_clock, + link_bw, &pipe_config->fdi_m_n); ++ ++ return ironlake_check_fdi_lanes(intel_crtc->base.dev, ++ intel_crtc->pipe, pipe_config); + } + + static bool intel_crtc_compute_config(struct drm_crtc *crtc, +@@ -4036,7 +4098,7 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc, + } + + if (pipe_config->has_pch_encoder) +- ironlake_fdi_compute_config(dev, pipe_config); ++ return ironlake_fdi_compute_config(to_intel_crtc(crtc), pipe_config); + + return true; + } +@@ -5436,63 +5498,6 @@ static void cpt_enable_fdi_bc_bifurcation(struct drm_device *dev) + POSTING_READ(SOUTH_CHICKEN1); + } + +-static bool ironlake_check_fdi_lanes(struct intel_crtc *intel_crtc) +-{ +- struct drm_device *dev = intel_crtc->base.dev; +- struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_crtc *pipe_B_crtc = +- to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_B]); +- +- DRM_DEBUG_KMS("checking fdi config on pipe %c, lanes %i\n", +- pipe_name(intel_crtc->pipe), intel_crtc->config.fdi_lanes); +- if (intel_crtc->config.fdi_lanes > 4) { +- DRM_DEBUG_KMS("invalid fdi lane config on pipe %c: %i lanes\n", +- pipe_name(intel_crtc->pipe), intel_crtc->config.fdi_lanes); +- /* Clamp lanes to avoid programming the hw with bogus values. */ +- intel_crtc->config.fdi_lanes = 4; +- +- return false; +- } +- +- if (INTEL_INFO(dev)->num_pipes == 2) +- return true; +- +- switch (intel_crtc->pipe) { +- case PIPE_A: +- return true; +- case PIPE_B: +- if (dev_priv->pipe_to_crtc_mapping[PIPE_C]->enabled && +- intel_crtc->config.fdi_lanes > 2) { +- DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n", +- pipe_name(intel_crtc->pipe), intel_crtc->config.fdi_lanes); +- /* Clamp lanes to avoid programming the hw with bogus values. */ +- intel_crtc->config.fdi_lanes = 2; +- +- return false; +- } +- +- return true; +- case PIPE_C: +- if (!pipe_B_crtc->base.enabled || pipe_B_crtc->config.fdi_lanes <= 2) { +- if (intel_crtc->config.fdi_lanes > 2) { +- DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n", +- pipe_name(intel_crtc->pipe), intel_crtc->config.fdi_lanes); +- /* Clamp lanes to avoid programming the hw with bogus values. */ +- intel_crtc->config.fdi_lanes = 2; +- +- return false; +- } +- } else { +- DRM_DEBUG_KMS("fdi link B uses too many lanes to enable link C\n"); +- return false; +- } +- +- return true; +- default: +- BUG(); +- } +-} +- + static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc) + { + struct drm_device *dev = intel_crtc->base.dev; +@@ -5684,7 +5689,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + bool is_lvds = false; + struct intel_encoder *encoder; + int ret; +- bool fdi_config_ok; + + for_each_encoder_on_crtc(dev, crtc, encoder) { + switch (encoder->type) { +@@ -5777,14 +5781,11 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + + intel_set_pipe_timings(intel_crtc, mode, adjusted_mode); + +- /* Note, this also computes intel_crtc->fdi_lanes which is used below in +- * ironlake_check_fdi_lanes. */ + if (intel_crtc->config.has_pch_encoder) { + intel_cpu_transcoder_set_m_n(intel_crtc, + &intel_crtc->config.fdi_m_n); + } + +- fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc); + if (IS_IVYBRIDGE(dev)) + ivybridge_update_fdi_bc_bifurcation(intel_crtc); + +@@ -5800,7 +5801,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + + intel_update_linetime_watermarks(dev, pipe, adjusted_mode); + +- return fdi_config_ok ? ret : -EINVAL; ++ return ret; + } + + static bool ironlake_get_pipe_config(struct intel_crtc *crtc, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0083-drm-i915-don-t-count-cpu-ports-for-fdi-B-C-lane-shar.patch b/patches.baytrail/0083-drm-i915-don-t-count-cpu-ports-for-fdi-B-C-lane-shar.patch new file mode 100644 index 000000000000..8e70a2e9add7 --- /dev/null +++ b/patches.baytrail/0083-drm-i915-don-t-count-cpu-ports-for-fdi-B-C-lane-shar.patch @@ -0,0 +1,65 @@ +From 206a00e0c53e9cee8e994009c72d4cf2b7bd2c95 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 19 Feb 2013 22:31:57 +0100 +Subject: drm/i915: don't count cpu ports for fdi B/C lane sharing + +This allows us to use all 4 fdi lanes on fdi B when the cpu eDP is +running on pipe C. Yay! + +v2: Encapsulate test into a little helper function, as suggested by +Chris Wilson. + +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 1e833f40eb38b033ea185687daa72c073f1acc15) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 1b4af98f416a..4fd41ecc063a 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2369,6 +2369,11 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc) + FDI_FE_ERRC_ENABLE); + } + ++static bool pipe_has_enabled_pch(struct intel_crtc *intel_crtc) ++{ ++ return intel_crtc->base.enabled && intel_crtc->config.has_pch_encoder; ++} ++ + static void ivb_modeset_global_resources(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -2378,10 +2383,13 @@ static void ivb_modeset_global_resources(struct drm_device *dev) + to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_C]); + uint32_t temp; + +- /* When everything is off disable fdi C so that we could enable fdi B +- * with all lanes. XXX: This misses the case where a pipe is not using +- * any pch resources and so doesn't need any fdi lanes. */ +- if (!pipe_B_crtc->base.enabled && !pipe_C_crtc->base.enabled) { ++ /* ++ * When everything is off disable fdi C so that we could enable fdi B ++ * with all lanes. Note that we don't care about enabled pipes without ++ * an enabled pch encoder. ++ */ ++ if (!pipe_has_enabled_pch(pipe_B_crtc) && ++ !pipe_has_enabled_pch(pipe_C_crtc)) { + WARN_ON(I915_READ(FDI_RX_CTL(PIPE_B)) & FDI_RX_ENABLE); + WARN_ON(I915_READ(FDI_RX_CTL(PIPE_C)) & FDI_RX_ENABLE); + +@@ -4011,7 +4019,7 @@ static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, + } + return true; + case PIPE_C: +- if (!pipe_B_crtc->base.enabled || ++ if (!pipe_has_enabled_pch(pipe_B_crtc) || + pipe_B_crtc->config.fdi_lanes <= 2) { + if (pipe_config->fdi_lanes > 2) { + DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n", +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0084-drm-i915-fixup-12bpc-hdmi-dotclock-handling.patch b/patches.baytrail/0084-drm-i915-fixup-12bpc-hdmi-dotclock-handling.patch new file mode 100644 index 000000000000..86ba0e3c08c6 --- /dev/null +++ b/patches.baytrail/0084-drm-i915-fixup-12bpc-hdmi-dotclock-handling.patch @@ -0,0 +1,80 @@ +From 0392902a59f13ae5b1bf023ee248a7f908df22d0 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 19 Apr 2013 11:24:33 +0200 +Subject: drm/i915: fixup 12bpc hdmi dotclock handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We need to multiply the hdmi port dotclock by 1.5x since it's not +really a dotclock, but the 10/8 encoding bitclock divided by 10. + +Also add correct limit checks for the dotclock and reject modes which +don't fit. HDMI 1.4 would allow more, but our hw doesn't support that +unfortunately :( + +Somehow I suspect 12bpc hdmi output never really worked - we really +need an i-g-t testcase to check all the different pixel modes and +outputs. + +v2: Fixup the adjusted port clock handling - we need to make sure that +the fdi link code still gets the real pixelclock. + +v3: g4x/vlv don't support 12bpc hdmi output so drop the bogus comment. + +Acked-by: Ville Syrjälä +[danvet: Switch dotclock limit check to <= as suggested by Ville.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 325b9d048810f7689ec644595061c0b700e64bce) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_hdmi.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 075b7d83d9f5..17e76478a8f5 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -783,6 +783,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); + struct drm_device *dev = encoder->base.dev; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; ++ int clock_12bpc = pipe_config->requested_mode.clock * 3 / 2; + + if (intel_hdmi->color_range_auto) { + /* See CEA-861-E - 5.1 Default Encoding Parameters */ +@@ -802,16 +803,28 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, + /* + * HDMI is either 12 or 8, so if the display lets 10bpc sneak + * through, clamp it down. Note that g4x/vlv don't support 12bpc hdmi +- * outputs. ++ * outputs. We also need to check that the higher clock still fits ++ * within limits. + */ +- if (pipe_config->pipe_bpp > 8*3 && HAS_PCH_SPLIT(dev)) { ++ if (pipe_config->pipe_bpp > 8*3 && clock_12bpc <= 225000 ++ && HAS_PCH_SPLIT(dev)) { + DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n"); + pipe_config->pipe_bpp = 12*3; ++ ++ /* Need to adjust the port link by 1.5x for 12bpc. */ ++ adjusted_mode->clock = clock_12bpc; ++ pipe_config->pixel_target_clock = ++ pipe_config->requested_mode.clock; + } else { + DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n"); + pipe_config->pipe_bpp = 8*3; + } + ++ if (adjusted_mode->clock > 225000) { ++ DRM_DEBUG_KMS("too high HDMI clock, rejecting mode\n"); ++ return false; ++ } ++ + return true; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0085-drm-i915-implement-fdi-auto-dithering.patch b/patches.baytrail/0085-drm-i915-implement-fdi-auto-dithering.patch new file mode 100644 index 000000000000..16bd86c281d6 --- /dev/null +++ b/patches.baytrail/0085-drm-i915-implement-fdi-auto-dithering.patch @@ -0,0 +1,264 @@ +From 97cd0f178e80376d1a83ee986b41454a2a461907 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 21 Feb 2013 00:00:16 +0100 +Subject: drm/i915: implement fdi auto-dithering + +So on a bunch of setups we only have 2 fdi lanes available, e.g. hsw +VGA or 3 pipes on ivb. And seemingly a lot of modes don't quite fit +into this, among them the default 1080p mode. + +The solution is to dither down the pipe a bit so that everything fits, +which this patch implements. + +But ports compute their state under the assumption that the bpp they +pick will be the one selected, e.g. the display port bw computations +won't work otherwise. Now we could adjust our code to again up-dither +to the computed DP link parameters, but that's pointless. + +So instead when the pipe needs to adjust parameters we need to retry +the pipe_config computation at the encoder stage. Furthermore we need +to inform encoders that they should not increase bandwidth +requirements if possible. This is required for the hdmi code, which +prefers the pipe to up-dither to either of the two possible hdmi bpc +values. + +LVDS has a similar requirement, although that's probably only +theoretical in nature: It's unlikely that we'll ever see an 8bpc +high-res lvds panel (which is required to hit the 2 fdi lane limit). + +eDP is the only thing which could increase the pipe_bpp setting again, +even when in the retry-loop. This could hit the WARN. Two reasons for +not bothering: +- On many eDP panels we'll get a black screen if the bpp settings + don't match vbt. So failing the modeset is the right thing to do. + But since that also means it's the only way to light up the panel, + it should work. So we shouldn't be able to hit this WARN. +- There are still opens around the eDP panel handling, and maybe we + need additional tricks. Before that happens it's imo no use trying + to be too clever. +Worst case we just need to kill that WARN or maybe fail the compute +config stage if the eDP connector can't get the bpp setting it wants. +And since this can only happen with an fdi link in between and so for +pch eDP panels it's rather unlikely to blow up, if ever. + +v2: Rebased on top of a bikeshed from Paulo. + +v3: Improve commit message around eDP handling with the stuff +things with Imre. + +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit e29c22c0c4fefeb48a0157811930f7e9df0bb3f3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 56 ++++++++++++++++++++++++++++-------- + drivers/gpu/drm/i915/intel_drv.h | 7 +++++ + drivers/gpu/drm/i915/intel_hdmi.c | 14 ++++++--- + drivers/gpu/drm/i915/intel_lvds.c | 2 +- + 4 files changed, 62 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 4fd41ecc063a..dc9d2753d756 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4036,13 +4036,16 @@ static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, + } + } + +-static bool ironlake_fdi_compute_config(struct intel_crtc *intel_crtc, +- struct intel_crtc_config *pipe_config) ++#define RETRY 1 ++static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc, ++ struct intel_crtc_config *pipe_config) + { + struct drm_device *dev = intel_crtc->base.dev; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; + int target_clock, lane, link_bw; ++ bool setup_ok, needs_recompute = false; + ++retry: + /* FDI is a binary signal running at ~2.7GHz, encoding + * each output octet as 10 bits. The actual frequency + * is stored as a divider into a 100MHz clock, and the +@@ -4067,12 +4070,26 @@ static bool ironlake_fdi_compute_config(struct intel_crtc *intel_crtc, + intel_link_compute_m_n(pipe_config->pipe_bpp, lane, target_clock, + link_bw, &pipe_config->fdi_m_n); + +- return ironlake_check_fdi_lanes(intel_crtc->base.dev, +- intel_crtc->pipe, pipe_config); ++ setup_ok = ironlake_check_fdi_lanes(intel_crtc->base.dev, ++ intel_crtc->pipe, pipe_config); ++ if (!setup_ok && pipe_config->pipe_bpp > 6*3) { ++ pipe_config->pipe_bpp -= 2*3; ++ DRM_DEBUG_KMS("fdi link bw constraint, reducing pipe bpp to %i\n", ++ pipe_config->pipe_bpp); ++ needs_recompute = true; ++ pipe_config->bw_constrained = true; ++ ++ goto retry; ++ } ++ ++ if (needs_recompute) ++ return RETRY; ++ ++ return setup_ok ? 0 : -EINVAL; + } + +-static bool intel_crtc_compute_config(struct drm_crtc *crtc, +- struct intel_crtc_config *pipe_config) ++static int intel_crtc_compute_config(struct drm_crtc *crtc, ++ struct intel_crtc_config *pipe_config) + { + struct drm_device *dev = crtc->dev; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; +@@ -4081,7 +4098,7 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc, + /* FDI link clock is fixed at 2.7G */ + if (pipe_config->requested_mode.clock * 3 + > IRONLAKE_FDI_FREQ * 4) +- return false; ++ return -EINVAL; + } + + /* All interlaced capable intel hw wants timings in frames. Note though +@@ -4095,7 +4112,7 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc, + */ + if ((INTEL_INFO(dev)->gen > 4 || IS_G4X(dev)) && + adjusted_mode->hsync_start == adjusted_mode->hdisplay) +- return false; ++ return -EINVAL; + + if ((IS_G4X(dev) || IS_VALLEYVIEW(dev)) && pipe_config->pipe_bpp > 10*3) { + pipe_config->pipe_bpp = 10*3; /* 12bpc is gen5+ */ +@@ -4108,7 +4125,7 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc, + if (pipe_config->has_pch_encoder) + return ironlake_fdi_compute_config(to_intel_crtc(crtc), pipe_config); + +- return true; ++ return 0; + } + + static int valleyview_get_display_clock_speed(struct drm_device *dev) +@@ -7708,7 +7725,8 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, + struct drm_encoder_helper_funcs *encoder_funcs; + struct intel_encoder *encoder; + struct intel_crtc_config *pipe_config; +- int plane_bpp; ++ int plane_bpp, ret = -EINVAL; ++ bool retry = true; + + pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); + if (!pipe_config) +@@ -7721,6 +7739,7 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, + if (plane_bpp < 0) + goto fail; + ++encoder_retry: + /* Pass our mode to the connectors and the CRTC to give them a chance to + * adjust it according to limitations or connector properties, and also + * a chance to reject the mode entirely. +@@ -7749,10 +7768,23 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, + } + } + +- if (!(intel_crtc_compute_config(crtc, pipe_config))) { ++ ret = intel_crtc_compute_config(crtc, pipe_config); ++ if (ret < 0) { + DRM_DEBUG_KMS("CRTC fixup failed\n"); + goto fail; + } ++ ++ if (ret == RETRY) { ++ if (WARN(!retry, "loop in pipe configuration computation\n")) { ++ ret = -EINVAL; ++ goto fail; ++ } ++ ++ DRM_DEBUG_KMS("CRTC bw constrained, retrying\n"); ++ retry = false; ++ goto encoder_retry; ++ } ++ + DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); + + pipe_config->dither = pipe_config->pipe_bpp != plane_bpp; +@@ -7762,7 +7794,7 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, + return pipe_config; + fail: + kfree(pipe_config); +- return ERR_PTR(-EINVAL); ++ return ERR_PTR(ret); + } + + /* Computes which crtcs are affected and sets the relevant bits in the mask. For +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index cee65ee5745c..174ba4e6a105 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -223,6 +223,13 @@ struct intel_crtc_config { + /* Controls for the clock computation, to override various stages. */ + bool clock_set; + ++ /* ++ * crtc bandwidth limit, don't increase pipe bpp or clock if not really ++ * required. This is set in the 2nd loop of calling encoder's ++ * ->compute_config if the first pick doesn't work out. ++ */ ++ bool bw_constrained; ++ + /* Settings for the intel dpll used on pretty much everything but + * haswell. */ + struct dpll dpll; +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 17e76478a8f5..2b727f0d201f 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -784,6 +784,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, + struct drm_device *dev = encoder->base.dev; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; + int clock_12bpc = pipe_config->requested_mode.clock * 3 / 2; ++ int desired_bpp; + + if (intel_hdmi->color_range_auto) { + /* See CEA-861-E - 5.1 Default Encoding Parameters */ +@@ -808,16 +809,21 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, + */ + if (pipe_config->pipe_bpp > 8*3 && clock_12bpc <= 225000 + && HAS_PCH_SPLIT(dev)) { +- DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n"); +- pipe_config->pipe_bpp = 12*3; ++ DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n"); ++ desired_bpp = 12*3; + + /* Need to adjust the port link by 1.5x for 12bpc. */ + adjusted_mode->clock = clock_12bpc; + pipe_config->pixel_target_clock = + pipe_config->requested_mode.clock; + } else { +- DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n"); +- pipe_config->pipe_bpp = 8*3; ++ DRM_DEBUG_KMS("picking bpc to 8 for HDMI output\n"); ++ desired_bpp = 8*3; ++ } ++ ++ if (!pipe_config->bw_constrained) { ++ DRM_DEBUG_KMS("forcing pipe bpc to %i for HDMI\n", desired_bpp); ++ pipe_config->pipe_bpp = desired_bpp; + } + + if (adjusted_mode->clock > 225000) { +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index d125756a2665..ab04cb9d0725 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -248,7 +248,7 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + else + lvds_bpp = 6*3; + +- if (lvds_bpp != pipe_config->pipe_bpp) { ++ if (lvds_bpp != pipe_config->pipe_bpp && !pipe_config->bw_constrained) { + DRM_DEBUG_KMS("forcing display bpp (was %d) to LVDS (%d)\n", + pipe_config->pipe_bpp, lvds_bpp); + pipe_config->pipe_bpp = lvds_bpp; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0086-drm-i915-stop-for_each_intel_crtc_masked-macro-from-.patch b/patches.baytrail/0086-drm-i915-stop-for_each_intel_crtc_masked-macro-from-.patch new file mode 100644 index 000000000000..d514613771f6 --- /dev/null +++ b/patches.baytrail/0086-drm-i915-stop-for_each_intel_crtc_masked-macro-from-.patch @@ -0,0 +1,31 @@ +From b8f0038d0ef746436f8176f92568288d27c7f922 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 19 Apr 2013 11:25:33 +0200 +Subject: drm/i915: stop for_each_intel_crtc_masked macro from leaking + +Spotted while changing related code. + +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 0973f18f8a764d869add12728887c2d1cc281ffb) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index dc9d2753d756..390d529da28e 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -7959,7 +7959,7 @@ intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes) + list_for_each_entry((intel_crtc), \ + &(dev)->mode_config.crtc_list, \ + base.head) \ +- if (mask & (1 <<(intel_crtc)->pipe)) \ ++ if (mask & (1 <<(intel_crtc)->pipe)) + + static bool + intel_pipe_config_compare(struct intel_crtc_config *current_config, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0087-drm-i915-introduce-macros-to-check-pipe-config-prope.patch b/patches.baytrail/0087-drm-i915-introduce-macros-to-check-pipe-config-prope.patch new file mode 100644 index 000000000000..afe00ffe3022 --- /dev/null +++ b/patches.baytrail/0087-drm-i915-introduce-macros-to-check-pipe-config-prope.patch @@ -0,0 +1,59 @@ +From 945b40b7459bf86cf9867ec08b073d72cd959f69 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 19 Apr 2013 11:25:34 +0200 +Subject: drm/i915: introduce macros to check pipe config properties + +This code will get _really_ repetive, and we'll end up with tons more +of this kind. So extract the common patterns. + +This should also help when we add a lazy pipe_config compare mode for +fastboot. + +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 08a24034a84866e3abb7fdb35ed0e479b240c205) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 24 +++++++++++------------- + 1 file changed, 11 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 390d529da28e..759034dfe617 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -7965,21 +7965,19 @@ static bool + intel_pipe_config_compare(struct intel_crtc_config *current_config, + struct intel_crtc_config *pipe_config) + { +- if (current_config->has_pch_encoder != pipe_config->has_pch_encoder) { +- DRM_ERROR("mismatch in has_pch_encoder " +- "(expected %i, found %i)\n", +- current_config->has_pch_encoder, +- pipe_config->has_pch_encoder); +- return false; ++#define PIPE_CONF_CHECK_I(name) \ ++ if (current_config->name != pipe_config->name) { \ ++ DRM_ERROR("mismatch in " #name " " \ ++ "(expected %i, found %i)\n", \ ++ current_config->name, \ ++ pipe_config->name); \ ++ return false; \ + } + +- if (current_config->fdi_lanes != pipe_config->fdi_lanes) { +- DRM_ERROR("mismatch in fdi_lanes " +- "(expected %i, found %i)\n", +- current_config->fdi_lanes, +- pipe_config->fdi_lanes); +- return false; +- } ++ PIPE_CONF_CHECK_I(has_pch_encoder); ++ PIPE_CONF_CHECK_I(fdi_lanes); ++ ++#undef PIPE_CONF_CHECK_I + + return true; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0088-drm-i915-hw-state-readout-support-for-fdi-m-n.patch b/patches.baytrail/0088-drm-i915-hw-state-readout-support-for-fdi-m-n.patch new file mode 100644 index 000000000000..911285d6acbc --- /dev/null +++ b/patches.baytrail/0088-drm-i915-hw-state-readout-support-for-fdi-m-n.patch @@ -0,0 +1,97 @@ +From bf13db128d25d79fb87a404590811433f6fe8cbd Mon Sep 17 00:00:00 2001 +From: James Ausmus +Date: Mon, 23 Sep 2013 16:49:38 -0700 +Subject: drm/i915: hw state readout support for fdi m/n + +We want to use the fdi m/n values to easily compute the adjusted mode +dotclock on pch ports. Hence make sure the values stored in the pipe +config are always reliable. + +v2: Fixup FDI TU readout. + +v3: Rebase on top of moved cpu_transcoder. + +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 72419203cab9acf173956f5564639b0012cd2604) + +Conflicts: + drivers/gpu/drm/i915/i915_reg.h +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 1 + + drivers/gpu/drm/i915/intel_display.c | 25 +++++++++++++++++++++++++ + 2 files changed, 26 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index efdc01b17c5c..1782b0c8a743 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -2779,6 +2779,7 @@ + + /* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */ + #define TU_SIZE(x) (((x)-1) << 25) /* default size 64 */ ++#define TU_SIZE_SHIFT 25 + #define TU_SIZE_MASK (0x3f << 25) + + #define DATA_LINK_M_N_MASK (0xffffff) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 759034dfe617..4882893a9fbd 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5829,6 +5829,22 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + return ret; + } + ++static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ enum transcoder transcoder = pipe_config->cpu_transcoder; ++ ++ pipe_config->fdi_m_n.link_m = I915_READ(PIPE_LINK_M1(transcoder)); ++ pipe_config->fdi_m_n.link_n = I915_READ(PIPE_LINK_N1(transcoder)); ++ pipe_config->fdi_m_n.gmch_m = I915_READ(PIPE_DATA_M1(transcoder)) ++ & ~TU_SIZE_MASK; ++ pipe_config->fdi_m_n.gmch_n = I915_READ(PIPE_DATA_N1(transcoder)); ++ pipe_config->fdi_m_n.tu = ((I915_READ(PIPE_DATA_M1(transcoder)) ++ & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1; ++} ++ + static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + struct intel_crtc_config *pipe_config) + { +@@ -5846,6 +5862,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + tmp = I915_READ(FDI_RX_CTL(crtc->pipe)); + pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >> + FDI_DP_PORT_WIDTH_SHIFT) + 1; ++ ++ ironlake_get_fdi_m_n_config(crtc, pipe_config); + } + + return true; +@@ -5991,6 +6009,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + tmp = I915_READ(FDI_RX_CTL(PIPE_A)); + pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >> + FDI_DP_PORT_WIDTH_SHIFT) + 1; ++ ++ ironlake_get_fdi_m_n_config(crtc, pipe_config); + } + + return true; +@@ -7976,6 +7996,11 @@ intel_pipe_config_compare(struct intel_crtc_config *current_config, + + PIPE_CONF_CHECK_I(has_pch_encoder); + PIPE_CONF_CHECK_I(fdi_lanes); ++ PIPE_CONF_CHECK_I(fdi_m_n.gmch_m); ++ PIPE_CONF_CHECK_I(fdi_m_n.gmch_n); ++ PIPE_CONF_CHECK_I(fdi_m_n.link_m); ++ PIPE_CONF_CHECK_I(fdi_m_n.link_n); ++ PIPE_CONF_CHECK_I(fdi_m_n.tu); + + #undef PIPE_CONF_CHECK_I + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0089-drm-i915-hw-state-readout-support-for-pipe-timings.patch b/patches.baytrail/0089-drm-i915-hw-state-readout-support-for-pipe-timings.patch new file mode 100644 index 000000000000..60cff1eb2d3f --- /dev/null +++ b/patches.baytrail/0089-drm-i915-hw-state-readout-support-for-pipe-timings.patch @@ -0,0 +1,168 @@ +From 1292d9d152fd59e386e9c87110e0dc1c5a4f0e91 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 29 Apr 2013 21:56:12 +0200 +Subject: drm/i915: hw state readout support for pipe timings + +This does duplicate the logic in intel_crtc_mode_get a bit, but the +issue is that we also should handle interlace modes and other insanity +correctly. + +Hence I've opted for a sligthly more elaborate route where we first +read out the crtc timings for the adjusted mode, and then optionally +(not sure if we really need it) compute the modeline from that. + +v2: Also read out the pipe source dimensions into the requested mode. + +v3: Rebase on top of the moved cpu_transcoder. + +v4: Simplify CHECK_FLAGS logic as suggested by Chris Wilson. Also +properly #undef that macro again. + +Reviewed-by: Mika Kuoppala (v3) +[danvet: Use the existing mask for interlaced bits, spotted by Mika.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 1bd1bd806037af04dd1d7bdd39b2b04090c10d2c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 1 + + drivers/gpu/drm/i915/intel_display.c | 75 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 76 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 1782b0c8a743..ded019718295 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -2844,6 +2844,7 @@ + #define PIPECONF_INTERLACED_ILK (3 << 21) + #define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */ + #define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */ ++#define PIPECONF_INTERLACE_MODE_MASK (7 << 21) + #define PIPECONF_CXSR_DOWNCLOCK (1<<16) + #define PIPECONF_COLOR_RANGE_SELECT (1 << 13) + #define PIPECONF_BPC_MASK (0x7 << 5) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 4882893a9fbd..f1b6ca3fe82a 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4728,6 +4728,45 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc, + ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); + } + ++static void intel_get_pipe_timings(struct intel_crtc *crtc, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; ++ uint32_t tmp; ++ ++ tmp = I915_READ(HTOTAL(cpu_transcoder)); ++ pipe_config->adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1; ++ pipe_config->adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1; ++ tmp = I915_READ(HBLANK(cpu_transcoder)); ++ pipe_config->adjusted_mode.crtc_hblank_start = (tmp & 0xffff) + 1; ++ pipe_config->adjusted_mode.crtc_hblank_end = ((tmp >> 16) & 0xffff) + 1; ++ tmp = I915_READ(HSYNC(cpu_transcoder)); ++ pipe_config->adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1; ++ pipe_config->adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1; ++ ++ tmp = I915_READ(VTOTAL(cpu_transcoder)); ++ pipe_config->adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1; ++ pipe_config->adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1; ++ tmp = I915_READ(VBLANK(cpu_transcoder)); ++ pipe_config->adjusted_mode.crtc_vblank_start = (tmp & 0xffff) + 1; ++ pipe_config->adjusted_mode.crtc_vblank_end = ((tmp >> 16) & 0xffff) + 1; ++ tmp = I915_READ(VSYNC(cpu_transcoder)); ++ pipe_config->adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1; ++ pipe_config->adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1; ++ ++ if (I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK) { ++ pipe_config->adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE; ++ pipe_config->adjusted_mode.crtc_vtotal += 1; ++ pipe_config->adjusted_mode.crtc_vblank_end += 1; ++ } ++ ++ tmp = I915_READ(PIPESRC(crtc->pipe)); ++ pipe_config->requested_mode.vdisplay = (tmp & 0xffff) + 1; ++ pipe_config->requested_mode.hdisplay = ((tmp >> 16) & 0xffff) + 1; ++} ++ + static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) + { + struct drm_device *dev = intel_crtc->base.dev; +@@ -4949,6 +4988,8 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, + if (!(tmp & PIPECONF_ENABLE)) + return false; + ++ intel_get_pipe_timings(crtc, pipe_config); ++ + return true; + } + +@@ -5866,6 +5907,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + ironlake_get_fdi_m_n_config(crtc, pipe_config); + } + ++ intel_get_pipe_timings(crtc, pipe_config); ++ + return true; + } + +@@ -6013,6 +6056,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + ironlake_get_fdi_m_n_config(crtc, pipe_config); + } + ++ intel_get_pipe_timings(crtc, pipe_config); ++ + return true; + } + +@@ -7994,6 +8039,15 @@ intel_pipe_config_compare(struct intel_crtc_config *current_config, + return false; \ + } + ++#define PIPE_CONF_CHECK_FLAGS(name, mask) \ ++ if ((current_config->name ^ pipe_config->name) & (mask)) { \ ++ DRM_ERROR("mismatch in " #name " " \ ++ "(expected %i, found %i)\n", \ ++ current_config->name & (mask), \ ++ pipe_config->name & (mask)); \ ++ return false; \ ++ } ++ + PIPE_CONF_CHECK_I(has_pch_encoder); + PIPE_CONF_CHECK_I(fdi_lanes); + PIPE_CONF_CHECK_I(fdi_m_n.gmch_m); +@@ -8002,7 +8056,28 @@ intel_pipe_config_compare(struct intel_crtc_config *current_config, + PIPE_CONF_CHECK_I(fdi_m_n.link_n); + PIPE_CONF_CHECK_I(fdi_m_n.tu); + ++ PIPE_CONF_CHECK_I(adjusted_mode.crtc_hdisplay); ++ PIPE_CONF_CHECK_I(adjusted_mode.crtc_htotal); ++ PIPE_CONF_CHECK_I(adjusted_mode.crtc_hblank_start); ++ PIPE_CONF_CHECK_I(adjusted_mode.crtc_hblank_end); ++ PIPE_CONF_CHECK_I(adjusted_mode.crtc_hsync_start); ++ PIPE_CONF_CHECK_I(adjusted_mode.crtc_hsync_end); ++ ++ PIPE_CONF_CHECK_I(adjusted_mode.crtc_vdisplay); ++ PIPE_CONF_CHECK_I(adjusted_mode.crtc_vtotal); ++ PIPE_CONF_CHECK_I(adjusted_mode.crtc_vblank_start); ++ PIPE_CONF_CHECK_I(adjusted_mode.crtc_vblank_end); ++ PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_start); ++ PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_end); ++ ++ PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, ++ DRM_MODE_FLAG_INTERLACE); ++ ++ PIPE_CONF_CHECK_I(requested_mode.hdisplay); ++ PIPE_CONF_CHECK_I(requested_mode.vdisplay); ++ + #undef PIPE_CONF_CHECK_I ++#undef PIPE_CONF_CHECK_FLAGS + + return true; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0090-drm-i915-cleanup-opregion-technology-enabled-indicat.patch b/patches.baytrail/0090-drm-i915-cleanup-opregion-technology-enabled-indicat.patch new file mode 100644 index 000000000000..b7d2903c89b1 --- /dev/null +++ b/patches.baytrail/0090-drm-i915-cleanup-opregion-technology-enabled-indicat.patch @@ -0,0 +1,57 @@ +From ba84753f54b55bd4ce5b995769da515cd936fa7c Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Mon, 29 Apr 2013 13:02:50 +0300 +Subject: drm/i915: cleanup opregion technology enabled indicator defines + +Move near other defines, add TCHE in the name. No functional changes. + +Signed-off-by: Jani Nikula +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit f599cc2917a1beb1a619d70e3ee7b9bc4dc17bb9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_opregion.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c +index 8f4989476a6f..3ddbffa1b792 100644 +--- a/drivers/gpu/drm/i915/intel_opregion.c ++++ b/drivers/gpu/drm/i915/intel_opregion.c +@@ -123,6 +123,12 @@ struct opregion_asle { + #define ASLE_PFIT_FAILED (1<<14) + #define ASLE_PWM_FREQ_FAILED (1<<16) + ++/* Technology enabled indicator */ ++#define ASLE_TCHE_ALS_EN (1 << 0) ++#define ASLE_TCHE_BLC_EN (1 << 1) ++#define ASLE_TCHE_PFIT_EN (1 << 2) ++#define ASLE_TCHE_PFMB_EN (1 << 3) ++ + /* ASLE backlight brightness to set */ + #define ASLE_BCLP_VALID (1<<31) + #define ASLE_BCLP_MSK (~(1<<31)) +@@ -222,11 +228,6 @@ void intel_opregion_asle_intr(struct drm_device *dev) + iowrite32(asle_stat, &asle->aslc); + } + +-#define ASLE_ALS_EN (1<<0) +-#define ASLE_BLC_EN (1<<1) +-#define ASLE_PFIT_EN (1<<2) +-#define ASLE_PFMB_EN (1<<3) +- + void intel_opregion_enable_asle(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -236,7 +237,7 @@ void intel_opregion_enable_asle(struct drm_device *dev) + if (IS_MOBILE(dev)) + intel_enable_asle(dev); + +- iowrite32(ASLE_BLC_EN, &asle->tche); ++ iowrite32(ASLE_TCHE_BLC_EN, &asle->tche); + iowrite32(1, &asle->ardy); + } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0091-drm-i915-manage-opregion-asle-driver-readiness-prope.patch b/patches.baytrail/0091-drm-i915-manage-opregion-asle-driver-readiness-prope.patch new file mode 100644 index 000000000000..14c9960d607d --- /dev/null +++ b/patches.baytrail/0091-drm-i915-manage-opregion-asle-driver-readiness-prope.patch @@ -0,0 +1,81 @@ +From 9ee0256b9568f3afc95f6a4cdeb9ffc0449377a8 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Mon, 29 Apr 2013 13:02:51 +0300 +Subject: drm/i915: manage opregion asle driver readiness properly + +Only set ASLE driver readiness (ARDY) and technology enabled indicator +(TCHE) once per opregion init. There should be no need to do that at irq +postinstall time. Also clear driver readiness at fini. + +While at it, add defines for driver readiness. + +Signed-off-by: Jani Nikula +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 68bca4b0c5553c0137d13df37f18a4b059d6e795) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_opregion.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c +index 3ddbffa1b792..c7b72efe6cd8 100644 +--- a/drivers/gpu/drm/i915/intel_opregion.c ++++ b/drivers/gpu/drm/i915/intel_opregion.c +@@ -110,6 +110,10 @@ struct opregion_asle { + u8 rsvd[102]; + } __attribute__((packed)); + ++/* Driver readiness indicator */ ++#define ASLE_ARDY_READY (1 << 0) ++#define ASLE_ARDY_NOT_READY (0 << 0) ++ + /* ASLE irq request bits */ + #define ASLE_SET_ALS_ILLUM (1 << 0) + #define ASLE_SET_BACKLIGHT (1 << 1) +@@ -236,9 +240,6 @@ void intel_opregion_enable_asle(struct drm_device *dev) + if (asle) { + if (IS_MOBILE(dev)) + intel_enable_asle(dev); +- +- iowrite32(ASLE_TCHE_BLC_EN, &asle->tche); +- iowrite32(1, &asle->ardy); + } + } + +@@ -425,8 +426,12 @@ void intel_opregion_init(struct drm_device *dev) + register_acpi_notifier(&intel_opregion_notifier); + } + +- if (opregion->asle) ++ if (opregion->asle) { + intel_opregion_enable_asle(dev); ++ ++ iowrite32(ASLE_TCHE_BLC_EN, &opregion->asle->tche); ++ iowrite32(ASLE_ARDY_READY, &opregion->asle->ardy); ++ } + } + + void intel_opregion_fini(struct drm_device *dev) +@@ -437,6 +442,9 @@ void intel_opregion_fini(struct drm_device *dev) + if (!opregion->header) + return; + ++ if (opregion->asle) ++ iowrite32(ASLE_ARDY_NOT_READY, &opregion->asle->ardy); ++ + if (opregion->acpi) { + iowrite32(0, &opregion->acpi->drdy); + +@@ -499,6 +507,8 @@ int intel_opregion_setup(struct drm_device *dev) + if (mboxes & MBOX_ASLE) { + DRM_DEBUG_DRIVER("ASLE supported\n"); + opregion->asle = base + OPREGION_ASLE_OFFSET; ++ ++ iowrite32(ASLE_ARDY_NOT_READY, &opregion->asle->ardy); + } + + return 0; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0092-drm-i915-untie-opregion-init-and-asle-irq-pipestat-e.patch b/patches.baytrail/0092-drm-i915-untie-opregion-init-and-asle-irq-pipestat-e.patch new file mode 100644 index 000000000000..ee6715e988a4 --- /dev/null +++ b/patches.baytrail/0092-drm-i915-untie-opregion-init-and-asle-irq-pipestat-e.patch @@ -0,0 +1,52 @@ +From 53388964db8ca6deedde875aea32d544685e4120 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Mon, 29 Apr 2013 13:02:52 +0300 +Subject: drm/i915: untie opregion init and asle irq/pipestat enable + +Stop calling intel_opregion_enable_asle() and consequently +intel_enable_asle() on opregion init. It should not be necessary for +these reasons: + +1) On PCH split platforms, it only enables GSE interrupt, which is + enabled in irq postinstall anyway. Moreover, the irq enable uses the + wrong bit on IVB+. + +2) On gen 2, it would enable a reserved pipestat bit. If there were gen + 2 systems with opregion asle support, that is. And the gen 2 irq + handler won't handle it anyway. + +3) On gen 3-4, the irq postinstall will call + intel_opregion_enable_asle() to enable the pipestat. + +In short, move the asle irq/pipestat enable responsibility to irq +postinstall, which already happens to be in place. + +This should not cause any functional changes, but only do the one line +change here for easier bisectability, just in case, and leave all the +cleanups this allows to followup patches. + +Signed-off-by: Jani Nikula +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 2cc7aa29143b1276db3e87d2a2d50d3625b77d60) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_opregion.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c +index c7b72efe6cd8..700e83ba3378 100644 +--- a/drivers/gpu/drm/i915/intel_opregion.c ++++ b/drivers/gpu/drm/i915/intel_opregion.c +@@ -427,8 +427,6 @@ void intel_opregion_init(struct drm_device *dev) + } + + if (opregion->asle) { +- intel_opregion_enable_asle(dev); +- + iowrite32(ASLE_TCHE_BLC_EN, &opregion->asle->tche); + iowrite32(ASLE_ARDY_READY, &opregion->asle->ardy); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0093-drm-i915-cleanup-redundant-checks-from-intel_enable_.patch b/patches.baytrail/0093-drm-i915-cleanup-redundant-checks-from-intel_enable_.patch new file mode 100644 index 000000000000..37c27cbf8741 --- /dev/null +++ b/patches.baytrail/0093-drm-i915-cleanup-redundant-checks-from-intel_enable_.patch @@ -0,0 +1,52 @@ +From 78faa70b81e0428debe2fb0c938a00d897fdff92 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Mon, 29 Apr 2013 13:02:53 +0300 +Subject: drm/i915: cleanup redundant checks from intel_enable_asle + +Realize that intel_enable_asle() is never called on PCH-split platforms +or on VLV. Rip out the GSE irq enable for PCH-split platforms, which +also happens to be incorrect for IVB+. + +This should not cause any functional changes. + +Signed-off-by: Jani Nikula +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit f898780ba020696e50c04abf2a55790df37ce384) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 16 +++------------- + 1 file changed, 3 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 3587ea7fa1fb..a39386c3d93a 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -347,21 +347,11 @@ void intel_enable_asle(struct drm_device *dev) + drm_i915_private_t *dev_priv = dev->dev_private; + unsigned long irqflags; + +- /* FIXME: opregion/asle for VLV */ +- if (IS_VALLEYVIEW(dev)) +- return; +- + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + +- if (HAS_PCH_SPLIT(dev)) +- ironlake_enable_display_irq(dev_priv, DE_GSE); +- else { +- i915_enable_pipestat(dev_priv, 1, +- PIPE_LEGACY_BLC_EVENT_ENABLE); +- if (INTEL_INFO(dev)->gen >= 4) +- i915_enable_pipestat(dev_priv, 0, +- PIPE_LEGACY_BLC_EVENT_ENABLE); +- } ++ i915_enable_pipestat(dev_priv, 1, PIPE_LEGACY_BLC_EVENT_ENABLE); ++ if (INTEL_INFO(dev)->gen >= 4) ++ i915_enable_pipestat(dev_priv, 0, PIPE_LEGACY_BLC_EVENT_ENABLE); + + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0094-drm-i915-cleanup-opregion-asle-pipestat-enable.patch b/patches.baytrail/0094-drm-i915-cleanup-opregion-asle-pipestat-enable.patch new file mode 100644 index 000000000000..2d80e38d8e00 --- /dev/null +++ b/patches.baytrail/0094-drm-i915-cleanup-opregion-asle-pipestat-enable.patch @@ -0,0 +1,114 @@ +From ac87d4f4f91fb9e3dd477ceb0fe4e7ebc45ffaec Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Mon, 29 Apr 2013 13:02:54 +0300 +Subject: drm/i915: cleanup opregion asle pipestat enable + +Both intel_opregion_enable_asle() and intel_enable_asle() have shrunk +considerably. Merge them together into a static function in i915_irq.c, +and rename to better reflect the purpose and the related platforms. + +No functional changes. + +Signed-off-by: Jani Nikula +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit f49e38dd23d28d4fceea1e84ae444b4c25fc0407) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 4 ---- + drivers/gpu/drm/i915/i915_irq.c | 11 +++++++---- + drivers/gpu/drm/i915/intel_opregion.c | 11 ----------- + 3 files changed, 7 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index a540b1f2354e..a3cdfbc3d8db 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1486,8 +1486,6 @@ i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); + void + i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); + +-void intel_enable_asle(struct drm_device *dev); +- + #ifdef CONFIG_DEBUG_FS + extern void i915_destroy_error_state(struct drm_device *dev); + #else +@@ -1823,12 +1821,10 @@ extern int intel_opregion_setup(struct drm_device *dev); + extern void intel_opregion_init(struct drm_device *dev); + extern void intel_opregion_fini(struct drm_device *dev); + extern void intel_opregion_asle_intr(struct drm_device *dev); +-extern void intel_opregion_enable_asle(struct drm_device *dev); + #else + static inline void intel_opregion_init(struct drm_device *dev) { return; } + static inline void intel_opregion_fini(struct drm_device *dev) { return; } + static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; } +-static inline void intel_opregion_enable_asle(struct drm_device *dev) { return; } + #endif + + /* intel_acpi.c */ +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index a39386c3d93a..7d8cfedfaf86 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -340,13 +340,16 @@ i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) + } + + /** +- * intel_enable_asle - enable ASLE interrupt for OpRegion ++ * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion + */ +-void intel_enable_asle(struct drm_device *dev) ++static void i915_enable_asle_pipestat(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; + unsigned long irqflags; + ++ if (!dev_priv->opregion.asle || !IS_MOBILE(dev)) ++ return; ++ + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + + i915_enable_pipestat(dev_priv, 1, PIPE_LEGACY_BLC_EVENT_ENABLE); +@@ -3001,7 +3004,7 @@ static int i915_irq_postinstall(struct drm_device *dev) + I915_WRITE(IER, enable_mask); + POSTING_READ(IER); + +- intel_opregion_enable_asle(dev); ++ i915_enable_asle_pipestat(dev); + + return 0; + } +@@ -3235,7 +3238,7 @@ static int i965_irq_postinstall(struct drm_device *dev) + I915_WRITE(PORT_HOTPLUG_EN, 0); + POSTING_READ(PORT_HOTPLUG_EN); + +- intel_opregion_enable_asle(dev); ++ i915_enable_asle_pipestat(dev); + + return 0; + } +diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c +index 700e83ba3378..5c2d6939600e 100644 +--- a/drivers/gpu/drm/i915/intel_opregion.c ++++ b/drivers/gpu/drm/i915/intel_opregion.c +@@ -232,17 +232,6 @@ void intel_opregion_asle_intr(struct drm_device *dev) + iowrite32(asle_stat, &asle->aslc); + } + +-void intel_opregion_enable_asle(struct drm_device *dev) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- struct opregion_asle __iomem *asle = dev_priv->opregion.asle; +- +- if (asle) { +- if (IS_MOBILE(dev)) +- intel_enable_asle(dev); +- } +-} +- + #define ACPI_EV_DISPLAY_SWITCH (1<<0) + #define ACPI_EV_LID (1<<1) + #define ACPI_EV_DOCK (1<<2) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0095-drm-i915-move-lvds_border_bits-to-pipe_config.patch b/patches.baytrail/0095-drm-i915-move-lvds_border_bits-to-pipe_config.patch new file mode 100644 index 000000000000..baad21feb7db --- /dev/null +++ b/patches.baytrail/0095-drm-i915-move-lvds_border_bits-to-pipe_config.patch @@ -0,0 +1,88 @@ +From 925df03211f20c2cab87e28cbf547abc1e4b2e9a Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 25 Apr 2013 22:52:16 +0200 +Subject: drm/i915: move lvds_border_bits to pipe_config + +pipe_config is the new dev_priv! + +More seriously, this is actually better since a pipe_config can be +thrown away if the modeset compute config stage fails. Whereas any +state stored in dev_prive needs to be painstakingly restored, since +otherwise a dpms off/on will wreak massive havoc. Yes, that even +applies to state only used in ->mode_set callbacks, since we need to +call those even for dpms on when the Haswell power well cleared +everything out. + +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 68fc874289e58e62bd0820db0d52150ce6d9fe03) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 -- + drivers/gpu/drm/i915/intel_drv.h | 1 + + drivers/gpu/drm/i915/intel_lvds.c | 2 +- + drivers/gpu/drm/i915/intel_panel.c | 3 +-- + 4 files changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index a3cdfbc3d8db..c5a31c628ab3 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1020,8 +1020,6 @@ typedef struct drm_i915_private { + /* Kernel Modesetting */ + + struct sdvo_device_mapping sdvo_mappings[2]; +- /* indicate whether the LVDS_BORDER should be enabled or not */ +- unsigned int lvds_border_bits; + + struct drm_crtc *plane_to_crtc_mapping[3]; + struct drm_crtc *pipe_to_crtc_mapping[3]; +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 174ba4e6a105..428b9c0357ba 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -249,6 +249,7 @@ struct intel_crtc_config { + struct { + u32 control; + u32 pgm_ratios; ++ u32 lvds_border_bits; + } gmch_pfit; + + /* Panel fitter placement and size for Ironlake+ */ +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index ab04cb9d0725..6e1f65c4d8a2 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -116,7 +116,7 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder) + } + + /* set the corresponsding LVDS_BORDER bit */ +- temp |= dev_priv->lvds_border_bits; ++ temp |= intel_crtc->config.gmch_pfit.lvds_border_bits; + /* Set the B0-B3 data pairs corresponding to whether we're going to + * set the DPLLs for dual-channel mode or not. + */ +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index 140f60d40105..d8139f126bea 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -183,7 +183,6 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, + int fitting_mode) + { + struct drm_device *dev = intel_crtc->base.dev; +- struct drm_i915_private *dev_priv = dev->dev_private; + u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; + struct drm_display_mode *mode, *adjusted_mode; + +@@ -312,7 +311,7 @@ out: + pipe_config->gmch_pfit.control = pfit_control; + pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios; + } +- dev_priv->lvds_border_bits = border; ++ pipe_config->gmch_pfit.lvds_border_bits = border; + } + + static int is_backlight_combination_mode(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0096-drm-i915-rip-out-indirection-for-pfit-pipe_config-as.patch b/patches.baytrail/0096-drm-i915-rip-out-indirection-for-pfit-pipe_config-as.patch new file mode 100644 index 000000000000..09432d2cd94b --- /dev/null +++ b/patches.baytrail/0096-drm-i915-rip-out-indirection-for-pfit-pipe_config-as.patch @@ -0,0 +1,41 @@ +From c3a9b19671d4ba953329d1fb2a7e1f4aafd66164 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 25 Apr 2013 22:52:17 +0200 +Subject: drm/i915: rip out indirection for pfit pipe_config assignment + +This was still required a bit (on the cargo-cult side though) when the +state was stored in dev_priv, and when the enable/disable sequence was +botched a bit (to avoid too many updates). + +But with pipeconfig we always get a clean slate, so this is pointless. +Rip it out. + +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 2deefda541edb0c73e57e988ccaac4cd014da0d3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_panel.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index d8139f126bea..8cae635bb90a 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -306,11 +306,8 @@ out: + if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18) + pfit_control |= PANEL_8TO6_DITHER_ENABLE; + +- if (pfit_control != pipe_config->gmch_pfit.control || +- pfit_pgm_ratios != pipe_config->gmch_pfit.pgm_ratios) { +- pipe_config->gmch_pfit.control = pfit_control; +- pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios; +- } ++ pipe_config->gmch_pfit.control = pfit_control; ++ pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios; + pipe_config->gmch_pfit.lvds_border_bits = border; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0097-drm-i915-move-border-color-writes-to-pfit_enable.patch b/patches.baytrail/0097-drm-i915-move-border-color-writes-to-pfit_enable.patch new file mode 100644 index 000000000000..432b75825362 --- /dev/null +++ b/patches.baytrail/0097-drm-i915-move-border-color-writes-to-pfit_enable.patch @@ -0,0 +1,70 @@ +From 2e1974cb6ac30203a60240adb8f7bf00019bd107 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 25 Apr 2013 22:52:18 +0200 +Subject: drm/i915: move border color writes to pfit_enable + +Writing hw registers from compute_config? +Just say no! + +In this case not too horrible since we write a constant 0, and only +debugging would put something else in there. But while checking that +code I've noticed that this register disappeared on pch platforms, so +fix that up, too. + +And adjust the comment a bit, it's outdated. + +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 5a80c45c5297a025c2615624042ea8b6840a5376) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ++++ + drivers/gpu/drm/i915/intel_lvds.c | 10 ---------- + 2 files changed, 4 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index f1b6ca3fe82a..5c89c0a293e5 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3632,6 +3632,10 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc) + + I915_WRITE(PFIT_PGM_RATIOS, pipe_config->gmch_pfit.pgm_ratios); + I915_WRITE(PFIT_CONTROL, pipe_config->gmch_pfit.control); ++ ++ /* Border color in case we don't scale up to the full screen. Black by ++ * default, change to something else for debugging. */ ++ I915_WRITE(BCLRPAT(crtc->pipe), 0); + } + + static void valleyview_crtc_enable(struct drm_crtc *crtc) +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 6e1f65c4d8a2..b314ef3ee644 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -231,7 +231,6 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; + struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc; + unsigned int lvds_bpp; +- int pipe; + + /* Should never happen!! */ + if (INTEL_INFO(dev)->gen < 4 && intel_crtc->pipe == 0) { +@@ -274,15 +273,6 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + intel_connector->panel.fitting_mode); + } + +- /* +- * Enable automatic panel scaling for non-native modes so that they fill +- * the screen. Should be enabled before the pipe is enabled, according +- * to register description and PRM. +- * Change the value here to see the borders for debugging +- */ +- for_each_pipe(pipe) +- I915_WRITE(BCLRPAT(pipe), 0); +- + drm_mode_set_crtcinfo(adjusted_mode, 0); + pipe_config->timings_set = true; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0098-drm-Add-struct-drm_rect-and-assorted-utility-functio.patch b/patches.baytrail/0098-drm-Add-struct-drm_rect-and-assorted-utility-functio.patch new file mode 100644 index 000000000000..f5398e81e606 --- /dev/null +++ b/patches.baytrail/0098-drm-Add-struct-drm_rect-and-assorted-utility-functio.patch @@ -0,0 +1,306 @@ +From dcbd4209c29fb5365e011e621a0e52dfddc9d2a4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 24 Apr 2013 18:52:34 +0300 +Subject: drm: Add struct drm_rect and assorted utility functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +struct drm_rect represents a simple rectangle. The utility +functions are there to help driver writers. + +v2: Moved the region stuff into its own file, made the smaller funcs + static inline, used 64bit maths in the scaled clipping function to + avoid overflows (instead it will saturate to INT_MIN or INT_MAX). +v3: Renamed drm_region to drm_rect, drm_region_clip to + drm_rect_intersect, and drm_region_subsample to drm_rect_downscale. +v4: Renamed some function parameters, improve kernel-doc comments a bit, + and actually generate documentation for drm_rect.[ch]. +v5: s/RETUTRNS/RETURNS/ + +Reviewed-by: Laurent Pinchart +Reviewed-by: Chris Wilson +Signed-off-by: Ville Syrjälä +Acked-by: Dave Airlie +Signed-off-by: Daniel Vetter +(cherry picked from commit 3512f976d252bd5d07d04e9e157f0cd210c959a0) +Signed-off-by: Darren Hart +--- + Documentation/DocBook/drm.tmpl | 2 + + drivers/gpu/drm/Makefile | 3 +- + drivers/gpu/drm/drm_rect.c | 96 ++++++++++++++++++++++++++++++ + include/drm/drm_rect.h | 132 +++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 232 insertions(+), 1 deletion(-) + create mode 100644 drivers/gpu/drm/drm_rect.c + create mode 100644 include/drm/drm_rect.h + +diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl +index f9df3b872c16..7c7af25b330c 100644 +--- a/Documentation/DocBook/drm.tmpl ++++ b/Documentation/DocBook/drm.tmpl +@@ -1653,6 +1653,8 @@ void intel_crt_init(struct drm_device *dev) + + KMS API Functions + !Edrivers/gpu/drm/drm_crtc.c ++!Edrivers/gpu/drm/drm_rect.c ++!Finclude/drm/drm_rect.h + + + +diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile +index 1c9f24396002..1ecbe5b7312d 100644 +--- a/drivers/gpu/drm/Makefile ++++ b/drivers/gpu/drm/Makefile +@@ -12,7 +12,8 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ + drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ + drm_crtc.o drm_modes.o drm_edid.o \ + drm_info.o drm_debugfs.o drm_encoder_slave.o \ +- drm_trace_points.o drm_global.o drm_prime.o ++ drm_trace_points.o drm_global.o drm_prime.o \ ++ drm_rect.o + + drm-$(CONFIG_COMPAT) += drm_ioc32.o + drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o +diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c +new file mode 100644 +index 000000000000..22091ecdbff4 +--- /dev/null ++++ b/drivers/gpu/drm/drm_rect.c +@@ -0,0 +1,96 @@ ++/* ++ * Copyright (C) 2011-2013 Intel Corporation ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++/** ++ * drm_rect_intersect - intersect two rectangles ++ * @r1: first rectangle ++ * @r2: second rectangle ++ * ++ * Calculate the intersection of rectangles @r1 and @r2. ++ * @r1 will be overwritten with the intersection. ++ * ++ * RETURNS: ++ * %true if rectangle @r1 is still visible after the operation, ++ * %false otherwise. ++ */ ++bool drm_rect_intersect(struct drm_rect *r1, const struct drm_rect *r2) ++{ ++ r1->x1 = max(r1->x1, r2->x1); ++ r1->y1 = max(r1->y1, r2->y1); ++ r1->x2 = min(r1->x2, r2->x2); ++ r1->y2 = min(r1->y2, r2->y2); ++ ++ return drm_rect_visible(r1); ++} ++EXPORT_SYMBOL(drm_rect_intersect); ++ ++/** ++ * drm_rect_clip_scaled - perform a scaled clip operation ++ * @src: source window rectangle ++ * @dst: destination window rectangle ++ * @clip: clip rectangle ++ * @hscale: horizontal scaling factor ++ * @vscale: vertical scaling factor ++ * ++ * Clip rectangle @dst by rectangle @clip. Clip rectangle @src by the ++ * same amounts multiplied by @hscale and @vscale. ++ * ++ * RETURNS: ++ * %true if rectangle @dst is still visible after being clipped, ++ * %false otherwise ++ */ ++bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, ++ const struct drm_rect *clip, ++ int hscale, int vscale) ++{ ++ int diff; ++ ++ diff = clip->x1 - dst->x1; ++ if (diff > 0) { ++ int64_t tmp = src->x1 + (int64_t) diff * hscale; ++ src->x1 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX); ++ } ++ diff = clip->y1 - dst->y1; ++ if (diff > 0) { ++ int64_t tmp = src->y1 + (int64_t) diff * vscale; ++ src->y1 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX); ++ } ++ diff = dst->x2 - clip->x2; ++ if (diff > 0) { ++ int64_t tmp = src->x2 - (int64_t) diff * hscale; ++ src->x2 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX); ++ } ++ diff = dst->y2 - clip->y2; ++ if (diff > 0) { ++ int64_t tmp = src->y2 - (int64_t) diff * vscale; ++ src->y2 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX); ++ } ++ ++ return drm_rect_intersect(dst, clip); ++} ++EXPORT_SYMBOL(drm_rect_clip_scaled); +diff --git a/include/drm/drm_rect.h b/include/drm/drm_rect.h +new file mode 100644 +index 000000000000..2b7278c1bc42 +--- /dev/null ++++ b/include/drm/drm_rect.h +@@ -0,0 +1,132 @@ ++/* ++ * Copyright (C) 2011-2013 Intel Corporation ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#ifndef DRM_RECT_H ++#define DRM_RECT_H ++ ++/** ++ * drm_rect - two dimensional rectangle ++ * @x1: horizontal starting coordinate (inclusive) ++ * @x2: horizontal ending coordinate (exclusive) ++ * @y1: vertical starting coordinate (inclusive) ++ * @y2: vertical ending coordinate (exclusive) ++ */ ++struct drm_rect { ++ int x1, y1, x2, y2; ++}; ++ ++/** ++ * drm_rect_adjust_size - adjust the size of the rectangle ++ * @r: rectangle to be adjusted ++ * @dw: horizontal adjustment ++ * @dh: vertical adjustment ++ * ++ * Change the size of rectangle @r by @dw in the horizontal direction, ++ * and by @dh in the vertical direction, while keeping the center ++ * of @r stationary. ++ * ++ * Positive @dw and @dh increase the size, negative values decrease it. ++ */ ++static inline void drm_rect_adjust_size(struct drm_rect *r, int dw, int dh) ++{ ++ r->x1 -= dw >> 1; ++ r->y1 -= dh >> 1; ++ r->x2 += (dw + 1) >> 1; ++ r->y2 += (dh + 1) >> 1; ++} ++ ++/** ++ * drm_rect_translate - translate the rectangle ++ * @r: rectangle to be tranlated ++ * @dx: horizontal translation ++ * @dy: vertical translation ++ * ++ * Move rectangle @r by @dx in the horizontal direction, ++ * and by @dy in the vertical direction. ++ */ ++static inline void drm_rect_translate(struct drm_rect *r, int dx, int dy) ++{ ++ r->x1 += dx; ++ r->y1 += dy; ++ r->x2 += dx; ++ r->y2 += dy; ++} ++ ++/** ++ * drm_rect_downscale - downscale a rectangle ++ * @r: rectangle to be downscaled ++ * @horz: horizontal downscale factor ++ * @vert: vertical downscale factor ++ * ++ * Divide the coordinates of rectangle @r by @horz and @vert. ++ */ ++static inline void drm_rect_downscale(struct drm_rect *r, int horz, int vert) ++{ ++ r->x1 /= horz; ++ r->y1 /= vert; ++ r->x2 /= horz; ++ r->y2 /= vert; ++} ++ ++/** ++ * drm_rect_width - determine the rectangle width ++ * @r: rectangle whose width is returned ++ * ++ * RETURNS: ++ * The width of the rectangle. ++ */ ++static inline int drm_rect_width(const struct drm_rect *r) ++{ ++ return r->x2 - r->x1; ++} ++ ++/** ++ * drm_rect_height - determine the rectangle height ++ * @r: rectangle whose height is returned ++ * ++ * RETURNS: ++ * The height of the rectangle. ++ */ ++static inline int drm_rect_height(const struct drm_rect *r) ++{ ++ return r->y2 - r->y1; ++} ++ ++/** ++ * drm_rect_visible - determine if the the rectangle is visible ++ * @r: rectangle whose visibility is returned ++ * ++ * RETURNS: ++ * %true if the rectangle is visible, %false otherwise. ++ */ ++static inline bool drm_rect_visible(const struct drm_rect *r) ++{ ++ return drm_rect_width(r) > 0 && drm_rect_height(r) > 0; ++} ++ ++bool drm_rect_intersect(struct drm_rect *r, const struct drm_rect *clip); ++bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, ++ const struct drm_rect *clip, ++ int hscale, int vscale); ++ ++#endif +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0099-drm-Add-drm_rect_calc_-hscale-vscale-utility-functio.patch b/patches.baytrail/0099-drm-Add-drm_rect_calc_-hscale-vscale-utility-functio.patch new file mode 100644 index 000000000000..5c32ac65da8e --- /dev/null +++ b/patches.baytrail/0099-drm-Add-drm_rect_calc_-hscale-vscale-utility-functio.patch @@ -0,0 +1,243 @@ +From c0ef841ef98c806b25480895da604d30a60a34fe Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 24 Apr 2013 18:52:35 +0300 +Subject: drm: Add drm_rect_calc_{hscale, vscale}() utility functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These functions calculate the scaling factor based on the source and +destination rectangles. + +There are two version of the functions, the strict ones that will +return an error if the min/max scaling factor is exceeded, and the +relaxed versions that will adjust the src/dst rectangles in order to +keep the scaling factor withing the limits. + +v2: Return error instead of adjusting regions, refactor common parts + into one function, and split into strict and relaxed versions. +v3: Renamed drm_region to drm_rect, add "_rect_" to the function + names. +v4: Fix "calculcate" typos + +Reviewed-by: Chris Wilson +Signed-off-by: Ville Syrjälä +Acked-by: Dave Airlie +Signed-off-by: Daniel Vetter +(cherry picked from commit 4954c4282f6b945f1dd5716f92b594a07fa4ffe3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_rect.c | 177 +++++++++++++++++++++++++++++++++++++++++++++ + include/drm/drm_rect.h | 12 +++ + 2 files changed, 189 insertions(+) + +diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c +index 22091ecdbff4..dc11a2867f20 100644 +--- a/drivers/gpu/drm/drm_rect.c ++++ b/drivers/gpu/drm/drm_rect.c +@@ -94,3 +94,180 @@ bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, + return drm_rect_intersect(dst, clip); + } + EXPORT_SYMBOL(drm_rect_clip_scaled); ++ ++static int drm_calc_scale(int src, int dst) ++{ ++ int scale = 0; ++ ++ if (src < 0 || dst < 0) ++ return -EINVAL; ++ ++ if (dst == 0) ++ return 0; ++ ++ scale = src / dst; ++ ++ return scale; ++} ++ ++/** ++ * drm_rect_calc_hscale - calculate the horizontal scaling factor ++ * @src: source window rectangle ++ * @dst: destination window rectangle ++ * @min_hscale: minimum allowed horizontal scaling factor ++ * @max_hscale: maximum allowed horizontal scaling factor ++ * ++ * Calculate the horizontal scaling factor as ++ * (@src width) / (@dst width). ++ * ++ * RETURNS: ++ * The horizontal scaling factor, or errno of out of limits. ++ */ ++int drm_rect_calc_hscale(const struct drm_rect *src, ++ const struct drm_rect *dst, ++ int min_hscale, int max_hscale) ++{ ++ int src_w = drm_rect_width(src); ++ int dst_w = drm_rect_width(dst); ++ int hscale = drm_calc_scale(src_w, dst_w); ++ ++ if (hscale < 0 || dst_w == 0) ++ return hscale; ++ ++ if (hscale < min_hscale || hscale > max_hscale) ++ return -ERANGE; ++ ++ return hscale; ++} ++EXPORT_SYMBOL(drm_rect_calc_hscale); ++ ++/** ++ * drm_rect_calc_vscale - calculate the vertical scaling factor ++ * @src: source window rectangle ++ * @dst: destination window rectangle ++ * @min_vscale: minimum allowed vertical scaling factor ++ * @max_vscale: maximum allowed vertical scaling factor ++ * ++ * Calculate the vertical scaling factor as ++ * (@src height) / (@dst height). ++ * ++ * RETURNS: ++ * The vertical scaling factor, or errno of out of limits. ++ */ ++int drm_rect_calc_vscale(const struct drm_rect *src, ++ const struct drm_rect *dst, ++ int min_vscale, int max_vscale) ++{ ++ int src_h = drm_rect_height(src); ++ int dst_h = drm_rect_height(dst); ++ int vscale = drm_calc_scale(src_h, dst_h); ++ ++ if (vscale < 0 || dst_h == 0) ++ return vscale; ++ ++ if (vscale < min_vscale || vscale > max_vscale) ++ return -ERANGE; ++ ++ return vscale; ++} ++EXPORT_SYMBOL(drm_rect_calc_vscale); ++ ++/** ++ * drm_calc_hscale_relaxed - calculate the horizontal scaling factor ++ * @src: source window rectangle ++ * @dst: destination window rectangle ++ * @min_hscale: minimum allowed horizontal scaling factor ++ * @max_hscale: maximum allowed horizontal scaling factor ++ * ++ * Calculate the horizontal scaling factor as ++ * (@src width) / (@dst width). ++ * ++ * If the calculated scaling factor is below @min_vscale, ++ * decrease the height of rectangle @dst to compensate. ++ * ++ * If the calculated scaling factor is above @max_vscale, ++ * decrease the height of rectangle @src to compensate. ++ * ++ * RETURNS: ++ * The horizontal scaling factor. ++ */ ++int drm_rect_calc_hscale_relaxed(struct drm_rect *src, ++ struct drm_rect *dst, ++ int min_hscale, int max_hscale) ++{ ++ int src_w = drm_rect_width(src); ++ int dst_w = drm_rect_width(dst); ++ int hscale = drm_calc_scale(src_w, dst_w); ++ ++ if (hscale < 0 || dst_w == 0) ++ return hscale; ++ ++ if (hscale < min_hscale) { ++ int max_dst_w = src_w / min_hscale; ++ ++ drm_rect_adjust_size(dst, max_dst_w - dst_w, 0); ++ ++ return min_hscale; ++ } ++ ++ if (hscale > max_hscale) { ++ int max_src_w = dst_w * max_hscale; ++ ++ drm_rect_adjust_size(src, max_src_w - src_w, 0); ++ ++ return max_hscale; ++ } ++ ++ return hscale; ++} ++EXPORT_SYMBOL(drm_rect_calc_hscale_relaxed); ++ ++/** ++ * drm_rect_calc_vscale_relaxed - calculate the vertical scaling factor ++ * @src: source window rectangle ++ * @dst: destination window rectangle ++ * @min_vscale: minimum allowed vertical scaling factor ++ * @max_vscale: maximum allowed vertical scaling factor ++ * ++ * Calculate the vertical scaling factor as ++ * (@src height) / (@dst height). ++ * ++ * If the calculated scaling factor is below @min_vscale, ++ * decrease the height of rectangle @dst to compensate. ++ * ++ * If the calculated scaling factor is above @max_vscale, ++ * decrease the height of rectangle @src to compensate. ++ * ++ * RETURNS: ++ * The vertical scaling factor. ++ */ ++int drm_rect_calc_vscale_relaxed(struct drm_rect *src, ++ struct drm_rect *dst, ++ int min_vscale, int max_vscale) ++{ ++ int src_h = drm_rect_height(src); ++ int dst_h = drm_rect_height(dst); ++ int vscale = drm_calc_scale(src_h, dst_h); ++ ++ if (vscale < 0 || dst_h == 0) ++ return vscale; ++ ++ if (vscale < min_vscale) { ++ int max_dst_h = src_h / min_vscale; ++ ++ drm_rect_adjust_size(dst, 0, max_dst_h - dst_h); ++ ++ return min_vscale; ++ } ++ ++ if (vscale > max_vscale) { ++ int max_src_h = dst_h * max_vscale; ++ ++ drm_rect_adjust_size(src, 0, max_src_h - src_h); ++ ++ return max_vscale; ++ } ++ ++ return vscale; ++} ++EXPORT_SYMBOL(drm_rect_calc_vscale_relaxed); +diff --git a/include/drm/drm_rect.h b/include/drm/drm_rect.h +index 2b7278c1bc42..de24f16a3c4f 100644 +--- a/include/drm/drm_rect.h ++++ b/include/drm/drm_rect.h +@@ -128,5 +128,17 @@ bool drm_rect_intersect(struct drm_rect *r, const struct drm_rect *clip); + bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, + const struct drm_rect *clip, + int hscale, int vscale); ++int drm_rect_calc_hscale(const struct drm_rect *src, ++ const struct drm_rect *dst, ++ int min_hscale, int max_hscale); ++int drm_rect_calc_vscale(const struct drm_rect *src, ++ const struct drm_rect *dst, ++ int min_vscale, int max_vscale); ++int drm_rect_calc_hscale_relaxed(struct drm_rect *src, ++ struct drm_rect *dst, ++ int min_hscale, int max_hscale); ++int drm_rect_calc_vscale_relaxed(struct drm_rect *src, ++ struct drm_rect *dst, ++ int min_vscale, int max_vscale); + + #endif +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0100-drm-Add-drm_rect_debug_print.patch b/patches.baytrail/0100-drm-Add-drm_rect_debug_print.patch new file mode 100644 index 000000000000..c42836be057e --- /dev/null +++ b/patches.baytrail/0100-drm-Add-drm_rect_debug_print.patch @@ -0,0 +1,76 @@ +From 56af839c13bd5e918dfbb2e6e6406fa08c5d5544 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 24 Apr 2013 18:52:36 +0300 +Subject: drm: Add drm_rect_debug_print() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add a debug function to print the rectangle in a human readable format. + +v2: Renamed drm_region to drm_rect, the function from drm_region_debug + to drm_rect_debug_print(), and use %+d instead of +%d in the format. +v3: Use %d format for width/height in the non fixed point case as well + +Reviewed-by: Chris Wilson +Signed-off-by: Ville Syrjälä +Acked-by: Dave Airlie +Signed-off-by: Daniel Vetter +(cherry picked from commit e7272df342ba337e87e210470bb93d97d192f2e0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_rect.c | 22 ++++++++++++++++++++++ + include/drm/drm_rect.h | 1 + + 2 files changed, 23 insertions(+) + +diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c +index dc11a2867f20..7047ca025787 100644 +--- a/drivers/gpu/drm/drm_rect.c ++++ b/drivers/gpu/drm/drm_rect.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + + /** +@@ -271,3 +272,24 @@ int drm_rect_calc_vscale_relaxed(struct drm_rect *src, + return vscale; + } + EXPORT_SYMBOL(drm_rect_calc_vscale_relaxed); ++ ++/** ++ * drm_rect_debug_print - print the rectangle information ++ * @r: rectangle to print ++ * @fixed_point: rectangle is in 16.16 fixed point format ++ */ ++void drm_rect_debug_print(const struct drm_rect *r, bool fixed_point) ++{ ++ int w = drm_rect_width(r); ++ int h = drm_rect_height(r); ++ ++ if (fixed_point) ++ DRM_DEBUG_KMS("%d.%06ux%d.%06u%+d.%06u%+d.%06u\n", ++ w >> 16, ((w & 0xffff) * 15625) >> 10, ++ h >> 16, ((h & 0xffff) * 15625) >> 10, ++ r->x1 >> 16, ((r->x1 & 0xffff) * 15625) >> 10, ++ r->y1 >> 16, ((r->y1 & 0xffff) * 15625) >> 10); ++ else ++ DRM_DEBUG_KMS("%dx%d%+d%+d\n", w, h, r->x1, r->y1); ++} ++EXPORT_SYMBOL(drm_rect_debug_print); +diff --git a/include/drm/drm_rect.h b/include/drm/drm_rect.h +index de24f16a3c4f..fe767b757c8c 100644 +--- a/include/drm/drm_rect.h ++++ b/include/drm/drm_rect.h +@@ -140,5 +140,6 @@ int drm_rect_calc_hscale_relaxed(struct drm_rect *src, + int drm_rect_calc_vscale_relaxed(struct drm_rect *src, + struct drm_rect *dst, + int min_vscale, int max_vscale); ++void drm_rect_debug_print(const struct drm_rect *r, bool fixed_point); + + #endif +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0101-drm-Add-drm_rect_equals.patch b/patches.baytrail/0101-drm-Add-drm_rect_equals.patch new file mode 100644 index 000000000000..b4d0f6fea8fc --- /dev/null +++ b/patches.baytrail/0101-drm-Add-drm_rect_equals.patch @@ -0,0 +1,49 @@ +From c8d54d7f83ac5816b2533468745e1eff6e61c84f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 24 Apr 2013 18:52:37 +0300 +Subject: drm: Add drm_rect_equals() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +drm_rect_equals() tells whether two drm_rects are equal. + +Reviewed-by: Chris Wilson +Signed-off-by: Ville Syrjälä +Acked-by: Dave Airlie +Signed-off-by: Daniel Vetter +(cherry picked from commit 0894c96bff762d0474a8722bba3d420f643db359) +Signed-off-by: Darren Hart +--- + include/drm/drm_rect.h | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/include/drm/drm_rect.h b/include/drm/drm_rect.h +index fe767b757c8c..64fa265c6ffb 100644 +--- a/include/drm/drm_rect.h ++++ b/include/drm/drm_rect.h +@@ -124,6 +124,21 @@ static inline bool drm_rect_visible(const struct drm_rect *r) + return drm_rect_width(r) > 0 && drm_rect_height(r) > 0; + } + ++/** ++ * drm_rect_equals - determine if two rectangles are equal ++ * @r1: first rectangle ++ * @r2: second rectangle ++ * ++ * RETURNS: ++ * %true if the rectangles are equal, %false otherwise. ++ */ ++static inline bool drm_rect_equals(const struct drm_rect *r1, ++ const struct drm_rect *r2) ++{ ++ return r1->x1 == r2->x1 && r1->x2 == r2->x2 && ++ r1->y1 == r2->y1 && r1->y2 == r2->y2; ++} ++ + bool drm_rect_intersect(struct drm_rect *r, const struct drm_rect *clip); + bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, + const struct drm_rect *clip, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0102-drm-i915-Implement-proper-clipping-for-video-sprites.patch b/patches.baytrail/0102-drm-i915-Implement-proper-clipping-for-video-sprites.patch new file mode 100644 index 000000000000..9a432b4611b6 --- /dev/null +++ b/patches.baytrail/0102-drm-i915-Implement-proper-clipping-for-video-sprites.patch @@ -0,0 +1,314 @@ +From 537809ef508043b78aa1476b199314793f665591 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 24 Apr 2013 18:52:38 +0300 +Subject: drm/i915: Implement proper clipping for video sprites +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Properly clip the source when the destination gets clipped +by the pipe dimensions. + +Sadly the video sprite hardware is rather limited so it can't do proper +sub-pixel postitioning. Resort to truncating the source coordinates to +(macro)pixel boundary. + +The scaling checks are done using the strict drm_region functions. +Which means that an error is returned when the min/max scaling +ratios are exceeded. + +Also do some additional checking against various hardware limits. + +v2: Truncate src coords instead of rounding to avoid increasing src + viewport size, and adapt to changes in drm_calc_{h,v}scale(). +v3: Adapt to drm_region->drm_rect rename. Fix misaligned crtc_w for + packed YUV formats when scaling isn't supported. +v4: Use stricter scaling checks, use drm_rect_equals() +v5: If sprite is below min size, make it invisible instead returning + an error. + Use WARN_ON() instead if BUG_ON(), and add one to sanity check the + src viewport size. +v6: Add comments to remind about src and dst coordinate types + +Reviewed-by: Chris Wilson +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 1731693a5a372869d017e601a23b1ce2eb3135ed) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sprite.c | 196 +++++++++++++++++++++++++++--------- + 1 file changed, 149 insertions(+), 47 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index 18993ad93540..87fe3b625c4b 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include "intel_drv.h" + #include + #include "i915_drv.h" +@@ -583,6 +584,20 @@ ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) + key->flags = I915_SET_COLORKEY_NONE; + } + ++static bool ++format_is_yuv(uint32_t format) ++{ ++ switch (format) { ++ case DRM_FORMAT_YUYV: ++ case DRM_FORMAT_UYVY: ++ case DRM_FORMAT_VYUY: ++ case DRM_FORMAT_YVYU: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static int + intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + struct drm_framebuffer *fb, int crtc_x, int crtc_y, +@@ -600,9 +615,29 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, + pipe); + int ret = 0; +- int x = src_x >> 16, y = src_y >> 16; +- int primary_w = crtc->mode.hdisplay, primary_h = crtc->mode.vdisplay; + bool disable_primary = false; ++ bool visible; ++ int hscale, vscale; ++ int max_scale, min_scale; ++ int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); ++ struct drm_rect src = { ++ /* sample coordinates in 16.16 fixed point */ ++ .x1 = src_x, ++ .x2 = src_x + src_w, ++ .y1 = src_y, ++ .y2 = src_y + src_h, ++ }; ++ struct drm_rect dst = { ++ /* integer pixels */ ++ .x1 = crtc_x, ++ .x2 = crtc_x + crtc_w, ++ .y1 = crtc_y, ++ .y2 = crtc_y + crtc_h, ++ }; ++ const struct drm_rect clip = { ++ .x2 = crtc->mode.hdisplay, ++ .y2 = crtc->mode.vdisplay, ++ }; + + intel_fb = to_intel_framebuffer(fb); + obj = intel_fb->obj; +@@ -618,19 +653,23 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + intel_plane->src_w = src_w; + intel_plane->src_h = src_h; + +- src_w = src_w >> 16; +- src_h = src_h >> 16; +- + /* Pipe must be running... */ +- if (!(I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE)) ++ if (!(I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE)) { ++ DRM_DEBUG_KMS("Pipe disabled\n"); + return -EINVAL; ++ } + +- if (crtc_x >= primary_w || crtc_y >= primary_h) ++ /* Don't modify another pipe's plane */ ++ if (intel_plane->pipe != intel_crtc->pipe) { ++ DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n"); + return -EINVAL; ++ } + +- /* Don't modify another pipe's plane */ +- if (intel_plane->pipe != intel_crtc->pipe) ++ /* FIXME check all gen limits */ ++ if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) { ++ DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n"); + return -EINVAL; ++ } + + /* Sprite planes can be linear or x-tiled surfaces */ + switch (obj->tiling_mode) { +@@ -638,55 +677,115 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + case I915_TILING_X: + break; + default: ++ DRM_DEBUG_KMS("Unsupported tiling mode\n"); + return -EINVAL; + } + +- /* +- * Clamp the width & height into the visible area. Note we don't +- * try to scale the source if part of the visible region is offscreen. +- * The caller must handle that by adjusting source offset and size. +- */ +- if ((crtc_x < 0) && ((crtc_x + crtc_w) > 0)) { +- crtc_w += crtc_x; +- crtc_x = 0; ++ max_scale = intel_plane->max_downscale << 16; ++ min_scale = intel_plane->can_scale ? 1 : (1 << 16); ++ ++ hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale); ++ if (hscale < 0) { ++ DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n"); ++ drm_rect_debug_print(&src, true); ++ drm_rect_debug_print(&dst, false); ++ ++ return hscale; + } +- if ((crtc_x + crtc_w) <= 0) /* Nothing to display */ +- goto out; +- if ((crtc_x + crtc_w) > primary_w) +- crtc_w = primary_w - crtc_x; + +- if ((crtc_y < 0) && ((crtc_y + crtc_h) > 0)) { +- crtc_h += crtc_y; +- crtc_y = 0; ++ vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale); ++ if (vscale < 0) { ++ DRM_DEBUG_KMS("Vertical scaling factor out of limits\n"); ++ drm_rect_debug_print(&src, true); ++ drm_rect_debug_print(&dst, false); ++ ++ return vscale; + } +- if ((crtc_y + crtc_h) <= 0) /* Nothing to display */ +- goto out; +- if (crtc_y + crtc_h > primary_h) +- crtc_h = primary_h - crtc_y; + +- if (!crtc_w || !crtc_h) /* Again, nothing to display */ +- goto out; ++ visible = drm_rect_clip_scaled(&src, &dst, &clip, hscale, vscale); + +- /* +- * We may not have a scaler, eg. HSW does not have it any more +- */ +- if (!intel_plane->can_scale && (crtc_w != src_w || crtc_h != src_h)) +- return -EINVAL; ++ crtc_x = dst.x1; ++ crtc_y = dst.y1; ++ crtc_w = drm_rect_width(&dst); ++ crtc_h = drm_rect_height(&dst); + +- /* +- * We can take a larger source and scale it down, but +- * only so much... 16x is the max on SNB. +- */ +- if (((src_w * src_h) / (crtc_w * crtc_h)) > intel_plane->max_downscale) +- return -EINVAL; ++ if (visible) { ++ /* Make the source viewport size an exact multiple of the scaling factors. */ ++ drm_rect_adjust_size(&src, ++ drm_rect_width(&dst) * hscale - drm_rect_width(&src), ++ drm_rect_height(&dst) * vscale - drm_rect_height(&src)); ++ ++ /* sanity check to make sure the src viewport wasn't enlarged */ ++ WARN_ON(src.x1 < (int) src_x || ++ src.y1 < (int) src_y || ++ src.x2 > (int) (src_x + src_w) || ++ src.y2 > (int) (src_y + src_h)); ++ ++ /* ++ * Hardware doesn't handle subpixel coordinates. ++ * Adjust to (macro)pixel boundary, but be careful not to ++ * increase the source viewport size, because that could ++ * push the downscaling factor out of bounds. ++ * ++ * FIXME Should we be really strict and reject the ++ * config if it results in non (macro)pixel aligned ++ * coords? ++ */ ++ src_x = src.x1 >> 16; ++ src_w = drm_rect_width(&src) >> 16; ++ src_y = src.y1 >> 16; ++ src_h = drm_rect_height(&src) >> 16; ++ ++ if (format_is_yuv(fb->pixel_format)) { ++ src_x &= ~1; ++ src_w &= ~1; ++ ++ /* ++ * Must keep src and dst the ++ * same if we can't scale. ++ */ ++ if (!intel_plane->can_scale) ++ crtc_w &= ~1; ++ ++ if (crtc_w == 0) ++ visible = false; ++ } ++ } ++ ++ /* Check size restrictions when scaling */ ++ if (visible && (src_w != crtc_w || src_h != crtc_h)) { ++ unsigned int width_bytes; ++ ++ WARN_ON(!intel_plane->can_scale); ++ ++ /* FIXME interlacing min height is 6 */ ++ ++ if (crtc_w < 3 || crtc_h < 3) ++ visible = false; ++ ++ if (src_w < 3 || src_h < 3) ++ visible = false; ++ ++ width_bytes = ((src_x * pixel_size) & 63) + src_w * pixel_size; ++ ++ if (src_w > 2048 || src_h > 2048 || ++ width_bytes > 4096 || fb->pitches[0] > 4096) { ++ DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n"); ++ return -EINVAL; ++ } ++ } ++ ++ dst.x1 = crtc_x; ++ dst.x2 = crtc_x + crtc_w; ++ dst.y1 = crtc_y; ++ dst.y2 = crtc_y + crtc_h; + + /* + * If the sprite is completely covering the primary plane, + * we can disable the primary and save power. + */ +- if ((crtc_x == 0) && (crtc_y == 0) && +- (crtc_w == primary_w) && (crtc_h == primary_h)) +- disable_primary = true; ++ disable_primary = drm_rect_equals(&dst, &clip); ++ WARN_ON(disable_primary && !visible); + + mutex_lock(&dev->struct_mutex); + +@@ -708,8 +807,12 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + if (!disable_primary) + intel_enable_primary(crtc); + +- intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y, +- crtc_w, crtc_h, x, y, src_w, src_h); ++ if (visible) ++ intel_plane->update_plane(plane, fb, obj, ++ crtc_x, crtc_y, crtc_w, crtc_h, ++ src_x, src_y, src_w, src_h); ++ else ++ intel_plane->disable_plane(plane); + + if (disable_primary) + intel_disable_primary(crtc); +@@ -732,7 +835,6 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + + out_unlock: + mutex_unlock(&dev->struct_mutex); +-out: + return ret; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0103-drm-i915-Relax-the-sprite-scaling-limits-checks.patch b/patches.baytrail/0103-drm-i915-Relax-the-sprite-scaling-limits-checks.patch new file mode 100644 index 000000000000..66782a65287e --- /dev/null +++ b/patches.baytrail/0103-drm-i915-Relax-the-sprite-scaling-limits-checks.patch @@ -0,0 +1,102 @@ +From d95b4ac7dbdf760f0e9008692771f6da34a05200 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 24 Apr 2013 18:52:39 +0300 +Subject: drm/i915: Relax the sprite scaling limits checks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reduce the size of the the src/dst viewport to keep the scalign ratios +in check. + +v2: Below min size sprite handling squashed to previous patch + +Reviewed-by: Chris Wilson +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 3c3686cd9700efefcfc24ab5910b3e5fffd0b069) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sprite.c | 48 +++++++++++++++++++++---------------- + 1 file changed, 28 insertions(+), 20 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index 87fe3b625c4b..19b9cb961b5a 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -681,26 +681,19 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + return -EINVAL; + } + ++ /* ++ * FIXME the following code does a bunch of fuzzy adjustments to the ++ * coordinates and sizes. We probably need some way to decide whether ++ * more strict checking should be done instead. ++ */ + max_scale = intel_plane->max_downscale << 16; + min_scale = intel_plane->can_scale ? 1 : (1 << 16); + +- hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale); +- if (hscale < 0) { +- DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n"); +- drm_rect_debug_print(&src, true); +- drm_rect_debug_print(&dst, false); +- +- return hscale; +- } +- +- vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale); +- if (vscale < 0) { +- DRM_DEBUG_KMS("Vertical scaling factor out of limits\n"); +- drm_rect_debug_print(&src, true); +- drm_rect_debug_print(&dst, false); ++ hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale); ++ BUG_ON(hscale < 0); + +- return vscale; +- } ++ vscale = drm_rect_calc_vscale_relaxed(&src, &dst, min_scale, max_scale); ++ BUG_ON(vscale < 0); + + visible = drm_rect_clip_scaled(&src, &dst, &clip, hscale, vscale); + +@@ -710,6 +703,25 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + crtc_h = drm_rect_height(&dst); + + if (visible) { ++ /* check again in case clipping clamped the results */ ++ hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale); ++ if (hscale < 0) { ++ DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n"); ++ drm_rect_debug_print(&src, true); ++ drm_rect_debug_print(&dst, false); ++ ++ return hscale; ++ } ++ ++ vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale); ++ if (vscale < 0) { ++ DRM_DEBUG_KMS("Vertical scaling factor out of limits\n"); ++ drm_rect_debug_print(&src, true); ++ drm_rect_debug_print(&dst, false); ++ ++ return vscale; ++ } ++ + /* Make the source viewport size an exact multiple of the scaling factors. */ + drm_rect_adjust_size(&src, + drm_rect_width(&dst) * hscale - drm_rect_width(&src), +@@ -726,10 +738,6 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + * Adjust to (macro)pixel boundary, but be careful not to + * increase the source viewport size, because that could + * push the downscaling factor out of bounds. +- * +- * FIXME Should we be really strict and reject the +- * config if it results in non (macro)pixel aligned +- * coords? + */ + src_x = src.x1 >> 16; + src_w = drm_rect_width(&src) >> 16; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0104-drm-i915-reference-count-for-i915_hw_contexts.patch b/patches.baytrail/0104-drm-i915-reference-count-for-i915_hw_contexts.patch new file mode 100644 index 000000000000..fd715fdd0ba0 --- /dev/null +++ b/patches.baytrail/0104-drm-i915-reference-count-for-i915_hw_contexts.patch @@ -0,0 +1,178 @@ +From 17d24d1cad976e85136fb806d891f01dabd90824 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Tue, 30 Apr 2013 13:30:33 +0300 +Subject: drm/i915: reference count for i915_hw_contexts + +Enabling PPGTT and also the need to track which context was guilty of +gpu hang (arb robustness enabling) have put pressure for struct i915_hw_context +to be more than just a placeholder for hw context state. + +In order to track object lifetime properly in a multi peer usage, add reference +counting for i915_hw_context. + +v2: track i915_hw_context pointers instead of using ctx_ids +(from Chris Wilson) + +v3 (Ben): Get rid of do_release() and handle refcounting more compactly. +(recommended by Chis) + +v4: kref_* put inside static inlines (Daniel Vetter) +remove code duplication on freeing context (Chris Wilson) + +v5: idr_remove and ctx->file_priv = NULL in destroy ioctl (Chris) +This actually will cause a problem if one destroys a context and later +refers to the idea of the context (multiple contexts may have the same +id, but only 1 will exist in the idr). + +v6: Strip out the request related stuff. Reworded commit message. +Got rid of do_destroy and introduced i915_gem_context_release_handle, +suggested by Chris Wilson. + +v7: idr_remove can't be called inside idr_for_each (Chris Wilson) + +Signed-off-by: Ben Widawsky (v5) +Signed-off-by: Mika Kuoppala (v7) +Reviewed-by: Ben Widawsky +Reviewed-by: Chris Wilson +[danvet: Squash sob lines, the patch ping-ponged between Ben and Mika +a bit ...] +Signed-off-by: Daniel Vetter + +(cherry picked from commit dce3271b1ee05ca01ebdde50d613d7b33ef178a9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 12 ++++++++++++ + drivers/gpu/drm/i915/i915_gem_context.c | 28 ++++++++++++++-------------- + 2 files changed, 26 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index c5a31c628ab3..aac5740f1ee9 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -452,6 +452,7 @@ struct i915_hw_ppgtt { + /* This must match up with the value previously used for execbuf2.rsvd1. */ + #define DEFAULT_CONTEXT_ID 0 + struct i915_hw_context { ++ struct kref ref; + int id; + bool is_initialized; + struct drm_i915_file_private *file_priv; +@@ -1701,6 +1702,17 @@ void i915_gem_context_fini(struct drm_device *dev); + void i915_gem_context_close(struct drm_device *dev, struct drm_file *file); + int i915_switch_context(struct intel_ring_buffer *ring, + struct drm_file *file, int to_id); ++void i915_gem_context_free(struct kref *ctx_ref); ++static inline void i915_gem_context_reference(struct i915_hw_context *ctx) ++{ ++ kref_get(&ctx->ref); ++} ++ ++static inline void i915_gem_context_unreference(struct i915_hw_context *ctx) ++{ ++ kref_put(&ctx->ref, i915_gem_context_free); ++} ++ + int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); + int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index 3bc8a58a8d5f..47ffea61c9fa 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -124,10 +124,10 @@ static int get_context_size(struct drm_device *dev) + return ret; + } + +-static void do_destroy(struct i915_hw_context *ctx) ++void i915_gem_context_free(struct kref *ctx_ref) + { +- if (ctx->file_priv) +- idr_remove(&ctx->file_priv->context_idr, ctx->id); ++ struct i915_hw_context *ctx = container_of(ctx_ref, ++ typeof(*ctx), ref); + + drm_gem_object_unreference(&ctx->obj->base); + kfree(ctx); +@@ -145,6 +145,7 @@ create_hw_context(struct drm_device *dev, + if (ctx == NULL) + return ERR_PTR(-ENOMEM); + ++ kref_init(&ctx->ref); + ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size); + if (ctx->obj == NULL) { + kfree(ctx); +@@ -169,18 +170,18 @@ create_hw_context(struct drm_device *dev, + if (file_priv == NULL) + return ctx; + +- ctx->file_priv = file_priv; +- + ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID + 1, 0, + GFP_KERNEL); + if (ret < 0) + goto err_out; ++ ++ ctx->file_priv = file_priv; + ctx->id = ret; + + return ctx; + + err_out: +- do_destroy(ctx); ++ i915_gem_context_unreference(ctx); + return ERR_PTR(ret); + } + +@@ -226,7 +227,7 @@ static int create_default_context(struct drm_i915_private *dev_priv) + err_unpin: + i915_gem_object_unpin(ctx->obj); + err_destroy: +- do_destroy(ctx); ++ i915_gem_context_unreference(ctx); + return ret; + } + +@@ -262,6 +263,7 @@ void i915_gem_context_init(struct drm_device *dev) + void i915_gem_context_fini(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; ++ struct i915_hw_context *dctx = dev_priv->ring[RCS].default_context; + + if (dev_priv->hw_contexts_disabled) + return; +@@ -271,9 +273,8 @@ void i915_gem_context_fini(struct drm_device *dev) + * other code, leading to spurious errors. */ + intel_gpu_reset(dev); + +- i915_gem_object_unpin(dev_priv->ring[RCS].default_context->obj); +- +- do_destroy(dev_priv->ring[RCS].default_context); ++ i915_gem_object_unpin(dctx->obj); ++ i915_gem_context_unreference(dctx); + } + + static int context_idr_cleanup(int id, void *p, void *data) +@@ -282,8 +283,7 @@ static int context_idr_cleanup(int id, void *p, void *data) + + BUG_ON(id == DEFAULT_CONTEXT_ID); + +- do_destroy(ctx); +- ++ i915_gem_context_unreference(ctx); + return 0; + } + +@@ -512,8 +512,8 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, + return -ENOENT; + } + +- do_destroy(ctx); +- ++ idr_remove(&ctx->file_priv->context_idr, ctx->id); ++ i915_gem_context_unreference(ctx); + mutex_unlock(&dev->struct_mutex); + + DRM_DEBUG_DRIVER("HW context %d destroyed\n", args->ctx_id); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0105-drm-i915-simplify-DP-DDI-port-width-macros.patch b/patches.baytrail/0105-drm-i915-simplify-DP-DDI-port-width-macros.patch new file mode 100644 index 000000000000..9258ba8994b3 --- /dev/null +++ b/patches.baytrail/0105-drm-i915-simplify-DP-DDI-port-width-macros.patch @@ -0,0 +1,141 @@ +From cd360890c9138ab0b281ea33b43f832a7a298393 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 30 Apr 2013 14:01:40 +0200 +Subject: drm/i915: simplify DP/DDI port width macros + +If we ever leak a non-DP compliant port width through here, we have a +pretty serious issue. So just rip out all these WARNs - if we need +them it's probably better to have them at a central place where we +compute the dp lane count. + +Also use the new DDI width macro for FDI mode. + +Cc: Paulo Zanoni +Reviewed-by: Paulo Zanoni +[danvet: fixup the embarrassing s/intel_dp->DP/temp/ mistake Paulo +spotted.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 17aa6be9579eb204b426eeae146a43bf3dd05078) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 11 ++--------- + drivers/gpu/drm/i915/intel_ddi.c | 34 ++-------------------------------- + drivers/gpu/drm/i915/intel_dp.c | 12 +----------- + 3 files changed, 5 insertions(+), 52 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index ded019718295..fe029b6f70bf 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -2668,9 +2668,7 @@ + #define DP_PRE_EMPHASIS_SHIFT 22 + + /* How many wires to use. I guess 3 was too hard */ +-#define DP_PORT_WIDTH_1 (0 << 19) +-#define DP_PORT_WIDTH_2 (1 << 19) +-#define DP_PORT_WIDTH_4 (3 << 19) ++#define DP_PORT_WIDTH(width) (((width) - 1) << 19) + #define DP_PORT_WIDTH_MASK (7 << 19) + + /* Mystic DPCD version 1.1 special mode */ +@@ -4755,9 +4753,6 @@ + #define TRANS_DDI_EDP_INPUT_B_ONOFF (5<<12) + #define TRANS_DDI_EDP_INPUT_C_ONOFF (6<<12) + #define TRANS_DDI_BFI_ENABLE (1<<4) +-#define TRANS_DDI_PORT_WIDTH_X1 (0<<1) +-#define TRANS_DDI_PORT_WIDTH_X2 (1<<1) +-#define TRANS_DDI_PORT_WIDTH_X4 (3<<1) + + /* DisplayPort Transport Control */ + #define DP_TP_CTL_A 0x64040 +@@ -4801,9 +4796,7 @@ + #define DDI_BUF_PORT_REVERSAL (1<<16) + #define DDI_BUF_IS_IDLE (1<<7) + #define DDI_A_4_LANES (1<<4) +-#define DDI_PORT_WIDTH_X1 (0<<1) +-#define DDI_PORT_WIDTH_X2 (1<<1) +-#define DDI_PORT_WIDTH_X4 (3<<1) ++#define DDI_PORT_WIDTH(width) (((width) - 1) << 1) + #define DDI_INIT_DISPLAY_DETECTED (1<<0) + + /* DDI Buffer Translations */ +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 2a84a5edbf45..832401312630 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -687,22 +687,7 @@ static void intel_ddi_mode_set(struct drm_encoder *encoder, + + intel_dp->DP = intel_dig_port->saved_port_bits | + DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; +- switch (intel_dp->lane_count) { +- case 1: +- intel_dp->DP |= DDI_PORT_WIDTH_X1; +- break; +- case 2: +- intel_dp->DP |= DDI_PORT_WIDTH_X2; +- break; +- case 4: +- intel_dp->DP |= DDI_PORT_WIDTH_X4; +- break; +- default: +- intel_dp->DP |= DDI_PORT_WIDTH_X4; +- WARN(1, "Unexpected DP lane count %d\n", +- intel_dp->lane_count); +- break; +- } ++ intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count); + + if (intel_dp->has_audio) { + DRM_DEBUG_DRIVER("DP audio on pipe %c on DDI\n", +@@ -1031,22 +1016,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) + + temp |= TRANS_DDI_MODE_SELECT_DP_SST; + +- switch (intel_dp->lane_count) { +- case 1: +- temp |= TRANS_DDI_PORT_WIDTH_X1; +- break; +- case 2: +- temp |= TRANS_DDI_PORT_WIDTH_X2; +- break; +- case 4: +- temp |= TRANS_DDI_PORT_WIDTH_X4; +- break; +- default: +- temp |= TRANS_DDI_PORT_WIDTH_X4; +- WARN(1, "Unsupported lane count %d\n", +- intel_dp->lane_count); +- } +- ++ temp |= DDI_PORT_WIDTH(intel_dp->lane_count); + } else { + WARN(1, "Invalid encoder type %d for pipe %c\n", + intel_encoder->type, pipe_name(pipe)); +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 98c871d1084c..f0159cc5159a 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -901,18 +901,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + + /* Handle DP bits in common between all three register formats */ + intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; ++ intel_dp->DP |= DP_PORT_WIDTH(intel_dp->lane_count); + +- switch (intel_dp->lane_count) { +- case 1: +- intel_dp->DP |= DP_PORT_WIDTH_1; +- break; +- case 2: +- intel_dp->DP |= DP_PORT_WIDTH_2; +- break; +- case 4: +- intel_dp->DP |= DP_PORT_WIDTH_4; +- break; +- } + if (intel_dp->has_audio) { + DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n", + pipe_name(intel_crtc->pipe)); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0106-drm-i915-unreference-default-context-on-module-unloa.patch b/patches.baytrail/0106-drm-i915-unreference-default-context-on-module-unloa.patch new file mode 100644 index 000000000000..6ddeea0ea526 --- /dev/null +++ b/patches.baytrail/0106-drm-i915-unreference-default-context-on-module-unloa.patch @@ -0,0 +1,44 @@ +From e3b596e2379e1ee1cb7d9bc4ab69f4cedd10a9f3 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Fri, 3 May 2013 16:29:08 +0300 +Subject: drm/i915: unreference default context on module unload + +Before module unload is called, gpu_idle() will switch +to default context. This will increment ref count of base +object as the default context is 'running' on module unload +time. Unreference the drm object so that when context +is freed, base object is freed as well. + +v2: added comment to explain the refcounts (Ben Widawsky) + +Signed-off-by: Mika Kuoppala +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 168f83660211b9e059e3bc0638daaa01e9ea0b71) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_context.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index 47ffea61c9fa..fa7d4a74af22 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -274,6 +274,14 @@ void i915_gem_context_fini(struct drm_device *dev) + intel_gpu_reset(dev); + + i915_gem_object_unpin(dctx->obj); ++ ++ /* When default context is created and switched to, base object refcount ++ * will be 2 (+1 from object creation and +1 from do_switch()). ++ * i915_gem_context_fini() will be called after gpu_idle() has switched ++ * to default context. So we need to unreference the base object once ++ * to offset the do_switch part, so that i915_gem_context_unreference() ++ * can then free the base object correctly. */ ++ drm_gem_object_unreference(&dctx->obj->base); + i915_gem_context_unreference(dctx); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0107-drm-i915-fix-Haswell-pfit-power-well-check-v2.patch b/patches.baytrail/0107-drm-i915-fix-Haswell-pfit-power-well-check-v2.patch new file mode 100644 index 000000000000..395bf545fa02 --- /dev/null +++ b/patches.baytrail/0107-drm-i915-fix-Haswell-pfit-power-well-check-v2.patch @@ -0,0 +1,48 @@ +From a407105bbac2be1b34addecd46d8c2fa03c2e5ab Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Thu, 2 May 2013 15:30:47 -0700 +Subject: drm/i915: fix Haswell pfit power well check v2 + +We can't read the pfit regs if the power well is off, so use the cached +value. + +v2: re-add lost comment (Jesse) + make sure the crtc using the fitter is actually enabled (Jesse) + +Signed-off-by: Jesse Barnes +[danvet: Drop now unused dev_priv, as spotted by Mika.] +Reviewed-by: Mika Kuoppala +Reviewed-by: Paulo Zanoni +Tested-by: Paulo Zanoni +Signed-off-by: Daniel Vetter + +(cherry picked from commit 2b87f3b1bab1df814057ff551f4fc49c22a7fde9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 5c89c0a293e5..d3c76234abda 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5918,7 +5918,6 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + + static void haswell_modeset_global_resources(struct drm_device *dev) + { +- struct drm_i915_private *dev_priv = dev->dev_private; + bool enable = false; + struct intel_crtc *crtc; + struct intel_encoder *encoder; +@@ -5930,7 +5929,7 @@ static void haswell_modeset_global_resources(struct drm_device *dev) + * sequence that's not yet available. Just in case desktop eDP + * on PORT D is possible on haswell, too. */ + /* Even the eDP panel fitter is outside the always-on well. */ +- if (I915_READ(PF_WIN_SZ(crtc->pipe))) ++ if (crtc->config.pch_pfit.size && crtc->base.enabled) + enable = true; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0108-drm-i915-don-t-setup-hdmi-for-port-D-edp-in-ddi_init.patch b/patches.baytrail/0108-drm-i915-don-t-setup-hdmi-for-port-D-edp-in-ddi_init.patch new file mode 100644 index 000000000000..2690ef71ed5b --- /dev/null +++ b/patches.baytrail/0108-drm-i915-don-t-setup-hdmi-for-port-D-edp-in-ddi_init.patch @@ -0,0 +1,69 @@ +From b2e4342340619e75727176da4002db22418a2d8d Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 10 Apr 2013 23:28:35 +0200 +Subject: drm/i915: don't setup hdmi for port D edp in ddi_init +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +dp_init_connector adjusts the encoder type if it is a eDP panel. Use +that to decide whether we should set up a hdmi connector or not. + +To do so reorder the hdmi connector setup sequence in ddi_init a bit. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 21a8e6a4853b2ed39fa4c5188a710f2cf1b92026) +[dbasehore: Removed unused variable to solve conflict] +Signed-off-by: Derek Basehore + +Conflicts: + drivers/gpu/drm/i915/intel_ddi.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 832401312630..6953a971a4ea 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -1490,16 +1490,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port) + return; + } + +- if (port != PORT_A) { +- hdmi_connector = kzalloc(sizeof(struct intel_connector), +- GFP_KERNEL); +- if (!hdmi_connector) { +- kfree(dp_connector); +- kfree(intel_dig_port); +- return; +- } +- } +- + intel_encoder = &intel_dig_port->base; + encoder = &intel_encoder->base; + +@@ -1527,7 +1517,16 @@ void intel_ddi_init(struct drm_device *dev, enum port port) + intel_encoder->cloneable = false; + intel_encoder->hot_plug = intel_ddi_hot_plug; + +- if (hdmi_connector) +- intel_hdmi_init_connector(intel_dig_port, hdmi_connector); + intel_dp_init_connector(intel_dig_port, dp_connector); ++ ++ if (intel_encoder->type != INTEL_OUTPUT_EDP) { ++ hdmi_connector = kzalloc(sizeof(struct intel_connector), ++ GFP_KERNEL); ++ if (!hdmi_connector) { ++ return; ++ } ++ ++ intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port); ++ intel_hdmi_init_connector(intel_dig_port, hdmi_connector); ++ } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0109-drm-i915-put-context-upon-switching.patch b/patches.baytrail/0109-drm-i915-put-context-upon-switching.patch new file mode 100644 index 000000000000..ac7c0bc5986f --- /dev/null +++ b/patches.baytrail/0109-drm-i915-put-context-upon-switching.patch @@ -0,0 +1,114 @@ +From 0c39fc7722280edbc1ef64adceaaf9a644fe2a06 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Thu, 2 May 2013 16:48:07 +0300 +Subject: drm/i915: put context upon switching + +In order to be notified of when the context and all of its associated +objects is idle (for if the context maps to a ppgtt) we need a callback +from the retire handler. We can arrange this by using the kref_get/put +of the context for request tracking and by inserting a request to +demarque the switch away from the old context. + +[Ben: fixed minor error to patch compile, AND s/last_context/from/] +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter + +(cherry picked from commit 112522f6789581824903f6f72082b5b841a7f0f9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_context.c | 37 +++++++++++++++++++++------------ + drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +- + 2 files changed, 25 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index fa7d4a74af22..0407e0a39987 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -361,13 +361,13 @@ mi_set_context(struct intel_ring_buffer *ring, + static int do_switch(struct i915_hw_context *to) + { + struct intel_ring_buffer *ring = to->ring; +- struct drm_i915_gem_object *from_obj = ring->last_context_obj; ++ struct i915_hw_context *from = ring->last_context; + u32 hw_flags = 0; + int ret; + +- BUG_ON(from_obj != NULL && from_obj->pin_count == 0); ++ BUG_ON(from != NULL && from->obj != NULL && from->obj->pin_count == 0); + +- if (from_obj == to->obj) ++ if (from == to) + return 0; + + ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false, false); +@@ -390,7 +390,7 @@ static int do_switch(struct i915_hw_context *to) + + if (!to->is_initialized || is_default_context(to)) + hw_flags |= MI_RESTORE_INHIBIT; +- else if (WARN_ON_ONCE(from_obj == to->obj)) /* not yet expected */ ++ else if (WARN_ON_ONCE(from == to)) /* not yet expected */ + hw_flags |= MI_FORCE_RESTORE; + + ret = mi_set_context(ring, to, hw_flags); +@@ -405,9 +405,9 @@ static int do_switch(struct i915_hw_context *to) + * is a bit suboptimal because the retiring can occur simply after the + * MI_SET_CONTEXT instead of when the next seqno has completed. + */ +- if (from_obj != NULL) { +- from_obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION; +- i915_gem_object_move_to_active(from_obj, ring); ++ if (from != NULL) { ++ from->obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION; ++ i915_gem_object_move_to_active(from->obj, ring); + /* As long as MI_SET_CONTEXT is serializing, ie. it flushes the + * whole damn pipeline, we don't need to explicitly mark the + * object dirty. The only exception is that the context must be +@@ -415,15 +415,26 @@ static int do_switch(struct i915_hw_context *to) + * able to defer doing this until we know the object would be + * swapped, but there is no way to do that yet. + */ +- from_obj->dirty = 1; +- BUG_ON(from_obj->ring != ring); +- i915_gem_object_unpin(from_obj); ++ from->obj->dirty = 1; ++ BUG_ON(from->obj->ring != ring); ++ ++ ret = i915_add_request(ring, NULL, NULL); ++ if (ret) { ++ /* Too late, we've already scheduled a context switch. ++ * Try to undo the change so that the hw state is ++ * consistent with out tracking. In case of emergency, ++ * scream. ++ */ ++ WARN_ON(mi_set_context(ring, from, MI_RESTORE_INHIBIT)); ++ return ret; ++ } + +- drm_gem_object_unreference(&from_obj->base); ++ i915_gem_object_unpin(from->obj); ++ i915_gem_context_unreference(from); + } + +- drm_gem_object_reference(&to->obj->base); +- ring->last_context_obj = to->obj; ++ i915_gem_context_reference(to); ++ ring->last_context = to; + to->is_initialized = true; + + return 0; +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index d66208c2c48b..dac1614a1bca 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -135,7 +135,7 @@ struct intel_ring_buffer { + */ + bool itlb_before_ctx_switch; + struct i915_hw_context *default_context; +- struct drm_i915_gem_object *last_context_obj; ++ struct i915_hw_context *last_context; + + void *private; + }; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0110-drm-i915-add-context-into-request-struct.patch b/patches.baytrail/0110-drm-i915-add-context-into-request-struct.patch new file mode 100644 index 000000000000..67758eb5233f --- /dev/null +++ b/patches.baytrail/0110-drm-i915-add-context-into-request-struct.patch @@ -0,0 +1,95 @@ +From 52ce134310edec31deee95091661e17e7e56e932 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Thu, 2 May 2013 16:48:08 +0300 +Subject: drm/i915: add context into request struct + +Storing context reference into request struct +allows us to inspect context and its associated +objects when requests are retired. + +Both ppgtt and arb robustness work will need +this. + +Signed-off-by: Mika Kuoppala +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 0e50e96bf2d89c3415cb68aead301f485938f1ca) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 3 +++ + drivers/gpu/drm/i915/i915_gem.c | 24 ++++++++++++++++++------ + 2 files changed, 21 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index aac5740f1ee9..b5cdc737232f 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1271,6 +1271,9 @@ struct drm_i915_gem_request { + /** Postion in the ringbuffer of the end of the request */ + u32 tail; + ++ /** Context related to this request */ ++ struct i915_hw_context *ctx; ++ + /** Time at which this request was emitted, in jiffies. */ + unsigned long emitted_jiffies; + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 0a30088178b0..34a1d71655a3 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2053,6 +2053,11 @@ i915_add_request(struct intel_ring_buffer *ring, + request->seqno = intel_ring_get_seqno(ring); + request->ring = ring; + request->tail = request_ring_position; ++ request->ctx = ring->last_context; ++ ++ if (request->ctx) ++ i915_gem_context_reference(request->ctx); ++ + request->emitted_jiffies = jiffies; + was_empty = list_empty(&ring->request_list); + list_add_tail(&request->list, &ring->request_list); +@@ -2105,6 +2110,17 @@ i915_gem_request_remove_from_client(struct drm_i915_gem_request *request) + spin_unlock(&file_priv->mm.lock); + } + ++static void i915_gem_free_request(struct drm_i915_gem_request *request) ++{ ++ list_del(&request->list); ++ i915_gem_request_remove_from_client(request); ++ ++ if (request->ctx) ++ i915_gem_context_unreference(request->ctx); ++ ++ kfree(request); ++} ++ + static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, + struct intel_ring_buffer *ring) + { +@@ -2115,9 +2131,7 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, + struct drm_i915_gem_request, + list); + +- list_del(&request->list); +- i915_gem_request_remove_from_client(request); +- kfree(request); ++ i915_gem_free_request(request); + } + + while (!list_empty(&ring->active_list)) { +@@ -2208,9 +2222,7 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) + */ + ring->last_retired_head = request->tail; + +- list_del(&request->list); +- i915_gem_request_remove_from_client(request); +- kfree(request); ++ i915_gem_free_request(request); + } + + /* Move any buffers on the active list that are no longer referenced +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0111-drm-i915-fix-up-adjusted_mode-tracking-for-interlace.patch b/patches.baytrail/0111-drm-i915-fix-up-adjusted_mode-tracking-for-interlace.patch new file mode 100644 index 000000000000..05a06d4e3a63 --- /dev/null +++ b/patches.baytrail/0111-drm-i915-fix-up-adjusted_mode-tracking-for-interlace.patch @@ -0,0 +1,71 @@ +From a29147460dad896ebc2de769daa9dfaec7a3d4c3 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 3 May 2013 11:49:51 +0200 +Subject: drm/i915: fix up adjusted_mode tracking for interlaced modes + +With the hw state readout&check code it's important that the values we +keep around are the canonical ones. Unfortunately when adding the pipe +timings readout support I've missed that the write side adjusts the +timings in the pipe config. + +Fix this up and so prevent the unsightly WARN noise in dmesg. This +regression has been introduced in + +commit 1bd1bd806037af04dd1d7bdd39b2b04090c10d2c +Author: Daniel Vetter +Date: Mon Apr 29 21:56:12 2013 +0200 + + drm/i915: hw state readout support for pipe timings + +Reported-by: Paulo Zanoni +Cc: Mika Kuoppala +Reviewed-by: Paulo Zanoni +Tested-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 4d8a62eac3caad710ef030aab25248d56693a8f1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index d3c76234abda..dbef6715aa86 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4682,12 +4682,17 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc, + struct drm_i915_private *dev_priv = dev->dev_private; + enum pipe pipe = intel_crtc->pipe; + enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; +- uint32_t vsyncshift; ++ uint32_t vsyncshift, crtc_vtotal, crtc_vblank_end; ++ ++ /* We need to be careful not to changed the adjusted mode, for otherwise ++ * the hw state checker will get angry at the mismatch. */ ++ crtc_vtotal = adjusted_mode->crtc_vtotal; ++ crtc_vblank_end = adjusted_mode->crtc_vblank_end; + + if (!IS_GEN2(dev) && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { + /* the chip adds 2 halflines automatically */ +- adjusted_mode->crtc_vtotal -= 1; +- adjusted_mode->crtc_vblank_end -= 1; ++ crtc_vtotal -= 1; ++ crtc_vblank_end -= 1; + vsyncshift = adjusted_mode->crtc_hsync_start + - adjusted_mode->crtc_htotal / 2; + } else { +@@ -4709,10 +4714,10 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc, + + I915_WRITE(VTOTAL(cpu_transcoder), + (adjusted_mode->crtc_vdisplay - 1) | +- ((adjusted_mode->crtc_vtotal - 1) << 16)); ++ ((crtc_vtotal - 1) << 16)); + I915_WRITE(VBLANK(cpu_transcoder), + (adjusted_mode->crtc_vblank_start - 1) | +- ((adjusted_mode->crtc_vblank_end - 1) << 16)); ++ ((crtc_vblank_end - 1) << 16)); + I915_WRITE(VSYNC(cpu_transcoder), + (adjusted_mode->crtc_vsync_start - 1) | + ((adjusted_mode->crtc_vsync_end - 1) << 16)); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0112-drm-i915-s-TRANSCONF-PCH_TRANSCONF.patch b/patches.baytrail/0112-drm-i915-s-TRANSCONF-PCH_TRANSCONF.patch new file mode 100644 index 000000000000..3a1734c6fc08 --- /dev/null +++ b/patches.baytrail/0112-drm-i915-s-TRANSCONF-PCH_TRANSCONF.patch @@ -0,0 +1,195 @@ +From 1e81b3c7c04b4627e19632c54a6b309d11321d3a Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 3 May 2013 11:49:46 +0200 +Subject: drm/i915: s/TRANSCONF/PCH_TRANSCONF/ + +Every time I read hsw code I get completely confused about this. So +call it what it is more explicitly. + +Also, add an LPT_TRANSCONF for the pch transcoder A and use it in +lpt-only code, to really unconfuse me. + +v2: s/plane/pipe/ in the TRANSCONF #define (Paulo). + +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit ab9412ba06484cdfd82bdb748689024efe2221fe) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 7 ++++--- + drivers/gpu/drm/i915/i915_ums.c | 8 ++++---- + drivers/gpu/drm/i915/intel_display.c | 30 +++++++++++++++--------------- + 3 files changed, 23 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index fe029b6f70bf..1ddd724094f5 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -4060,9 +4060,10 @@ + #define TRANSDPLINK_M2(pipe) _PIPE(pipe, _TRANSA_DP_LINK_M2, _TRANSB_DP_LINK_M2) + #define TRANSDPLINK_N2(pipe) _PIPE(pipe, _TRANSA_DP_LINK_N2, _TRANSB_DP_LINK_N2) + +-#define _TRANSACONF 0xf0008 +-#define _TRANSBCONF 0xf1008 +-#define TRANSCONF(plane) _PIPE(plane, _TRANSACONF, _TRANSBCONF) ++#define _PCH_TRANSACONF 0xf0008 ++#define _PCH_TRANSBCONF 0xf1008 ++#define PCH_TRANSCONF(pipe) _PIPE(pipe, _PCH_TRANSACONF, _PCH_TRANSBCONF) ++#define LPT_TRANSCONF _PCH_TRANSACONF /* lpt has only one transcoder */ + #define TRANS_DISABLE (0<<31) + #define TRANS_ENABLE (1<<31) + #define TRANS_STATE_MASK (1<<30) +diff --git a/drivers/gpu/drm/i915/i915_ums.c b/drivers/gpu/drm/i915/i915_ums.c +index 985a09716237..75960dd81b5a 100644 +--- a/drivers/gpu/drm/i915/i915_ums.c ++++ b/drivers/gpu/drm/i915/i915_ums.c +@@ -148,7 +148,7 @@ void i915_save_display_reg(struct drm_device *dev) + dev_priv->regfile.savePFA_WIN_SZ = I915_READ(_PFA_WIN_SZ); + dev_priv->regfile.savePFA_WIN_POS = I915_READ(_PFA_WIN_POS); + +- dev_priv->regfile.saveTRANSACONF = I915_READ(_TRANSACONF); ++ dev_priv->regfile.saveTRANSACONF = I915_READ(_PCH_TRANSACONF); + dev_priv->regfile.saveTRANS_HTOTAL_A = I915_READ(_TRANS_HTOTAL_A); + dev_priv->regfile.saveTRANS_HBLANK_A = I915_READ(_TRANS_HBLANK_A); + dev_priv->regfile.saveTRANS_HSYNC_A = I915_READ(_TRANS_HSYNC_A); +@@ -205,7 +205,7 @@ void i915_save_display_reg(struct drm_device *dev) + dev_priv->regfile.savePFB_WIN_SZ = I915_READ(_PFB_WIN_SZ); + dev_priv->regfile.savePFB_WIN_POS = I915_READ(_PFB_WIN_POS); + +- dev_priv->regfile.saveTRANSBCONF = I915_READ(_TRANSBCONF); ++ dev_priv->regfile.saveTRANSBCONF = I915_READ(_PCH_TRANSBCONF); + dev_priv->regfile.saveTRANS_HTOTAL_B = I915_READ(_TRANS_HTOTAL_B); + dev_priv->regfile.saveTRANS_HBLANK_B = I915_READ(_TRANS_HBLANK_B); + dev_priv->regfile.saveTRANS_HSYNC_B = I915_READ(_TRANS_HSYNC_B); +@@ -379,7 +379,7 @@ void i915_restore_display_reg(struct drm_device *dev) + I915_WRITE(_PFA_WIN_SZ, dev_priv->regfile.savePFA_WIN_SZ); + I915_WRITE(_PFA_WIN_POS, dev_priv->regfile.savePFA_WIN_POS); + +- I915_WRITE(_TRANSACONF, dev_priv->regfile.saveTRANSACONF); ++ I915_WRITE(_PCH_TRANSACONF, dev_priv->regfile.saveTRANSACONF); + I915_WRITE(_TRANS_HTOTAL_A, dev_priv->regfile.saveTRANS_HTOTAL_A); + I915_WRITE(_TRANS_HBLANK_A, dev_priv->regfile.saveTRANS_HBLANK_A); + I915_WRITE(_TRANS_HSYNC_A, dev_priv->regfile.saveTRANS_HSYNC_A); +@@ -448,7 +448,7 @@ void i915_restore_display_reg(struct drm_device *dev) + I915_WRITE(_PFB_WIN_SZ, dev_priv->regfile.savePFB_WIN_SZ); + I915_WRITE(_PFB_WIN_POS, dev_priv->regfile.savePFB_WIN_POS); + +- I915_WRITE(_TRANSBCONF, dev_priv->regfile.saveTRANSBCONF); ++ I915_WRITE(_PCH_TRANSBCONF, dev_priv->regfile.saveTRANSBCONF); + I915_WRITE(_TRANS_HTOTAL_B, dev_priv->regfile.saveTRANS_HTOTAL_B); + I915_WRITE(_TRANS_HBLANK_B, dev_priv->regfile.saveTRANS_HBLANK_B); + I915_WRITE(_TRANS_HSYNC_B, dev_priv->regfile.saveTRANS_HSYNC_B); +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index dbef6715aa86..a9386819ed19 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1206,14 +1206,14 @@ static void assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) + WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n"); + } + +-static void assert_transcoder_disabled(struct drm_i915_private *dev_priv, +- enum pipe pipe) ++static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, ++ enum pipe pipe) + { + int reg; + u32 val; + bool enabled; + +- reg = TRANSCONF(pipe); ++ reg = PCH_TRANSCONF(pipe); + val = I915_READ(reg); + enabled = !!(val & TRANS_ENABLE); + WARN(enabled, +@@ -1565,7 +1565,7 @@ static void intel_disable_pch_pll(struct intel_crtc *intel_crtc) + DRM_DEBUG_KMS("disabling PCH PLL %x\n", pll->pll_reg); + + /* Make sure transcoder isn't still depending on us */ +- assert_transcoder_disabled(dev_priv, intel_crtc->pipe); ++ assert_pch_transcoder_disabled(dev_priv, intel_crtc->pipe); + + reg = pll->pll_reg; + val = I915_READ(reg); +@@ -1605,7 +1605,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, + I915_WRITE(reg, val); + } + +- reg = TRANSCONF(pipe); ++ reg = PCH_TRANSCONF(pipe); + val = I915_READ(reg); + pipeconf_val = I915_READ(PIPECONF(pipe)); + +@@ -1659,8 +1659,8 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv, + else + val |= TRANS_PROGRESSIVE; + +- I915_WRITE(TRANSCONF(TRANSCODER_A), val); +- if (wait_for(I915_READ(_TRANSACONF) & TRANS_STATE_ENABLE, 100)) ++ I915_WRITE(LPT_TRANSCONF, val); ++ if (wait_for(I915_READ(LPT_TRANSCONF) & TRANS_STATE_ENABLE, 100)) + DRM_ERROR("Failed to enable PCH transcoder\n"); + } + +@@ -1677,7 +1677,7 @@ static void ironlake_disable_pch_transcoder(struct drm_i915_private *dev_priv, + /* Ports must be off as well */ + assert_pch_ports_disabled(dev_priv, pipe); + +- reg = TRANSCONF(pipe); ++ reg = PCH_TRANSCONF(pipe); + val = I915_READ(reg); + val &= ~TRANS_ENABLE; + I915_WRITE(reg, val); +@@ -1698,11 +1698,11 @@ static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv) + { + u32 val; + +- val = I915_READ(_TRANSACONF); ++ val = I915_READ(LPT_TRANSCONF); + val &= ~TRANS_ENABLE; +- I915_WRITE(_TRANSACONF, val); ++ I915_WRITE(LPT_TRANSCONF, val); + /* wait for PCH transcoder off, transcoder state */ +- if (wait_for((I915_READ(_TRANSACONF) & TRANS_STATE_ENABLE) == 0, 50)) ++ if (wait_for((I915_READ(LPT_TRANSCONF) & TRANS_STATE_ENABLE) == 0, 50)) + DRM_ERROR("Failed to disable PCH transcoder\n"); + + /* Workaround: clear timing override bit. */ +@@ -3011,7 +3011,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) + int pipe = intel_crtc->pipe; + u32 reg, temp; + +- assert_transcoder_disabled(dev_priv, pipe); ++ assert_pch_transcoder_disabled(dev_priv, pipe); + + /* Write the TU size bits before fdi link training, so that error + * detection works. */ +@@ -3115,7 +3115,7 @@ static void lpt_pch_enable(struct drm_crtc *crtc) + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; + +- assert_transcoder_disabled(dev_priv, TRANSCODER_A); ++ assert_pch_transcoder_disabled(dev_priv, TRANSCODER_A); + + lpt_program_iclkip(crtc); + +@@ -5906,7 +5906,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + if (!(tmp & PIPECONF_ENABLE)) + return false; + +- if (I915_READ(TRANSCONF(crtc->pipe)) & TRANS_ENABLE) { ++ if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) { + pipe_config->has_pch_encoder = true; + + tmp = I915_READ(FDI_RX_CTL(crtc->pipe)); +@@ -6054,7 +6054,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + */ + tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); + if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(PORT_E) && +- I915_READ(TRANSCONF(PIPE_A)) & TRANS_ENABLE) { ++ I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) { + pipe_config->has_pch_encoder = true; + + tmp = I915_READ(FDI_RX_CTL(PIPE_A)); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0113-drm-i915-PCH_-prefix-for-transcoder-timings.patch b/patches.baytrail/0113-drm-i915-PCH_-prefix-for-transcoder-timings.patch new file mode 100644 index 000000000000..5bd3d5005b7d --- /dev/null +++ b/patches.baytrail/0113-drm-i915-PCH_-prefix-for-transcoder-timings.patch @@ -0,0 +1,267 @@ +From 85799446ff2f1d06aef076526ffb5dbc6c38a6ee Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 3 May 2013 11:49:47 +0200 +Subject: drm/i915: PCH_ prefix for transcoder timings + +While at it, also extract a common helper to copy the timings from the +cpu transcoder to the pch transcoder. That way it's really explicit +how the lpt transcoder is hardcoded. + +v2: +- Re-align #defines properly (Paulo). +- Use cpu_transcoder when copying pipe timings (Paulo). +- s/intel_pch_transcoder_enable/intel_pch_transcoder_set_timings/ + since we already have a pch transcoder enable function, and this is + clearer, too. +- Fixup 80 char line overflow in intel_display.c. I've opted to ignore + this in i915_reg.h and i915_ums.c since meh. + +Cc: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 275f01b2694a52d13c32358d17d594ec9aba55e3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 70 ++++++++++++++++++------------------ + drivers/gpu/drm/i915/i915_ums.c | 48 ++++++++++++------------- + drivers/gpu/drm/i915/intel_display.c | 42 +++++++++++++--------- + 3 files changed, 85 insertions(+), 75 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 1ddd724094f5..b8ac1810b753 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -3929,25 +3929,25 @@ + + /* transcoder */ + +-#define _TRANS_HTOTAL_A 0xe0000 +-#define TRANS_HTOTAL_SHIFT 16 +-#define TRANS_HACTIVE_SHIFT 0 +-#define _TRANS_HBLANK_A 0xe0004 +-#define TRANS_HBLANK_END_SHIFT 16 +-#define TRANS_HBLANK_START_SHIFT 0 +-#define _TRANS_HSYNC_A 0xe0008 +-#define TRANS_HSYNC_END_SHIFT 16 +-#define TRANS_HSYNC_START_SHIFT 0 +-#define _TRANS_VTOTAL_A 0xe000c +-#define TRANS_VTOTAL_SHIFT 16 +-#define TRANS_VACTIVE_SHIFT 0 +-#define _TRANS_VBLANK_A 0xe0010 +-#define TRANS_VBLANK_END_SHIFT 16 +-#define TRANS_VBLANK_START_SHIFT 0 +-#define _TRANS_VSYNC_A 0xe0014 +-#define TRANS_VSYNC_END_SHIFT 16 +-#define TRANS_VSYNC_START_SHIFT 0 +-#define _TRANS_VSYNCSHIFT_A 0xe0028 ++#define _PCH_TRANS_HTOTAL_A 0xe0000 ++#define TRANS_HTOTAL_SHIFT 16 ++#define TRANS_HACTIVE_SHIFT 0 ++#define _PCH_TRANS_HBLANK_A 0xe0004 ++#define TRANS_HBLANK_END_SHIFT 16 ++#define TRANS_HBLANK_START_SHIFT 0 ++#define _PCH_TRANS_HSYNC_A 0xe0008 ++#define TRANS_HSYNC_END_SHIFT 16 ++#define TRANS_HSYNC_START_SHIFT 0 ++#define _PCH_TRANS_VTOTAL_A 0xe000c ++#define TRANS_VTOTAL_SHIFT 16 ++#define TRANS_VACTIVE_SHIFT 0 ++#define _PCH_TRANS_VBLANK_A 0xe0010 ++#define TRANS_VBLANK_END_SHIFT 16 ++#define TRANS_VBLANK_START_SHIFT 0 ++#define _PCH_TRANS_VSYNC_A 0xe0014 ++#define TRANS_VSYNC_END_SHIFT 16 ++#define TRANS_VSYNC_START_SHIFT 0 ++#define _PCH_TRANS_VSYNCSHIFT_A 0xe0028 + + #define _TRANSA_DATA_M1 0xe0030 + #define _TRANSA_DATA_N1 0xe0034 +@@ -4025,22 +4025,22 @@ + #define HSW_TVIDEO_DIP_VSC_DATA(trans) \ + _TRANSCODER(trans, HSW_VIDEO_DIP_VSC_DATA_A, HSW_VIDEO_DIP_VSC_DATA_B) + +-#define _TRANS_HTOTAL_B 0xe1000 +-#define _TRANS_HBLANK_B 0xe1004 +-#define _TRANS_HSYNC_B 0xe1008 +-#define _TRANS_VTOTAL_B 0xe100c +-#define _TRANS_VBLANK_B 0xe1010 +-#define _TRANS_VSYNC_B 0xe1014 +-#define _TRANS_VSYNCSHIFT_B 0xe1028 +- +-#define TRANS_HTOTAL(pipe) _PIPE(pipe, _TRANS_HTOTAL_A, _TRANS_HTOTAL_B) +-#define TRANS_HBLANK(pipe) _PIPE(pipe, _TRANS_HBLANK_A, _TRANS_HBLANK_B) +-#define TRANS_HSYNC(pipe) _PIPE(pipe, _TRANS_HSYNC_A, _TRANS_HSYNC_B) +-#define TRANS_VTOTAL(pipe) _PIPE(pipe, _TRANS_VTOTAL_A, _TRANS_VTOTAL_B) +-#define TRANS_VBLANK(pipe) _PIPE(pipe, _TRANS_VBLANK_A, _TRANS_VBLANK_B) +-#define TRANS_VSYNC(pipe) _PIPE(pipe, _TRANS_VSYNC_A, _TRANS_VSYNC_B) +-#define TRANS_VSYNCSHIFT(pipe) _PIPE(pipe, _TRANS_VSYNCSHIFT_A, \ +- _TRANS_VSYNCSHIFT_B) ++#define _PCH_TRANS_HTOTAL_B 0xe1000 ++#define _PCH_TRANS_HBLANK_B 0xe1004 ++#define _PCH_TRANS_HSYNC_B 0xe1008 ++#define _PCH_TRANS_VTOTAL_B 0xe100c ++#define _PCH_TRANS_VBLANK_B 0xe1010 ++#define _PCH_TRANS_VSYNC_B 0xe1014 ++#define _PCH_TRANS_VSYNCSHIFT_B 0xe1028 ++ ++#define PCH_TRANS_HTOTAL(pipe) _PIPE(pipe, _PCH_TRANS_HTOTAL_A, _PCH_TRANS_HTOTAL_B) ++#define PCH_TRANS_HBLANK(pipe) _PIPE(pipe, _PCH_TRANS_HBLANK_A, _PCH_TRANS_HBLANK_B) ++#define PCH_TRANS_HSYNC(pipe) _PIPE(pipe, _PCH_TRANS_HSYNC_A, _PCH_TRANS_HSYNC_B) ++#define PCH_TRANS_VTOTAL(pipe) _PIPE(pipe, _PCH_TRANS_VTOTAL_A, _PCH_TRANS_VTOTAL_B) ++#define PCH_TRANS_VBLANK(pipe) _PIPE(pipe, _PCH_TRANS_VBLANK_A, _PCH_TRANS_VBLANK_B) ++#define PCH_TRANS_VSYNC(pipe) _PIPE(pipe, _PCH_TRANS_VSYNC_A, _PCH_TRANS_VSYNC_B) ++#define PCH_TRANS_VSYNCSHIFT(pipe) _PIPE(pipe, _PCH_TRANS_VSYNCSHIFT_A, \ ++ _PCH_TRANS_VSYNCSHIFT_B) + + #define _TRANSB_DATA_M1 0xe1030 + #define _TRANSB_DATA_N1 0xe1034 +diff --git a/drivers/gpu/drm/i915/i915_ums.c b/drivers/gpu/drm/i915/i915_ums.c +index 75960dd81b5a..4168d2b6b4f1 100644 +--- a/drivers/gpu/drm/i915/i915_ums.c ++++ b/drivers/gpu/drm/i915/i915_ums.c +@@ -149,12 +149,12 @@ void i915_save_display_reg(struct drm_device *dev) + dev_priv->regfile.savePFA_WIN_POS = I915_READ(_PFA_WIN_POS); + + dev_priv->regfile.saveTRANSACONF = I915_READ(_PCH_TRANSACONF); +- dev_priv->regfile.saveTRANS_HTOTAL_A = I915_READ(_TRANS_HTOTAL_A); +- dev_priv->regfile.saveTRANS_HBLANK_A = I915_READ(_TRANS_HBLANK_A); +- dev_priv->regfile.saveTRANS_HSYNC_A = I915_READ(_TRANS_HSYNC_A); +- dev_priv->regfile.saveTRANS_VTOTAL_A = I915_READ(_TRANS_VTOTAL_A); +- dev_priv->regfile.saveTRANS_VBLANK_A = I915_READ(_TRANS_VBLANK_A); +- dev_priv->regfile.saveTRANS_VSYNC_A = I915_READ(_TRANS_VSYNC_A); ++ dev_priv->regfile.saveTRANS_HTOTAL_A = I915_READ(_PCH_TRANS_HTOTAL_A); ++ dev_priv->regfile.saveTRANS_HBLANK_A = I915_READ(_PCH_TRANS_HBLANK_A); ++ dev_priv->regfile.saveTRANS_HSYNC_A = I915_READ(_PCH_TRANS_HSYNC_A); ++ dev_priv->regfile.saveTRANS_VTOTAL_A = I915_READ(_PCH_TRANS_VTOTAL_A); ++ dev_priv->regfile.saveTRANS_VBLANK_A = I915_READ(_PCH_TRANS_VBLANK_A); ++ dev_priv->regfile.saveTRANS_VSYNC_A = I915_READ(_PCH_TRANS_VSYNC_A); + } + + dev_priv->regfile.saveDSPACNTR = I915_READ(_DSPACNTR); +@@ -206,12 +206,12 @@ void i915_save_display_reg(struct drm_device *dev) + dev_priv->regfile.savePFB_WIN_POS = I915_READ(_PFB_WIN_POS); + + dev_priv->regfile.saveTRANSBCONF = I915_READ(_PCH_TRANSBCONF); +- dev_priv->regfile.saveTRANS_HTOTAL_B = I915_READ(_TRANS_HTOTAL_B); +- dev_priv->regfile.saveTRANS_HBLANK_B = I915_READ(_TRANS_HBLANK_B); +- dev_priv->regfile.saveTRANS_HSYNC_B = I915_READ(_TRANS_HSYNC_B); +- dev_priv->regfile.saveTRANS_VTOTAL_B = I915_READ(_TRANS_VTOTAL_B); +- dev_priv->regfile.saveTRANS_VBLANK_B = I915_READ(_TRANS_VBLANK_B); +- dev_priv->regfile.saveTRANS_VSYNC_B = I915_READ(_TRANS_VSYNC_B); ++ dev_priv->regfile.saveTRANS_HTOTAL_B = I915_READ(_PCH_TRANS_HTOTAL_B); ++ dev_priv->regfile.saveTRANS_HBLANK_B = I915_READ(_PCH_TRANS_HBLANK_B); ++ dev_priv->regfile.saveTRANS_HSYNC_B = I915_READ(_PCH_TRANS_HSYNC_B); ++ dev_priv->regfile.saveTRANS_VTOTAL_B = I915_READ(_PCH_TRANS_VTOTAL_B); ++ dev_priv->regfile.saveTRANS_VBLANK_B = I915_READ(_PCH_TRANS_VBLANK_B); ++ dev_priv->regfile.saveTRANS_VSYNC_B = I915_READ(_PCH_TRANS_VSYNC_B); + } + + dev_priv->regfile.saveDSPBCNTR = I915_READ(_DSPBCNTR); +@@ -380,12 +380,12 @@ void i915_restore_display_reg(struct drm_device *dev) + I915_WRITE(_PFA_WIN_POS, dev_priv->regfile.savePFA_WIN_POS); + + I915_WRITE(_PCH_TRANSACONF, dev_priv->regfile.saveTRANSACONF); +- I915_WRITE(_TRANS_HTOTAL_A, dev_priv->regfile.saveTRANS_HTOTAL_A); +- I915_WRITE(_TRANS_HBLANK_A, dev_priv->regfile.saveTRANS_HBLANK_A); +- I915_WRITE(_TRANS_HSYNC_A, dev_priv->regfile.saveTRANS_HSYNC_A); +- I915_WRITE(_TRANS_VTOTAL_A, dev_priv->regfile.saveTRANS_VTOTAL_A); +- I915_WRITE(_TRANS_VBLANK_A, dev_priv->regfile.saveTRANS_VBLANK_A); +- I915_WRITE(_TRANS_VSYNC_A, dev_priv->regfile.saveTRANS_VSYNC_A); ++ I915_WRITE(_PCH_TRANS_HTOTAL_A, dev_priv->regfile.saveTRANS_HTOTAL_A); ++ I915_WRITE(_PCH_TRANS_HBLANK_A, dev_priv->regfile.saveTRANS_HBLANK_A); ++ I915_WRITE(_PCH_TRANS_HSYNC_A, dev_priv->regfile.saveTRANS_HSYNC_A); ++ I915_WRITE(_PCH_TRANS_VTOTAL_A, dev_priv->regfile.saveTRANS_VTOTAL_A); ++ I915_WRITE(_PCH_TRANS_VBLANK_A, dev_priv->regfile.saveTRANS_VBLANK_A); ++ I915_WRITE(_PCH_TRANS_VSYNC_A, dev_priv->regfile.saveTRANS_VSYNC_A); + } + + /* Restore plane info */ +@@ -449,12 +449,12 @@ void i915_restore_display_reg(struct drm_device *dev) + I915_WRITE(_PFB_WIN_POS, dev_priv->regfile.savePFB_WIN_POS); + + I915_WRITE(_PCH_TRANSBCONF, dev_priv->regfile.saveTRANSBCONF); +- I915_WRITE(_TRANS_HTOTAL_B, dev_priv->regfile.saveTRANS_HTOTAL_B); +- I915_WRITE(_TRANS_HBLANK_B, dev_priv->regfile.saveTRANS_HBLANK_B); +- I915_WRITE(_TRANS_HSYNC_B, dev_priv->regfile.saveTRANS_HSYNC_B); +- I915_WRITE(_TRANS_VTOTAL_B, dev_priv->regfile.saveTRANS_VTOTAL_B); +- I915_WRITE(_TRANS_VBLANK_B, dev_priv->regfile.saveTRANS_VBLANK_B); +- I915_WRITE(_TRANS_VSYNC_B, dev_priv->regfile.saveTRANS_VSYNC_B); ++ I915_WRITE(_PCH_TRANS_HTOTAL_B, dev_priv->regfile.saveTRANS_HTOTAL_B); ++ I915_WRITE(_PCH_TRANS_HBLANK_B, dev_priv->regfile.saveTRANS_HBLANK_B); ++ I915_WRITE(_PCH_TRANS_HSYNC_B, dev_priv->regfile.saveTRANS_HSYNC_B); ++ I915_WRITE(_PCH_TRANS_VTOTAL_B, dev_priv->regfile.saveTRANS_VTOTAL_B); ++ I915_WRITE(_PCH_TRANS_VBLANK_B, dev_priv->regfile.saveTRANS_VBLANK_B); ++ I915_WRITE(_PCH_TRANS_VSYNC_B, dev_priv->regfile.saveTRANS_VSYNC_B); + } + + /* Restore plane info */ +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index a9386819ed19..e051ca86248e 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2995,6 +2995,30 @@ static void lpt_program_iclkip(struct drm_crtc *crtc) + mutex_unlock(&dev_priv->dpio_lock); + } + ++static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc, ++ enum pipe pch_transcoder) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ enum transcoder cpu_transcoder = crtc->config.cpu_transcoder; ++ ++ I915_WRITE(PCH_TRANS_HTOTAL(pch_transcoder), ++ I915_READ(HTOTAL(cpu_transcoder))); ++ I915_WRITE(PCH_TRANS_HBLANK(pch_transcoder), ++ I915_READ(HBLANK(cpu_transcoder))); ++ I915_WRITE(PCH_TRANS_HSYNC(pch_transcoder), ++ I915_READ(HSYNC(cpu_transcoder))); ++ ++ I915_WRITE(PCH_TRANS_VTOTAL(pch_transcoder), ++ I915_READ(VTOTAL(cpu_transcoder))); ++ I915_WRITE(PCH_TRANS_VBLANK(pch_transcoder), ++ I915_READ(VBLANK(cpu_transcoder))); ++ I915_WRITE(PCH_TRANS_VSYNC(pch_transcoder), ++ I915_READ(VSYNC(cpu_transcoder))); ++ I915_WRITE(PCH_TRANS_VSYNCSHIFT(pch_transcoder), ++ I915_READ(VSYNCSHIFT(cpu_transcoder))); ++} ++ + /* + * Enable PCH resources required for PCH ports: + * - PCH PLLs +@@ -3058,14 +3082,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) + + /* set transcoder timing, panel must allow it */ + assert_panel_unlocked(dev_priv, pipe); +- I915_WRITE(TRANS_HTOTAL(pipe), I915_READ(HTOTAL(pipe))); +- I915_WRITE(TRANS_HBLANK(pipe), I915_READ(HBLANK(pipe))); +- I915_WRITE(TRANS_HSYNC(pipe), I915_READ(HSYNC(pipe))); +- +- I915_WRITE(TRANS_VTOTAL(pipe), I915_READ(VTOTAL(pipe))); +- I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe))); +- I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe))); +- I915_WRITE(TRANS_VSYNCSHIFT(pipe), I915_READ(VSYNCSHIFT(pipe))); ++ ironlake_pch_transcoder_set_timings(intel_crtc, pipe); + + intel_fdi_normal_train(crtc); + +@@ -3120,14 +3137,7 @@ static void lpt_pch_enable(struct drm_crtc *crtc) + lpt_program_iclkip(crtc); + + /* Set transcoder timing. */ +- I915_WRITE(_TRANS_HTOTAL_A, I915_READ(HTOTAL(cpu_transcoder))); +- I915_WRITE(_TRANS_HBLANK_A, I915_READ(HBLANK(cpu_transcoder))); +- I915_WRITE(_TRANS_HSYNC_A, I915_READ(HSYNC(cpu_transcoder))); +- +- I915_WRITE(_TRANS_VTOTAL_A, I915_READ(VTOTAL(cpu_transcoder))); +- I915_WRITE(_TRANS_VBLANK_A, I915_READ(VBLANK(cpu_transcoder))); +- I915_WRITE(_TRANS_VSYNC_A, I915_READ(VSYNC(cpu_transcoder))); +- I915_WRITE(_TRANS_VSYNCSHIFT_A, I915_READ(VSYNCSHIFT(cpu_transcoder))); ++ ironlake_pch_transcoder_set_timings(intel_crtc, PIPE_A); + + lpt_enable_pch_transcoder(dev_priv, cpu_transcoder); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0114-drm-i915-make-set_m_n-functions-static.patch b/patches.baytrail/0114-drm-i915-make-set_m_n-functions-static.patch new file mode 100644 index 000000000000..4653d1c65d20 --- /dev/null +++ b/patches.baytrail/0114-drm-i915-make-set_m_n-functions-static.patch @@ -0,0 +1,123 @@ +From ce4074ac37288d6f94d1d93e8dabdaa795701ab5 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 3 May 2013 11:49:48 +0200 +Subject: drm/i915: make set_m_n functions static + +This is possible thanks to moving the m/n stuff into pipe_config. + +Unfortunately we need to move them a bit to avoid forward +declarations. + +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit b551842d4d92cd337cc2af27947cc53e09fe34ab) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 68 ++++++++++++++++++------------------ + drivers/gpu/drm/i915/intel_drv.h | 4 --- + 2 files changed, 34 insertions(+), 38 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index e051ca86248e..27da171b6411 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4388,6 +4388,40 @@ static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv) + intel_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val); + } + ++static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc, ++ struct intel_link_m_n *m_n) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int pipe = crtc->pipe; ++ ++ I915_WRITE(TRANSDATA_M1(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m); ++ I915_WRITE(TRANSDATA_N1(pipe), m_n->gmch_n); ++ I915_WRITE(TRANSDPLINK_M1(pipe), m_n->link_m); ++ I915_WRITE(TRANSDPLINK_N1(pipe), m_n->link_n); ++} ++ ++static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, ++ struct intel_link_m_n *m_n) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int pipe = crtc->pipe; ++ enum transcoder transcoder = crtc->config.cpu_transcoder; ++ ++ if (INTEL_INFO(dev)->gen >= 5) { ++ I915_WRITE(PIPE_DATA_M1(transcoder), TU_SIZE(m_n->tu) | m_n->gmch_m); ++ I915_WRITE(PIPE_DATA_N1(transcoder), m_n->gmch_n); ++ I915_WRITE(PIPE_LINK_M1(transcoder), m_n->link_m); ++ I915_WRITE(PIPE_LINK_N1(transcoder), m_n->link_n); ++ } else { ++ I915_WRITE(PIPE_GMCH_DATA_M(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m); ++ I915_WRITE(PIPE_GMCH_DATA_N(pipe), m_n->gmch_n); ++ I915_WRITE(PIPE_DP_LINK_M(pipe), m_n->link_m); ++ I915_WRITE(PIPE_DP_LINK_N(pipe), m_n->link_n); ++ } ++} ++ + static void intel_dp_set_m_n(struct intel_crtc *crtc) + { + if (crtc->config.has_pch_encoder) +@@ -5618,40 +5652,6 @@ int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp) + return bps / (link_bw * 8) + 1; + } + +-void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc, +- struct intel_link_m_n *m_n) +-{ +- struct drm_device *dev = crtc->base.dev; +- struct drm_i915_private *dev_priv = dev->dev_private; +- int pipe = crtc->pipe; +- +- I915_WRITE(TRANSDATA_M1(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m); +- I915_WRITE(TRANSDATA_N1(pipe), m_n->gmch_n); +- I915_WRITE(TRANSDPLINK_M1(pipe), m_n->link_m); +- I915_WRITE(TRANSDPLINK_N1(pipe), m_n->link_n); +-} +- +-void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, +- struct intel_link_m_n *m_n) +-{ +- struct drm_device *dev = crtc->base.dev; +- struct drm_i915_private *dev_priv = dev->dev_private; +- int pipe = crtc->pipe; +- enum transcoder transcoder = crtc->config.cpu_transcoder; +- +- if (INTEL_INFO(dev)->gen >= 5) { +- I915_WRITE(PIPE_DATA_M1(transcoder), TU_SIZE(m_n->tu) | m_n->gmch_m); +- I915_WRITE(PIPE_DATA_N1(transcoder), m_n->gmch_n); +- I915_WRITE(PIPE_LINK_M1(transcoder), m_n->link_m); +- I915_WRITE(PIPE_LINK_N1(transcoder), m_n->link_n); +- } else { +- I915_WRITE(PIPE_GMCH_DATA_M(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m); +- I915_WRITE(PIPE_GMCH_DATA_N(pipe), m_n->gmch_n); +- I915_WRITE(PIPE_DP_LINK_M(pipe), m_n->link_m); +- I915_WRITE(PIPE_DP_LINK_N(pipe), m_n->link_n); +- } +-} +- + static bool ironlake_needs_fb_cb_tune(struct dpll *dpll, int factor) + { + return i9xx_dpll_compute_m(dpll) < factor * dpll->n; +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 428b9c0357ba..ce12398c34a6 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -720,10 +720,6 @@ extern void intel_init_clock_gating(struct drm_device *dev); + extern void intel_write_eld(struct drm_encoder *encoder, + struct drm_display_mode *mode); + extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe); +-extern void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, +- struct intel_link_m_n *m_n); +-extern void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc, +- struct intel_link_m_n *m_n); + extern void intel_prepare_ddi(struct drm_device *dev); + extern void hsw_fdi_link_train(struct drm_crtc *crtc); + extern void intel_ddi_init(struct drm_device *dev, enum port port); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0115-drm-i915-Apply-OCD-to-data-link-m-n-register-defines.patch b/patches.baytrail/0115-drm-i915-Apply-OCD-to-data-link-m-n-register-defines.patch new file mode 100644 index 000000000000..613c91c814dd --- /dev/null +++ b/patches.baytrail/0115-drm-i915-Apply-OCD-to-data-link-m-n-register-defines.patch @@ -0,0 +1,231 @@ +From e3f17cf16015ade2884b65081dd67c88b1a3aebd Mon Sep 17 00:00:00 2001 +From: James Ausmus +Date: Mon, 23 Sep 2013 16:50:30 -0700 +Subject: drm/i915: Apply OCD to data/link m/n register #defines + +- PCH_ prefix for pch registers on ibx/cpt/ppt. +- Drop the DP_ from the link defines, redundant. +- Drop the GMCH from the data defines and instead give the special g4x + registers a consistent _G4X postfix. + +v2: +- Realign #defines and use tabs (Paulo). + +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit e3b95f1eb5b9a7ecc7241a27499ae8754b845926) + +Conflicts: + drivers/gpu/drm/i915/i915_reg.h +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 77 +++++++++++++++++++----------------- + drivers/gpu/drm/i915/i915_ums.c | 32 +++++++-------- + drivers/gpu/drm/i915/intel_display.c | 16 ++++---- + 3 files changed, 64 insertions(+), 61 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index b8ac1810b753..325534eb7fd2 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -2772,8 +2772,8 @@ + * which is after the LUTs, so we want the bytes for our color format. + * For our current usage, this is always 3, one byte for R, G and B. + */ +-#define _PIPEA_GMCH_DATA_M 0x70050 +-#define _PIPEB_GMCH_DATA_M 0x71050 ++#define _PIPEA_DATA_M_G4X 0x70050 ++#define _PIPEB_DATA_M_G4X 0x71050 + + /* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */ + #define TU_SIZE(x) (((x)-1) << 25) /* default size 64 */ +@@ -2783,8 +2783,9 @@ + #define DATA_LINK_M_N_MASK (0xffffff) + #define DATA_LINK_N_MAX (0x800000) + +-#define _PIPEA_GMCH_DATA_N 0x70054 +-#define _PIPEB_GMCH_DATA_N 0x71054 ++#define _PIPEA_DATA_N_G4X 0x70054 ++#define _PIPEB_DATA_N_G4X 0x71054 ++#define PIPE_GMCH_DATA_N_MASK (0xffffff) + + /* + * Computing Link M and N values for the Display Port link +@@ -2797,16 +2798,18 @@ + * Attributes and VB-ID. + */ + +-#define _PIPEA_DP_LINK_M 0x70060 +-#define _PIPEB_DP_LINK_M 0x71060 ++#define _PIPEA_LINK_M_G4X 0x70060 ++#define _PIPEB_LINK_M_G4X 0x71060 ++#define PIPEA_DP_LINK_M_MASK (0xffffff) + +-#define _PIPEA_DP_LINK_N 0x70064 +-#define _PIPEB_DP_LINK_N 0x71064 ++#define _PIPEA_LINK_N_G4X 0x70064 ++#define _PIPEB_LINK_N_G4X 0x71064 ++#define PIPEA_DP_LINK_N_MASK (0xffffff) + +-#define PIPE_GMCH_DATA_M(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_M, _PIPEB_GMCH_DATA_M) +-#define PIPE_GMCH_DATA_N(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_N, _PIPEB_GMCH_DATA_N) +-#define PIPE_DP_LINK_M(pipe) _PIPE(pipe, _PIPEA_DP_LINK_M, _PIPEB_DP_LINK_M) +-#define PIPE_DP_LINK_N(pipe) _PIPE(pipe, _PIPEA_DP_LINK_N, _PIPEB_DP_LINK_N) ++#define PIPE_DATA_M_G4X(pipe) _PIPE(pipe, _PIPEA_DATA_M_G4X, _PIPEB_DATA_M_G4X) ++#define PIPE_DATA_N_G4X(pipe) _PIPE(pipe, _PIPEA_DATA_N_G4X, _PIPEB_DATA_N_G4X) ++#define PIPE_LINK_M_G4X(pipe) _PIPE(pipe, _PIPEA_LINK_M_G4X, _PIPEB_LINK_M_G4X) ++#define PIPE_LINK_N_G4X(pipe) _PIPE(pipe, _PIPEA_LINK_N_G4X, _PIPEB_LINK_N_G4X) + + /* Display & cursor control */ + +@@ -3949,14 +3952,14 @@ + #define TRANS_VSYNC_START_SHIFT 0 + #define _PCH_TRANS_VSYNCSHIFT_A 0xe0028 + +-#define _TRANSA_DATA_M1 0xe0030 +-#define _TRANSA_DATA_N1 0xe0034 +-#define _TRANSA_DATA_M2 0xe0038 +-#define _TRANSA_DATA_N2 0xe003c +-#define _TRANSA_DP_LINK_M1 0xe0040 +-#define _TRANSA_DP_LINK_N1 0xe0044 +-#define _TRANSA_DP_LINK_M2 0xe0048 +-#define _TRANSA_DP_LINK_N2 0xe004c ++#define _PCH_TRANSA_DATA_M1 0xe0030 ++#define _PCH_TRANSA_DATA_N1 0xe0034 ++#define _PCH_TRANSA_DATA_M2 0xe0038 ++#define _PCH_TRANSA_DATA_N2 0xe003c ++#define _PCH_TRANSA_LINK_M1 0xe0040 ++#define _PCH_TRANSA_LINK_N1 0xe0044 ++#define _PCH_TRANSA_LINK_M2 0xe0048 ++#define _PCH_TRANSA_LINK_N2 0xe004c + + /* Per-transcoder DIP controls */ + +@@ -4042,23 +4045,23 @@ + #define PCH_TRANS_VSYNCSHIFT(pipe) _PIPE(pipe, _PCH_TRANS_VSYNCSHIFT_A, \ + _PCH_TRANS_VSYNCSHIFT_B) + +-#define _TRANSB_DATA_M1 0xe1030 +-#define _TRANSB_DATA_N1 0xe1034 +-#define _TRANSB_DATA_M2 0xe1038 +-#define _TRANSB_DATA_N2 0xe103c +-#define _TRANSB_DP_LINK_M1 0xe1040 +-#define _TRANSB_DP_LINK_N1 0xe1044 +-#define _TRANSB_DP_LINK_M2 0xe1048 +-#define _TRANSB_DP_LINK_N2 0xe104c +- +-#define TRANSDATA_M1(pipe) _PIPE(pipe, _TRANSA_DATA_M1, _TRANSB_DATA_M1) +-#define TRANSDATA_N1(pipe) _PIPE(pipe, _TRANSA_DATA_N1, _TRANSB_DATA_N1) +-#define TRANSDATA_M2(pipe) _PIPE(pipe, _TRANSA_DATA_M2, _TRANSB_DATA_M2) +-#define TRANSDATA_N2(pipe) _PIPE(pipe, _TRANSA_DATA_N2, _TRANSB_DATA_N2) +-#define TRANSDPLINK_M1(pipe) _PIPE(pipe, _TRANSA_DP_LINK_M1, _TRANSB_DP_LINK_M1) +-#define TRANSDPLINK_N1(pipe) _PIPE(pipe, _TRANSA_DP_LINK_N1, _TRANSB_DP_LINK_N1) +-#define TRANSDPLINK_M2(pipe) _PIPE(pipe, _TRANSA_DP_LINK_M2, _TRANSB_DP_LINK_M2) +-#define TRANSDPLINK_N2(pipe) _PIPE(pipe, _TRANSA_DP_LINK_N2, _TRANSB_DP_LINK_N2) ++#define _PCH_TRANSB_DATA_M1 0xe1030 ++#define _PCH_TRANSB_DATA_N1 0xe1034 ++#define _PCH_TRANSB_DATA_M2 0xe1038 ++#define _PCH_TRANSB_DATA_N2 0xe103c ++#define _PCH_TRANSB_LINK_M1 0xe1040 ++#define _PCH_TRANSB_LINK_N1 0xe1044 ++#define _PCH_TRANSB_LINK_M2 0xe1048 ++#define _PCH_TRANSB_LINK_N2 0xe104c ++ ++#define PCH_TRANS_DATA_M1(pipe) _PIPE(pipe, _PCH_TRANSA_DATA_M1, _PCH_TRANSB_DATA_M1) ++#define PCH_TRANS_DATA_N1(pipe) _PIPE(pipe, _PCH_TRANSA_DATA_N1, _PCH_TRANSB_DATA_N1) ++#define PCH_TRANS_DATA_M2(pipe) _PIPE(pipe, _PCH_TRANSA_DATA_M2, _PCH_TRANSB_DATA_M2) ++#define PCH_TRANS_DATA_N2(pipe) _PIPE(pipe, _PCH_TRANSA_DATA_N2, _PCH_TRANSB_DATA_N2) ++#define PCH_TRANS_LINK_M1(pipe) _PIPE(pipe, _PCH_TRANSA_LINK_M1, _PCH_TRANSB_LINK_M1) ++#define PCH_TRANS_LINK_N1(pipe) _PIPE(pipe, _PCH_TRANSA_LINK_N1, _PCH_TRANSB_LINK_N1) ++#define PCH_TRANS_LINK_M2(pipe) _PIPE(pipe, _PCH_TRANSA_LINK_M2, _PCH_TRANSB_LINK_M2) ++#define PCH_TRANS_LINK_N2(pipe) _PIPE(pipe, _PCH_TRANSA_LINK_N2, _PCH_TRANSB_LINK_N2) + + #define _PCH_TRANSACONF 0xf0008 + #define _PCH_TRANSBCONF 0xf1008 +diff --git a/drivers/gpu/drm/i915/i915_ums.c b/drivers/gpu/drm/i915/i915_ums.c +index 4168d2b6b4f1..5ef30b2e6bc6 100644 +--- a/drivers/gpu/drm/i915/i915_ums.c ++++ b/drivers/gpu/drm/i915/i915_ums.c +@@ -259,14 +259,14 @@ void i915_save_display_reg(struct drm_device *dev) + dev_priv->regfile.saveDP_B = I915_READ(DP_B); + dev_priv->regfile.saveDP_C = I915_READ(DP_C); + dev_priv->regfile.saveDP_D = I915_READ(DP_D); +- dev_priv->regfile.savePIPEA_GMCH_DATA_M = I915_READ(_PIPEA_GMCH_DATA_M); +- dev_priv->regfile.savePIPEB_GMCH_DATA_M = I915_READ(_PIPEB_GMCH_DATA_M); +- dev_priv->regfile.savePIPEA_GMCH_DATA_N = I915_READ(_PIPEA_GMCH_DATA_N); +- dev_priv->regfile.savePIPEB_GMCH_DATA_N = I915_READ(_PIPEB_GMCH_DATA_N); +- dev_priv->regfile.savePIPEA_DP_LINK_M = I915_READ(_PIPEA_DP_LINK_M); +- dev_priv->regfile.savePIPEB_DP_LINK_M = I915_READ(_PIPEB_DP_LINK_M); +- dev_priv->regfile.savePIPEA_DP_LINK_N = I915_READ(_PIPEA_DP_LINK_N); +- dev_priv->regfile.savePIPEB_DP_LINK_N = I915_READ(_PIPEB_DP_LINK_N); ++ dev_priv->regfile.savePIPEA_GMCH_DATA_M = I915_READ(_PIPEA_DATA_M_G4X); ++ dev_priv->regfile.savePIPEB_GMCH_DATA_M = I915_READ(_PIPEB_DATA_M_G4X); ++ dev_priv->regfile.savePIPEA_GMCH_DATA_N = I915_READ(_PIPEA_DATA_N_G4X); ++ dev_priv->regfile.savePIPEB_GMCH_DATA_N = I915_READ(_PIPEB_DATA_N_G4X); ++ dev_priv->regfile.savePIPEA_DP_LINK_M = I915_READ(_PIPEA_LINK_M_G4X); ++ dev_priv->regfile.savePIPEB_DP_LINK_M = I915_READ(_PIPEB_LINK_M_G4X); ++ dev_priv->regfile.savePIPEA_DP_LINK_N = I915_READ(_PIPEA_LINK_N_G4X); ++ dev_priv->regfile.savePIPEB_DP_LINK_N = I915_READ(_PIPEB_LINK_N_G4X); + } + /* FIXME: regfile.save TV & SDVO state */ + +@@ -282,14 +282,14 @@ void i915_restore_display_reg(struct drm_device *dev) + + /* Display port ratios (must be done before clock is set) */ + if (SUPPORTS_INTEGRATED_DP(dev)) { +- I915_WRITE(_PIPEA_GMCH_DATA_M, dev_priv->regfile.savePIPEA_GMCH_DATA_M); +- I915_WRITE(_PIPEB_GMCH_DATA_M, dev_priv->regfile.savePIPEB_GMCH_DATA_M); +- I915_WRITE(_PIPEA_GMCH_DATA_N, dev_priv->regfile.savePIPEA_GMCH_DATA_N); +- I915_WRITE(_PIPEB_GMCH_DATA_N, dev_priv->regfile.savePIPEB_GMCH_DATA_N); +- I915_WRITE(_PIPEA_DP_LINK_M, dev_priv->regfile.savePIPEA_DP_LINK_M); +- I915_WRITE(_PIPEB_DP_LINK_M, dev_priv->regfile.savePIPEB_DP_LINK_M); +- I915_WRITE(_PIPEA_DP_LINK_N, dev_priv->regfile.savePIPEA_DP_LINK_N); +- I915_WRITE(_PIPEB_DP_LINK_N, dev_priv->regfile.savePIPEB_DP_LINK_N); ++ I915_WRITE(_PIPEA_DATA_M_G4X, dev_priv->regfile.savePIPEA_GMCH_DATA_M); ++ I915_WRITE(_PIPEB_DATA_M_G4X, dev_priv->regfile.savePIPEB_GMCH_DATA_M); ++ I915_WRITE(_PIPEA_DATA_N_G4X, dev_priv->regfile.savePIPEA_GMCH_DATA_N); ++ I915_WRITE(_PIPEB_DATA_N_G4X, dev_priv->regfile.savePIPEB_GMCH_DATA_N); ++ I915_WRITE(_PIPEA_LINK_M_G4X, dev_priv->regfile.savePIPEA_DP_LINK_M); ++ I915_WRITE(_PIPEB_LINK_M_G4X, dev_priv->regfile.savePIPEB_DP_LINK_M); ++ I915_WRITE(_PIPEA_LINK_N_G4X, dev_priv->regfile.savePIPEA_DP_LINK_N); ++ I915_WRITE(_PIPEB_LINK_N_G4X, dev_priv->regfile.savePIPEB_DP_LINK_N); + } + + /* Fences */ +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 27da171b6411..3915973ca2df 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4395,10 +4395,10 @@ static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc, + struct drm_i915_private *dev_priv = dev->dev_private; + int pipe = crtc->pipe; + +- I915_WRITE(TRANSDATA_M1(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m); +- I915_WRITE(TRANSDATA_N1(pipe), m_n->gmch_n); +- I915_WRITE(TRANSDPLINK_M1(pipe), m_n->link_m); +- I915_WRITE(TRANSDPLINK_N1(pipe), m_n->link_n); ++ I915_WRITE(PCH_TRANS_DATA_M1(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m); ++ I915_WRITE(PCH_TRANS_DATA_N1(pipe), m_n->gmch_n); ++ I915_WRITE(PCH_TRANS_LINK_M1(pipe), m_n->link_m); ++ I915_WRITE(PCH_TRANS_LINK_N1(pipe), m_n->link_n); + } + + static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, +@@ -4415,10 +4415,10 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, + I915_WRITE(PIPE_LINK_M1(transcoder), m_n->link_m); + I915_WRITE(PIPE_LINK_N1(transcoder), m_n->link_n); + } else { +- I915_WRITE(PIPE_GMCH_DATA_M(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m); +- I915_WRITE(PIPE_GMCH_DATA_N(pipe), m_n->gmch_n); +- I915_WRITE(PIPE_DP_LINK_M(pipe), m_n->link_m); +- I915_WRITE(PIPE_DP_LINK_N(pipe), m_n->link_n); ++ I915_WRITE(PIPE_DATA_M_G4X(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m); ++ I915_WRITE(PIPE_DATA_N_G4X(pipe), m_n->gmch_n); ++ I915_WRITE(PIPE_LINK_M_G4X(pipe), m_n->link_m); ++ I915_WRITE(PIPE_LINK_N_G4X(pipe), m_n->link_n); + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0116-drm-i915-make-intel_cpt_verify_modeset-static.patch b/patches.baytrail/0116-drm-i915-make-intel_cpt_verify_modeset-static.patch new file mode 100644 index 000000000000..6a214344af1f --- /dev/null +++ b/patches.baytrail/0116-drm-i915-make-intel_cpt_verify_modeset-static.patch @@ -0,0 +1,54 @@ +From 0830eaca32a57729894d179c7ffa376ceb527dc5 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 3 May 2013 11:49:50 +0200 +Subject: drm/i915: make intel_cpt_verify_modeset static + +Only one caller. Also drop the intel_ prefix as is now customary for +platform specific and static functions. + +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit a1520318a51d6c21b1d9229a9c35b4fcb890b175) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ++-- + drivers/gpu/drm/i915/intel_drv.h | 1 - + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 3915973ca2df..41df62afc08c 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3229,7 +3229,7 @@ prepare: /* separate function? */ + return pll; + } + +-void intel_cpt_verify_modeset(struct drm_device *dev, int pipe) ++static void cpt_verify_modeset(struct drm_device *dev, int pipe) + { + struct drm_i915_private *dev_priv = dev->dev_private; + int dslreg = PIPEDSL(pipe); +@@ -3334,7 +3334,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + encoder->enable(encoder); + + if (HAS_PCH_CPT(dev)) +- intel_cpt_verify_modeset(dev, intel_crtc->pipe); ++ cpt_verify_modeset(dev, intel_crtc->pipe); + + /* + * There seems to be a race in PCH platform hw (at least on some +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index ce12398c34a6..1e79be305396 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -719,7 +719,6 @@ extern void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, + extern void intel_init_clock_gating(struct drm_device *dev); + extern void intel_write_eld(struct drm_encoder *encoder, + struct drm_display_mode *mode); +-extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe); + extern void intel_prepare_ddi(struct drm_device *dev); + extern void hsw_fdi_link_train(struct drm_crtc *crtc); + extern void intel_ddi_init(struct drm_device *dev, enum port port); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0117-drm-i915-Assert-mutex_is_locked-on-context-lookup.patch b/patches.baytrail/0117-drm-i915-Assert-mutex_is_locked-on-context-lookup.patch new file mode 100644 index 000000000000..c5bde4458de5 --- /dev/null +++ b/patches.baytrail/0117-drm-i915-Assert-mutex_is_locked-on-context-lookup.patch @@ -0,0 +1,40 @@ +From fb62a7a27c88ebb40af5d53dca686287413af01d Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 23 Apr 2013 23:15:29 -0700 +Subject: drm/i915: Assert mutex_is_locked on context lookup + +Because our context refcounting doesn't grab a ref at lookup time, it is +unsafe to do so without the lock. + +NOTE: We don't have an easy way to put the assertion in the lookup +function which is where this really belongs. Context switching is good +enough because it actually asserts even more correctness by protecting +the default_context. + +Signed-off-by: Ben Widawsky +Reviewed-by: Jesse Barnes +[danvet: s/BUG/WARN/] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 186507e9e8e89d5920305fdffd8cbba6366da795) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_context.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index 0407e0a39987..604ecd3e3a7f 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -463,6 +463,8 @@ int i915_switch_context(struct intel_ring_buffer *ring, + if (dev_priv->hw_contexts_disabled) + return 0; + ++ WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); ++ + if (ring != &dev_priv->ring[RCS]) + return 0; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0118-drm-i915-BUG_ON-bad-PPGTT-offset.patch b/patches.baytrail/0118-drm-i915-BUG_ON-bad-PPGTT-offset.patch new file mode 100644 index 000000000000..0928d1de99fa --- /dev/null +++ b/patches.baytrail/0118-drm-i915-BUG_ON-bad-PPGTT-offset.patch @@ -0,0 +1,40 @@ +From beb91f82dc8961b39bb0a815ef62d2db08777ed4 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 23 Apr 2013 23:15:30 -0700 +Subject: drm/i915: BUG_ON bad PPGTT offset + +Because PPGTT PDEs within the GTT are calculated in cachelines +(HW guys consistency ftw) we do a divide which will wreak havoc if this +is wrong, and I know that from experience). + +If/when we move to multiple PPGTTs this will have to become a WARN, and +return an error. For now however it should always be considered fatal, +and only a developer could hit it. + +Signed-off-by: Ben Widawsky +Reviewed-by: Jesse Barnes +[danvet: s/BUG/WARN] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 0a73287060cdd8fc2b50ecd216c918c2d097de59) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_gtt.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index de6e7c54ea56..a22e22cfd105 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -110,6 +110,8 @@ static int gen6_ppgtt_enable(struct drm_device *dev) + uint32_t pd_entry; + int i; + ++ WARN_ON(ppgtt->pd_offset & 0x3f); ++ + pd_addr = (gen6_gtt_pte_t __iomem*)dev_priv->gtt.gsm + + ppgtt->pd_offset / sizeof(gen6_gtt_pte_t); + for (i = 0; i < ppgtt->num_pd_entries; i++) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0119-drm-i915-Extract-PDE-writes.patch b/patches.baytrail/0119-drm-i915-Extract-PDE-writes.patch new file mode 100644 index 000000000000..611d5826ebc2 --- /dev/null +++ b/patches.baytrail/0119-drm-i915-Extract-PDE-writes.patch @@ -0,0 +1,70 @@ +From 068bcd070c2a567005b5356da74456f5f2f4c6a7 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 23 Apr 2013 23:15:32 -0700 +Subject: drm/i915: Extract PDE writes + +It also makes some sense IMO to have these two functions separate +irrespective of the number of callers. + +Only the single caller for now, but that will change as we add more +PPGTTs. + +Signed-off-by: Ben Widawsky +Reviewed-by: Jesse Barnes +[danvet: Resolve conflict.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 3e302542055617703b260489ec1ff6fc6f1e68cd) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_gtt.c | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index a22e22cfd105..1bddf477304a 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -100,18 +100,14 @@ static gen6_gtt_pte_t hsw_pte_encode(struct drm_device *dev, + return pte; + } + +-static int gen6_ppgtt_enable(struct drm_device *dev) ++static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt) + { +- drm_i915_private_t *dev_priv = dev->dev_private; +- uint32_t pd_offset; +- struct intel_ring_buffer *ring; +- struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; ++ struct drm_i915_private *dev_priv = ppgtt->dev->dev_private; + gen6_gtt_pte_t __iomem *pd_addr; + uint32_t pd_entry; + int i; + + WARN_ON(ppgtt->pd_offset & 0x3f); +- + pd_addr = (gen6_gtt_pte_t __iomem*)dev_priv->gtt.gsm + + ppgtt->pd_offset / sizeof(gen6_gtt_pte_t); + for (i = 0; i < ppgtt->num_pd_entries; i++) { +@@ -124,6 +120,19 @@ static int gen6_ppgtt_enable(struct drm_device *dev) + writel(pd_entry, pd_addr + i); + } + readl(pd_addr); ++} ++ ++static int gen6_ppgtt_enable(struct drm_device *dev) ++{ ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ uint32_t pd_offset; ++ struct intel_ring_buffer *ring; ++ struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; ++ int i; ++ ++ BUG_ON(ppgtt->pd_offset & 0x3f); ++ ++ gen6_write_pdes(ppgtt); + + pd_offset = ppgtt->pd_offset; + pd_offset /= 64; /* in cachelines, */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0120-drm-i915-Fix-declaration-of-intel_gmbus_-is_forced_b.patch b/patches.baytrail/0120-drm-i915-Fix-declaration-of-intel_gmbus_-is_forced_b.patch new file mode 100644 index 000000000000..ddf725f5b641 --- /dev/null +++ b/patches.baytrail/0120-drm-i915-Fix-declaration-of-intel_gmbus_-is_forced_b.patch @@ -0,0 +1,60 @@ +From 8a8ff6c93bfa455d5dfad94507fd669396a086cf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan-Simon=20M=C3=B6ller?= +Date: Mon, 6 May 2013 14:52:08 +0200 +Subject: drm/i915: Fix declaration of + intel_gmbus_{is_forced_bit/is_port_falid} +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Description: +intel_gmbus_is_forced_bit is no extern as its body is right below. +Likewise for intel_gmbus_is_port_valid. + +This fixes a compilation issue with clang. An initial version of this patch +was developed by PaX Team . +This is respin of this patch. + +20130509: v2: (re-)add inline upon request. + +Signed-off-by: Jan-Simon Möller +CC: pageexec@freemail.hu +CC: daniel.vetter@ffwll.ch +CC: airlied@linux.ie +CC: intel-gfx@lists.freedesktop.org +CC: dri-devel@lists.freedesktop.org +CC: linux-kernel@vger.kernel.org +[danvet: Bikeshed commit message.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 8f375e10ee47b9d7b9b3aefcf67854c6e92708be) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index b5cdc737232f..1c8896cbbf11 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1813,7 +1813,7 @@ void i915_teardown_sysfs(struct drm_device *dev_priv); + /* intel_i2c.c */ + extern int intel_setup_gmbus(struct drm_device *dev); + extern void intel_teardown_gmbus(struct drm_device *dev); +-extern inline bool intel_gmbus_is_port_valid(unsigned port) ++static inline bool intel_gmbus_is_port_valid(unsigned port) + { + return (port >= GMBUS_PORT_SSC && port <= GMBUS_PORT_DPD); + } +@@ -1822,7 +1822,7 @@ extern struct i2c_adapter *intel_gmbus_get_adapter( + struct drm_i915_private *dev_priv, unsigned port); + extern void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed); + extern void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit); +-extern inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter) ++static inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter) + { + return container_of(adapter, struct intel_gmbus, adapter)->force_bit; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0121-drm-i915-read-current-freq-from-Punit-on-VLV.patch b/patches.baytrail/0121-drm-i915-read-current-freq-from-Punit-on-VLV.patch new file mode 100644 index 000000000000..efa3415a3144 --- /dev/null +++ b/patches.baytrail/0121-drm-i915-read-current-freq-from-Punit-on-VLV.patch @@ -0,0 +1,41 @@ +From 97e7d634e0ec64c8977e8584f3067d09b7ca4efc Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Thu, 2 May 2013 10:48:07 -0700 +Subject: drm/i915: read current freq from Punit on VLV + +Instead of returning the cached value, which is just what the kernel +requested. + +Reviewed-by: Kenneth Graunke +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 177006a10b33c9bd729cd60be0a37b41a23e4df3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_sysfs.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c +index ca00df2de07b..c0d7875b475c 100644 +--- a/drivers/gpu/drm/i915/i915_sysfs.c ++++ b/drivers/gpu/drm/i915/i915_sysfs.c +@@ -212,10 +212,13 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev, + int ret; + + mutex_lock(&dev_priv->rps.hw_lock); +- if (IS_VALLEYVIEW(dev_priv->dev)) +- ret = vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.cur_delay); +- else ++ if (IS_VALLEYVIEW(dev_priv->dev)) { ++ u32 freq; ++ valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &freq); ++ ret = vlv_gpu_freq(dev_priv->mem_freq, (freq >> 8) & 0xff); ++ } else { + ret = dev_priv->rps.cur_delay * GT_FREQUENCY_MULTIPLIER; ++ } + mutex_unlock(&dev_priv->rps.hw_lock); + + return snprintf(buf, PAGE_SIZE, "%d\n", ret); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0122-drm-i915-go-back-to-switch-for-VLV-mem-freq-detectio.patch b/patches.baytrail/0122-drm-i915-go-back-to-switch-for-VLV-mem-freq-detectio.patch new file mode 100644 index 000000000000..4ed79de6d9af --- /dev/null +++ b/patches.baytrail/0122-drm-i915-go-back-to-switch-for-VLV-mem-freq-detectio.patch @@ -0,0 +1,44 @@ +From 7fca879e3e68b2240cee2a10a9bceaf455d0e7a3 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Thu, 2 May 2013 10:48:08 -0700 +Subject: drm/i915: go back to switch for VLV mem freq detection v2 + +Both the docs and the existing code were wrong. So fix both and use a +switch statement like we do elsewhere to make things simple & clear. + +Signed-off-by: Jesse Barnes +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 2445966ee80837116498bd83084ad6d28272320c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 5977599bde42..c0a4f68f8a49 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2902,7 +2902,18 @@ static void valleyview_enable_rps(struct drm_device *dev) + GEN7_RC_CTL_TO_MODE); + + valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &val); +- dev_priv->mem_freq = 800 + (266 * (val >> 6) & 3); ++ switch ((val >> 6) & 3) { ++ case 0: ++ case 1: ++ dev_priv->mem_freq = 800; ++ break; ++ case 2: ++ dev_priv->mem_freq = 1066; ++ break; ++ case 3: ++ dev_priv->mem_freq = 1333; ++ break; ++ } + DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq); + + DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & 0x10 ? "yes" : "no"); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0123-drm-i915-fix-panel-fitting-on-LVDS-on-ILK-v2.patch b/patches.baytrail/0123-drm-i915-fix-panel-fitting-on-LVDS-on-ILK-v2.patch new file mode 100644 index 000000000000..9459a92d2087 --- /dev/null +++ b/patches.baytrail/0123-drm-i915-fix-panel-fitting-on-LVDS-on-ILK-v2.patch @@ -0,0 +1,44 @@ +From efd13db78707e9745a874a32e75df44ebf6b1920 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Fri, 3 May 2013 13:26:37 -0700 +Subject: drm/i915: fix panel fitting on LVDS on ILK+ v2 + +This regression was introduced in: + +commit b074cec8c652f2d273907a4b35239b4766c894ac +Author: Jesse Barnes +Date: Thu Apr 25 12:55:02 2013 -0700 + + drm/i915: move PCH pfit controls into pipe_config + +In refactoring this, it was only applied to eDP, which is incorrect. In +fact, if we ever use the panel fitter to deal with overscan on HDMI, +we'll need to extend it again, so just drop the conditional altogether. + +v2: drop check for eDP since we can use the fitter in any config (Daniel) + +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 0ef37f3f5e33eae7d6c388a7b374397794beca39) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 41df62afc08c..745bcca57db6 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3249,8 +3249,7 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc) + struct drm_i915_private *dev_priv = dev->dev_private; + int pipe = crtc->pipe; + +- if (crtc->config.pch_pfit.size && +- intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP)) { ++ if (crtc->config.pch_pfit.size) { + /* Force use of hard-coded filter coefficients + * as some pre-programmed values are broken, + * e.g. x201. +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0124-drm-i915-set-proper-DPIO-post-divider-for-VGA-on-VLV.patch b/patches.baytrail/0124-drm-i915-set-proper-DPIO-post-divider-for-VGA-on-VLV.patch new file mode 100644 index 000000000000..b439904d2ef5 --- /dev/null +++ b/patches.baytrail/0124-drm-i915-set-proper-DPIO-post-divider-for-VGA-on-VLV.patch @@ -0,0 +1,49 @@ +From 412c0089d9c529c571dc103885b206841d856db9 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Thu, 2 May 2013 10:48:09 -0700 +Subject: drm/i915: set proper DPIO post divider for VGA on VLV v4 + +Supposedly we should use the DAC divider for <300MHz pixel clocks, but as +that doesn't actually work as well as the high freq divider here in +practice, just use the high freq divider all the time. + +v2: remove unconditional write (Jesse) + check for pixel rate properly (Jesse) +v3: give up, the DAC divider apparently doesn't work, and low res modes + work ok (Jesse) + remove debug msg (Jesse) + +Signed-off-by: Jesse Barnes +Tested-by: Kenneth Graunke +Signed-off-by: Daniel Vetter +(cherry picked from commit 7df5080bc7f3e3fba9cddac71133ed52864c40be) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 745bcca57db6..b13dc43725da 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4474,10 +4474,13 @@ static void vlv_update_pll(struct intel_crtc *crtc) + mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT)); + mdiv |= ((bestn << DPIO_N_SHIFT)); + mdiv |= (1 << DPIO_K_SHIFT); +- if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI) || +- intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) || +- intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)) +- mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT); ++ ++ /* ++ * Post divider depends on pixel clock rate, DAC vs digital (and LVDS, ++ * but we don't support that). ++ * Note: don't use the DAC post divider as it seems unstable. ++ */ ++ mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT); + intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); + + mdiv |= DPIO_ENABLE_CALIBRATION; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0125-drm-i915-add-intel_display_power_enabled.patch b/patches.baytrail/0125-drm-i915-add-intel_display_power_enabled.patch new file mode 100644 index 000000000000..aca8818f389e --- /dev/null +++ b/patches.baytrail/0125-drm-i915-add-intel_display_power_enabled.patch @@ -0,0 +1,148 @@ +From 2cdd2a5774fa76ce0eb7b7a34f9d79580b511f6c Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 3 May 2013 12:15:36 -0300 +Subject: drm/i915: add intel_display_power_enabled + +This should replace intel_using_power_well. The idea is that we're +adding the requested power domain as an argument, so this might enable +the code to look less platform-specific and also allows us to easily +add new domains in case we need. + +v2: Add more domains to enum intel_display_power_domain +v3: Even more domains requested + +Requested-by: Daniel Vetter +Signed-off-by: Paulo Zanoni +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit b97186f0d94808ce94cd9b77b40e78f2fbd6e6b2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 18 ++++++++++++++++++ + drivers/gpu/drm/i915/intel_display.c | 11 ++++++----- + drivers/gpu/drm/i915/intel_drv.h | 3 ++- + drivers/gpu/drm/i915/intel_pm.c | 24 ++++++++++++++++++++---- + 4 files changed, 46 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 1c8896cbbf11..eee5f8358579 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -88,6 +88,24 @@ enum port { + }; + #define port_name(p) ((p) + 'A') + ++enum intel_display_power_domain { ++ POWER_DOMAIN_PIPE_A, ++ POWER_DOMAIN_PIPE_B, ++ POWER_DOMAIN_PIPE_C, ++ POWER_DOMAIN_PIPE_A_PANEL_FITTER, ++ POWER_DOMAIN_PIPE_B_PANEL_FITTER, ++ POWER_DOMAIN_PIPE_C_PANEL_FITTER, ++ POWER_DOMAIN_TRANSCODER_A, ++ POWER_DOMAIN_TRANSCODER_B, ++ POWER_DOMAIN_TRANSCODER_C, ++ POWER_DOMAIN_TRANSCODER_EDP = POWER_DOMAIN_TRANSCODER_A + 0xF, ++}; ++ ++#define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A) ++#define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \ ++ ((pipe) + POWER_DOMAIN_PIPE_A_PANEL_FITTER) ++#define POWER_DOMAIN_TRANSCODER(tran) ((tran) + POWER_DOMAIN_TRANSCODER_A) ++ + enum hpd_pin { + HPD_NONE = 0, + HPD_PORT_A = HPD_NONE, /* PORT_A is internal */ +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index b13dc43725da..4978de91fa5d 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1110,8 +1110,8 @@ void assert_pipe(struct drm_i915_private *dev_priv, + if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) + state = true; + +- if (!intel_using_power_well(dev_priv->dev) && +- cpu_transcoder != TRANSCODER_EDP) { ++ if (!intel_display_power_enabled(dev_priv->dev, ++ POWER_DOMAIN_TRANSCODER(cpu_transcoder))) { + cur_state = false; + } else { + reg = PIPECONF(cpu_transcoder); +@@ -3532,7 +3532,8 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) + /* XXX: Once we have proper panel fitter state tracking implemented with + * hardware state read/check support we should switch to only disable + * the panel fitter when we know it's used. */ +- if (intel_using_power_well(dev)) { ++ if (intel_display_power_enabled(dev, ++ POWER_DOMAIN_PIPE_PANEL_FITTER(pipe))) { + I915_WRITE(PF_CTL(pipe), 0); + I915_WRITE(PF_WIN_SZ(pipe), 0); + } +@@ -6051,8 +6052,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + enum transcoder cpu_transcoder = crtc->config.cpu_transcoder; + uint32_t tmp; + +- if (!intel_using_power_well(dev_priv->dev) && +- cpu_transcoder != TRANSCODER_EDP) ++ if (!intel_display_power_enabled(dev, ++ POWER_DOMAIN_TRANSCODER(cpu_transcoder))) + return false; + + tmp = I915_READ(PIPECONF(cpu_transcoder)); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 1e79be305396..e0d68179d80e 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -755,7 +755,8 @@ extern void intel_update_fbc(struct drm_device *dev); + extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv); + extern void intel_gpu_ips_teardown(void); + +-extern bool intel_using_power_well(struct drm_device *dev); ++extern bool intel_display_power_enabled(struct drm_device *dev, ++ enum intel_display_power_domain domain); + extern void intel_init_power_well(struct drm_device *dev); + extern void intel_set_power_well(struct drm_device *dev, bool enable); + extern void intel_enable_gt_powersave(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index c0a4f68f8a49..2f94a1c1f4a5 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4344,15 +4344,31 @@ void intel_init_clock_gating(struct drm_device *dev) + * enable it, so check if it's enabled and also check if we've requested it to + * be enabled. + */ +-bool intel_using_power_well(struct drm_device *dev) ++bool intel_display_power_enabled(struct drm_device *dev, ++ enum intel_display_power_domain domain) + { + struct drm_i915_private *dev_priv = dev->dev_private; + +- if (IS_HASWELL(dev)) ++ if (!HAS_POWER_WELL(dev)) ++ return true; ++ ++ switch (domain) { ++ case POWER_DOMAIN_PIPE_A: ++ case POWER_DOMAIN_TRANSCODER_EDP: ++ return true; ++ case POWER_DOMAIN_PIPE_B: ++ case POWER_DOMAIN_PIPE_C: ++ case POWER_DOMAIN_PIPE_A_PANEL_FITTER: ++ case POWER_DOMAIN_PIPE_B_PANEL_FITTER: ++ case POWER_DOMAIN_PIPE_C_PANEL_FITTER: ++ case POWER_DOMAIN_TRANSCODER_A: ++ case POWER_DOMAIN_TRANSCODER_B: ++ case POWER_DOMAIN_TRANSCODER_C: + return I915_READ(HSW_PWR_WELL_DRIVER) == + (HSW_PWR_WELL_ENABLE | HSW_PWR_WELL_STATE); +- else +- return true; ++ default: ++ BUG(); ++ } + } + + void intel_set_power_well(struct drm_device *dev, bool enable) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0126-drm-i915-add-power-well-and-cpu-transcoder-info-to-t.patch b/patches.baytrail/0126-drm-i915-add-power-well-and-cpu-transcoder-info-to-t.patch new file mode 100644 index 000000000000..449b3c094ffd --- /dev/null +++ b/patches.baytrail/0126-drm-i915-add-power-well-and-cpu-transcoder-info-to-t.patch @@ -0,0 +1,69 @@ +From 1502d4c0ce6baa9003fa855f3bdec24591d4b919 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 3 May 2013 12:15:37 -0300 +Subject: drm/i915: add power well and cpu transcoder info to the error state + +We need to dump these registers if we want to properly interpret the +others. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit ff57f1b095e7c3ad0720193cd341d8ac1c781156) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 4978de91fa5d..35fc69351889 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -9811,6 +9811,9 @@ int intel_modeset_vga_set_state(struct drm_device *dev, bool state) + #include + + struct intel_display_error_state { ++ ++ u32 power_well_driver; ++ + struct intel_cursor_error_state { + u32 control; + u32 position; +@@ -9819,6 +9822,7 @@ struct intel_display_error_state { + } cursor[I915_MAX_PIPES]; + + struct intel_pipe_error_state { ++ enum transcoder cpu_transcoder; + u32 conf; + u32 source; + +@@ -9853,8 +9857,12 @@ intel_display_capture_error_state(struct drm_device *dev) + if (error == NULL) + return NULL; + ++ if (HAS_POWER_WELL(dev)) ++ error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER); ++ + for_each_pipe(i) { + cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, i); ++ error->pipe[i].cpu_transcoder = cpu_transcoder; + + if (INTEL_INFO(dev)->gen <= 6 || IS_VALLEYVIEW(dev)) { + error->cursor[i].control = I915_READ(CURCNTR(i)); +@@ -9900,8 +9908,13 @@ intel_display_print_error_state(struct seq_file *m, + int i; + + seq_printf(m, "Num Pipes: %d\n", INTEL_INFO(dev)->num_pipes); ++ if (HAS_POWER_WELL(dev)) ++ seq_printf(m, "PWR_WELL_CTL2: %08x\n", ++ error->power_well_driver); + for_each_pipe(i) { + seq_printf(m, "Pipe [%d]:\n", i); ++ seq_printf(m, " CPU transcoder: %c\n", ++ transcoder_name(error->pipe[i].cpu_transcoder)); + seq_printf(m, " CONF: %08x\n", error->pipe[i].conf); + seq_printf(m, " SRC: %08x\n", error->pipe[i].source); + seq_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0127-drm-i915-clear-FPGA_DBG_RM_NOCLAIM-when-capturing-er.patch b/patches.baytrail/0127-drm-i915-clear-FPGA_DBG_RM_NOCLAIM-when-capturing-er.patch new file mode 100644 index 000000000000..bc37343093d4 --- /dev/null +++ b/patches.baytrail/0127-drm-i915-clear-FPGA_DBG_RM_NOCLAIM-when-capturing-er.patch @@ -0,0 +1,45 @@ +From 656d6aba4a2cd5dfb2f9c4b4f49e238a278aa81c Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 3 May 2013 12:15:38 -0300 +Subject: drm/i915: clear FPGA_DBG_RM_NOCLAIM when capturing error state + +In the error state function we read the registers without checking if +the power well is on, so after doing this we have to clear the +FPGA_DBG_RM_NOCLAIM bit to prevent the next I915_WRITE from detecting +it and printing an error message. + +The first version of this patch was checking for the power well state +and then avoiding reading registers that were off, but the reviewers +requested to just read the registers any way and then later clear the +FPGA_DBG_RM_NOCLAIM bit. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 12d217c795071bfee483158e1397c57e8dc3cb76) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 35fc69351889..7e3b4663e51d 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -9897,6 +9897,13 @@ intel_display_capture_error_state(struct drm_device *dev) + error->pipe[i].vsync = I915_READ(VSYNC(cpu_transcoder)); + } + ++ /* In the code above we read the registers without checking if the power ++ * well was on, so here we have to clear the FPGA_DBG_RM_NOCLAIM bit to ++ * prevent the next I915_WRITE from detecting it and printing an error ++ * message. */ ++ if (HAS_POWER_WELL(dev)) ++ I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); ++ + return error; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0128-drm-i915-check-the-power-well-on-i915_pipe_enabled.patch b/patches.baytrail/0128-drm-i915-check-the-power-well-on-i915_pipe_enabled.patch new file mode 100644 index 000000000000..871c9292a5e0 --- /dev/null +++ b/patches.baytrail/0128-drm-i915-check-the-power-well-on-i915_pipe_enabled.patch @@ -0,0 +1,38 @@ +From c59e6c26e846e04192582e28deba8a7cb8e36e3b Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 3 May 2013 12:15:39 -0300 +Subject: drm/i915: check the power well on i915_pipe_enabled + +This fixes "unclaimed register" messages when the power well is +disabled and there's a GPU hang. + +v2: Use the new intel_display_power_enabled(). +v3: Use the new domains for intel_display_power_enabled(). + +Signed-off-by: Paulo Zanoni +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 71f8ba6b7e44fc525fb15a60997c0c5064c160e6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 7d8cfedfaf86..ae19a7cff5f9 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -375,6 +375,10 @@ i915_pipe_enabled(struct drm_device *dev, int pipe) + enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, + pipe); + ++ if (!intel_display_power_enabled(dev, ++ POWER_DOMAIN_TRANSCODER(cpu_transcoder))) ++ return false; ++ + return I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0129-drm-i915-only-disable-DDI-sound-if-intel_crtc-eld_vl.patch b/patches.baytrail/0129-drm-i915-only-disable-DDI-sound-if-intel_crtc-eld_vl.patch new file mode 100644 index 000000000000..3e3f8fc56bfc --- /dev/null +++ b/patches.baytrail/0129-drm-i915-only-disable-DDI-sound-if-intel_crtc-eld_vl.patch @@ -0,0 +1,68 @@ +From d13af6a5925bb25ee61e52d1ef5993fa5f3ba020 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 3 May 2013 12:15:40 -0300 +Subject: drm/i915: only disable DDI sound if intel_crtc->eld_vld + +We already have the same check on intel_enable_ddi. This patch +prevents "unclaimed register" messages when the power well is +disabled. + +V2: Reset intel_crtc->eld_vld to false after the mode_set function. +V3: Add both "type != INTEL_OUTPUT_EDP" requested. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit c77bf5659deb9405ef61080c148e47d2c8ee31e5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 11 +++++++---- + drivers/gpu/drm/i915/intel_display.c | 2 +- + 2 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 6953a971a4ea..46181000f6bd 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -1306,7 +1306,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) + ironlake_edp_backlight_on(intel_dp); + } + +- if (intel_crtc->eld_vld) { ++ if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) { + tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); + tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); + I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); +@@ -1324,9 +1324,12 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t tmp; + +- tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); +- tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4)); +- I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); ++ if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) { ++ tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); ++ tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << ++ (pipe * 4)); ++ I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); ++ } + + if (type == INTEL_OUTPUT_EDP) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 7e3b4663e51d..f3d8e0915d7f 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3864,8 +3864,8 @@ static void intel_crtc_disable(struct drm_crtc *crtc) + /* crtc should still be enabled when we disable it. */ + WARN_ON(!crtc->enabled); + +- intel_crtc->eld_vld = false; + dev_priv->display.crtc_disable(crtc); ++ intel_crtc->eld_vld = false; + intel_crtc_update_sarea(crtc, false); + dev_priv->display.off(crtc); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0130-drm-i915-Add-platform-information-to-implemented-wor.patch b/patches.baytrail/0130-drm-i915-Add-platform-information-to-implemented-wor.patch new file mode 100644 index 000000000000..1d37375e791e --- /dev/null +++ b/patches.baytrail/0130-drm-i915-Add-platform-information-to-implemented-wor.patch @@ -0,0 +1,294 @@ +From c523a9fe6d04280ec994f1a7f88ab736c18f8e26 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Fri, 3 May 2013 18:48:10 +0100 +Subject: drm/i915: Add platform information to implemented workarounds + +Signed-off-by: Damien Lespiau +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit ecdb4eb71b8f76db2bf58c86af907e7b8ee056b0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 6 ++-- + drivers/gpu/drm/i915/intel_pm.c | 77 +++++++++++++++++++++-------------------- + 2 files changed, 42 insertions(+), 41 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index b7fdafdb496e..7610a28a1bf6 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -1222,9 +1222,9 @@ MODULE_LICENSE("GPL and additional rights"); + static void + ilk_dummy_write(struct drm_i915_private *dev_priv) + { +- /* WaIssueDummyWriteToWakeupFromRC6: Issue a dummy write to wake up the +- * chip from rc6 before touching it for real. MI_MODE is masked, hence +- * harmless to write 0 into. */ ++ /* WaIssueDummyWriteToWakeupFromRC6:ilk Issue a dummy write to wake up ++ * the chip from rc6 before touching it for real. MI_MODE is masked, ++ * hence harmless to write 0 into. */ + I915_WRITE_NOTRACE(MI_MODE, 0); + } + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 2f94a1c1f4a5..89fe32002246 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3808,7 +3808,7 @@ static void ironlake_init_clock_gating(struct drm_device *dev) + _3D_CHICKEN2_WM_READ_PIPELINED << 16 | + _3D_CHICKEN2_WM_READ_PIPELINED); + +- /* WaDisableRenderCachePipelinedFlush */ ++ /* WaDisableRenderCachePipelinedFlush:ilk */ + I915_WRITE(CACHE_MODE_0, + _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE)); + +@@ -3875,11 +3875,11 @@ static void gen6_init_clock_gating(struct drm_device *dev) + I915_READ(ILK_DISPLAY_CHICKEN2) | + ILK_ELPIN_409_SELECT); + +- /* WaDisableHiZPlanesWhenMSAAEnabled */ ++ /* WaDisableHiZPlanesWhenMSAAEnabled:snb */ + I915_WRITE(_3D_CHICKEN, + _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB)); + +- /* WaSetupGtModeTdRowDispatch */ ++ /* WaSetupGtModeTdRowDispatch:snb */ + if (IS_SNB_GT1(dev)) + I915_WRITE(GEN6_GT_MODE, + _MASKED_BIT_ENABLE(GEN6_TD_FOUR_ROW_DISPATCH_DISABLE)); +@@ -3906,8 +3906,8 @@ static void gen6_init_clock_gating(struct drm_device *dev) + * According to the spec, bit 11 (RCCUNIT) must also be set, + * but we didn't debug actual testcases to find it out. + * +- * Also apply WaDisableVDSUnitClockGating and +- * WaDisableRCPBUnitClockGating. ++ * Also apply WaDisableVDSUnitClockGating:snb and ++ * WaDisableRCPBUnitClockGating:snb. + */ + I915_WRITE(GEN6_UCGCTL2, + GEN7_VDSUNIT_CLOCK_GATE_DISABLE | +@@ -3938,7 +3938,7 @@ static void gen6_init_clock_gating(struct drm_device *dev) + ILK_DPARBUNIT_CLOCK_GATE_ENABLE | + ILK_DPFDUNIT_CLOCK_GATE_ENABLE); + +- /* WaMbcDriverBootEnable */ ++ /* WaMbcDriverBootEnable:snb */ + I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | + GEN6_MBCTL_ENABLE_BOOT_FETCH); + +@@ -3968,7 +3968,6 @@ static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) + reg |= GEN7_FF_VS_SCHED_HW; + reg |= GEN7_FF_DS_SCHED_HW; + +- /* WaVSRefCountFullforceMissDisable */ + if (IS_HASWELL(dev_priv->dev)) + reg &= ~GEN7_FF_VS_REF_CNT_FFME; + +@@ -3999,21 +3998,21 @@ static void haswell_init_clock_gating(struct drm_device *dev) + I915_WRITE(WM1_LP_ILK, 0); + + /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. +- * This implements the WaDisableRCZUnitClockGating workaround. ++ * This implements the WaDisableRCZUnitClockGating:hsw workaround. + */ + I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); + +- /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ ++ /* Apply the WaDisableRHWOOptimizationForRenderHang:hsw workaround. */ + I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, + GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); + +- /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */ ++ /* WaApplyL3ControlAndL3ChickenMode:hsw */ + I915_WRITE(GEN7_L3CNTLREG1, + GEN7_WA_FOR_GEN7_L3_CONTROL); + I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, + GEN7_WA_L3_CHICKEN_MODE); + +- /* This is required by WaCatErrorRejectionIssue */ ++ /* This is required by WaCatErrorRejectionIssue:hsw */ + I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | + GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); +@@ -4025,17 +4024,18 @@ static void haswell_init_clock_gating(struct drm_device *dev) + intel_flush_display_plane(dev_priv, pipe); + } + ++ /* WaVSRefCountFullforceMissDisable:hsw */ + gen7_setup_fixed_func_scheduler(dev_priv); + +- /* WaDisable4x2SubspanOptimization */ ++ /* WaDisable4x2SubspanOptimization:hsw */ + I915_WRITE(CACHE_MODE_1, + _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); + +- /* WaMbcDriverBootEnable */ ++ /* WaMbcDriverBootEnable:hsw */ + I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | + GEN6_MBCTL_ENABLE_BOOT_FETCH); + +- /* WaSwitchSolVfFArbitrationPriority */ ++ /* WaSwitchSolVfFArbitrationPriority:hsw */ + I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); + + /* XXX: This is a workaround for early silicon revisions and should be +@@ -4062,16 +4062,16 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) + + I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); + +- /* WaDisableEarlyCull */ ++ /* WaDisableEarlyCull:ivb */ + I915_WRITE(_3D_CHICKEN3, + _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL)); + +- /* WaDisableBackToBackFlipFix */ ++ /* WaDisableBackToBackFlipFix:ivb */ + I915_WRITE(IVB_CHICKEN3, + CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | + CHICKEN3_DGMG_DONE_FIX_DISABLE); + +- /* WaDisablePSDDualDispatchEnable */ ++ /* WaDisablePSDDualDispatchEnable:ivb */ + if (IS_IVB_GT1(dev)) + I915_WRITE(GEN7_HALF_SLICE_CHICKEN1, + _MASKED_BIT_ENABLE(GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE)); +@@ -4079,11 +4079,11 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) + I915_WRITE(GEN7_HALF_SLICE_CHICKEN1_GT2, + _MASKED_BIT_ENABLE(GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE)); + +- /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ ++ /* Apply the WaDisableRHWOOptimizationForRenderHang:ivb workaround. */ + I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, + GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); + +- /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */ ++ /* WaApplyL3ControlAndL3ChickenMode:ivb */ + I915_WRITE(GEN7_L3CNTLREG1, + GEN7_WA_FOR_GEN7_L3_CONTROL); + I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, +@@ -4096,7 +4096,7 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) + _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + + +- /* WaForceL3Serialization */ ++ /* WaForceL3Serialization:ivb */ + I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) & + ~L3SQ_URB_READ_CAM_MATCH_DISABLE); + +@@ -4111,13 +4111,13 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) + * but we didn't debug actual testcases to find it out. + * + * According to the spec, bit 13 (RCZUNIT) must be set on IVB. +- * This implements the WaDisableRCZUnitClockGating workaround. ++ * This implements the WaDisableRCZUnitClockGating:ivb workaround. + */ + I915_WRITE(GEN6_UCGCTL2, + GEN6_RCZUNIT_CLOCK_GATE_DISABLE | + GEN6_RCCUNIT_CLOCK_GATE_DISABLE); + +- /* This is required by WaCatErrorRejectionIssue */ ++ /* This is required by WaCatErrorRejectionIssue:ivb */ + I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | + GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); +@@ -4129,13 +4129,14 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) + intel_flush_display_plane(dev_priv, pipe); + } + +- /* WaMbcDriverBootEnable */ ++ /* WaMbcDriverBootEnable:ivb */ + I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | + GEN6_MBCTL_ENABLE_BOOT_FETCH); + ++ /* WaVSRefCountFullforceMissDisable:ivb */ + gen7_setup_fixed_func_scheduler(dev_priv); + +- /* WaDisable4x2SubspanOptimization */ ++ /* WaDisable4x2SubspanOptimization:ivb */ + I915_WRITE(CACHE_MODE_1, + _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); + +@@ -4161,46 +4162,46 @@ static void valleyview_init_clock_gating(struct drm_device *dev) + + I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); + +- /* WaDisableEarlyCull */ ++ /* WaDisableEarlyCull:vlv */ + I915_WRITE(_3D_CHICKEN3, + _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL)); + +- /* WaDisableBackToBackFlipFix */ ++ /* WaDisableBackToBackFlipFix:vlv */ + I915_WRITE(IVB_CHICKEN3, + CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | + CHICKEN3_DGMG_DONE_FIX_DISABLE); + +- /* WaDisablePSDDualDispatchEnable */ ++ /* WaDisablePSDDualDispatchEnable:vlv */ + I915_WRITE(GEN7_HALF_SLICE_CHICKEN1, + _MASKED_BIT_ENABLE(GEN7_MAX_PS_THREAD_DEP | + GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE)); + +- /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ ++ /* Apply the WaDisableRHWOOptimizationForRenderHang:vlv workaround. */ + I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, + GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); + +- /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */ ++ /* WaApplyL3ControlAndL3ChickenMode:vlv */ + I915_WRITE(GEN7_L3CNTLREG1, I915_READ(GEN7_L3CNTLREG1) | GEN7_L3AGDIS); + I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, GEN7_WA_L3_CHICKEN_MODE); + +- /* WaForceL3Serialization */ ++ /* WaForceL3Serialization:vlv */ + I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) & + ~L3SQ_URB_READ_CAM_MATCH_DISABLE); + +- /* WaDisableDopClockGating */ ++ /* WaDisableDopClockGating:vlv */ + I915_WRITE(GEN7_ROW_CHICKEN2, + _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + +- /* WaForceL3Serialization */ ++ /* WaForceL3Serialization:vlv */ + I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) & + ~L3SQ_URB_READ_CAM_MATCH_DISABLE); + +- /* This is required by WaCatErrorRejectionIssue */ ++ /* This is required by WaCatErrorRejectionIssue:vlv */ + I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | + GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); + +- /* WaMbcDriverBootEnable */ ++ /* WaMbcDriverBootEnable:vlv */ + I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | + GEN6_MBCTL_ENABLE_BOOT_FETCH); + +@@ -4216,10 +4217,10 @@ static void valleyview_init_clock_gating(struct drm_device *dev) + * but we didn't debug actual testcases to find it out. + * + * According to the spec, bit 13 (RCZUNIT) must be set on IVB. +- * This implements the WaDisableRCZUnitClockGating workaround. ++ * This implements the WaDisableRCZUnitClockGating:vlv workaround. + * +- * Also apply WaDisableVDSUnitClockGating and +- * WaDisableRCPBUnitClockGating. ++ * Also apply WaDisableVDSUnitClockGating:vlv and ++ * WaDisableRCPBUnitClockGating:vlv. + */ + I915_WRITE(GEN6_UCGCTL2, + GEN7_VDSUNIT_CLOCK_GATE_DISABLE | +@@ -4241,7 +4242,7 @@ static void valleyview_init_clock_gating(struct drm_device *dev) + _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); + + /* +- * WaDisableVLVClockGating_VBIIssue ++ * WaDisableVLVClockGating_VBIIssue:vlv + * Disable clock gating on th GCFG unit to prevent a delay + * in the reporting of vblank events. + */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0131-drm-i915-Add-references-to-some-workaround-we-implem.patch b/patches.baytrail/0131-drm-i915-Add-references-to-some-workaround-we-implem.patch new file mode 100644 index 000000000000..0f3d10b5adff --- /dev/null +++ b/patches.baytrail/0131-drm-i915-Add-references-to-some-workaround-we-implem.patch @@ -0,0 +1,105 @@ +From a6354f167ba5c01d1ee64f6292dcbd2ebb030e55 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Fri, 3 May 2013 18:48:11 +0100 +Subject: drm/i915: Add references to some workaround we implement + +We did not mention the workaround name when implementing those. This +should help us track what we already implement. + +Signed-off-by: Damien Lespiau +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 8693a824873a0a97be77c1d5f1e98777f06f7305) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_context.c | 1 + + drivers/gpu/drm/i915/intel_ddi.c | 2 ++ + drivers/gpu/drm/i915/intel_display.c | 4 ++-- + drivers/gpu/drm/i915/intel_pm.c | 3 +++ + drivers/gpu/drm/i915/intel_ringbuffer.c | 2 ++ + 5 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index 604ecd3e3a7f..59b536a7f773 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -333,6 +333,7 @@ mi_set_context(struct intel_ring_buffer *ring, + if (ret) + return ret; + ++ /* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw */ + if (IS_GEN7(ring->dev)) + intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE); + else +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 46181000f6bd..217308ec3b3d 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -174,6 +174,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) + * mode set "sequence for CRT port" document: + * - TP1 to TP2 time with the default value + * - FDI delay to 90h ++ * ++ * WaFDIAutoLinkSetTimingOverrride:hsw + */ + I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) | + FDI_RX_PWRDN_LANE0_VAL(2) | +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index f3d8e0915d7f..e43dad8d28bb 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4121,8 +4121,8 @@ static int intel_crtc_compute_config(struct drm_crtc *crtc, + if (!pipe_config->timings_set) + drm_mode_set_crtcinfo(adjusted_mode, 0); + +- /* WaPruneModeWithIncorrectHsyncOffset: Cantiga+ cannot handle modes +- * with a hsync front porch of 0. ++ /* Cantiga+ cannot handle modes with a hsync front porch of 0. ++ * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw. + */ + if ((INTEL_INFO(dev)->gen > 4 || IS_G4X(dev)) && + adjusted_mode->hsync_start == adjusted_mode->hdisplay) +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 89fe32002246..f88cfbedc90e 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4586,6 +4586,7 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); + ++ /* WaRsForcewakeWaitTC0:snb */ + __gen6_gt_wait_for_thread_c0(dev_priv); + } + +@@ -4617,6 +4618,7 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); + ++ /* WaRsForcewakeWaitTC0:ivb,hsw */ + __gen6_gt_wait_for_thread_c0(dev_priv); + } + +@@ -4720,6 +4722,7 @@ static void vlv_force_wake_get(struct drm_i915_private *dev_priv) + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out waiting for media to ack forcewake request.\n"); + ++ /* WaRsForcewakeWaitTC0:vlv */ + __gen6_gt_wait_for_thread_c0(dev_priv); + } + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 48fe23e8d180..d99ff99b07b2 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -511,6 +511,8 @@ static int init_render_ring(struct intel_ring_buffer *ring) + /* We need to disable the AsyncFlip performance optimisations in order + * to use MI_WAIT_FOR_EVENT within the CS. It should already be + * programmed to '1' on all products. ++ * ++ * WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv + */ + if (INTEL_INFO(dev)->gen >= 6) + I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE)); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0132-drm-i915-fix-hotplug-event-bit-tracking.patch b/patches.baytrail/0132-drm-i915-fix-hotplug-event-bit-tracking.patch new file mode 100644 index 000000000000..12b0dc2f55b8 --- /dev/null +++ b/patches.baytrail/0132-drm-i915-fix-hotplug-event-bit-tracking.patch @@ -0,0 +1,59 @@ +From 2f3effdedbbd3c2559ab6ce8282472bc43961280 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 7 May 2013 15:10:29 +0300 +Subject: drm/i915: fix hotplug event bit tracking + +commit 142e239849c800f9dc23f828762873073f612d3f +Author: Egbert Eich +Date: Thu Apr 11 15:57:57 2013 +0200 + + drm/i915: Add bit field to record which pins have received HPD events (v3) + +added a bit field for hotplug event tracking. There ended up being three +different v3 of the patch: [1], [2], and [3]. Apparently [1] was the +correct one, but some frankenstein combination of the three got +committed, which reversed the logic for setting the hotplug bits and +misplaced a continue statement, skipping the hotplug irq storm handling +altogether. + +This lead to broken hotplug detection, bisected to +commit 321a1b3026ea194dd084cf3bda1e235b2986b0af +Author: Egbert Eich +Date: Thu Apr 11 16:00:26 2013 +0200 + + drm/i915: Only reprobe display on encoder which has received an HPD event (v2) + +which uses the incorrectly set hotplug event bits. + +Fix the mess. + +[1] http://mid.gmane.org/1366112220-7638-6-git-send-email-eich@suse.de +[2] http://mid.gmane.org/1365688677-13682-1-git-send-email-eich@suse.de +[3] http://mid.gmane.org/1365688996-13874-1-git-send-email-eich@suse.de + +Signed-off-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit bc5ead8c09b51e85d110132495a9bfa58dc39dab) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index ae19a7cff5f9..6b9bc815cc70 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -873,9 +873,9 @@ static inline bool hotplug_irq_storm_detect(struct drm_device *dev, + + if (!(hpd[i] & hotplug_trigger) || + dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) +- dev_priv->hpd_event_bits |= (1 << i); + continue; + ++ dev_priv->hpd_event_bits |= (1 << i); + if (!time_in_range(jiffies, dev_priv->hpd_stats[i].hpd_last_jiffies, + dev_priv->hpd_stats[i].hpd_last_jiffies + + msecs_to_jiffies(HPD_STORM_DETECT_PERIOD))) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0133-drm-i915-HSW-allow-PCH-clock-gating-for-suspend.patch b/patches.baytrail/0133-drm-i915-HSW-allow-PCH-clock-gating-for-suspend.patch new file mode 100644 index 000000000000..18284ed9e34b --- /dev/null +++ b/patches.baytrail/0133-drm-i915-HSW-allow-PCH-clock-gating-for-suspend.patch @@ -0,0 +1,116 @@ +From 586758d9bec7b9acb46c94c37ae33c506f895bd1 Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Wed, 17 Apr 2013 14:04:50 +0300 +Subject: drm/i915: HSW: allow PCH clock gating for suspend + +For the device to enter D3 we should enable PCH clock gating. + +v2: +- use HAS_PCH_LPT instead of IS_HASWELL (Ville, Paolo) +- rename lpt_allow_clock_gating to lpt_suspend_hw (Paolo) + +Signed-off-by: Imre Deak +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 7d708ee40a6b9ca1112a322e554c887df105b025) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 2 ++ + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/intel_display.c | 5 +++++ + drivers/gpu/drm/i915/intel_drv.h | 1 + + drivers/gpu/drm/i915/intel_pm.c | 18 ++++++++++++++++++ + 5 files changed, 27 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 7610a28a1bf6..e91593a4d450 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -553,6 +553,8 @@ static int i915_drm_freeze(struct drm_device *dev) + */ + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + dev_priv->display.crtc_disable(crtc); ++ ++ intel_modeset_suspend_hw(dev); + } + + i915_save_state(dev); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index eee5f8358579..aa81716db4f3 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1869,6 +1869,7 @@ static inline void intel_unregister_dsm_handler(void) { return; } + + /* modesetting */ + extern void intel_modeset_init_hw(struct drm_device *dev); ++extern void intel_modeset_suspend_hw(struct drm_device *dev); + extern void intel_modeset_init(struct drm_device *dev); + extern void intel_modeset_gem_init(struct drm_device *dev); + extern void intel_modeset_cleanup(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index e43dad8d28bb..87414ec78fd4 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -9326,6 +9326,11 @@ void intel_modeset_init_hw(struct drm_device *dev) + mutex_unlock(&dev->struct_mutex); + } + ++void intel_modeset_suspend_hw(struct drm_device *dev) ++{ ++ intel_suspend_hw(dev); ++} ++ + void intel_modeset_init(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index e0d68179d80e..cb5e0cea4e93 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -717,6 +717,7 @@ extern void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, + #define assert_pipe_disabled(d, p) assert_pipe(d, p, false) + + extern void intel_init_clock_gating(struct drm_device *dev); ++extern void intel_suspend_hw(struct drm_device *dev); + extern void intel_write_eld(struct drm_encoder *encoder, + struct drm_display_mode *mode); + extern void intel_prepare_ddi(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index f88cfbedc90e..863eaec77481 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3988,6 +3988,18 @@ static void lpt_init_clock_gating(struct drm_device *dev) + PCH_LP_PARTITION_LEVEL_DISABLE); + } + ++static void lpt_suspend_hw(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { ++ uint32_t val = I915_READ(SOUTH_DSPCLK_GATE_D); ++ ++ val &= ~PCH_LP_PARTITION_LEVEL_DISABLE; ++ I915_WRITE(SOUTH_DSPCLK_GATE_D, val); ++ } ++} ++ + static void haswell_init_clock_gating(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -4340,6 +4352,12 @@ void intel_init_clock_gating(struct drm_device *dev) + dev_priv->display.init_clock_gating(dev); + } + ++void intel_suspend_hw(struct drm_device *dev) ++{ ++ if (HAS_PCH_LPT(dev)) ++ lpt_suspend_hw(dev); ++} ++ + /** + * We should only use the power well if we explicitly asked the hardware to + * enable it, so check if it's enabled and also check if we've requested it to +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0134-drm-i915-Re-enable-FBC-WM-if-the-watermark-is-good-o.patch b/patches.baytrail/0134-drm-i915-Re-enable-FBC-WM-if-the-watermark-is-good-o.patch new file mode 100644 index 000000000000..2f066b36d68b --- /dev/null +++ b/patches.baytrail/0134-drm-i915-Re-enable-FBC-WM-if-the-watermark-is-good-o.patch @@ -0,0 +1,42 @@ +From 8e16290f459196a1ea24fe8093a98c9ddec09eda Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 24 Apr 2013 21:09:10 +0300 +Subject: drm/i915: Re-enable FBC WM if the watermark is good on gen6+ +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If the calculated FBC watermark is no good, we simply disable FBC +watermarks. But we fail to re-enable them later if the calculated +watermark becomes good again. Fix that, but remember to leave FBC +watermarks disabled on ILK since that's required by some workarounds. + +v2: Fix checkpatch complaint + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 615aaa5f96e40971039e01105c09808a3dead7d5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 863eaec77481..5a9b5bea5d10 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -1631,6 +1631,10 @@ static bool ironlake_check_srwm(struct drm_device *dev, int level, + I915_WRITE(DISP_ARB_CTL, + I915_READ(DISP_ARB_CTL) | DISP_FBC_WM_DIS); + return false; ++ } else if (INTEL_INFO(dev)->gen >= 6) { ++ /* enable FBC WM (except on ILK, where it must remain off) */ ++ I915_WRITE(DISP_ARB_CTL, ++ I915_READ(DISP_ARB_CTL) & ~DISP_FBC_WM_DIS); + } + + if (display_wm > display->max_wm) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0135-drm-i915-BIOS-and-power-context-stolen-mem-handling-.patch b/patches.baytrail/0135-drm-i915-BIOS-and-power-context-stolen-mem-handling-.patch new file mode 100644 index 000000000000..5dbe1cac08fc --- /dev/null +++ b/patches.baytrail/0135-drm-i915-BIOS-and-power-context-stolen-mem-handling-.patch @@ -0,0 +1,173 @@ +From 4b319c03ceffcd07ec0ef7268d348df1b1b53906 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Wed, 8 May 2013 10:45:13 -0700 +Subject: drm/i915: BIOS and power context stolen mem handling for VLV v7 + +But we need to get the right stolen base and make pre-allocated objects +for BIOS stuff so we don't clobber it. If the BIOS hasn't allocated a +power context, we allocate one here too, from stolen space as required +by the docs. + +v2: fix stolen to phys if ladder (Ben) + keep BIOS reserved space out of allocator altogether (Ben) +v3: fix mask of stolen base (Ben) +v4: clean up preallocated object on unload (Ben) + don't zero reg on unload (Jesse) + fix mask harder (Jesse) +v5: use unref for freeing stolen bits (Chris) + move alloc/free to intel_pm.c (Chris) +v6: NULL pctx at disable time so error paths work (Ben) +v7: use correct PCI device for config read (Jesse) + +Reviewed-by: Ben Widawsky +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit c9cddffc669408a361c62353a36dd40b469dd9c2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 ++ + drivers/gpu/drm/i915/i915_gem_stolen.c | 12 +++++++-- + drivers/gpu/drm/i915/i915_reg.h | 1 + + drivers/gpu/drm/i915/intel_pm.c | 49 ++++++++++++++++++++++++++++++++++ + 4 files changed, 62 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index aa81716db4f3..05752eb2eb0c 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1074,6 +1074,8 @@ typedef struct drm_i915_private { + + struct i915_gpu_error gpu_error; + ++ struct drm_i915_gem_object *vlv_pctx; ++ + /* list of fbdev register on this device */ + struct intel_fbdev *fbdev; + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 67d3510cafed..913994cd0a3a 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -62,7 +62,10 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) + * its value of TOLUD. + */ + base = 0; +- if (INTEL_INFO(dev)->gen >= 6) { ++ if (IS_VALLEYVIEW(dev)) { ++ pci_read_config_dword(dev->pdev, 0x5c, &base); ++ base &= ~((1<<20) - 1); ++ } else if (INTEL_INFO(dev)->gen >= 6) { + /* Read Base Data of Stolen Memory Register (BDSM) directly. + * Note that there is also a MCHBAR miror at 0x1080c0 or + * we could use device 2:0x5c instead. +@@ -183,6 +186,7 @@ void i915_gem_cleanup_stolen(struct drm_device *dev) + int i915_gem_init_stolen(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; ++ int bios_reserved = 0; + + dev_priv->mm.stolen_base = i915_stolen_to_physical(dev); + if (dev_priv->mm.stolen_base == 0) +@@ -191,8 +195,12 @@ int i915_gem_init_stolen(struct drm_device *dev) + DRM_DEBUG_KMS("found %zd bytes of stolen memory at %08lx\n", + dev_priv->gtt.stolen_size, dev_priv->mm.stolen_base); + ++ if (IS_VALLEYVIEW(dev)) ++ bios_reserved = 1024*1024; /* top 1M on VLV/BYT */ ++ + /* Basic memrange allocator for stolen space */ +- drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_size); ++ drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_size - ++ bios_reserved); + + return 0; + } +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 325534eb7fd2..5de7b03ff32a 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -698,6 +698,7 @@ + #define VLV_IIR (VLV_DISPLAY_BASE + 0x20a4) + #define VLV_IMR (VLV_DISPLAY_BASE + 0x20a8) + #define VLV_ISR (VLV_DISPLAY_BASE + 0x20ac) ++#define VLV_PCBR (VLV_DISPLAY_BASE + 0x2120) + #define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) + #define I915_DISPLAY_PORT_INTERRUPT (1<<17) + #define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15) +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 5a9b5bea5d10..78b523e688da 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2566,6 +2566,11 @@ static void valleyview_disable_rps(struct drm_device *dev) + spin_unlock_irq(&dev_priv->rps.lock); + + I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); ++ ++ if (dev_priv->vlv_pctx) { ++ drm_gem_object_unreference(&dev_priv->vlv_pctx->base); ++ dev_priv->vlv_pctx = NULL; ++ } + } + + int intel_enable_rc6(const struct drm_device *dev) +@@ -2860,6 +2865,48 @@ static void vlv_rps_timer_work(struct work_struct *work) + mutex_unlock(&dev_priv->rps.hw_lock); + } + ++static void valleyview_setup_pctx(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_i915_gem_object *pctx; ++ unsigned long pctx_paddr; ++ u32 pcbr; ++ int pctx_size = 24*1024; ++ ++ pcbr = I915_READ(VLV_PCBR); ++ if (pcbr) { ++ /* BIOS set it up already, grab the pre-alloc'd space */ ++ int pcbr_offset; ++ ++ pcbr_offset = (pcbr & (~4095)) - dev_priv->mm.stolen_base; ++ pctx = i915_gem_object_create_stolen_for_preallocated(dev_priv->dev, ++ pcbr_offset, ++ pcbr_offset, ++ pctx_size); ++ goto out; ++ } ++ ++ /* ++ * From the Gunit register HAS: ++ * The Gfx driver is expected to program this register and ensure ++ * proper allocation within Gfx stolen memory. For example, this ++ * register should be programmed such than the PCBR range does not ++ * overlap with other ranges, such as the frame buffer, protected ++ * memory, or any other relevant ranges. ++ */ ++ pctx = i915_gem_object_create_stolen(dev, pctx_size); ++ if (!pctx) { ++ DRM_DEBUG("not enough stolen space for PCTX, disabling\n"); ++ return; ++ } ++ ++ pctx_paddr = dev_priv->mm.stolen_base + pctx->stolen->start; ++ I915_WRITE(VLV_PCBR, pctx_paddr); ++ ++out: ++ dev_priv->vlv_pctx = pctx; ++} ++ + static void valleyview_enable_rps(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -2874,6 +2921,8 @@ static void valleyview_enable_rps(struct drm_device *dev) + I915_WRITE(GTFIFODBG, gtfifodbg); + } + ++ valleyview_setup_pctx(dev); ++ + gen6_gt_force_wake_get(dev_priv); + + I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0136-drm-i915-allow-stolen-pre-allocated-objects-to-avoid.patch b/patches.baytrail/0136-drm-i915-allow-stolen-pre-allocated-objects-to-avoid.patch new file mode 100644 index 000000000000..9ac896243038 --- /dev/null +++ b/patches.baytrail/0136-drm-i915-allow-stolen-pre-allocated-objects-to-avoid.patch @@ -0,0 +1,61 @@ +From 3106d2e0e3bdc0f36dd266a60029cd9e06587a3b Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Wed, 8 May 2013 10:45:14 -0700 +Subject: drm/i915: allow stolen, pre-allocated objects to avoid GTT allocation + v2 + +In some cases, we may not need GTT address space allocated to a stolen +object, so allow passing -1 to the preallocated function to indicate as +much. + +v2: remove BUG_ON(gtt_offset & 4095) now that -1 is allowed (Ville) + +Reviewed-by: Chris Wilson +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 3727d55e4d85836aa6cb759a965daaef88074150) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_stolen.c | 5 ++++- + drivers/gpu/drm/i915/intel_pm.c | 2 +- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 913994cd0a3a..89cbfab9570e 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -339,7 +339,6 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + + /* KISS and expect everything to be page-aligned */ + BUG_ON(stolen_offset & 4095); +- BUG_ON(gtt_offset & 4095); + BUG_ON(size & 4095); + + if (WARN_ON(size == 0)) +@@ -360,6 +359,10 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + return NULL; + } + ++ /* Some objects just need physical mem from stolen space */ ++ if (gtt_offset == -1) ++ return obj; ++ + /* To simplify the initialisation sequence between KMS and GTT, + * we allow construction of the stolen object prior to + * setting up the GTT space. The actual reservation will occur +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 78b523e688da..787813bb61c2 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2881,7 +2881,7 @@ static void valleyview_setup_pctx(struct drm_device *dev) + pcbr_offset = (pcbr & (~4095)) - dev_priv->mm.stolen_base; + pctx = i915_gem_object_create_stolen_for_preallocated(dev_priv->dev, + pcbr_offset, +- pcbr_offset, ++ -1, + pctx_size); + goto out; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0137-drm-i915-VLV-support-is-no-longer-preliminary.patch b/patches.baytrail/0137-drm-i915-VLV-support-is-no-longer-preliminary.patch new file mode 100644 index 000000000000..ba84acd21028 --- /dev/null +++ b/patches.baytrail/0137-drm-i915-VLV-support-is-no-longer-preliminary.patch @@ -0,0 +1,35 @@ +From 21c1350adda6b531d992f3ad8ce9ab4a7864a4b1 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Wed, 8 May 2013 10:45:15 -0700 +Subject: drm/i915: VLV support is no longer preliminary + +Works pretty well actually. + +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 590e4df8c82e6c2707ae12ba6672ab6fb9cd4b89) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index e91593a4d450..9e9b612828b2 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -990,12 +990,6 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + struct intel_device_info *intel_info = + (struct intel_device_info *) ent->driver_data; + +- if (intel_info->is_valleyview) +- if(!i915_preliminary_hw_support) { +- DRM_ERROR("Preliminary hardware support disabled\n"); +- return -ENODEV; +- } +- + /* Only bind to function 0 of the device. Early generations + * used function 1 as a placeholder for multi-head. This causes + * us confusion instead, especially on the systems where both +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0138-drm-i915-use-enc_to_intel_dp-instead-of-opencoding-t.patch b/patches.baytrail/0138-drm-i915-use-enc_to_intel_dp-instead-of-opencoding-t.patch new file mode 100644 index 000000000000..07a1df49d0f4 --- /dev/null +++ b/patches.baytrail/0138-drm-i915-use-enc_to_intel_dp-instead-of-opencoding-t.patch @@ -0,0 +1,45 @@ +From 1ab9e79d9c8d9ecba0446bd0871739fbe61e0efa Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Wed, 8 May 2013 13:14:02 +0300 +Subject: drm/i915: use enc_to_intel_dp() instead of opencoding the same + +Signed-off-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 9ff8c9bac2d78634f34d9b6e43e04bf316a7f456) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_drv.h | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index cb5e0cea4e93..ba12b5b47257 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -621,19 +621,17 @@ static inline struct intel_encoder *intel_attached_encoder(struct drm_connector + return to_intel_connector(connector)->encoder; + } + +-static inline struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder) +-{ +- struct intel_digital_port *intel_dig_port = +- container_of(encoder, struct intel_digital_port, base.base); +- return &intel_dig_port->dp; +-} +- + static inline struct intel_digital_port * + enc_to_dig_port(struct drm_encoder *encoder) + { + return container_of(encoder, struct intel_digital_port, base.base); + } + ++static inline struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder) ++{ ++ return &enc_to_dig_port(encoder)->dp; ++} ++ + static inline struct intel_digital_port * + dp_to_dig_port(struct intel_dp *intel_dp) + { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0139-drm-i915-hsw-replace-is_pch_edp-with-port-PORT_A.patch b/patches.baytrail/0139-drm-i915-hsw-replace-is_pch_edp-with-port-PORT_A.patch new file mode 100644 index 000000000000..c9a317a34c20 --- /dev/null +++ b/patches.baytrail/0139-drm-i915-hsw-replace-is_pch_edp-with-port-PORT_A.patch @@ -0,0 +1,32 @@ +From 73f5f53cbaa356d2a0c2f268caf707b14b89762d Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Wed, 8 May 2013 13:14:03 +0300 +Subject: drm/i915: hsw: replace !is_pch_edp() with port==PORT_A + +On HSW the CPU side eDP is always on port-A, the PCH side eDP is always +on port-D. + +Signed-off-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit d8e8b582b4e685a0e2a95ca0f4862582d465c649) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 87414ec78fd4..ee297a878aa5 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5981,7 +5981,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + for_each_encoder_on_crtc(dev, crtc, encoder) { + switch (encoder->type) { + case INTEL_OUTPUT_EDP: +- if (!intel_encoder_is_pch_edp(&encoder->base)) ++ if (enc_to_dig_port(&encoder->base)->port == PORT_A) + is_cpu_edp = true; + break; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0140-drm-i915-ilk-ivb-replace-is_pch_edp-with-port-PORT_A.patch b/patches.baytrail/0140-drm-i915-ilk-ivb-replace-is_pch_edp-with-port-PORT_A.patch new file mode 100644 index 000000000000..0d04295ce57e --- /dev/null +++ b/patches.baytrail/0140-drm-i915-ilk-ivb-replace-is_pch_edp-with-port-PORT_A.patch @@ -0,0 +1,58 @@ +From 78f768ff627c426dc0f4475fc751baf79d01d8bf Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Wed, 8 May 2013 13:14:04 +0300 +Subject: drm/i915: ilk-ivb: replace !is_pch_edp() with port==PORT_A + +On ILK-IVB the CPU side eDP is always on port-A. + +Also reduce somewhat the debug verbosity. + +v2: +- reduce debug verbosity + +Signed-off-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 2de6905f0a30c8fbe293e1e3ecdb766bbf5f7760) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index ee297a878aa5..b93b2407ab57 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5057,7 +5057,6 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) + u32 val, final; + bool has_lvds = false; + bool has_cpu_edp = false; +- bool has_pch_edp = false; + bool has_panel = false; + bool has_ck505 = false; + bool can_ssc = false; +@@ -5072,9 +5071,7 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) + break; + case INTEL_OUTPUT_EDP: + has_panel = true; +- if (intel_encoder_is_pch_edp(&encoder->base)) +- has_pch_edp = true; +- else ++ if (enc_to_dig_port(&encoder->base)->port == PORT_A) + has_cpu_edp = true; + break; + } +@@ -5088,9 +5085,8 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) + can_ssc = true; + } + +- DRM_DEBUG_KMS("has_panel %d has_lvds %d has_pch_edp %d has_cpu_edp %d has_ck505 %d\n", +- has_panel, has_lvds, has_pch_edp, has_cpu_edp, +- has_ck505); ++ DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d\n", ++ has_panel, has_lvds, has_ck505); + + /* Ironlake: try to setup display ref clock before DPLL + * enabling. This is only under driver's control after +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0141-drm-i915-stop-using-is_pch_edp-in-intel_dp_init_conn.patch b/patches.baytrail/0141-drm-i915-stop-using-is_pch_edp-in-intel_dp_init_conn.patch new file mode 100644 index 000000000000..7466cc9abeeb --- /dev/null +++ b/patches.baytrail/0141-drm-i915-stop-using-is_pch_edp-in-intel_dp_init_conn.patch @@ -0,0 +1,76 @@ +From 82e6f928e0ffcef0d452617b53f02273d666638c Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Wed, 8 May 2013 13:14:05 +0300 +Subject: drm/i915: stop using is_pch_edp() in intel_dp_init_connector() + +is_pch_edp() will be removed in a follow-up patch, so replace it +with a check for the port and VBT info (for port-D eDP). + +Also make things a bit clearer by using a switch on the ports. + +v2: +- make the comment about not setting the conder type for DP clearer + (Ville) + +Signed-off-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit f7d24902e197824eee717e4c3f406eb8623e67e0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 33 ++++++++++++++++++++++----------- + 1 file changed, 22 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index f0159cc5159a..76c4f114674b 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -3030,24 +3030,35 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + if (intel_dpd_is_edp(dev)) + intel_dp->is_pch_edp = true; + ++ type = DRM_MODE_CONNECTOR_DisplayPort; + /* + * FIXME : We need to initialize built-in panels before external panels. + * For X0, DP_C is fixed as eDP. Revisit this as part of VLV eDP cleanup + */ +- if (IS_VALLEYVIEW(dev) && port == PORT_C) { +- type = DRM_MODE_CONNECTOR_eDP; +- intel_encoder->type = INTEL_OUTPUT_EDP; +- } else if (port == PORT_A || is_pch_edp(intel_dp)) { ++ switch (port) { ++ case PORT_A: + type = DRM_MODE_CONNECTOR_eDP; +- intel_encoder->type = INTEL_OUTPUT_EDP; +- } else { +- /* The intel_encoder->type value may be INTEL_OUTPUT_UNKNOWN for +- * DDI or INTEL_OUTPUT_DISPLAYPORT for the older gens, so don't +- * rewrite it. +- */ +- type = DRM_MODE_CONNECTOR_DisplayPort; ++ break; ++ case PORT_C: ++ if (IS_VALLEYVIEW(dev)) ++ type = DRM_MODE_CONNECTOR_eDP; ++ break; ++ case PORT_D: ++ if (HAS_PCH_SPLIT(dev) && intel_dpd_is_edp(dev)) ++ type = DRM_MODE_CONNECTOR_eDP; ++ break; ++ default: /* silence GCC warning */ ++ break; + } + ++ /* ++ * For eDP we always set the encoder type to INTEL_OUTPUT_EDP, but ++ * for DP the encoder type can be set by the caller to ++ * INTEL_OUTPUT_UNKNOWN for DDI, so don't rewrite it. ++ */ ++ if (type == DRM_MODE_CONNECTOR_eDP) ++ intel_encoder->type = INTEL_OUTPUT_EDP; ++ + drm_connector_init(dev, connector, &intel_dp_connector_funcs, type); + drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0142-drm-i915-stop-using-is_pch_edp-in-is_cpu_edp.patch b/patches.baytrail/0142-drm-i915-stop-using-is_pch_edp-in-is_cpu_edp.patch new file mode 100644 index 000000000000..b24e6cec1ba9 --- /dev/null +++ b/patches.baytrail/0142-drm-i915-stop-using-is_pch_edp-in-is_cpu_edp.patch @@ -0,0 +1,56 @@ +From 7c355b40a2f117d867af4f2e8b7e83879b68eb01 Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Wed, 8 May 2013 13:14:06 +0300 +Subject: drm/i915: stop using is_pch_edp() in is_cpu_edp() + +is_pch_edp() will be removed by the next patch, so replace it by a check +for the port and device type. + +Signed-off-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 68b4d8247033b425ae948f02885c2aed5ae823f3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 76c4f114674b..e69c84b6838b 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -65,6 +65,13 @@ static bool is_pch_edp(struct intel_dp *intel_dp) + return intel_dp->is_pch_edp; + } + ++static struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp) ++{ ++ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); ++ ++ return intel_dig_port->base.base.dev; ++} ++ + /** + * is_cpu_edp - is the port on the CPU and attached to an eDP panel? + * @intel_dp: DP struct +@@ -73,14 +80,12 @@ static bool is_pch_edp(struct intel_dp *intel_dp) + */ + static bool is_cpu_edp(struct intel_dp *intel_dp) + { +- return is_edp(intel_dp) && !is_pch_edp(intel_dp); +-} +- +-static struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp) +-{ ++ struct drm_device *dev = intel_dp_to_dev(intel_dp); + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); ++ enum port port = intel_dig_port->port; + +- return intel_dig_port->base.base.dev; ++ return is_edp(intel_dp) && ++ (port == PORT_A || (port == PORT_C && IS_VALLEYVIEW(dev))); + } + + static struct intel_dp *intel_attached_dp(struct drm_connector *connector) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0143-drm-i915-remove-is_pch_edp-helpers-and-state-variabl.patch b/patches.baytrail/0143-drm-i915-remove-is_pch_edp-helpers-and-state-variabl.patch new file mode 100644 index 000000000000..630a917f9f6d --- /dev/null +++ b/patches.baytrail/0143-drm-i915-remove-is_pch_edp-helpers-and-state-variabl.patch @@ -0,0 +1,100 @@ +From 6f8562a66fcf33734e5aac04f1c0247ef277772b Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Wed, 8 May 2013 13:14:07 +0300 +Subject: drm/i915: remove is_pch_edp() helpers and state variable + +There are no more users for these, so remove them. + +Signed-off-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 15e6bf74b660c2e7aecc200ac77eb19eb6628240) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 36 ------------------------------------ + drivers/gpu/drm/i915/intel_drv.h | 2 -- + 2 files changed, 38 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index e69c84b6838b..a9a2ca201fa8 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -52,19 +52,6 @@ static bool is_edp(struct intel_dp *intel_dp) + return intel_dig_port->base.type == INTEL_OUTPUT_EDP; + } + +-/** +- * is_pch_edp - is the port on the PCH and attached to an eDP panel? +- * @intel_dp: DP struct +- * +- * Returns true if the given DP struct corresponds to a PCH DP port attached +- * to an eDP panel, false otherwise. Helpful for determining whether we +- * may need FDI resources for a given DP output or not. +- */ +-static bool is_pch_edp(struct intel_dp *intel_dp) +-{ +- return intel_dp->is_pch_edp; +-} +- + static struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp) + { + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); +@@ -93,25 +80,6 @@ static struct intel_dp *intel_attached_dp(struct drm_connector *connector) + return enc_to_intel_dp(&intel_attached_encoder(connector)->base); + } + +-/** +- * intel_encoder_is_pch_edp - is the given encoder a PCH attached eDP? +- * @encoder: DRM encoder +- * +- * Return true if @encoder corresponds to a PCH attached eDP panel. Needed +- * by intel_display.c. +- */ +-bool intel_encoder_is_pch_edp(struct drm_encoder *encoder) +-{ +- struct intel_dp *intel_dp; +- +- if (!encoder) +- return false; +- +- intel_dp = enc_to_intel_dp(encoder); +- +- return is_pch_edp(intel_dp); +-} +- + static void intel_dp_link_down(struct intel_dp *intel_dp); + + static int +@@ -3031,10 +2999,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + intel_dp->DP = I915_READ(intel_dp->output_reg); + intel_dp->attached_connector = intel_connector; + +- if (HAS_PCH_SPLIT(dev) && port == PORT_D) +- if (intel_dpd_is_edp(dev)) +- intel_dp->is_pch_edp = true; +- + type = DRM_MODE_CONNECTOR_DisplayPort; + /* + * FIXME : We need to initialize built-in panels before external panels. +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index ba12b5b47257..7744595b07e2 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -451,7 +451,6 @@ struct intel_dp { + uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS]; + struct i2c_adapter adapter; + struct i2c_algo_dp_aux_data algo; +- bool is_pch_edp; + uint8_t train_set[4]; + int panel_power_up_delay; + int panel_power_down_delay; +@@ -566,7 +565,6 @@ extern void ironlake_edp_panel_on(struct intel_dp *intel_dp); + extern void ironlake_edp_panel_off(struct intel_dp *intel_dp); + extern void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp); + extern void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync); +-extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder); + extern int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane); + extern void intel_flush_display_plane(struct drm_i915_private *dev_priv, + enum plane plane); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0144-drm-i915-print-DP-init-debug-messages-from-a-single-.patch b/patches.baytrail/0144-drm-i915-print-DP-init-debug-messages-from-a-single-.patch new file mode 100644 index 000000000000..aa250264b38f --- /dev/null +++ b/patches.baytrail/0144-drm-i915-print-DP-init-debug-messages-from-a-single-.patch @@ -0,0 +1,68 @@ +From c7340a18574d949caa2400ced8a3bb66531123e6 Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Wed, 8 May 2013 13:14:08 +0300 +Subject: drm/i915: print DP init debug messages from a single place + +Signed-off-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit e7281eab0bb4a5265593866d6f7acea2812fe0ec) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 12 +++--------- + drivers/gpu/drm/i915/intel_dp.c | 4 ++++ + 2 files changed, 7 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index b93b2407ab57..66e8ba541084 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8860,10 +8860,8 @@ static void intel_setup_outputs(struct drm_device *dev) + intel_hdmi_init(dev, GEN4_HDMIB, PORT_B); + } + +- if (!found && SUPPORTS_INTEGRATED_DP(dev)) { +- DRM_DEBUG_KMS("probing DP_B\n"); ++ if (!found && SUPPORTS_INTEGRATED_DP(dev)) + intel_dp_init(dev, DP_B, PORT_B); +- } + } + + /* Before G4X SDVOC doesn't have its own detect register */ +@@ -8879,17 +8877,13 @@ static void intel_setup_outputs(struct drm_device *dev) + DRM_DEBUG_KMS("probing HDMI on SDVOC\n"); + intel_hdmi_init(dev, GEN4_HDMIC, PORT_C); + } +- if (SUPPORTS_INTEGRATED_DP(dev)) { +- DRM_DEBUG_KMS("probing DP_C\n"); ++ if (SUPPORTS_INTEGRATED_DP(dev)) + intel_dp_init(dev, DP_C, PORT_C); +- } + } + + if (SUPPORTS_INTEGRATED_DP(dev) && +- (I915_READ(DP_D) & DP_DETECTED)) { +- DRM_DEBUG_KMS("probing DP_D\n"); ++ (I915_READ(DP_D) & DP_DETECTED)) + intel_dp_init(dev, DP_D, PORT_D); +- } + } else if (IS_GEN2(dev)) + intel_dvo_init(dev); + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index a9a2ca201fa8..58186ba367d1 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -3028,6 +3028,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + if (type == DRM_MODE_CONNECTOR_eDP) + intel_encoder->type = INTEL_OUTPUT_EDP; + ++ DRM_DEBUG_KMS("Adding %s connector on port %c\n", ++ type == DRM_MODE_CONNECTOR_eDP ? "eDP" : "DP", ++ port_name(port)); ++ + drm_connector_init(dev, connector, &intel_dp_connector_funcs, type); + drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0145-drm-i915-move-sdvo-TV-clock-computation-to-intel_sdv.patch b/patches.baytrail/0145-drm-i915-move-sdvo-TV-clock-computation-to-intel_sdv.patch new file mode 100644 index 000000000000..bd3d53242d5a --- /dev/null +++ b/patches.baytrail/0145-drm-i915-move-sdvo-TV-clock-computation-to-intel_sdv.patch @@ -0,0 +1,132 @@ +From b1dbf2e4102430c03e7b724ba06cb4b20acf54b7 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 30 Apr 2013 14:01:41 +0200 +Subject: drm/i915: move sdvo TV clock computation to intel_sdvo.c + +We have a very nice infrastructure for this now! + +Note that the multifunction sdvo support is pretty neatly broken: We +completely ignore userspace's request for which connector to wire up +with the encoder and just use whatever the last detect callback has +seen. + +Not something I'll fix in this patch, but unfortunately something +which is also broken in the DDI code ... + +v2: Don't call sdvo_tv_clock twice. + +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 70484559296623d49e559a3a10fa32fd2bc5dcc3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 30 ------------------------------ + drivers/gpu/drm/i915/intel_sdvo.c | 30 ++++++++++++++++++++++++++++++ + 2 files changed, 30 insertions(+), 30 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 66e8ba541084..1315576ee14b 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4296,30 +4296,6 @@ static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors) + return refclk; + } + +-static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc *crtc) +-{ +- unsigned dotclock = crtc->config.adjusted_mode.clock; +- struct dpll *clock = &crtc->config.dpll; +- +- /* SDVO TV has fixed PLL values depend on its clock range, +- this mirrors vbios setting. */ +- if (dotclock >= 100000 && dotclock < 140500) { +- clock->p1 = 2; +- clock->p2 = 10; +- clock->n = 3; +- clock->m1 = 16; +- clock->m2 = 8; +- } else if (dotclock >= 140500 && dotclock <= 200000) { +- clock->p1 = 1; +- clock->p2 = 10; +- clock->n = 6; +- clock->m1 = 12; +- clock->m2 = 8; +- } +- +- crtc->config.clock_set = true; +-} +- + static uint32_t pnv_dpll_compute_fp(struct dpll *dpll) + { + return (1 << dpll->n) << 16 | dpll->m1 << 8 | dpll->m2; +@@ -4983,9 +4959,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + intel_crtc->config.dpll.p2 = clock.p2; + } + +- if (is_sdvo && is_tv) +- i9xx_adjust_sdvo_tv_clock(intel_crtc); +- + if (IS_GEN2(dev)) + i8xx_update_pll(intel_crtc, adjusted_mode, + has_reduced_clock ? &reduced_clock : NULL, +@@ -5592,9 +5565,6 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, + reduced_clock); + } + +- if (is_sdvo && is_tv) +- i9xx_adjust_sdvo_tv_clock(to_intel_crtc(crtc)); +- + return true; + } + +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index d4ea6c265ce1..e1e59578db2d 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1041,6 +1041,32 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, + return true; + } + ++static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_config *pipe_config) ++{ ++ unsigned dotclock = pipe_config->adjusted_mode.clock; ++ struct dpll *clock = &pipe_config->dpll; ++ ++ /* SDVO TV has fixed PLL values depend on its clock range, ++ this mirrors vbios setting. */ ++ if (dotclock >= 100000 && dotclock < 140500) { ++ clock->p1 = 2; ++ clock->p2 = 10; ++ clock->n = 3; ++ clock->m1 = 16; ++ clock->m2 = 8; ++ } else if (dotclock >= 140500 && dotclock <= 200000) { ++ clock->p1 = 1; ++ clock->p2 = 10; ++ clock->n = 6; ++ clock->m1 = 12; ++ clock->m2 = 8; ++ } else { ++ WARN(1, "SDVO TV clock out of range: %i\n", dotclock); ++ } ++ ++ pipe_config->clock_set = true; ++} ++ + static bool intel_sdvo_compute_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) + { +@@ -1097,6 +1123,10 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder, + if (intel_sdvo->color_range) + pipe_config->limited_color_range = true; + ++ /* Clock computation needs to happen after pixel multiplier. */ ++ if (intel_sdvo->is_tv) ++ i9xx_adjust_sdvo_tv_clock(pipe_config); ++ + return true; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0146-drm-i915-drop-TVclock-special-casing-on-ilk.patch b/patches.baytrail/0146-drm-i915-drop-TVclock-special-casing-on-ilk.patch new file mode 100644 index 000000000000..21af39a6921b --- /dev/null +++ b/patches.baytrail/0146-drm-i915-drop-TVclock-special-casing-on-ilk.patch @@ -0,0 +1,57 @@ +From a3870966ac27eef95da068ecfb4ca761ceeda19b Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 30 Apr 2013 14:01:42 +0200 +Subject: drm/i915: drop TVclock special casing on ilk+ + +TV-out uses the same reference clock as everyone else. The only +difference seems to be in the slightly different CB tuning limit. + +Note that PLL_REF_INPUT_TVCLKINBC is a reserved value on ilk+. Also +strictly speaking we don't support native TV-out on ilk+, hence all +that code is dead. But Bspec still contains some residual mentions of +native TV-out on some pch-split platforms, so I've figured it doesn't +hurt to keep the code around a bit longer (e.g. in the cb tune +function). + +v2: Improve the commit message as Jani suggested in his review. + +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit b4c09f3bbda97ec685afd604d8a3a08c72465910) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 11 +---------- + 1 file changed, 1 insertion(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 1315576ee14b..d747f227bfe3 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5649,9 +5649,6 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, + if (intel_encoder->needs_tv_clock) + is_tv = true; + break; +- case INTEL_OUTPUT_TVOUT: +- is_tv = true; +- break; + } + + num_connectors++; +@@ -5710,13 +5707,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, + break; + } + +- if (is_sdvo && is_tv) +- dpll |= PLL_REF_INPUT_TVCLKINBC; +- else if (is_tv) +- /* XXX: just matching BIOS for now */ +- /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ +- dpll |= 3; +- else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) ++ if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) + dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; + else + dpll |= PLL_REF_INPUT_DREFCLK; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0147-drm-i915-rip-out-TV-out-lore.patch b/patches.baytrail/0147-drm-i915-rip-out-TV-out-lore.patch new file mode 100644 index 000000000000..f50fe2d37833 --- /dev/null +++ b/patches.baytrail/0147-drm-i915-rip-out-TV-out-lore.patch @@ -0,0 +1,43 @@ +From 7e26f0edcc0626e680878903e2806ae7695b9ef9 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 30 Apr 2013 14:01:43 +0200 +Subject: drm/i915: rip out TV-out lore ... + +This seems to be an impressive piece of copy&pasta lore. I've +checked all docs and on most platforms these bits are all MBZ, with +the exception of the SDVO pixel multiplier on gen3. On gen4 that +moved to a special DPLL_MD registers. + +No indication whatsoever that we actually need this for native +TV-out support. I suspect this started as a hack when we didn't +yet have proper pixel multiplier support in place for SDVO TV, but +then got stuck in a life of its own. + +Just rip it out. + +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit fec32900cc8f4ec8ad6b3007d2035e598f128f24) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index d747f227bfe3..ca2d851d3b73 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4596,10 +4596,6 @@ static void i9xx_update_pll(struct intel_crtc *crtc, + + if (is_sdvo && needs_tv_clock) + dpll |= PLL_REF_INPUT_TVCLKINBC; +- else if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_TVOUT)) +- /* XXX: just matching BIOS for now */ +- /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ +- dpll |= 3; + else if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) && + intel_panel_use_ssc(dev_priv) && num_connectors < 2) + dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0148-drm-i915-rip-out-now-unused-is_foo-tracking-from-crt.patch b/patches.baytrail/0148-drm-i915-rip-out-now-unused-is_foo-tracking-from-crt.patch new file mode 100644 index 000000000000..fd1fe64bf8a2 --- /dev/null +++ b/patches.baytrail/0148-drm-i915-rip-out-now-unused-is_foo-tracking-from-crt.patch @@ -0,0 +1,92 @@ +From 837ba391ce81f7fee547b684e7ddb89e86f1a219 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 30 Apr 2013 14:01:44 +0200 +Subject: drm/i915: rip out now unused is_foo tracking from crtc code + +More ugly stuff gone for good! The big special case left now is +lvds (which is indeed really special). + +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit a16af721e83466b965c7e53d5350e16abf9691e4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 28 +++------------------------- + 1 file changed, 3 insertions(+), 25 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index ca2d851d3b73..72433196d976 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4890,8 +4890,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + int refclk, num_connectors = 0; + intel_clock_t clock, reduced_clock; + u32 dspcntr; +- bool ok, has_reduced_clock = false, is_sdvo = false; +- bool is_lvds = false, is_tv = false; ++ bool ok, has_reduced_clock = false; ++ bool is_lvds = false; + struct intel_encoder *encoder; + const intel_limit_t *limit; + int ret; +@@ -4901,15 +4901,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + case INTEL_OUTPUT_LVDS: + is_lvds = true; + break; +- case INTEL_OUTPUT_SDVO: +- case INTEL_OUTPUT_HDMI: +- is_sdvo = true; +- if (encoder->needs_tv_clock) +- is_tv = true; +- break; +- case INTEL_OUTPUT_TVOUT: +- is_tv = true; +- break; + } + + num_connectors++; +@@ -5345,7 +5336,6 @@ static int ironlake_get_refclk(struct drm_crtc *crtc) + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_encoder *encoder; +- struct intel_encoder *edp_encoder = NULL; + int num_connectors = 0; + bool is_lvds = false; + +@@ -5354,9 +5344,6 @@ static int ironlake_get_refclk(struct drm_crtc *crtc) + case INTEL_OUTPUT_LVDS: + is_lvds = true; + break; +- case INTEL_OUTPUT_EDP: +- edp_encoder = encoder; +- break; + } + num_connectors++; + } +@@ -5515,22 +5502,13 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, + struct intel_encoder *intel_encoder; + int refclk; + const intel_limit_t *limit; +- bool ret, is_sdvo = false, is_tv = false, is_lvds = false; ++ bool ret, is_lvds = false; + + for_each_encoder_on_crtc(dev, crtc, intel_encoder) { + switch (intel_encoder->type) { + case INTEL_OUTPUT_LVDS: + is_lvds = true; + break; +- case INTEL_OUTPUT_SDVO: +- case INTEL_OUTPUT_HDMI: +- is_sdvo = true; +- if (intel_encoder->needs_tv_clock) +- is_tv = true; +- break; +- case INTEL_OUTPUT_TVOUT: +- is_tv = true; +- break; + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0149-drm-i915-make-SDVO-TV-out-work-for-multifunction-dev.patch b/patches.baytrail/0149-drm-i915-make-SDVO-TV-out-work-for-multifunction-dev.patch new file mode 100644 index 000000000000..919c36df64ee --- /dev/null +++ b/patches.baytrail/0149-drm-i915-make-SDVO-TV-out-work-for-multifunction-dev.patch @@ -0,0 +1,156 @@ +From 023747d4c8ddcacb3bdc2b5944f2517f26e2207f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 30 Apr 2013 14:01:45 +0200 +Subject: drm/i915: make SDVO TV-out work for multifunction devices + +We need to track this correctly. While at it shovel the boolean +to track whether the sdvo is in tv mode or not into pipe_config. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=36997 +Tested-by: Pierre Assal +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=63609 +Tested-by: cancan,feng +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 09ede5414f0215461c933032630bf9c3a61a8ba3) +[dbasehore: Fix simple conflict by using new version and compile error by +removing no longer used function argument] +Signed-off-by: Derek Basehore + +Conflicts: + drivers/gpu/drm/i915/intel_display.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 14 +++++--------- + drivers/gpu/drm/i915/intel_drv.h | 5 ++++- + drivers/gpu/drm/i915/intel_sdvo.c | 8 ++------ + 3 files changed, 11 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 72433196d976..0cfe23a65439 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4534,8 +4534,7 @@ static void vlv_update_pll(struct intel_crtc *crtc) + + static void i9xx_update_pll(struct intel_crtc *crtc, + intel_clock_t *reduced_clock, +- int num_connectors, +- bool needs_tv_clock) ++ int num_connectors) + { + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -4594,7 +4593,7 @@ static void i9xx_update_pll(struct intel_crtc *crtc, + if (INTEL_INFO(dev)->gen >= 4) + dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); + +- if (is_sdvo && needs_tv_clock) ++ if (crtc->config.sdvo_tv_clock) + dpll |= PLL_REF_INPUT_TVCLKINBC; + else if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) && + intel_panel_use_ssc(dev_priv) && num_connectors < 2) +@@ -4955,8 +4954,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + else + i9xx_update_pll(intel_crtc, + has_reduced_clock ? &reduced_clock : NULL, +- num_connectors, +- is_sdvo && is_tv); ++ num_connectors); + + /* Set up the display plane register */ + dspcntr = DISPPLANE_GAMMA_ENABLE; +@@ -5610,7 +5608,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, + struct intel_encoder *intel_encoder; + uint32_t dpll; + int factor, num_connectors = 0; +- bool is_lvds = false, is_sdvo = false, is_tv = false; ++ bool is_lvds = false, is_sdvo = false; + + for_each_encoder_on_crtc(dev, crtc, intel_encoder) { + switch (intel_encoder->type) { +@@ -5620,8 +5618,6 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, + case INTEL_OUTPUT_SDVO: + case INTEL_OUTPUT_HDMI: + is_sdvo = true; +- if (intel_encoder->needs_tv_clock) +- is_tv = true; + break; + } + +@@ -5635,7 +5631,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, + dev_priv->lvds_ssc_freq == 100) || + (HAS_PCH_IBX(dev) && intel_is_dual_link_lvds(dev))) + factor = 25; +- } else if (is_sdvo && is_tv) ++ } else if (intel_crtc->config.sdvo_tv_clock) + factor = 20; + + if (ironlake_needs_fb_cb_tune(&intel_crtc->config.dpll, factor)) +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 7744595b07e2..8ef7496b74ef 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -120,7 +120,6 @@ struct intel_encoder { + struct intel_crtc *new_crtc; + + int type; +- bool needs_tv_clock; + /* + * Intel hw has only one MUX where encoders could be clone, hence a + * simple flag is enough to compute the possible_clones mask. +@@ -223,6 +222,10 @@ struct intel_crtc_config { + /* Controls for the clock computation, to override various stages. */ + bool clock_set; + ++ /* SDVO TV has a bunch of special case. To make multifunction encoders ++ * work correctly, we need to track this at runtime.*/ ++ bool sdvo_tv_clock; ++ + /* + * crtc bandwidth limit, don't increase pipe bpp or clock if not really + * required. This is set in the 2nd loop of calling encoder's +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index e1e59578db2d..03831c95b228 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1092,6 +1092,7 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder, + (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, + mode, + adjusted_mode); ++ pipe_config->sdvo_tv_clock = true; + } else if (intel_sdvo->is_lvds) { + if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, + intel_sdvo->sdvo_lvds_fixed_mode)) +@@ -1655,12 +1656,9 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) + if (ret == connector_status_connected) { + intel_sdvo->is_tv = false; + intel_sdvo->is_lvds = false; +- intel_sdvo->base.needs_tv_clock = false; + +- if (response & SDVO_TV_MASK) { ++ if (response & SDVO_TV_MASK) + intel_sdvo->is_tv = true; +- intel_sdvo->base.needs_tv_clock = true; +- } + if (response & SDVO_LVDS_MASK) + intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL; + } +@@ -2359,7 +2357,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) + intel_sdvo_connector->output_flag = type; + + intel_sdvo->is_tv = true; +- intel_sdvo->base.needs_tv_clock = true; + + intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); + +@@ -2447,7 +2444,6 @@ static bool + intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) + { + intel_sdvo->is_tv = false; +- intel_sdvo->base.needs_tv_clock = false; + intel_sdvo->is_lvds = false; + + /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0150-drm-i915-Organize-VBT-stuff-inside-drm_i915_private.patch b/patches.baytrail/0150-drm-i915-Organize-VBT-stuff-inside-drm_i915_private.patch new file mode 100644 index 000000000000..bb98dfe1a1bf --- /dev/null +++ b/patches.baytrail/0150-drm-i915-Organize-VBT-stuff-inside-drm_i915_private.patch @@ -0,0 +1,666 @@ +From 82b4a30a84555370265717f340fde4dae7ecf935 Mon Sep 17 00:00:00 2001 +From: James Ausmus +Date: Mon, 23 Sep 2013 16:51:08 -0700 +Subject: drm/i915: Organize VBT stuff inside drm_i915_private + +drm_i915_private is getting bigger and bigger when adding new vbt stuff. +So, the better way of getting drm_i915_private organized is to create +a special structure for vbt stuff. + +v2: Basically conflicts fixes + +Reviewed-by: Jani Nikula +Signed-off-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 41aa344866e3ba1d117a798355c35d44d7cc6318) + +Conflicts: + drivers/gpu/drm/i915/intel_sdvo.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 8 +-- + drivers/gpu/drm/i915/i915_drv.h | 57 +++++++++++--------- + drivers/gpu/drm/i915/intel_bios.c | 100 +++++++++++++++++------------------ + drivers/gpu/drm/i915/intel_crt.c | 4 +- + drivers/gpu/drm/i915/intel_display.c | 12 ++--- + drivers/gpu/drm/i915/intel_dp.c | 18 +++---- + drivers/gpu/drm/i915/intel_lvds.c | 16 +++--- + drivers/gpu/drm/i915/intel_pm.c | 2 +- + drivers/gpu/drm/i915/intel_sdvo.c | 24 ++++----- + drivers/gpu/drm/i915/intel_tv.c | 8 +-- + 10 files changed, 127 insertions(+), 122 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 68a57031db2c..18caacf647d0 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1744,10 +1744,10 @@ int i915_driver_unload(struct drm_device *dev) + * free the memory space allocated for the child device + * config parsed from VBT + */ +- if (dev_priv->child_dev && dev_priv->child_dev_num) { +- kfree(dev_priv->child_dev); +- dev_priv->child_dev = NULL; +- dev_priv->child_dev_num = 0; ++ if (dev_priv->vbt.child_dev && dev_priv->vbt.child_dev_num) { ++ kfree(dev_priv->vbt.child_dev); ++ dev_priv->vbt.child_dev = NULL; ++ dev_priv->vbt.child_dev_num = 0; + } + + vga_switcheroo_unregister_client(dev->pdev); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 05752eb2eb0c..dc2997828af1 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -892,6 +892,37 @@ enum modeset_restore { + MODESET_SUSPENDED, + }; + ++struct intel_vbt_data { ++ struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */ ++ struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */ ++ ++ /* Feature bits */ ++ unsigned int int_tv_support:1; ++ unsigned int lvds_dither:1; ++ unsigned int lvds_vbt:1; ++ unsigned int int_crt_support:1; ++ unsigned int lvds_use_ssc:1; ++ unsigned int display_clock_mode:1; ++ unsigned int fdi_rx_polarity_inverted:1; ++ int lvds_ssc_freq; ++ unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */ ++ ++ /* eDP */ ++ int edp_rate; ++ int edp_lanes; ++ int edp_preemphasis; ++ int edp_vswing; ++ bool edp_initialized; ++ bool edp_support; ++ int edp_bpp; ++ struct edp_power_seq edp_pps; ++ ++ int crt_ddc_pin; ++ ++ int child_dev_num; ++ struct child_device_config *child_dev; ++}; ++ + typedef struct drm_i915_private { + struct drm_device *dev; + struct kmem_cache *slab; +@@ -971,6 +1002,7 @@ typedef struct drm_i915_private { + struct intel_fbc_work *fbc_work; + + struct intel_opregion opregion; ++ struct intel_vbt_data vbt; + + /* overlay */ + struct intel_overlay *overlay; +@@ -987,31 +1019,8 @@ typedef struct drm_i915_private { + /* LVDS info */ + struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */ + struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */ +- +- /* Feature bits from the VBIOS */ +- unsigned int int_tv_support:1; +- unsigned int lvds_dither:1; +- unsigned int lvds_vbt:1; +- unsigned int int_crt_support:1; +- unsigned int lvds_use_ssc:1; +- unsigned int display_clock_mode:1; +- unsigned int fdi_rx_polarity_inverted:1; +- int lvds_ssc_freq; +- unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */ +- struct { +- int rate; +- int lanes; +- int preemphasis; +- int vswing; +- +- bool initialized; +- bool support; +- int bpp; +- struct edp_power_seq pps; +- } edp; + bool no_aux_handshake; + +- int crt_ddc_pin; + struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */ + int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ + int num_fence_regs; /* 8 on pre-965, 16 otherwise */ +@@ -1053,8 +1062,6 @@ typedef struct drm_i915_private { + /* indicates the reduced downclock for LVDS*/ + int lvds_downclock; + u16 orig_clock; +- int child_dev_num; +- struct child_device_config *child_dev; + + bool mchbar_need_disable; + +diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c +index 95070b2124c6..53f2bed8bc5f 100644 +--- a/drivers/gpu/drm/i915/intel_bios.c ++++ b/drivers/gpu/drm/i915/intel_bios.c +@@ -212,7 +212,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, + if (!lvds_options) + return; + +- dev_priv->lvds_dither = lvds_options->pixel_dither; ++ dev_priv->vbt.lvds_dither = lvds_options->pixel_dither; + if (lvds_options->panel_type == 0xff) + return; + +@@ -226,7 +226,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, + if (!lvds_lfp_data_ptrs) + return; + +- dev_priv->lvds_vbt = 1; ++ dev_priv->vbt.lvds_vbt = 1; + + panel_dvo_timing = get_lvds_dvo_timing(lvds_lfp_data, + lvds_lfp_data_ptrs, +@@ -238,7 +238,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, + + fill_detail_timing_data(panel_fixed_mode, panel_dvo_timing); + +- dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode; ++ dev_priv->vbt.lfp_lvds_vbt_mode = panel_fixed_mode; + + DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n"); + drm_mode_debug_printmodeline(panel_fixed_mode); +@@ -274,9 +274,9 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, + /* check the resolution, just to be sure */ + if (fp_timing->x_res == panel_fixed_mode->hdisplay && + fp_timing->y_res == panel_fixed_mode->vdisplay) { +- dev_priv->bios_lvds_val = fp_timing->lvds_reg_val; ++ dev_priv->vbt.bios_lvds_val = fp_timing->lvds_reg_val; + DRM_DEBUG_KMS("VBT initial LVDS value %x\n", +- dev_priv->bios_lvds_val); ++ dev_priv->vbt.bios_lvds_val); + } + } + } +@@ -316,7 +316,7 @@ parse_sdvo_panel_data(struct drm_i915_private *dev_priv, + + fill_detail_timing_data(panel_fixed_mode, dvo_timing + index); + +- dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode; ++ dev_priv->vbt.sdvo_lvds_vbt_mode = panel_fixed_mode; + + DRM_DEBUG_KMS("Found SDVO panel mode in BIOS VBT tables:\n"); + drm_mode_debug_printmodeline(panel_fixed_mode); +@@ -345,20 +345,20 @@ parse_general_features(struct drm_i915_private *dev_priv, + + general = find_section(bdb, BDB_GENERAL_FEATURES); + if (general) { +- dev_priv->int_tv_support = general->int_tv_support; +- dev_priv->int_crt_support = general->int_crt_support; +- dev_priv->lvds_use_ssc = general->enable_ssc; +- dev_priv->lvds_ssc_freq = ++ dev_priv->vbt.int_tv_support = general->int_tv_support; ++ dev_priv->vbt.int_crt_support = general->int_crt_support; ++ dev_priv->vbt.lvds_use_ssc = general->enable_ssc; ++ dev_priv->vbt.lvds_ssc_freq = + intel_bios_ssc_frequency(dev, general->ssc_freq); +- dev_priv->display_clock_mode = general->display_clock_mode; +- dev_priv->fdi_rx_polarity_inverted = general->fdi_rx_polarity_inverted; ++ dev_priv->vbt.display_clock_mode = general->display_clock_mode; ++ dev_priv->vbt.fdi_rx_polarity_inverted = general->fdi_rx_polarity_inverted; + DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d fdi_rx_polarity_inverted %d\n", +- dev_priv->int_tv_support, +- dev_priv->int_crt_support, +- dev_priv->lvds_use_ssc, +- dev_priv->lvds_ssc_freq, +- dev_priv->display_clock_mode, +- dev_priv->fdi_rx_polarity_inverted); ++ dev_priv->vbt.int_tv_support, ++ dev_priv->vbt.int_crt_support, ++ dev_priv->vbt.lvds_use_ssc, ++ dev_priv->vbt.lvds_ssc_freq, ++ dev_priv->vbt.display_clock_mode, ++ dev_priv->vbt.fdi_rx_polarity_inverted); + } + } + +@@ -375,7 +375,7 @@ parse_general_definitions(struct drm_i915_private *dev_priv, + int bus_pin = general->crt_ddc_gmbus_pin; + DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin); + if (intel_gmbus_is_port_valid(bus_pin)) +- dev_priv->crt_ddc_pin = bus_pin; ++ dev_priv->vbt.crt_ddc_pin = bus_pin; + } else { + DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n", + block_size); +@@ -486,7 +486,7 @@ parse_driver_features(struct drm_i915_private *dev_priv, + + if (SUPPORTS_EDP(dev) && + driver->lvds_config == BDB_DRIVER_FEATURE_EDP) +- dev_priv->edp.support = 1; ++ dev_priv->vbt.edp_support = 1; + + if (driver->dual_frequency) + dev_priv->render_reclock_avail = true; +@@ -501,20 +501,20 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) + + edp = find_section(bdb, BDB_EDP); + if (!edp) { +- if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) ++ if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->vbt.edp_support) + DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n"); + return; + } + + switch ((edp->color_depth >> (panel_type * 2)) & 3) { + case EDP_18BPP: +- dev_priv->edp.bpp = 18; ++ dev_priv->vbt.edp_bpp = 18; + break; + case EDP_24BPP: +- dev_priv->edp.bpp = 24; ++ dev_priv->vbt.edp_bpp = 24; + break; + case EDP_30BPP: +- dev_priv->edp.bpp = 30; ++ dev_priv->vbt.edp_bpp = 30; + break; + } + +@@ -522,48 +522,48 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) + edp_pps = &edp->power_seqs[panel_type]; + edp_link_params = &edp->link_params[panel_type]; + +- dev_priv->edp.pps = *edp_pps; ++ dev_priv->vbt.edp_pps = *edp_pps; + +- dev_priv->edp.rate = edp_link_params->rate ? DP_LINK_BW_2_7 : ++ dev_priv->vbt.edp_rate = edp_link_params->rate ? DP_LINK_BW_2_7 : + DP_LINK_BW_1_62; + switch (edp_link_params->lanes) { + case 0: +- dev_priv->edp.lanes = 1; ++ dev_priv->vbt.edp_lanes = 1; + break; + case 1: +- dev_priv->edp.lanes = 2; ++ dev_priv->vbt.edp_lanes = 2; + break; + case 3: + default: +- dev_priv->edp.lanes = 4; ++ dev_priv->vbt.edp_lanes = 4; + break; + } + switch (edp_link_params->preemphasis) { + case 0: +- dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_0; ++ dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_0; + break; + case 1: +- dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5; ++ dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5; + break; + case 2: +- dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_6; ++ dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_6; + break; + case 3: +- dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5; ++ dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5; + break; + } + switch (edp_link_params->vswing) { + case 0: +- dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_400; ++ dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_400; + break; + case 1: +- dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_600; ++ dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_600; + break; + case 2: +- dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_800; ++ dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_800; + break; + case 3: +- dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_1200; ++ dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_1200; + break; + } + } +@@ -611,13 +611,13 @@ parse_device_mapping(struct drm_i915_private *dev_priv, + DRM_DEBUG_KMS("no child dev is parsed from VBT\n"); + return; + } +- dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL); +- if (!dev_priv->child_dev) { ++ dev_priv->vbt.child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL); ++ if (!dev_priv->vbt.child_dev) { + DRM_DEBUG_KMS("No memory space for child device\n"); + return; + } + +- dev_priv->child_dev_num = count; ++ dev_priv->vbt.child_dev_num = count; + count = 0; + for (i = 0; i < child_device_num; i++) { + p_child = &(p_defs->devices[i]); +@@ -625,7 +625,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, + /* skip the device block if device type is invalid */ + continue; + } +- child_dev_ptr = dev_priv->child_dev + count; ++ child_dev_ptr = dev_priv->vbt.child_dev + count; + count++; + memcpy((void *)child_dev_ptr, (void *)p_child, + sizeof(*p_child)); +@@ -638,23 +638,23 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) + { + struct drm_device *dev = dev_priv->dev; + +- dev_priv->crt_ddc_pin = GMBUS_PORT_VGADDC; ++ dev_priv->vbt.crt_ddc_pin = GMBUS_PORT_VGADDC; + + /* LFP panel data */ +- dev_priv->lvds_dither = 1; +- dev_priv->lvds_vbt = 0; ++ dev_priv->vbt.lvds_dither = 1; ++ dev_priv->vbt.lvds_vbt = 0; + + /* SDVO panel data */ +- dev_priv->sdvo_lvds_vbt_mode = NULL; ++ dev_priv->vbt.sdvo_lvds_vbt_mode = NULL; + + /* general features */ +- dev_priv->int_tv_support = 1; +- dev_priv->int_crt_support = 1; ++ dev_priv->vbt.int_tv_support = 1; ++ dev_priv->vbt.int_crt_support = 1; + + /* Default to using SSC */ +- dev_priv->lvds_use_ssc = 1; +- dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1); +- DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq); ++ dev_priv->vbt.lvds_use_ssc = 1; ++ dev_priv->vbt.lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1); ++ DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->vbt.lvds_ssc_freq); + } + + static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id) +diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c +index 1b9ebf4b77fc..66a0c6f0bb81 100644 +--- a/drivers/gpu/drm/i915/intel_crt.c ++++ b/drivers/gpu/drm/i915/intel_crt.c +@@ -435,7 +435,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector) + + BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG); + +- i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); ++ i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin); + edid = intel_crt_get_edid(connector, i2c); + + if (edid) { +@@ -641,7 +641,7 @@ static int intel_crt_get_modes(struct drm_connector *connector) + int ret; + struct i2c_adapter *i2c; + +- i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); ++ i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin); + ret = intel_crt_ddc_get_modes(connector, i2c); + if (ret || !IS_G4X(dev)) + return ret; +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 0cfe23a65439..cd9600956dd7 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4248,7 +4248,7 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) + { + if (i915_panel_use_ssc >= 0) + return i915_panel_use_ssc != 0; +- return dev_priv->lvds_use_ssc ++ return dev_priv->vbt.lvds_use_ssc + && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE); + } + +@@ -4284,7 +4284,7 @@ static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors) + refclk = vlv_get_refclk(crtc); + } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + intel_panel_use_ssc(dev_priv) && num_connectors < 2) { +- refclk = dev_priv->lvds_ssc_freq * 1000; ++ refclk = dev_priv->vbt.lvds_ssc_freq * 1000; + DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", + refclk / 1000); + } else if (!IS_GEN2(dev)) { +@@ -5036,7 +5036,7 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) + } + + if (HAS_PCH_IBX(dev)) { +- has_ck505 = dev_priv->display_clock_mode; ++ has_ck505 = dev_priv->vbt.display_clock_mode; + can_ssc = has_ck505; + } else { + has_ck505 = false; +@@ -5348,8 +5348,8 @@ static int ironlake_get_refclk(struct drm_crtc *crtc) + + if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { + DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", +- dev_priv->lvds_ssc_freq); +- return dev_priv->lvds_ssc_freq * 1000; ++ dev_priv->vbt.lvds_ssc_freq); ++ return dev_priv->vbt.lvds_ssc_freq * 1000; + } + + return 120000; +@@ -5628,7 +5628,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, + factor = 21; + if (is_lvds) { + if ((intel_panel_use_ssc(dev_priv) && +- dev_priv->lvds_ssc_freq == 100) || ++ dev_priv->vbt.lvds_ssc_freq == 100) || + (HAS_PCH_IBX(dev) && intel_is_dual_link_lvds(dev))) + factor = 25; + } else if (intel_crtc->config.sdvo_tv_clock) +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 58186ba367d1..848d3d436f7e 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -738,10 +738,10 @@ intel_dp_compute_config(struct intel_encoder *encoder, + * recomments. This means we'll up-dither 16bpp framebuffers on + * high-depth panels. + */ +- if (is_edp(intel_dp) && dev_priv->edp.bpp) { ++ if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp) { + DRM_DEBUG_KMS("forcing bpp for eDP panel to BIOS-provided %i\n", +- dev_priv->edp.bpp); +- bpp = dev_priv->edp.bpp; ++ dev_priv->vbt.edp_bpp); ++ bpp = dev_priv->vbt.edp_bpp; + } + + for (; bpp >= 6*3; bpp -= 2*3) { +@@ -2795,11 +2795,11 @@ bool intel_dpd_is_edp(struct drm_device *dev) + struct child_device_config *p_child; + int i; + +- if (!dev_priv->child_dev_num) ++ if (!dev_priv->vbt.child_dev_num) + return false; + +- for (i = 0; i < dev_priv->child_dev_num; i++) { +- p_child = dev_priv->child_dev + i; ++ for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { ++ p_child = dev_priv->vbt.child_dev + i; + + if (p_child->dvo_port == PORT_IDPD && + p_child->device_type == DEVICE_TYPE_eDP) +@@ -2877,7 +2877,7 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, + DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n", + cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12); + +- vbt = dev_priv->edp.pps; ++ vbt = dev_priv->vbt.edp_pps; + + /* Upper limits from eDP 1.3 spec. Note that we use the clunky units of + * our hw here, which are all in 100usec. */ +@@ -3147,8 +3147,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + } + + /* fallback to VBT if available for eDP */ +- if (!fixed_mode && dev_priv->lfp_lvds_vbt_mode) { +- fixed_mode = drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); ++ if (!fixed_mode && dev_priv->vbt.lfp_lvds_vbt_mode) { ++ fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode); + if (fixed_mode) + fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; + } +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index b314ef3ee644..04da66914757 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -767,11 +767,11 @@ static bool lvds_is_present_in_vbt(struct drm_device *dev, + struct drm_i915_private *dev_priv = dev->dev_private; + int i; + +- if (!dev_priv->child_dev_num) ++ if (!dev_priv->vbt.child_dev_num) + return true; + +- for (i = 0; i < dev_priv->child_dev_num; i++) { +- struct child_device_config *child = dev_priv->child_dev + i; ++ for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { ++ struct child_device_config *child = dev_priv->vbt.child_dev + i; + + /* If the device type is not LFP, continue. + * We have to check both the new identifiers as well as the +@@ -859,7 +859,7 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder) + */ + val = I915_READ(lvds_encoder->reg); + if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED))) +- val = dev_priv->bios_lvds_val; ++ val = dev_priv->vbt.bios_lvds_val; + + return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP; + } +@@ -919,7 +919,7 @@ bool intel_lvds_init(struct drm_device *dev) + if (HAS_PCH_SPLIT(dev)) { + if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) + return false; +- if (dev_priv->edp.support) { ++ if (dev_priv->vbt.edp_support) { + DRM_DEBUG_KMS("disable LVDS for eDP support\n"); + return false; + } +@@ -1037,11 +1037,11 @@ bool intel_lvds_init(struct drm_device *dev) + } + + /* Failed to get EDID, what about VBT? */ +- if (dev_priv->lfp_lvds_vbt_mode) { ++ if (dev_priv->vbt.lfp_lvds_vbt_mode) { + DRM_DEBUG_KMS("using mode from VBT: "); +- drm_mode_debug_printmodeline(dev_priv->lfp_lvds_vbt_mode); ++ drm_mode_debug_printmodeline(dev_priv->vbt.lfp_lvds_vbt_mode); + +- fixed_mode = drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); ++ fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode); + if (fixed_mode) { + fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; + goto out; +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 787813bb61c2..df200a67492f 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3889,7 +3889,7 @@ static void cpt_init_clock_gating(struct drm_device *dev) + val = I915_READ(TRANS_CHICKEN2(pipe)); + val |= TRANS_CHICKEN2_TIMING_OVERRIDE; + val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED; +- if (dev_priv->fdi_rx_polarity_inverted) ++ if (dev_priv->vbt.fdi_rx_polarity_inverted) + val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED; + val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK; + val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER; +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 03831c95b228..474fa8addab1 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1526,7 +1526,7 @@ intel_sdvo_get_analog_edid(struct drm_connector *connector) + + return drm_get_edid(connector, + intel_gmbus_get_adapter(dev_priv, +- dev_priv->crt_ddc_pin)); ++ dev_priv->vbt.crt_ddc_pin)); + } + + static enum drm_connector_status +@@ -1800,21 +1800,12 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) + struct drm_display_mode *newmode; + + /* +- * Attempt to get the mode list from DDC. +- * Assume that the preferred modes are +- * arranged in priority order. +- */ +- intel_ddc_get_modes(connector, &intel_sdvo->ddc); +- +- /* + * Fetch modes from VBT. For SDVO prefer the VBT mode since some +- * SDVO->LVDS transcoders can't cope with the EDID mode. Since +- * drm_mode_probed_add adds the mode at the head of the list we add it +- * last. ++ * SDVO->LVDS transcoders can't cope with the EDID mode. + */ +- if (dev_priv->sdvo_lvds_vbt_mode != NULL) { ++ if (dev_priv->vbt.sdvo_lvds_vbt_mode != NULL) { + newmode = drm_mode_duplicate(connector->dev, +- dev_priv->sdvo_lvds_vbt_mode); ++ dev_priv->vbt.sdvo_lvds_vbt_mode); + if (newmode != NULL) { + /* Guarantee the mode is preferred */ + newmode->type = (DRM_MODE_TYPE_PREFERRED | +@@ -1823,6 +1814,13 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) + } + } + ++ /* ++ * Attempt to get the mode list from DDC. ++ * Assume that the preferred modes are ++ * arranged in priority order. ++ */ ++ intel_ddc_get_modes(connector, &intel_sdvo->ddc); ++ + list_for_each_entry(newmode, &connector->probed_modes, head) { + if (newmode->type & DRM_MODE_TYPE_PREFERRED) { + intel_sdvo->sdvo_lvds_fixed_mode = +diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c +index a202d8d08c56..a2fb39dede3c 100644 +--- a/drivers/gpu/drm/i915/intel_tv.c ++++ b/drivers/gpu/drm/i915/intel_tv.c +@@ -1529,12 +1529,12 @@ static int tv_is_present_in_vbt(struct drm_device *dev) + struct child_device_config *p_child; + int i, ret; + +- if (!dev_priv->child_dev_num) ++ if (!dev_priv->vbt.child_dev_num) + return 1; + + ret = 0; +- for (i = 0; i < dev_priv->child_dev_num; i++) { +- p_child = dev_priv->child_dev + i; ++ for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { ++ p_child = dev_priv->vbt.child_dev + i; + /* + * If the device type is not TV, continue. + */ +@@ -1572,7 +1572,7 @@ intel_tv_init(struct drm_device *dev) + return; + } + /* Even if we have an encoder we may not have a connector */ +- if (!dev_priv->int_tv_support) ++ if (!dev_priv->vbt.int_tv_support) + return; + + /* +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0151-drm-i915-Add-support-for-FBC-on-Ivybridge.patch b/patches.baytrail/0151-drm-i915-Add-support-for-FBC-on-Ivybridge.patch new file mode 100644 index 000000000000..4e646d215076 --- /dev/null +++ b/patches.baytrail/0151-drm-i915-Add-support-for-FBC-on-Ivybridge.patch @@ -0,0 +1,145 @@ +From d99cb6d41f54512a1db8488fdf35847fc98bb419 Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Mon, 6 May 2013 19:37:33 -0300 +Subject: drm/i915: Add support for FBC on Ivybridge. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch introduce Frame Buffer Compression (FBC) support for IVB, +without enabling it by default. +It adds a new function gen7_enable_fbc to avoid getting +ironlake_enable_fbc messed with many IS_IVYBRIDGE checks. + +v2: Fixes from Ville. + * Fix Plane. FBC is tied to primary plane A in HSW + * Fix DPFC initial write to avoid let trash on the register. +v3: Checking for bad plane on intel_update_fbc() as Chris suggested. +v4: Ville pointed out that according to BSpec FBC_CTL bits 0:3 must be 0. +v5: Up to v4 this work was entirely focused on Haswell. However Ville + noticed I could reuse the FBC work done for HSW and get FBC for free + at Ivybridge. So it makes more sense enable FBC for IVB first. + FBC for HSW comming on next patches. We are just not enabling it by + default on IVB. +v6: Fix confused commit name (by Matt Turner). +v7: Remove gtt_offset shift since it is page aligned byte offset (by Ville). + +Cc: Matt Turner +Cc: Chris Wilson +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit abe959c7e06f62f064432a2aa00c199f1f672c81) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 1 + + drivers/gpu/drm/i915/i915_reg.h | 6 ++++++ + drivers/gpu/drm/i915/intel_pm.c | 33 +++++++++++++++++++++++++++++++-- + 3 files changed, 38 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 9e9b612828b2..e7099372913c 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -280,6 +280,7 @@ static const struct intel_device_info intel_ivybridge_m_info = { + GEN7_FEATURES, + .is_ivybridge = 1, + .is_mobile = 1, ++ .has_fbc = 1, + }; + + static const struct intel_device_info intel_ivybridge_q_info = { +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 5de7b03ff32a..b7e222464d42 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -925,7 +925,9 @@ + #define DPFC_CTL_EN (1<<31) + #define DPFC_CTL_PLANEA (0<<30) + #define DPFC_CTL_PLANEB (1<<30) ++#define IVB_DPFC_CTL_PLANE_SHIFT (29) + #define DPFC_CTL_FENCE_EN (1<<29) ++#define IVB_DPFC_CTL_FENCE_EN (1<<28) + #define DPFC_CTL_PERSISTENT_MODE (1<<25) + #define DPFC_SR_EN (1<<10) + #define DPFC_CTL_LIMIT_1X (0<<6) +@@ -958,6 +960,7 @@ + #define ILK_DPFC_CHICKEN 0x43224 + #define ILK_FBC_RT_BASE 0x2128 + #define ILK_FBC_RT_VALID (1<<0) ++#define SNB_FBC_FRONT_BUFFER (1<<1) + + #define ILK_DISPLAY_CHICKEN1 0x42000 + #define ILK_FBCQ_DIS (1<<22) +@@ -973,6 +976,9 @@ + #define SNB_CPU_FENCE_ENABLE (1<<29) + #define DPFC_CPU_FENCE_OFFSET 0x100104 + ++/* Framebuffer compression for Ivybridge */ ++#define IVB_FBC_RT_BASE 0x7020 ++ + + /* + * GPIO regs +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index df200a67492f..5c976e8aba4c 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -253,6 +253,30 @@ static bool ironlake_fbc_enabled(struct drm_device *dev) + return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN; + } + ++static void gen7_enable_fbc(struct drm_crtc *crtc, unsigned long interval) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_framebuffer *fb = crtc->fb; ++ struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); ++ struct drm_i915_gem_object *obj = intel_fb->obj; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ ++ I915_WRITE(IVB_FBC_RT_BASE, obj->gtt_offset | ILK_FBC_RT_VALID); ++ ++ I915_WRITE(ILK_DPFC_CONTROL, DPFC_CTL_EN | DPFC_CTL_LIMIT_1X | ++ IVB_DPFC_CTL_FENCE_EN | ++ intel_crtc->plane << IVB_DPFC_CTL_PLANE_SHIFT); ++ ++ I915_WRITE(SNB_DPFC_CTL_SA, ++ SNB_CPU_FENCE_ENABLE | obj->fence_reg); ++ I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y); ++ ++ sandybridge_blit_fbc_update(dev); ++ ++ DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); ++} ++ + bool intel_fbc_enabled(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -439,7 +463,7 @@ void intel_update_fbc(struct drm_device *dev) + if (enable_fbc < 0) { + DRM_DEBUG_KMS("fbc set to per-chip default\n"); + enable_fbc = 1; +- if (INTEL_INFO(dev)->gen <= 6) ++ if (INTEL_INFO(dev)->gen <= 7) + enable_fbc = 0; + } + if (!enable_fbc) { +@@ -4507,7 +4531,12 @@ void intel_init_pm(struct drm_device *dev) + if (I915_HAS_FBC(dev)) { + if (HAS_PCH_SPLIT(dev)) { + dev_priv->display.fbc_enabled = ironlake_fbc_enabled; +- dev_priv->display.enable_fbc = ironlake_enable_fbc; ++ if (IS_IVYBRIDGE(dev)) ++ dev_priv->display.enable_fbc = ++ gen7_enable_fbc; ++ else ++ dev_priv->display.enable_fbc = ++ ironlake_enable_fbc; + dev_priv->display.disable_fbc = ironlake_disable_fbc; + } else if (IS_GM45(dev)) { + dev_priv->display.fbc_enabled = g4x_fbc_enabled; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0152-drm-i915-IVB-FBC-WaFbcAsynchFlipDisableFbcQueue.patch b/patches.baytrail/0152-drm-i915-IVB-FBC-WaFbcAsynchFlipDisableFbcQueue.patch new file mode 100644 index 000000000000..611b5bcad838 --- /dev/null +++ b/patches.baytrail/0152-drm-i915-IVB-FBC-WaFbcAsynchFlipDisableFbcQueue.patch @@ -0,0 +1,36 @@ +From 1942bc78fa200b14c821f42f57114f48fabbe5e7 Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Mon, 6 May 2013 19:37:34 -0300 +Subject: drm/i915: IVB FBC WaFbcAsynchFlipDisableFbcQueue +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Display register 42000h bit 22 must be set to 1b for the entire time that +Frame Buffer Compression is enabled. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 30ca7c6f97e266d122b03261f75f530d5c83608b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 5c976e8aba4c..26aabed959fa 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -268,6 +268,8 @@ static void gen7_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + IVB_DPFC_CTL_FENCE_EN | + intel_crtc->plane << IVB_DPFC_CTL_PLANE_SHIFT); + ++ /* WaFbcAsynchFlipDisableFbcQueue */ ++ I915_WRITE(ILK_DISPLAY_CHICKEN1, ILK_FBCQ_DIS); + I915_WRITE(SNB_DPFC_CTL_SA, + SNB_CPU_FENCE_ENABLE | obj->fence_reg); + I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0153-drm-i915-IVB-FBC-WaFbcDisableDpfcClockGating.patch b/patches.baytrail/0153-drm-i915-IVB-FBC-WaFbcDisableDpfcClockGating.patch new file mode 100644 index 000000000000..8baa017b5b1a --- /dev/null +++ b/patches.baytrail/0153-drm-i915-IVB-FBC-WaFbcDisableDpfcClockGating.patch @@ -0,0 +1,57 @@ +From 5da0d11e20f7ce731582e8bc9ef8398149768469 Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Thu, 9 May 2013 14:08:38 -0300 +Subject: drm/i915: IVB FBC WaFbcDisableDpfcClockGating +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Display register 42020h bit 9 must be set to 1b for the entire time that +Frame Buffer Compression is enabled. + +v2: RMW to preserve other bits (by Ville) +v3: Fix from Ville: sed &/| at RMW +v4: Too far on sed. + +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit b74ea102b746a1e5157d6b0c83f486ad3c6235d1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 26aabed959fa..61420e64a6e6 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -242,6 +242,12 @@ static void ironlake_disable_fbc(struct drm_device *dev) + dpfc_ctl &= ~DPFC_CTL_EN; + I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); + ++ if (IS_IVYBRIDGE(dev)) ++ /* WaFbcDisableDpfcClockGating */ ++ I915_WRITE(ILK_DSPCLK_GATE_D, ++ I915_READ(ILK_DSPCLK_GATE_D) & ++ ~ILK_DPFCUNIT_CLOCK_GATE_DISABLE); ++ + DRM_DEBUG_KMS("disabled FBC\n"); + } + } +@@ -270,6 +276,11 @@ static void gen7_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + + /* WaFbcAsynchFlipDisableFbcQueue */ + I915_WRITE(ILK_DISPLAY_CHICKEN1, ILK_FBCQ_DIS); ++ /* WaFbcDisableDpfcClockGating */ ++ I915_WRITE(ILK_DSPCLK_GATE_D, ++ I915_READ(ILK_DSPCLK_GATE_D) | ++ ILK_DPFCUNIT_CLOCK_GATE_DISABLE); ++ + I915_WRITE(SNB_DPFC_CTL_SA, + SNB_CPU_FENCE_ENABLE | obj->fence_reg); + I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0154-drm-i915-Enable-FBC-at-Haswell.patch b/patches.baytrail/0154-drm-i915-Enable-FBC-at-Haswell.patch new file mode 100644 index 000000000000..6e81104754c9 --- /dev/null +++ b/patches.baytrail/0154-drm-i915-Enable-FBC-at-Haswell.patch @@ -0,0 +1,114 @@ +From 7d76969ff0fbacb8563c0fa1f2c90a26c5c50cf3 Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Mon, 6 May 2013 19:37:36 -0300 +Subject: drm/i915: Enable FBC at Haswell. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch introduce Frame Buffer Compression (FBC) support for HSW. +FBC is tied to primary plane A in HSW. + +v2: Ville pointed out docs say FBC must be disabled before disabling + the plane on HSW. +v3: Really enabling it by default at HSW. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Rodrigo Vivi +Tested-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 891348b2bf08d8946e0621bec49802897b28c1c4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 1 + + drivers/gpu/drm/i915/intel_display.c | 5 +++-- + drivers/gpu/drm/i915/intel_pm.c | 21 ++++++++++++--------- + 3 files changed, 16 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index e7099372913c..daf727e79ded 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -319,6 +319,7 @@ static const struct intel_device_info intel_haswell_m_info = { + .is_mobile = 1, + .has_ddi = 1, + .has_fpga_dbg = 1, ++ .has_fbc = 1, + }; + + static const struct pci_device_id pciidlist[] = { /* aka */ +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index cd9600956dd7..ef6aa3496cbf 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3518,11 +3518,12 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) + drm_vblank_off(dev, pipe); + intel_crtc_update_cursor(crtc, false); + +- intel_disable_plane(dev_priv, plane, pipe); +- ++ /* FBC must be disabled before disabling the plane on HSW. */ + if (dev_priv->cfb_plane == plane) + intel_disable_fbc(dev); + ++ intel_disable_plane(dev_priv, plane, pipe); ++ + if (intel_crtc->config.has_pch_encoder) + intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false); + intel_disable_pipe(dev_priv, pipe); +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 61420e64a6e6..c28c0ac072bf 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -274,12 +274,14 @@ static void gen7_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + IVB_DPFC_CTL_FENCE_EN | + intel_crtc->plane << IVB_DPFC_CTL_PLANE_SHIFT); + +- /* WaFbcAsynchFlipDisableFbcQueue */ +- I915_WRITE(ILK_DISPLAY_CHICKEN1, ILK_FBCQ_DIS); +- /* WaFbcDisableDpfcClockGating */ +- I915_WRITE(ILK_DSPCLK_GATE_D, +- I915_READ(ILK_DSPCLK_GATE_D) | +- ILK_DPFCUNIT_CLOCK_GATE_DISABLE); ++ if (IS_IVYBRIDGE(dev)) { ++ /* WaFbcAsynchFlipDisableFbcQueue */ ++ I915_WRITE(ILK_DISPLAY_CHICKEN1, ILK_FBCQ_DIS); ++ /* WaFbcDisableDpfcClockGating */ ++ I915_WRITE(ILK_DSPCLK_GATE_D, ++ I915_READ(ILK_DSPCLK_GATE_D) | ++ ILK_DPFCUNIT_CLOCK_GATE_DISABLE); ++ } + + I915_WRITE(SNB_DPFC_CTL_SA, + SNB_CPU_FENCE_ENABLE | obj->fence_reg); +@@ -476,7 +478,7 @@ void intel_update_fbc(struct drm_device *dev) + if (enable_fbc < 0) { + DRM_DEBUG_KMS("fbc set to per-chip default\n"); + enable_fbc = 1; +- if (INTEL_INFO(dev)->gen <= 7) ++ if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) + enable_fbc = 0; + } + if (!enable_fbc) { +@@ -497,7 +499,8 @@ void intel_update_fbc(struct drm_device *dev) + dev_priv->no_fbc_reason = FBC_MODE_TOO_LARGE; + goto out_disable; + } +- if ((IS_I915GM(dev) || IS_I945GM(dev)) && intel_crtc->plane != 0) { ++ if ((IS_I915GM(dev) || IS_I945GM(dev) || IS_HASWELL(dev)) && ++ intel_crtc->plane != 0) { + DRM_DEBUG_KMS("plane not 0, disabling compression\n"); + dev_priv->no_fbc_reason = FBC_BAD_PLANE; + goto out_disable; +@@ -4544,7 +4547,7 @@ void intel_init_pm(struct drm_device *dev) + if (I915_HAS_FBC(dev)) { + if (HAS_PCH_SPLIT(dev)) { + dev_priv->display.fbc_enabled = ironlake_fbc_enabled; +- if (IS_IVYBRIDGE(dev)) ++ if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) + dev_priv->display.enable_fbc = + gen7_enable_fbc; + else +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0155-drm-i915-HSW-FBC-WaFbcAsynchFlipDisableFbcQueue.patch b/patches.baytrail/0155-drm-i915-HSW-FBC-WaFbcAsynchFlipDisableFbcQueue.patch new file mode 100644 index 000000000000..174d9428444f --- /dev/null +++ b/patches.baytrail/0155-drm-i915-HSW-FBC-WaFbcAsynchFlipDisableFbcQueue.patch @@ -0,0 +1,57 @@ +From 988115b9951d3f5d51619d1cbb249431956de23e Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Mon, 6 May 2013 19:37:37 -0300 +Subject: drm/i915: HSW FBC WaFbcAsynchFlipDisableFbcQueue +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Display register 420B0h bit 22 must be set to 1b for the entire time that +Frame Buffer Compression is enabled. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 285541647a816e00348916ba7387eeacea30eba9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 7 +++++++ + drivers/gpu/drm/i915/intel_pm.c | 4 ++++ + 2 files changed, 11 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index b7e222464d42..21a1d4640310 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -980,6 +980,13 @@ + #define IVB_FBC_RT_BASE 0x7020 + + ++#define _HSW_PIPE_SLICE_CHICKEN_1_A 0x420B0 ++#define _HSW_PIPE_SLICE_CHICKEN_1_B 0x420B4 ++#define HSW_BYPASS_FBC_QUEUE (1<<22) ++#define HSW_PIPE_SLICE_CHICKEN_1(pipe) _PIPE(pipe, + \ ++ _HSW_PIPE_SLICE_CHICKEN_1_A, + \ ++ _HSW_PIPE_SLICE_CHICKEN_1_B) ++ + /* + * GPIO regs + */ +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index c28c0ac072bf..0b4429252c0c 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -281,6 +281,10 @@ static void gen7_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + I915_WRITE(ILK_DSPCLK_GATE_D, + I915_READ(ILK_DSPCLK_GATE_D) | + ILK_DPFCUNIT_CLOCK_GATE_DISABLE); ++ } else { ++ /* WaFbcAsynchFlipDisableFbcQueue */ ++ I915_WRITE(HSW_PIPE_SLICE_CHICKEN_1(intel_crtc->pipe), ++ HSW_BYPASS_FBC_QUEUE); + } + + I915_WRITE(SNB_DPFC_CTL_SA, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0156-drm-i915-HSW-FBC-WaFbcDisableDpfcClockGating.patch b/patches.baytrail/0156-drm-i915-HSW-FBC-WaFbcDisableDpfcClockGating.patch new file mode 100644 index 000000000000..162646f6f737 --- /dev/null +++ b/patches.baytrail/0156-drm-i915-HSW-FBC-WaFbcDisableDpfcClockGating.patch @@ -0,0 +1,76 @@ +From fc6d6db5663ee3cbe8744b5f2152e243a01fe572 Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Thu, 9 May 2013 14:20:50 -0300 +Subject: drm/i915: HSW FBC WaFbcDisableDpfcClockGating +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Display register 46500h bit 23 must be set to 1b for the entire time that +Frame Buffer Compression is enabled. + +v2: Ville suggested to enable it back when disabling fbc to avoid wasting + power. + +v3: RMW to preserve other bits (by Ville) +v4: Fix from Ville: sed &/| at RMW +v5: Too far on sed. + +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Rodrigo Vivi +[danvet: Insert missing space that checkpatch spotted.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit d89f2071461d5682b897c73278daaf25fd11aff5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 3 +++ + drivers/gpu/drm/i915/intel_pm.c | 10 ++++++++++ + 2 files changed, 13 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 21a1d4640310..83cc2e5dbd79 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -987,6 +987,9 @@ + _HSW_PIPE_SLICE_CHICKEN_1_A, + \ + _HSW_PIPE_SLICE_CHICKEN_1_B) + ++#define HSW_CLKGATE_DISABLE_PART_1 0x46500 ++#define HSW_DPFC_GATING_DISABLE (1<<23) ++ + /* + * GPIO regs + */ +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 0b4429252c0c..656ee57d1e05 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -248,6 +248,12 @@ static void ironlake_disable_fbc(struct drm_device *dev) + I915_READ(ILK_DSPCLK_GATE_D) & + ~ILK_DPFCUNIT_CLOCK_GATE_DISABLE); + ++ if (IS_HASWELL(dev)) ++ /* WaFbcDisableDpfcClockGating */ ++ I915_WRITE(HSW_CLKGATE_DISABLE_PART_1, ++ I915_READ(HSW_CLKGATE_DISABLE_PART_1) & ++ ~HSW_DPFC_GATING_DISABLE); ++ + DRM_DEBUG_KMS("disabled FBC\n"); + } + } +@@ -285,6 +291,10 @@ static void gen7_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + /* WaFbcAsynchFlipDisableFbcQueue */ + I915_WRITE(HSW_PIPE_SLICE_CHICKEN_1(intel_crtc->pipe), + HSW_BYPASS_FBC_QUEUE); ++ /* WaFbcDisableDpfcClockGating */ ++ I915_WRITE(HSW_CLKGATE_DISABLE_PART_1, ++ I915_READ(HSW_CLKGATE_DISABLE_PART_1) | ++ HSW_DPFC_GATING_DISABLE); + } + + I915_WRITE(SNB_DPFC_CTL_SA, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0157-drm-i915-Compute-WR-PLL-dividers-dynamically.patch b/patches.baytrail/0157-drm-i915-Compute-WR-PLL-dividers-dynamically.patch new file mode 100644 index 000000000000..3c86f7a34486 --- /dev/null +++ b/patches.baytrail/0157-drm-i915-Compute-WR-PLL-dividers-dynamically.patch @@ -0,0 +1,685 @@ +From 47e16de4f9c39209142b58457859334ae65e48e5 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Fri, 10 May 2013 14:01:51 +0100 +Subject: drm/i915: Compute WR PLL dividers dynamically + +Up to now, we were using a static table to match the clock frequency +with a (r2,n2,p) triplet. Despite this table being big, it's by no mean +comprehensive and we had to fall back to the closest frequency when the +requested TMDS clock wasn't in the table. + +This patch computes (r2,n2,p) dynamically and get rid of The Big Table. + +v2: Replace the floating point constant 1e6 by 1000000 + +Bugzilla: http://bugs.freedesktop.org/show_bug.cgi?id=58497 +Signed-off-by: Damien Lespiau +Reviewed-by: Paulo Zanoni (v1) +Tested-by: Paulo Zanoni (v1) +[danvet: s/ /^T/] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 1c0b85c566b7a5a5cdabb767a39b445ce271a4fa) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 617 ++++++++++++++------------------------- + 1 file changed, 214 insertions(+), 403 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 217308ec3b3d..7799de733917 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -281,392 +281,6 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) + DRM_ERROR("FDI link training failed!\n"); + } + +-/* WRPLL clock dividers */ +-struct wrpll_tmds_clock { +- u32 clock; +- u16 p; /* Post divider */ +- u16 n2; /* Feedback divider */ +- u16 r2; /* Reference divider */ +-}; +- +-/* Table of matching values for WRPLL clocks programming for each frequency. +- * The code assumes this table is sorted. */ +-static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = { +- {19750, 38, 25, 18}, +- {20000, 48, 32, 18}, +- {21000, 36, 21, 15}, +- {21912, 42, 29, 17}, +- {22000, 36, 22, 15}, +- {23000, 36, 23, 15}, +- {23500, 40, 40, 23}, +- {23750, 26, 16, 14}, +- {24000, 36, 24, 15}, +- {25000, 36, 25, 15}, +- {25175, 26, 40, 33}, +- {25200, 30, 21, 15}, +- {26000, 36, 26, 15}, +- {27000, 30, 21, 14}, +- {27027, 18, 100, 111}, +- {27500, 30, 29, 19}, +- {28000, 34, 30, 17}, +- {28320, 26, 30, 22}, +- {28322, 32, 42, 25}, +- {28750, 24, 23, 18}, +- {29000, 30, 29, 18}, +- {29750, 32, 30, 17}, +- {30000, 30, 25, 15}, +- {30750, 30, 41, 24}, +- {31000, 30, 31, 18}, +- {31500, 30, 28, 16}, +- {32000, 30, 32, 18}, +- {32500, 28, 32, 19}, +- {33000, 24, 22, 15}, +- {34000, 28, 30, 17}, +- {35000, 26, 32, 19}, +- {35500, 24, 30, 19}, +- {36000, 26, 26, 15}, +- {36750, 26, 46, 26}, +- {37000, 24, 23, 14}, +- {37762, 22, 40, 26}, +- {37800, 20, 21, 15}, +- {38000, 24, 27, 16}, +- {38250, 24, 34, 20}, +- {39000, 24, 26, 15}, +- {40000, 24, 32, 18}, +- {40500, 20, 21, 14}, +- {40541, 22, 147, 89}, +- {40750, 18, 19, 14}, +- {41000, 16, 17, 14}, +- {41500, 22, 44, 26}, +- {41540, 22, 44, 26}, +- {42000, 18, 21, 15}, +- {42500, 22, 45, 26}, +- {43000, 20, 43, 27}, +- {43163, 20, 24, 15}, +- {44000, 18, 22, 15}, +- {44900, 20, 108, 65}, +- {45000, 20, 25, 15}, +- {45250, 20, 52, 31}, +- {46000, 18, 23, 15}, +- {46750, 20, 45, 26}, +- {47000, 20, 40, 23}, +- {48000, 18, 24, 15}, +- {49000, 18, 49, 30}, +- {49500, 16, 22, 15}, +- {50000, 18, 25, 15}, +- {50500, 18, 32, 19}, +- {51000, 18, 34, 20}, +- {52000, 18, 26, 15}, +- {52406, 14, 34, 25}, +- {53000, 16, 22, 14}, +- {54000, 16, 24, 15}, +- {54054, 16, 173, 108}, +- {54500, 14, 24, 17}, +- {55000, 12, 22, 18}, +- {56000, 14, 45, 31}, +- {56250, 16, 25, 15}, +- {56750, 14, 25, 17}, +- {57000, 16, 27, 16}, +- {58000, 16, 43, 25}, +- {58250, 16, 38, 22}, +- {58750, 16, 40, 23}, +- {59000, 14, 26, 17}, +- {59341, 14, 40, 26}, +- {59400, 16, 44, 25}, +- {60000, 16, 32, 18}, +- {60500, 12, 39, 29}, +- {61000, 14, 49, 31}, +- {62000, 14, 37, 23}, +- {62250, 14, 42, 26}, +- {63000, 12, 21, 15}, +- {63500, 14, 28, 17}, +- {64000, 12, 27, 19}, +- {65000, 14, 32, 19}, +- {65250, 12, 29, 20}, +- {65500, 12, 32, 22}, +- {66000, 12, 22, 15}, +- {66667, 14, 38, 22}, +- {66750, 10, 21, 17}, +- {67000, 14, 33, 19}, +- {67750, 14, 58, 33}, +- {68000, 14, 30, 17}, +- {68179, 14, 46, 26}, +- {68250, 14, 46, 26}, +- {69000, 12, 23, 15}, +- {70000, 12, 28, 18}, +- {71000, 12, 30, 19}, +- {72000, 12, 24, 15}, +- {73000, 10, 23, 17}, +- {74000, 12, 23, 14}, +- {74176, 8, 100, 91}, +- {74250, 10, 22, 16}, +- {74481, 12, 43, 26}, +- {74500, 10, 29, 21}, +- {75000, 12, 25, 15}, +- {75250, 10, 39, 28}, +- {76000, 12, 27, 16}, +- {77000, 12, 53, 31}, +- {78000, 12, 26, 15}, +- {78750, 12, 28, 16}, +- {79000, 10, 38, 26}, +- {79500, 10, 28, 19}, +- {80000, 12, 32, 18}, +- {81000, 10, 21, 14}, +- {81081, 6, 100, 111}, +- {81624, 8, 29, 24}, +- {82000, 8, 17, 14}, +- {83000, 10, 40, 26}, +- {83950, 10, 28, 18}, +- {84000, 10, 28, 18}, +- {84750, 6, 16, 17}, +- {85000, 6, 17, 18}, +- {85250, 10, 30, 19}, +- {85750, 10, 27, 17}, +- {86000, 10, 43, 27}, +- {87000, 10, 29, 18}, +- {88000, 10, 44, 27}, +- {88500, 10, 41, 25}, +- {89000, 10, 28, 17}, +- {89012, 6, 90, 91}, +- {89100, 10, 33, 20}, +- {90000, 10, 25, 15}, +- {91000, 10, 32, 19}, +- {92000, 10, 46, 27}, +- {93000, 10, 31, 18}, +- {94000, 10, 40, 23}, +- {94500, 10, 28, 16}, +- {95000, 10, 44, 25}, +- {95654, 10, 39, 22}, +- {95750, 10, 39, 22}, +- {96000, 10, 32, 18}, +- {97000, 8, 23, 16}, +- {97750, 8, 42, 29}, +- {98000, 8, 45, 31}, +- {99000, 8, 22, 15}, +- {99750, 8, 34, 23}, +- {100000, 6, 20, 18}, +- {100500, 6, 19, 17}, +- {101000, 6, 37, 33}, +- {101250, 8, 21, 14}, +- {102000, 6, 17, 15}, +- {102250, 6, 25, 22}, +- {103000, 8, 29, 19}, +- {104000, 8, 37, 24}, +- {105000, 8, 28, 18}, +- {106000, 8, 22, 14}, +- {107000, 8, 46, 29}, +- {107214, 8, 27, 17}, +- {108000, 8, 24, 15}, +- {108108, 8, 173, 108}, +- {109000, 6, 23, 19}, +- {110000, 6, 22, 18}, +- {110013, 6, 22, 18}, +- {110250, 8, 49, 30}, +- {110500, 8, 36, 22}, +- {111000, 8, 23, 14}, +- {111264, 8, 150, 91}, +- {111375, 8, 33, 20}, +- {112000, 8, 63, 38}, +- {112500, 8, 25, 15}, +- {113100, 8, 57, 34}, +- {113309, 8, 42, 25}, +- {114000, 8, 27, 16}, +- {115000, 6, 23, 18}, +- {116000, 8, 43, 25}, +- {117000, 8, 26, 15}, +- {117500, 8, 40, 23}, +- {118000, 6, 38, 29}, +- {119000, 8, 30, 17}, +- {119500, 8, 46, 26}, +- {119651, 8, 39, 22}, +- {120000, 8, 32, 18}, +- {121000, 6, 39, 29}, +- {121250, 6, 31, 23}, +- {121750, 6, 23, 17}, +- {122000, 6, 42, 31}, +- {122614, 6, 30, 22}, +- {123000, 6, 41, 30}, +- {123379, 6, 37, 27}, +- {124000, 6, 51, 37}, +- {125000, 6, 25, 18}, +- {125250, 4, 13, 14}, +- {125750, 4, 27, 29}, +- {126000, 6, 21, 15}, +- {127000, 6, 24, 17}, +- {127250, 6, 41, 29}, +- {128000, 6, 27, 19}, +- {129000, 6, 43, 30}, +- {129859, 4, 25, 26}, +- {130000, 6, 26, 18}, +- {130250, 6, 42, 29}, +- {131000, 6, 32, 22}, +- {131500, 6, 38, 26}, +- {131850, 6, 41, 28}, +- {132000, 6, 22, 15}, +- {132750, 6, 28, 19}, +- {133000, 6, 34, 23}, +- {133330, 6, 37, 25}, +- {134000, 6, 61, 41}, +- {135000, 6, 21, 14}, +- {135250, 6, 167, 111}, +- {136000, 6, 62, 41}, +- {137000, 6, 35, 23}, +- {138000, 6, 23, 15}, +- {138500, 6, 40, 26}, +- {138750, 6, 37, 24}, +- {139000, 6, 34, 22}, +- {139050, 6, 34, 22}, +- {139054, 6, 34, 22}, +- {140000, 6, 28, 18}, +- {141000, 6, 36, 23}, +- {141500, 6, 22, 14}, +- {142000, 6, 30, 19}, +- {143000, 6, 27, 17}, +- {143472, 4, 17, 16}, +- {144000, 6, 24, 15}, +- {145000, 6, 29, 18}, +- {146000, 6, 47, 29}, +- {146250, 6, 26, 16}, +- {147000, 6, 49, 30}, +- {147891, 6, 23, 14}, +- {148000, 6, 23, 14}, +- {148250, 6, 28, 17}, +- {148352, 4, 100, 91}, +- {148500, 6, 33, 20}, +- {149000, 6, 48, 29}, +- {150000, 6, 25, 15}, +- {151000, 4, 19, 17}, +- {152000, 6, 27, 16}, +- {152280, 6, 44, 26}, +- {153000, 6, 34, 20}, +- {154000, 6, 53, 31}, +- {155000, 6, 31, 18}, +- {155250, 6, 50, 29}, +- {155750, 6, 45, 26}, +- {156000, 6, 26, 15}, +- {157000, 6, 61, 35}, +- {157500, 6, 28, 16}, +- {158000, 6, 65, 37}, +- {158250, 6, 44, 25}, +- {159000, 6, 53, 30}, +- {159500, 6, 39, 22}, +- {160000, 6, 32, 18}, +- {161000, 4, 31, 26}, +- {162000, 4, 18, 15}, +- {162162, 4, 131, 109}, +- {162500, 4, 53, 44}, +- {163000, 4, 29, 24}, +- {164000, 4, 17, 14}, +- {165000, 4, 22, 18}, +- {166000, 4, 32, 26}, +- {167000, 4, 26, 21}, +- {168000, 4, 46, 37}, +- {169000, 4, 104, 83}, +- {169128, 4, 64, 51}, +- {169500, 4, 39, 31}, +- {170000, 4, 34, 27}, +- {171000, 4, 19, 15}, +- {172000, 4, 51, 40}, +- {172750, 4, 32, 25}, +- {172800, 4, 32, 25}, +- {173000, 4, 41, 32}, +- {174000, 4, 49, 38}, +- {174787, 4, 22, 17}, +- {175000, 4, 35, 27}, +- {176000, 4, 30, 23}, +- {177000, 4, 38, 29}, +- {178000, 4, 29, 22}, +- {178500, 4, 37, 28}, +- {179000, 4, 53, 40}, +- {179500, 4, 73, 55}, +- {180000, 4, 20, 15}, +- {181000, 4, 55, 41}, +- {182000, 4, 31, 23}, +- {183000, 4, 42, 31}, +- {184000, 4, 30, 22}, +- {184750, 4, 26, 19}, +- {185000, 4, 37, 27}, +- {186000, 4, 51, 37}, +- {187000, 4, 36, 26}, +- {188000, 4, 32, 23}, +- {189000, 4, 21, 15}, +- {190000, 4, 38, 27}, +- {190960, 4, 41, 29}, +- {191000, 4, 41, 29}, +- {192000, 4, 27, 19}, +- {192250, 4, 37, 26}, +- {193000, 4, 20, 14}, +- {193250, 4, 53, 37}, +- {194000, 4, 23, 16}, +- {194208, 4, 23, 16}, +- {195000, 4, 26, 18}, +- {196000, 4, 45, 31}, +- {197000, 4, 35, 24}, +- {197750, 4, 41, 28}, +- {198000, 4, 22, 15}, +- {198500, 4, 25, 17}, +- {199000, 4, 28, 19}, +- {200000, 4, 37, 25}, +- {201000, 4, 61, 41}, +- {202000, 4, 112, 75}, +- {202500, 4, 21, 14}, +- {203000, 4, 146, 97}, +- {204000, 4, 62, 41}, +- {204750, 4, 44, 29}, +- {205000, 4, 38, 25}, +- {206000, 4, 29, 19}, +- {207000, 4, 23, 15}, +- {207500, 4, 40, 26}, +- {208000, 4, 37, 24}, +- {208900, 4, 48, 31}, +- {209000, 4, 48, 31}, +- {209250, 4, 31, 20}, +- {210000, 4, 28, 18}, +- {211000, 4, 25, 16}, +- {212000, 4, 22, 14}, +- {213000, 4, 30, 19}, +- {213750, 4, 38, 24}, +- {214000, 4, 46, 29}, +- {214750, 4, 35, 22}, +- {215000, 4, 43, 27}, +- {216000, 4, 24, 15}, +- {217000, 4, 37, 23}, +- {218000, 4, 42, 26}, +- {218250, 4, 42, 26}, +- {218750, 4, 34, 21}, +- {219000, 4, 47, 29}, +- {220000, 4, 44, 27}, +- {220640, 4, 49, 30}, +- {220750, 4, 36, 22}, +- {221000, 4, 36, 22}, +- {222000, 4, 23, 14}, +- {222525, 4, 28, 17}, +- {222750, 4, 33, 20}, +- {227000, 4, 37, 22}, +- {230250, 4, 29, 17}, +- {233500, 4, 38, 22}, +- {235000, 4, 40, 23}, +- {238000, 4, 30, 17}, +- {241500, 2, 17, 19}, +- {245250, 2, 20, 22}, +- {247750, 2, 22, 24}, +- {253250, 2, 15, 16}, +- {256250, 2, 18, 19}, +- {262500, 2, 31, 32}, +- {267250, 2, 66, 67}, +- {268500, 2, 94, 95}, +- {270000, 2, 14, 14}, +- {272500, 2, 77, 76}, +- {273750, 2, 57, 56}, +- {280750, 2, 24, 23}, +- {281250, 2, 23, 22}, +- {286000, 2, 17, 16}, +- {291750, 2, 26, 24}, +- {296703, 2, 56, 51}, +- {297000, 2, 22, 20}, +- {298000, 2, 21, 19}, +-}; +- + static void intel_ddi_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +@@ -790,27 +404,224 @@ void intel_ddi_put_crtc_pll(struct drm_crtc *crtc) + intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE; + } + +-static void intel_ddi_calculate_wrpll(int clock, int *p, int *n2, int *r2) ++#define LC_FREQ 2700 ++#define LC_FREQ_2K (LC_FREQ * 2000) ++ ++#define P_MIN 2 ++#define P_MAX 64 ++#define P_INC 2 ++ ++/* Constraints for PLL good behavior */ ++#define REF_MIN 48 ++#define REF_MAX 400 ++#define VCO_MIN 2400 ++#define VCO_MAX 4800 ++ ++#define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a)) ++ ++struct wrpll_rnp { ++ unsigned p, n2, r2; ++}; ++ ++static unsigned wrpll_get_budget_for_freq(int clock) ++{ ++ unsigned budget; ++ ++ switch (clock) { ++ case 25175000: ++ case 25200000: ++ case 27000000: ++ case 27027000: ++ case 37762500: ++ case 37800000: ++ case 40500000: ++ case 40541000: ++ case 54000000: ++ case 54054000: ++ case 59341000: ++ case 59400000: ++ case 72000000: ++ case 74176000: ++ case 74250000: ++ case 81000000: ++ case 81081000: ++ case 89012000: ++ case 89100000: ++ case 108000000: ++ case 108108000: ++ case 111264000: ++ case 111375000: ++ case 148352000: ++ case 148500000: ++ case 162000000: ++ case 162162000: ++ case 222525000: ++ case 222750000: ++ case 296703000: ++ case 297000000: ++ budget = 0; ++ break; ++ case 233500000: ++ case 245250000: ++ case 247750000: ++ case 253250000: ++ case 298000000: ++ budget = 1500; ++ break; ++ case 169128000: ++ case 169500000: ++ case 179500000: ++ case 202000000: ++ budget = 2000; ++ break; ++ case 256250000: ++ case 262500000: ++ case 270000000: ++ case 272500000: ++ case 273750000: ++ case 280750000: ++ case 281250000: ++ case 286000000: ++ case 291750000: ++ budget = 4000; ++ break; ++ case 267250000: ++ case 268500000: ++ budget = 5000; ++ break; ++ default: ++ budget = 1000; ++ break; ++ } ++ ++ return budget; ++} ++ ++static void wrpll_update_rnp(uint64_t freq2k, unsigned budget, ++ unsigned r2, unsigned n2, unsigned p, ++ struct wrpll_rnp *best) + { +- u32 i; ++ uint64_t a, b, c, d, diff, diff_best; + +- for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++) +- if (clock <= wrpll_tmds_clock_table[i].clock) +- break; ++ /* No best (r,n,p) yet */ ++ if (best->p == 0) { ++ best->p = p; ++ best->n2 = n2; ++ best->r2 = r2; ++ return; ++ } ++ ++ /* ++ * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to ++ * freq2k. ++ * ++ * delta = 1e6 * ++ * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) / ++ * freq2k; ++ * ++ * and we would like delta <= budget. ++ * ++ * If the discrepancy is above the PPM-based budget, always prefer to ++ * improve upon the previous solution. However, if you're within the ++ * budget, try to maximize Ref * VCO, that is N / (P * R^2). ++ */ ++ a = freq2k * budget * p * r2; ++ b = freq2k * budget * best->p * best->r2; ++ diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2)); ++ diff_best = ABS_DIFF((freq2k * best->p * best->r2), ++ (LC_FREQ_2K * best->n2)); ++ c = 1000000 * diff; ++ d = 1000000 * diff_best; ++ ++ if (a < c && b < d) { ++ /* If both are above the budget, pick the closer */ ++ if (best->p * best->r2 * diff < p * r2 * diff_best) { ++ best->p = p; ++ best->n2 = n2; ++ best->r2 = r2; ++ } ++ } else if (a >= c && b < d) { ++ /* If A is below the threshold but B is above it? Update. */ ++ best->p = p; ++ best->n2 = n2; ++ best->r2 = r2; ++ } else if (a >= c && b >= d) { ++ /* Both are below the limit, so pick the higher n2/(r2*r2) */ ++ if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) { ++ best->p = p; ++ best->n2 = n2; ++ best->r2 = r2; ++ } ++ } ++ /* Otherwise a < c && b >= d, do nothing */ ++} ++ ++static void ++intel_ddi_calculate_wrpll(int clock /* in Hz */, ++ unsigned *r2_out, unsigned *n2_out, unsigned *p_out) ++{ ++ uint64_t freq2k; ++ unsigned p, n2, r2; ++ struct wrpll_rnp best = { 0, 0, 0 }; ++ unsigned budget; + +- if (i == ARRAY_SIZE(wrpll_tmds_clock_table)) +- i--; ++ freq2k = clock / 100; + +- *p = wrpll_tmds_clock_table[i].p; +- *n2 = wrpll_tmds_clock_table[i].n2; +- *r2 = wrpll_tmds_clock_table[i].r2; ++ budget = wrpll_get_budget_for_freq(clock); ++ ++ /* Special case handling for 540 pixel clock: bypass WR PLL entirely ++ * and directly pass the LC PLL to it. */ ++ if (freq2k == 5400000) { ++ *n2_out = 2; ++ *p_out = 1; ++ *r2_out = 2; ++ return; ++ } ++ ++ /* ++ * Ref = LC_FREQ / R, where Ref is the actual reference input seen by ++ * the WR PLL. ++ * ++ * We want R so that REF_MIN <= Ref <= REF_MAX. ++ * Injecting R2 = 2 * R gives: ++ * REF_MAX * r2 > LC_FREQ * 2 and ++ * REF_MIN * r2 < LC_FREQ * 2 ++ * ++ * Which means the desired boundaries for r2 are: ++ * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN ++ * ++ */ ++ for (r2 = LC_FREQ * 2 / REF_MAX + 1; ++ r2 <= LC_FREQ * 2 / REF_MIN; ++ r2++) { ++ ++ /* ++ * VCO = N * Ref, that is: VCO = N * LC_FREQ / R ++ * ++ * Once again we want VCO_MIN <= VCO <= VCO_MAX. ++ * Injecting R2 = 2 * R and N2 = 2 * N, we get: ++ * VCO_MAX * r2 > n2 * LC_FREQ and ++ * VCO_MIN * r2 < n2 * LC_FREQ) ++ * ++ * Which means the desired boundaries for n2 are: ++ * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ ++ */ ++ for (n2 = VCO_MIN * r2 / LC_FREQ + 1; ++ n2 <= VCO_MAX * r2 / LC_FREQ; ++ n2++) { ++ ++ for (p = P_MIN; p <= P_MAX; p += P_INC) ++ wrpll_update_rnp(freq2k, budget, ++ r2, n2, p, &best); ++ } ++ } + +- if (wrpll_tmds_clock_table[i].clock != clock) +- DRM_INFO("WRPLL: using settings for %dKHz on %dKHz mode\n", +- wrpll_tmds_clock_table[i].clock, clock); ++ *n2_out = best.n2; ++ *p_out = best.p; ++ *r2_out = best.r2; + +- DRM_DEBUG_KMS("WRPLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n", +- clock, *p, *n2, *r2); ++ DRM_DEBUG_KMS("WRPLL: %dHz refresh rate with p=%d, n2=%d r2=%d\n", ++ clock, *p_out, *n2_out, *r2_out); + } + + bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock) +@@ -851,7 +662,7 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock) + return true; + + } else if (type == INTEL_OUTPUT_HDMI) { +- int p, n2, r2; ++ unsigned p, n2, r2; + + if (plls->wrpll1_refcount == 0) { + DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n", +@@ -873,7 +684,7 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock) + WARN(I915_READ(reg) & WRPLL_PLL_ENABLE, + "WRPLL already enabled\n"); + +- intel_ddi_calculate_wrpll(clock, &p, &n2, &r2); ++ intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); + + val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 | + WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0158-drm-i915-rip-out-an-unused-lvds_reg-variable.patch b/patches.baytrail/0158-drm-i915-rip-out-an-unused-lvds_reg-variable.patch new file mode 100644 index 000000000000..c27bfcd7b541 --- /dev/null +++ b/patches.baytrail/0158-drm-i915-rip-out-an-unused-lvds_reg-variable.patch @@ -0,0 +1,41 @@ +From 760627400cb04570026084d661434bd447b01d11 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 30 Apr 2013 14:01:46 +0200 +Subject: drm/i915: rip out an unused lvds_reg variable + +Somehow this has been forgotten in + +commit 1974cad0ee4ce84e5cb792e49c4f0d9421e0312c +Author: Daniel Vetter +Date: Mon Nov 26 17:22:09 2012 +0100 + + drm/i915: move is_dual_link_lvds to intel_lvds.c + +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 7881d4f11c00f506907b1bccb73df81509dc9c15) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index ef6aa3496cbf..b5462d028883 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -651,12 +651,6 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, + found = false; + + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { +- int lvds_reg; +- +- if (HAS_PCH_SPLIT(dev)) +- lvds_reg = PCH_LVDS; +- else +- lvds_reg = LVDS; + if (intel_is_dual_link_lvds(dev)) + clock.p2 = limit->p2.p2_fast; + else +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0159-drm-i915-Add-missing-platform-tags-to-FBC-workaround.patch b/patches.baytrail/0159-drm-i915-Add-missing-platform-tags-to-FBC-workaround.patch new file mode 100644 index 000000000000..33a9d7d10e97 --- /dev/null +++ b/patches.baytrail/0159-drm-i915-Add-missing-platform-tags-to-FBC-workaround.patch @@ -0,0 +1,61 @@ +From 6d96af3ccda7a6e5361c5fc53abb5ca3dd4ac573 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Fri, 10 May 2013 14:33:17 +0100 +Subject: drm/i915: Add missing platform tags to FBC workaround comments + +There was a race between Rodrigo writing those patches and me +formalizing the addition of platform tags. This patches fixes it. + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 7dd23ba0899bd1a203cc1d6e7878d7dfc910a511) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 656ee57d1e05..5736098f9b0f 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -243,13 +243,13 @@ static void ironlake_disable_fbc(struct drm_device *dev) + I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); + + if (IS_IVYBRIDGE(dev)) +- /* WaFbcDisableDpfcClockGating */ ++ /* WaFbcDisableDpfcClockGating:ivb */ + I915_WRITE(ILK_DSPCLK_GATE_D, + I915_READ(ILK_DSPCLK_GATE_D) & + ~ILK_DPFCUNIT_CLOCK_GATE_DISABLE); + + if (IS_HASWELL(dev)) +- /* WaFbcDisableDpfcClockGating */ ++ /* WaFbcDisableDpfcClockGating:hsw */ + I915_WRITE(HSW_CLKGATE_DISABLE_PART_1, + I915_READ(HSW_CLKGATE_DISABLE_PART_1) & + ~HSW_DPFC_GATING_DISABLE); +@@ -281,17 +281,17 @@ static void gen7_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + intel_crtc->plane << IVB_DPFC_CTL_PLANE_SHIFT); + + if (IS_IVYBRIDGE(dev)) { +- /* WaFbcAsynchFlipDisableFbcQueue */ ++ /* WaFbcAsynchFlipDisableFbcQueue:ivb */ + I915_WRITE(ILK_DISPLAY_CHICKEN1, ILK_FBCQ_DIS); +- /* WaFbcDisableDpfcClockGating */ ++ /* WaFbcDisableDpfcClockGating:ivb */ + I915_WRITE(ILK_DSPCLK_GATE_D, + I915_READ(ILK_DSPCLK_GATE_D) | + ILK_DPFCUNIT_CLOCK_GATE_DISABLE); + } else { +- /* WaFbcAsynchFlipDisableFbcQueue */ ++ /* WaFbcAsynchFlipDisableFbcQueue:hsw */ + I915_WRITE(HSW_PIPE_SLICE_CHICKEN_1(intel_crtc->pipe), + HSW_BYPASS_FBC_QUEUE); +- /* WaFbcDisableDpfcClockGating */ ++ /* WaFbcDisableDpfcClockGating:hsw */ + I915_WRITE(HSW_CLKGATE_DISABLE_PART_1, + I915_READ(HSW_CLKGATE_DISABLE_PART_1) | + HSW_DPFC_GATING_DISABLE); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0160-drm-i915-implement-WADPOClockGatingDisable-for-LPT.patch b/patches.baytrail/0160-drm-i915-implement-WADPOClockGatingDisable-for-LPT.patch new file mode 100644 index 000000000000..b655c8475711 --- /dev/null +++ b/patches.baytrail/0160-drm-i915-implement-WADPOClockGatingDisable-for-LPT.patch @@ -0,0 +1,37 @@ +From 0a19680e6aa233046a19de41914db5d0315fd118 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Wed, 17 Apr 2013 18:15:49 -0300 +Subject: drm/i915: implement WADPOClockGatingDisable for LPT + +This should prevent mode set failures on LPT. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Damien Lespiau +[danvet: Pimp the w/a tag to fit into Damien's new scheme.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 0a790cdbfc526890af7dc41515a563f09e427129) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 5736098f9b0f..71752d5cdaf4 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4093,6 +4093,11 @@ static void lpt_init_clock_gating(struct drm_device *dev) + I915_WRITE(SOUTH_DSPCLK_GATE_D, + I915_READ(SOUTH_DSPCLK_GATE_D) | + PCH_LP_PARTITION_LEVEL_DISABLE); ++ ++ /* WADPOClockGatingDisable:hsw */ ++ I915_WRITE(_TRANSA_CHICKEN1, ++ I915_READ(_TRANSA_CHICKEN1) | ++ TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); + } + + static void lpt_suspend_hw(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0161-drm-i915-panel-fitter-hw-state-readout-check-support.patch b/patches.baytrail/0161-drm-i915-panel-fitter-hw-state-readout-check-support.patch new file mode 100644 index 000000000000..86eb76894da7 --- /dev/null +++ b/patches.baytrail/0161-drm-i915-panel-fitter-hw-state-readout-check-support.patch @@ -0,0 +1,179 @@ +From e6f30762d39e439dc8426f7487214e4541d45f63 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 7 May 2013 23:34:16 +0200 +Subject: drm/i915: panel fitter hw state readout&check support + +Pfit state readout is a bit ugly on gen2/3 due to the intermingling +with the lvds state, but alas. + +Also note that since state is always cleared to zero we can +unconditonally compare all the state and completely neglect the actual +platform we're running on. + +v2: Properly check for the pfit power domain on haswell. + +v3: Don't check pgm_ratios on gen4+, they're auto-computed by the hw. + +v4: Properly clear the lvds border bits, upset the state checker a +bit. + +v5: Unconditionally read out panel dither settings on gen2/3. + +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 2fa2fe9a142cf8c8a30916ccf7ca6a27019fd6d2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 67 ++++++++++++++++++++++++++++++++++-- + drivers/gpu/drm/i915/intel_lvds.c | 1 + + 2 files changed, 66 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index b5462d028883..e6939d5b6a18 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4986,6 +4986,36 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + return ret; + } + ++static void i9xx_get_pfit_config(struct intel_crtc *crtc, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ tmp = I915_READ(PFIT_CONTROL); ++ ++ if (INTEL_INFO(dev)->gen < 4) { ++ if (crtc->pipe != PIPE_B) ++ return; ++ ++ /* gen2/3 store dither state in pfit control, needs to match */ ++ pipe_config->gmch_pfit.control = tmp & PANEL_8TO6_DITHER_ENABLE; ++ } else { ++ if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT)) ++ return; ++ } ++ ++ if (!(tmp & PFIT_ENABLE)) ++ return; ++ ++ pipe_config->gmch_pfit.control = I915_READ(PFIT_CONTROL); ++ pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS); ++ if (INTEL_INFO(dev)->gen < 5) ++ pipe_config->gmch_pfit.lvds_border_bits = ++ I915_READ(LVDS) & LVDS_BORDER_ENABLE; ++} ++ + static bool i9xx_get_pipe_config(struct intel_crtc *crtc, + struct intel_crtc_config *pipe_config) + { +@@ -4999,6 +5029,8 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, + + intel_get_pipe_timings(crtc, pipe_config); + ++ i9xx_get_pfit_config(crtc, pipe_config); ++ + return true; + } + +@@ -5830,6 +5862,21 @@ static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc, + & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1; + } + ++static void ironlake_get_pfit_config(struct intel_crtc *crtc, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ tmp = I915_READ(PF_CTL(crtc->pipe)); ++ ++ if (tmp & PF_ENABLE) { ++ pipe_config->pch_pfit.pos = I915_READ(PF_WIN_POS(crtc->pipe)); ++ pipe_config->pch_pfit.size = I915_READ(PF_WIN_SZ(crtc->pipe)); ++ } ++} ++ + static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + struct intel_crtc_config *pipe_config) + { +@@ -5853,6 +5900,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + + intel_get_pipe_timings(crtc, pipe_config); + ++ ironlake_get_pfit_config(crtc, pipe_config); ++ + return true; + } + +@@ -5972,6 +6021,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum transcoder cpu_transcoder = crtc->config.cpu_transcoder; ++ enum intel_display_power_domain pfit_domain; + uint32_t tmp; + + if (!intel_display_power_enabled(dev, +@@ -6001,6 +6051,10 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + + intel_get_pipe_timings(crtc, pipe_config); + ++ pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe); ++ if (intel_display_power_enabled(dev, pfit_domain)) ++ ironlake_get_pfit_config(crtc, pipe_config); ++ + return true; + } + +@@ -7970,7 +8024,8 @@ intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes) + if (mask & (1 <<(intel_crtc)->pipe)) + + static bool +-intel_pipe_config_compare(struct intel_crtc_config *current_config, ++intel_pipe_config_compare(struct drm_device *dev, ++ struct intel_crtc_config *current_config, + struct intel_crtc_config *pipe_config) + { + #define PIPE_CONF_CHECK_I(name) \ +@@ -8019,6 +8074,14 @@ intel_pipe_config_compare(struct intel_crtc_config *current_config, + PIPE_CONF_CHECK_I(requested_mode.hdisplay); + PIPE_CONF_CHECK_I(requested_mode.vdisplay); + ++ PIPE_CONF_CHECK_I(gmch_pfit.control); ++ /* pfit ratios are autocomputed by the hw on gen4+ */ ++ if (INTEL_INFO(dev)->gen < 4) ++ PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios); ++ PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits); ++ PIPE_CONF_CHECK_I(pch_pfit.pos); ++ PIPE_CONF_CHECK_I(pch_pfit.size); ++ + #undef PIPE_CONF_CHECK_I + #undef PIPE_CONF_CHECK_FLAGS + +@@ -8135,7 +8198,7 @@ intel_modeset_check_state(struct drm_device *dev) + "(expected %i, found %i)\n", crtc->active, active); + + WARN(active && +- !intel_pipe_config_compare(&crtc->config, &pipe_config), ++ !intel_pipe_config_compare(dev, &crtc->config, &pipe_config), + "pipe state doesn't match!\n"); + } + } +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 04da66914757..fa7511143974 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -116,6 +116,7 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder) + } + + /* set the corresponsding LVDS_BORDER bit */ ++ temp &= ~LVDS_BORDER_ENABLE; + temp |= intel_crtc->config.gmch_pfit.lvds_border_bits; + /* Set the B0-B3 data pairs corresponding to whether we're going to + * set the DPLLs for dual-channel mode or not. +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0162-drm-i915-Use-pipe_config-state-to-disable-ilk-pfit.patch b/patches.baytrail/0162-drm-i915-Use-pipe_config-state-to-disable-ilk-pfit.patch new file mode 100644 index 000000000000..a6491f049348 --- /dev/null +++ b/patches.baytrail/0162-drm-i915-Use-pipe_config-state-to-disable-ilk-pfit.patch @@ -0,0 +1,78 @@ +From 007c257f6a644dc90a20ca232f183bb304c82341 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 8 May 2013 10:36:30 +0200 +Subject: drm/i915: Use pipe_config state to disable ilk+ pfit + +No more need to guard the write with a power well check on Haswell now +that we have proper pfit state readout: We can simply only clear the +pfit if it's actually on. + +This removes some duplication of knowledge between the haswell pfit +disable and pfit state readout code about. + +While at it extract a little helper for this. + +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 3f8dce3ade6ae025a8a77e7b74ec58a5c26b17e2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 28 +++++++++++++++++----------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index e6939d5b6a18..bb4c50f9243e 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3410,6 +3410,21 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) + intel_wait_for_vblank(dev, intel_crtc->pipe); + } + ++static void ironlake_pfit_disable(struct intel_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int pipe = crtc->pipe; ++ ++ /* To avoid upsetting the power well on haswell only disable the pfit if ++ * it's in use. The hw state code will make sure we get this right. */ ++ if (crtc->config.pch_pfit.size) { ++ I915_WRITE(PF_CTL(pipe), 0); ++ I915_WRITE(PF_WIN_POS(pipe), 0); ++ I915_WRITE(PF_WIN_SZ(pipe), 0); ++ } ++} ++ + static void ironlake_crtc_disable(struct drm_crtc *crtc) + { + struct drm_device *dev = crtc->dev; +@@ -3439,9 +3454,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) + intel_set_pch_fifo_underrun_reporting(dev, pipe, false); + intel_disable_pipe(dev_priv, pipe); + +- /* Disable PF */ +- I915_WRITE(PF_CTL(pipe), 0); +- I915_WRITE(PF_WIN_SZ(pipe), 0); ++ ironlake_pfit_disable(intel_crtc); + + for_each_encoder_on_crtc(dev, crtc, encoder) + if (encoder->post_disable) +@@ -3524,14 +3537,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) + + intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); + +- /* XXX: Once we have proper panel fitter state tracking implemented with +- * hardware state read/check support we should switch to only disable +- * the panel fitter when we know it's used. */ +- if (intel_display_power_enabled(dev, +- POWER_DOMAIN_PIPE_PANEL_FITTER(pipe))) { +- I915_WRITE(PF_CTL(pipe), 0); +- I915_WRITE(PF_WIN_SZ(pipe), 0); +- } ++ ironlake_pfit_disable(intel_crtc); + + intel_ddi_disable_pipe_clock(intel_crtc); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0163-drm-i915-Use-pipe-config-state-to-control-gmch-pfit-.patch b/patches.baytrail/0163-drm-i915-Use-pipe-config-state-to-control-gmch-pfit-.patch new file mode 100644 index 000000000000..76b529fd3c24 --- /dev/null +++ b/patches.baytrail/0163-drm-i915-Use-pipe-config-state-to-control-gmch-pfit-.patch @@ -0,0 +1,61 @@ +From 10675524e7a7ae39415ff4574b80a61a38327c2f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 8 May 2013 10:36:31 +0200 +Subject: drm/i915: Use pipe config state to control gmch pfit enable/disable + +Allows us to rip out a few fragile checks (which are duplicated in the +hw state readout now, too). Also prepares us a bit for more than one +panel/pfit. + +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 328d8e829b9a05814af4722c1091d62c5533c4f8) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 20 +++++++------------- + 1 file changed, 7 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index bb4c50f9243e..957dd91803fa 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3624,8 +3624,7 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc) + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc_config *pipe_config = &crtc->config; + +- if (!(intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) || +- intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS))) ++ if (!crtc->config.gmch_pfit.control) + return; + + WARN_ON(I915_READ(PFIT_CONTROL) & PFIT_ENABLE); +@@ -3744,20 +3743,15 @@ static void i9xx_pfit_disable(struct intel_crtc *crtc) + { + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- enum pipe pipe; +- uint32_t pctl = I915_READ(PFIT_CONTROL); + +- assert_pipe_disabled(dev_priv, crtc->pipe); ++ if (!crtc->config.gmch_pfit.control) ++ return; + +- if (INTEL_INFO(dev)->gen >= 4) +- pipe = (pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT; +- else +- pipe = PIPE_B; ++ assert_pipe_disabled(dev_priv, crtc->pipe); + +- if (pipe == crtc->pipe) { +- DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n", pctl); +- I915_WRITE(PFIT_CONTROL, 0); +- } ++ DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n", ++ I915_READ(PFIT_CONTROL)); ++ I915_WRITE(PFIT_CONTROL, 0); + } + + static void i9xx_crtc_disable(struct drm_crtc *crtc) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0164-drm-i915-add-support-for-dvo-Chrontel-7010B.patch b/patches.baytrail/0164-drm-i915-add-support-for-dvo-Chrontel-7010B.patch new file mode 100644 index 000000000000..ad52c928e0f2 --- /dev/null +++ b/patches.baytrail/0164-drm-i915-add-support-for-dvo-Chrontel-7010B.patch @@ -0,0 +1,118 @@ +From 6b5742b2072ef2441c813ac70828f8cc123eea61 Mon Sep 17 00:00:00 2001 +From: "braggle@free.fr" +Date: Thu, 16 May 2013 12:57:38 +0200 +Subject: drm/i915: add support for dvo Chrontel 7010B + +This patch add dvo detection for the Chrontel 7010B on some old hardware. + +References: https://bugzilla.kernel.org/show_bug.cgi?id=55101 +Signed-off-by: Braggle +[danvet: Fix up whitespace mangling.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 98304ad186296dc1e655399e28d5973c21db6a73) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/dvo_ch7xxx.c | 28 ++++++++++++++++++++++++++-- + drivers/gpu/drm/i915/intel_dvo.c | 7 +++++++ + 2 files changed, 33 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c +index 3edd981e0770..757e0fa11043 100644 +--- a/drivers/gpu/drm/i915/dvo_ch7xxx.c ++++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c +@@ -32,12 +32,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #define CH7xxx_REG_DID 0x4b + + #define CH7011_VID 0x83 /* 7010 as well */ ++#define CH7010B_VID 0x05 + #define CH7009A_VID 0x84 + #define CH7009B_VID 0x85 + #define CH7301_VID 0x95 + + #define CH7xxx_VID 0x84 + #define CH7xxx_DID 0x17 ++#define CH7010_DID 0x16 + + #define CH7xxx_NUM_REGS 0x4c + +@@ -87,11 +89,20 @@ static struct ch7xxx_id_struct { + char *name; + } ch7xxx_ids[] = { + { CH7011_VID, "CH7011" }, ++ { CH7010B_VID, "CH7010B" }, + { CH7009A_VID, "CH7009A" }, + { CH7009B_VID, "CH7009B" }, + { CH7301_VID, "CH7301" }, + }; + ++static struct ch7xxx_did_struct { ++ uint8_t did; ++ char *name; ++} ch7xxx_dids[] = { ++ { CH7xxx_DID, "CH7XXX" }, ++ { CH7010_DID, "CH7010B" }, ++}; ++ + struct ch7xxx_priv { + bool quiet; + }; +@@ -108,6 +119,18 @@ static char *ch7xxx_get_id(uint8_t vid) + return NULL; + } + ++static char *ch7xxx_get_did(uint8_t did) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(ch7xxx_dids); i++) { ++ if (ch7xxx_dids[i].did == did) ++ return ch7xxx_dids[i].name; ++ } ++ ++ return NULL; ++} ++ + /** Reads an 8 bit register */ + static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) + { +@@ -179,7 +202,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, + /* this will detect the CH7xxx chip on the specified i2c bus */ + struct ch7xxx_priv *ch7xxx; + uint8_t vendor, device; +- char *name; ++ char *name, *devid; + + ch7xxx = kzalloc(sizeof(struct ch7xxx_priv), GFP_KERNEL); + if (ch7xxx == NULL) +@@ -204,7 +227,8 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, + if (!ch7xxx_readb(dvo, CH7xxx_REG_DID, &device)) + goto out; + +- if (device != CH7xxx_DID) { ++ devid = ch7xxx_get_did(device); ++ if (!devid) { + DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s " + "slave %d.\n", + vendor, adapter->name, dvo->slave_addr); +diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c +index cc70b16d5d42..2c0be924e9a9 100644 +--- a/drivers/gpu/drm/i915/intel_dvo.c ++++ b/drivers/gpu/drm/i915/intel_dvo.c +@@ -54,6 +54,13 @@ static const struct intel_dvo_device intel_dvo_devices[] = { + .dev_ops = &ch7xxx_ops, + }, + { ++ .type = INTEL_DVO_CHIP_TMDS, ++ .name = "ch7xxx", ++ .dvo_reg = DVOC, ++ .slave_addr = 0x75, /* For some ch7010 */ ++ .dev_ops = &ch7xxx_ops, ++ }, ++ { + .type = INTEL_DVO_CHIP_LVDS, + .name = "ivch", + .dvo_reg = DVOA, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0165-Add-arch_phys_wc_-add-del-to-manipulate-WC-MTRRs-if-.patch b/patches.baytrail/0165-Add-arch_phys_wc_-add-del-to-manipulate-WC-MTRRs-if-.patch new file mode 100644 index 000000000000..c7aa2906e3e2 --- /dev/null +++ b/patches.baytrail/0165-Add-arch_phys_wc_-add-del-to-manipulate-WC-MTRRs-if-.patch @@ -0,0 +1,211 @@ +From 6327ea0a9ef45cb41e24adc59acbf8fcc2cd443b Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Mon, 13 May 2013 23:58:40 +0000 +Subject: Add arch_phys_wc_{add, del} to manipulate WC MTRRs if needed + +Several drivers currently use mtrr_add through various #ifdef guards +and/or drm wrappers. The vast majority of them want to add WC MTRRs +on x86 systems and don't actually need the MTRR if PAT (i.e. +ioremap_wc, etc) are working. + +arch_phys_wc_add and arch_phys_wc_del are new functions, available +on all architectures and configurations, that add WC MTRRs on x86 if +needed (and handle errors) and do nothing at all otherwise. They're +also easier to use than mtrr_add and mtrr_del, so the call sites can +be simplified. + +As an added benefit, this will avoid wasting MTRRs and possibly +warning pointlessly on PAT-supporting systems. + +Reviewed-by: Daniel Vetter +Signed-off-by: Andy Lutomirski +Signed-off-by: Dave Airlie +(cherry picked from commit d0d98eedee2178c803dd824bb09f52b0e2ac1811) +Signed-off-by: Darren Hart +--- + arch/x86/include/asm/io.h | 7 ++++ + arch/x86/include/asm/mtrr.h | 10 +++++- + arch/x86/kernel/cpu/mtrr/main.c | 71 +++++++++++++++++++++++++++++++++++++++++ + include/linux/io.h | 25 +++++++++++++++ + 4 files changed, 112 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h +index d8e8eefbe24c..34f69cb9350a 100644 +--- a/arch/x86/include/asm/io.h ++++ b/arch/x86/include/asm/io.h +@@ -345,4 +345,11 @@ extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, + + #define IO_SPACE_LIMIT 0xffff + ++#ifdef CONFIG_MTRR ++extern int __must_check arch_phys_wc_add(unsigned long base, ++ unsigned long size); ++extern void arch_phys_wc_del(int handle); ++#define arch_phys_wc_add arch_phys_wc_add ++#endif ++ + #endif /* _ASM_X86_IO_H */ +diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h +index e235582f9930..f768f6298419 100644 +--- a/arch/x86/include/asm/mtrr.h ++++ b/arch/x86/include/asm/mtrr.h +@@ -26,7 +26,10 @@ + #include + + +-/* The following functions are for use by other drivers */ ++/* ++ * The following functions are for use by other drivers that cannot use ++ * arch_phys_wc_add and arch_phys_wc_del. ++ */ + # ifdef CONFIG_MTRR + extern u8 mtrr_type_lookup(u64 addr, u64 end); + extern void mtrr_save_fixed_ranges(void *); +@@ -45,6 +48,7 @@ extern void mtrr_aps_init(void); + extern void mtrr_bp_restore(void); + extern int mtrr_trim_uncached_memory(unsigned long end_pfn); + extern int amd_special_default_mtrr(void); ++extern int phys_wc_to_mtrr_index(int handle); + # else + static inline u8 mtrr_type_lookup(u64 addr, u64 end) + { +@@ -80,6 +84,10 @@ static inline int mtrr_trim_uncached_memory(unsigned long end_pfn) + static inline void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) + { + } ++static inline int phys_wc_to_mtrr_index(int handle) ++{ ++ return -1; ++} + + #define mtrr_ap_init() do {} while (0) + #define mtrr_bp_init() do {} while (0) +diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c +index ca22b73aaa25..f961de9964c7 100644 +--- a/arch/x86/kernel/cpu/mtrr/main.c ++++ b/arch/x86/kernel/cpu/mtrr/main.c +@@ -51,9 +51,13 @@ + #include + #include + #include ++#include + + #include "mtrr.h" + ++/* arch_phys_wc_add returns an MTRR register index plus this offset. */ ++#define MTRR_TO_PHYS_WC_OFFSET 1000 ++ + u32 num_var_ranges; + + unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES]; +@@ -525,6 +529,73 @@ int mtrr_del(int reg, unsigned long base, unsigned long size) + } + EXPORT_SYMBOL(mtrr_del); + ++/** ++ * arch_phys_wc_add - add a WC MTRR and handle errors if PAT is unavailable ++ * @base: Physical base address ++ * @size: Size of region ++ * ++ * If PAT is available, this does nothing. If PAT is unavailable, it ++ * attempts to add a WC MTRR covering size bytes starting at base and ++ * logs an error if this fails. ++ * ++ * Drivers must store the return value to pass to mtrr_del_wc_if_needed, ++ * but drivers should not try to interpret that return value. ++ */ ++int arch_phys_wc_add(unsigned long base, unsigned long size) ++{ ++ int ret; ++ ++ if (pat_enabled) ++ return 0; /* Success! (We don't need to do anything.) */ ++ ++ ret = mtrr_add(base, size, MTRR_TYPE_WRCOMB, true); ++ if (ret < 0) { ++ pr_warn("Failed to add WC MTRR for [%p-%p]; performance may suffer.", ++ (void *)base, (void *)(base + size - 1)); ++ return ret; ++ } ++ return ret + MTRR_TO_PHYS_WC_OFFSET; ++} ++EXPORT_SYMBOL(arch_phys_wc_add); ++ ++/* ++ * arch_phys_wc_del - undoes arch_phys_wc_add ++ * @handle: Return value from arch_phys_wc_add ++ * ++ * This cleans up after mtrr_add_wc_if_needed. ++ * ++ * The API guarantees that mtrr_del_wc_if_needed(error code) and ++ * mtrr_del_wc_if_needed(0) do nothing. ++ */ ++void arch_phys_wc_del(int handle) ++{ ++ if (handle >= 1) { ++ WARN_ON(handle < MTRR_TO_PHYS_WC_OFFSET); ++ mtrr_del(handle - MTRR_TO_PHYS_WC_OFFSET, 0, 0); ++ } ++} ++EXPORT_SYMBOL(arch_phys_wc_del); ++ ++/* ++ * phys_wc_to_mtrr_index - translates arch_phys_wc_add's return value ++ * @handle: Return value from arch_phys_wc_add ++ * ++ * This will turn the return value from arch_phys_wc_add into an mtrr ++ * index suitable for debugging. ++ * ++ * Note: There is no legitimate use for this function, except possibly ++ * in printk line. Alas there is an illegitimate use in some ancient ++ * drm ioctls. ++ */ ++int phys_wc_to_mtrr_index(int handle) ++{ ++ if (handle < MTRR_TO_PHYS_WC_OFFSET) ++ return -1; ++ else ++ return handle - MTRR_TO_PHYS_WC_OFFSET; ++} ++EXPORT_SYMBOL_GPL(phys_wc_to_mtrr_index); ++ + /* + * HACK ALERT! + * These should be called implicitly, but we can't yet until all the initcall +diff --git a/include/linux/io.h b/include/linux/io.h +index 069e4075f872..f4f42faec686 100644 +--- a/include/linux/io.h ++++ b/include/linux/io.h +@@ -76,4 +76,29 @@ void devm_ioremap_release(struct device *dev, void *res); + #define arch_has_dev_port() (1) + #endif + ++/* ++ * Some systems (x86 without PAT) have a somewhat reliable way to mark a ++ * physical address range such that uncached mappings will actually ++ * end up write-combining. This facility should be used in conjunction ++ * with pgprot_writecombine, ioremap-wc, or set_memory_wc, since it has ++ * no effect if the per-page mechanisms are functional. ++ * (On x86 without PAT, these functions manipulate MTRRs.) ++ * ++ * arch_phys_del_wc(0) or arch_phys_del_wc(any error code) is guaranteed ++ * to have no effect. ++ */ ++#ifndef arch_phys_wc_add ++static inline int __must_check arch_phys_wc_add(unsigned long base, ++ unsigned long size) ++{ ++ return 0; /* It worked (i.e. did nothing). */ ++} ++ ++static inline void arch_phys_wc_del(int handle) ++{ ++} ++ ++#define arch_phys_wc_add arch_phys_wc_add ++#endif ++ + #endif /* _LINUX_IO_H */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0166-i915-Use-arch_phys_wc_-add-del.patch b/patches.baytrail/0166-i915-Use-arch_phys_wc_-add-del.patch new file mode 100644 index 000000000000..55bf6ae2d3f6 --- /dev/null +++ b/patches.baytrail/0166-i915-Use-arch_phys_wc_-add-del.patch @@ -0,0 +1,100 @@ +From c3448c1871794fd45a2162ec3c2b6bbaa1d0d0e0 Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Mon, 13 May 2013 23:58:44 +0000 +Subject: i915: Use arch_phys_wc_{add,del} + +i915 open-coded logic that was essentially equivalent to the new API. + +Reviewed-by: Daniel Vetter +Signed-off-by: Andy Lutomirski +Signed-off-by: Dave Airlie +(cherry picked from commit 1c0f6749e86a990eca10499c8da2b04888ce4560) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 42 ++++------------------------------------- + 1 file changed, 4 insertions(+), 38 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 18caacf647d0..29bb1303e662 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -42,7 +42,6 @@ + #include + #include + #include +-#include + + #define LP_RING(d) (&((struct drm_i915_private *)(d))->ring[RCS]) + +@@ -1397,29 +1396,6 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) + master->driver_priv = NULL; + } + +-static void +-i915_mtrr_setup(struct drm_i915_private *dev_priv, unsigned long base, +- unsigned long size) +-{ +- dev_priv->mm.gtt_mtrr = -1; +- +-#if defined(CONFIG_X86_PAT) +- if (cpu_has_pat) +- return; +-#endif +- +- /* Set up a WC MTRR for non-PAT systems. This is more common than +- * one would think, because the kernel disables PAT on first +- * generation Core chips because WC PAT gets overridden by a UC +- * MTRR if present. Even if a UC MTRR isn't present. +- */ +- dev_priv->mm.gtt_mtrr = mtrr_add(base, size, MTRR_TYPE_WRCOMB, 1); +- if (dev_priv->mm.gtt_mtrr < 0) { +- DRM_INFO("MTRR allocation failed. Graphics " +- "performance may suffer.\n"); +- } +-} +- + static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) + { + struct apertures_struct *ap; +@@ -1587,8 +1563,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + goto out_rmmap; + } + +- i915_mtrr_setup(dev_priv, dev_priv->gtt.mappable_base, +- aperture_size); ++ dev_priv->mm.gtt_mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base, ++ aperture_size); + + /* The i915 workqueue is primarily used for batched retirement of + * requests (and thus managing bo) once the task has been completed +@@ -1686,12 +1662,7 @@ out_gem_unload: + intel_teardown_mchbar(dev); + destroy_workqueue(dev_priv->wq); + out_mtrrfree: +- if (dev_priv->mm.gtt_mtrr >= 0) { +- mtrr_del(dev_priv->mm.gtt_mtrr, +- dev_priv->gtt.mappable_base, +- aperture_size); +- dev_priv->mm.gtt_mtrr = -1; +- } ++ arch_phys_wc_del(dev_priv->mm.gtt_mtrr); + io_mapping_free(dev_priv->gtt.mappable); + dev_priv->gtt.gtt_remove(dev); + out_rmmap: +@@ -1726,12 +1697,7 @@ int i915_driver_unload(struct drm_device *dev) + cancel_delayed_work_sync(&dev_priv->mm.retire_work); + + io_mapping_free(dev_priv->gtt.mappable); +- if (dev_priv->mm.gtt_mtrr >= 0) { +- mtrr_del(dev_priv->mm.gtt_mtrr, +- dev_priv->gtt.mappable_base, +- dev_priv->gtt.mappable_end); +- dev_priv->mm.gtt_mtrr = -1; +- } ++ arch_phys_wc_del(dev_priv->mm.gtt_mtrr); + + acpi_video_unregister(); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0167-drm-Print-pretty-names-for-pixel-formats.patch b/patches.baytrail/0167-drm-Print-pretty-names-for-pixel-formats.patch new file mode 100644 index 000000000000..e5dae324f1cd --- /dev/null +++ b/patches.baytrail/0167-drm-Print-pretty-names-for-pixel-formats.patch @@ -0,0 +1,106 @@ +From 79c344a29a11a32a899891b27d4943661930a9f3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Mon, 10 Jun 2013 11:15:10 +0300 +Subject: drm: Print pretty names for pixel formats +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Rather than just printing the pixel format as a hex number, decode the +fourcc into human readable form, and also decode the LE vs. BE flag. + +Keep printing the raw hex number too in case it contains non-printable +characters. + +Some examples what the new drm_get_format_name() produces: +DRM_FORMAT_XRGB8888: "XR24 little-endian (0x34325258)" +DRM_FORMAT_YUYV: "YUYV little-endian (0x56595559)" +DRM_FORMAT_RGB565|DRM_FORMAT_BIG_ENDIAN: "RG16 big-endian (0xb6314752)" +Unprintable characters: "D??? big-endian (0xff7f0244)" + +v2: Fix patch author + +Signed-off-by: Ville Syrjälä +Signed-off-by: Dave Airlie +(cherry picked from commit 6ba6d03e69125ef42a63e90d45e49c659ea3c34f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_crtc.c | 29 +++++++++++++++++++++++++++-- + include/drm/drm_crtc.h | 1 + + 2 files changed, 28 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c +index 8759d699bd8e..f4831510d38a 100644 +--- a/drivers/gpu/drm/drm_crtc.c ++++ b/drivers/gpu/drm/drm_crtc.c +@@ -29,6 +29,7 @@ + * Dave Airlie + * Jesse Barnes + */ ++#include + #include + #include + #include +@@ -252,6 +253,28 @@ char *drm_get_connector_status_name(enum drm_connector_status status) + } + EXPORT_SYMBOL(drm_get_connector_status_name); + ++static char printable_char(int c) ++{ ++ return isascii(c) && isprint(c) ? c : '?'; ++} ++ ++char *drm_get_format_name(uint32_t format) ++{ ++ static char buf[32]; ++ ++ snprintf(buf, sizeof(buf), ++ "%c%c%c%c %s-endian (0x%08x)", ++ printable_char(format & 0xff), ++ printable_char((format >> 8) & 0xff), ++ printable_char((format >> 16) & 0xff), ++ printable_char((format >> 24) & 0x7f), ++ format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little", ++ format); ++ ++ return buf; ++} ++EXPORT_SYMBOL(drm_get_format_name); ++ + /** + * drm_mode_object_get - allocate a new modeset identifier + * @dev: DRM device +@@ -1834,7 +1857,8 @@ int drm_mode_setplane(struct drm_device *dev, void *data, + if (fb->pixel_format == plane->format_types[i]) + break; + if (i == plane->format_count) { +- DRM_DEBUG_KMS("Invalid pixel format 0x%08x\n", fb->pixel_format); ++ DRM_DEBUG_KMS("Invalid pixel format %s\n", ++ drm_get_format_name(fb->pixel_format)); + ret = -EINVAL; + goto out; + } +@@ -2312,7 +2336,8 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) + + ret = format_check(r); + if (ret) { +- DRM_DEBUG_KMS("bad framebuffer format 0x%08x\n", r->pixel_format); ++ DRM_DEBUG_KMS("bad framebuffer format %s\n", ++ drm_get_format_name(r->pixel_format)); + return ret; + } + +diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h +index adb3f9b625f6..2cbbfd44c6df 100644 +--- a/include/drm/drm_crtc.h ++++ b/include/drm/drm_crtc.h +@@ -1094,5 +1094,6 @@ extern int drm_format_num_planes(uint32_t format); + extern int drm_format_plane_cpp(uint32_t format, int plane); + extern int drm_format_horz_chroma_subsampling(uint32_t format); + extern int drm_format_vert_chroma_subsampling(uint32_t format); ++extern char *drm_get_format_name(uint32_t format); + + #endif /* __DRM_CRTC_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0168-drm-i915-Print-pretty-names-for-pixel-formats.patch b/patches.baytrail/0168-drm-i915-Print-pretty-names-for-pixel-formats.patch new file mode 100644 index 000000000000..e4a2b2fc61c1 --- /dev/null +++ b/patches.baytrail/0168-drm-i915-Print-pretty-names-for-pixel-formats.patch @@ -0,0 +1,67 @@ +From e14831c7f71a50e363b95d2edfc59fe5eb335a92 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 7 Jun 2013 15:43:05 +0000 +Subject: drm/i915: Print pretty names for pixel formats +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use drm_get_format_name to print more readable pixel format names +in debug output. + +Also unify the debug messages to say "unsupported pixel format", +which better describes what is going on. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit 4ee62c7669be1a6f1dd407e5ba7e38c0e2204e92) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 957dd91803fa..7137d17f16b3 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8957,7 +8957,8 @@ int intel_framebuffer_init(struct drm_device *dev, + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_ARGB1555: + if (INTEL_INFO(dev)->gen > 3) { +- DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); ++ DRM_DEBUG("unsupported pixel format: %s\n", ++ drm_get_format_name(mode_cmd->pixel_format)); + return -EINVAL; + } + break; +@@ -8968,7 +8969,8 @@ int intel_framebuffer_init(struct drm_device *dev, + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: + if (INTEL_INFO(dev)->gen < 4) { +- DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); ++ DRM_DEBUG("unsupported pixel format: %s\n", ++ drm_get_format_name(mode_cmd->pixel_format)); + return -EINVAL; + } + break; +@@ -8977,12 +8979,14 @@ int intel_framebuffer_init(struct drm_device *dev, + case DRM_FORMAT_YVYU: + case DRM_FORMAT_VYUY: + if (INTEL_INFO(dev)->gen < 5) { +- DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); ++ DRM_DEBUG("unsupported pixel format: %s\n", ++ drm_get_format_name(mode_cmd->pixel_format)); + return -EINVAL; + } + break; + default: +- DRM_DEBUG("unsupported pixel format 0x%08x\n", mode_cmd->pixel_format); ++ DRM_DEBUG("unsupported pixel format: %s\n", ++ drm_get_format_name(mode_cmd->pixel_format)); + return -EINVAL; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0169-drm-i915-add-encoder-get_config-function-v5.patch b/patches.baytrail/0169-drm-i915-add-encoder-get_config-function-v5.patch new file mode 100644 index 000000000000..414fe578a238 --- /dev/null +++ b/patches.baytrail/0169-drm-i915-add-encoder-get_config-function-v5.patch @@ -0,0 +1,438 @@ +From e94917dfbe1dab1819af4b23f0c7450bafb803a0 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Tue, 14 May 2013 17:08:26 -0700 +Subject: drm/i915: add encoder get_config function v5 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We can use this for fetching encoder specific pipe_config state, like +mode flags, adjusted clock, etc. + +Just used for mode flags atm, so we can check the pipe config state at +mode set time. + +v2: get_config when checking hw state too +v3: fix DVO and LVDS mode flags (Ville) + get SDVO DTD for flag fetch (Ville) +v4: use input timings (Ville) + correct command used (Ville) + remove gen4 check (Ville) +v5: get DDI flag config too + +Signed-off-by: Jesse Barnes +Reviewed-by: Ville Syrjälä (v4) +Tested-by: Paulo Zanoni (the new hsw ddi stuff) +Signed-off-by: Daniel Vetter +(cherry picked from commit 045ac3b5629d9711531a408e92f9074db6afe7ce) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_crt.c | 23 ++++++++++++++++++++ + drivers/gpu/drm/i915/intel_ddi.c | 23 ++++++++++++++++++++ + drivers/gpu/drm/i915/intel_display.c | 20 ++++++++++++++--- + drivers/gpu/drm/i915/intel_dp.c | 23 ++++++++++++++++++++ + drivers/gpu/drm/i915/intel_drv.h | 4 ++++ + drivers/gpu/drm/i915/intel_dvo.c | 21 ++++++++++++++++++ + drivers/gpu/drm/i915/intel_hdmi.c | 23 ++++++++++++++++++++ + drivers/gpu/drm/i915/intel_lvds.c | 26 ++++++++++++++++++++++ + drivers/gpu/drm/i915/intel_sdvo.c | 42 ++++++++++++++++++++++++++++++++++++ + 9 files changed, 202 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c +index 66a0c6f0bb81..5e9f93e53255 100644 +--- a/drivers/gpu/drm/i915/intel_crt.c ++++ b/drivers/gpu/drm/i915/intel_crt.c +@@ -84,6 +84,28 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, + return true; + } + ++static void intel_crt_get_config(struct intel_encoder *encoder, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; ++ struct intel_crt *crt = intel_encoder_to_crt(encoder); ++ u32 tmp, flags = 0; ++ ++ tmp = I915_READ(crt->adpa_reg); ++ ++ if (tmp & ADPA_HSYNC_ACTIVE_HIGH) ++ flags |= DRM_MODE_FLAG_PHSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NHSYNC; ++ ++ if (tmp & ADPA_VSYNC_ACTIVE_HIGH) ++ flags |= DRM_MODE_FLAG_PVSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NVSYNC; ++ ++ pipe_config->adjusted_mode.flags |= flags; ++} ++ + /* Note: The caller is required to filter out dpms modes not supported by the + * platform. */ + static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) +@@ -778,6 +800,7 @@ void intel_crt_init(struct drm_device *dev) + crt->base.compute_config = intel_crt_compute_config; + crt->base.disable = intel_disable_crt; + crt->base.enable = intel_enable_crt; ++ crt->base.get_config = intel_crt_get_config; + if (I915_HAS_HOTPLUG(dev)) + crt->base.hpd_pin = HPD_CRT; + if (HAS_DDI(dev)) +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 7799de733917..af699def47f0 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -1260,6 +1260,28 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder) + intel_dp_check_link_status(intel_dp); + } + ++static void intel_ddi_get_config(struct intel_encoder *encoder, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; ++ struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); ++ enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; ++ u32 temp, flags = 0; ++ ++ temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); ++ if (temp & TRANS_DDI_PHSYNC) ++ flags |= DRM_MODE_FLAG_PHSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NHSYNC; ++ if (temp & TRANS_DDI_PVSYNC) ++ flags |= DRM_MODE_FLAG_PVSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NVSYNC; ++ ++ pipe_config->adjusted_mode.flags |= flags; ++ pipe_config->pixel_multiplier = 1; ++} ++ + static void intel_ddi_destroy(struct drm_encoder *encoder) + { + /* HDMI has nothing special to destroy, so we can go with this. */ +@@ -1319,6 +1341,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port) + intel_encoder->disable = intel_disable_ddi; + intel_encoder->post_disable = intel_ddi_post_disable; + intel_encoder->get_hw_state = intel_ddi_get_hw_state; ++ intel_encoder->get_config = intel_ddi_get_config; + + intel_dig_port->port = port; + intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 7137d17f16b3..d2a01268443b 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8071,6 +8071,15 @@ intel_pipe_config_compare(struct drm_device *dev, + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, + DRM_MODE_FLAG_INTERLACE); + ++ PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, ++ DRM_MODE_FLAG_PHSYNC); ++ PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, ++ DRM_MODE_FLAG_NHSYNC); ++ PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, ++ DRM_MODE_FLAG_PVSYNC); ++ PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, ++ DRM_MODE_FLAG_NVSYNC); ++ + PIPE_CONF_CHECK_I(requested_mode.hdisplay); + PIPE_CONF_CHECK_I(requested_mode.vdisplay); + +@@ -8163,6 +8172,8 @@ intel_modeset_check_state(struct drm_device *dev) + bool enabled = false; + bool active = false; + ++ memset(&pipe_config, 0, sizeof(pipe_config)); ++ + DRM_DEBUG_KMS("[CRTC:%d]\n", + crtc->base.base.id); + +@@ -8176,6 +8187,8 @@ intel_modeset_check_state(struct drm_device *dev) + enabled = true; + if (encoder->connectors_active) + active = true; ++ if (encoder->get_config) ++ encoder->get_config(encoder, &pipe_config); + } + WARN(active != crtc->active, + "crtc's computed active state doesn't match tracked active state " +@@ -8184,7 +8197,6 @@ intel_modeset_check_state(struct drm_device *dev) + "crtc's computed enabled state doesn't match tracked enabled state " + "(expected %i, found %i)\n", enabled, crtc->base.enabled); + +- memset(&pipe_config, 0, sizeof(pipe_config)); + pipe_config.cpu_transcoder = crtc->config.cpu_transcoder; + active = dev_priv->display.get_pipe_config(crtc, + &pipe_config); +@@ -9636,8 +9648,10 @@ setup_pipes: + pipe = 0; + + if (encoder->get_hw_state(encoder, &pipe)) { +- encoder->base.crtc = +- dev_priv->pipe_to_crtc_mapping[pipe]; ++ crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); ++ encoder->base.crtc = &crtc->base; ++ if (encoder->get_config) ++ encoder->get_config(encoder, &crtc->config); + } else { + encoder->base.crtc = NULL; + } +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 848d3d436f7e..8c282c8af0ed 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1366,6 +1366,28 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, + return true; + } + ++static void intel_dp_get_config(struct intel_encoder *encoder, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); ++ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; ++ u32 tmp, flags = 0; ++ ++ tmp = I915_READ(intel_dp->output_reg); ++ ++ if (tmp & DP_SYNC_HS_HIGH) ++ flags |= DRM_MODE_FLAG_PHSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NHSYNC; ++ ++ if (tmp & DP_SYNC_VS_HIGH) ++ flags |= DRM_MODE_FLAG_PVSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NVSYNC; ++ ++ pipe_config->adjusted_mode.flags |= flags; ++} ++ + static void intel_disable_dp(struct intel_encoder *encoder) + { + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); +@@ -3204,6 +3226,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) + intel_encoder->disable = intel_disable_dp; + intel_encoder->post_disable = intel_post_disable_dp; + intel_encoder->get_hw_state = intel_dp_get_hw_state; ++ intel_encoder->get_config = intel_dp_get_config; + if (IS_VALLEYVIEW(dev)) + intel_encoder->pre_pll_enable = intel_dp_pre_pll_enable; + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 8ef7496b74ef..f0cae755a0a6 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -139,6 +139,10 @@ struct intel_encoder { + * the encoder is active. If the encoder is enabled it also set the pipe + * it is connected to in the pipe parameter. */ + bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe); ++ /* Reconstructs the equivalent mode flags for the current hardware ++ * state. */ ++ void (*get_config)(struct intel_encoder *, ++ struct intel_crtc_config *pipe_config); + int crtc_mask; + enum hpd_pin hpd_pin; + }; +diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c +index 2c0be924e9a9..9e80d487b5cb 100644 +--- a/drivers/gpu/drm/i915/intel_dvo.c ++++ b/drivers/gpu/drm/i915/intel_dvo.c +@@ -136,6 +136,26 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder, + return true; + } + ++static void intel_dvo_get_config(struct intel_encoder *encoder, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; ++ struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); ++ u32 tmp, flags = 0; ++ ++ tmp = I915_READ(intel_dvo->dev.dvo_reg); ++ if (tmp & DVO_HSYNC_ACTIVE_HIGH) ++ flags |= DRM_MODE_FLAG_PHSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NHSYNC; ++ if (tmp & DVO_VSYNC_ACTIVE_HIGH) ++ flags |= DRM_MODE_FLAG_PVSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NVSYNC; ++ ++ pipe_config->adjusted_mode.flags |= flags; ++} ++ + static void intel_disable_dvo(struct intel_encoder *encoder) + { + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; +@@ -447,6 +467,7 @@ void intel_dvo_init(struct drm_device *dev) + intel_encoder->disable = intel_disable_dvo; + intel_encoder->enable = intel_enable_dvo; + intel_encoder->get_hw_state = intel_dvo_get_hw_state; ++ intel_encoder->get_config = intel_dvo_get_config; + intel_connector->get_hw_state = intel_dvo_connector_get_hw_state; + + /* Now, try to find a controller */ +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 2b727f0d201f..18f8ce0404c6 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -658,6 +658,28 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, + return true; + } + ++static void intel_hdmi_get_config(struct intel_encoder *encoder, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); ++ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; ++ u32 tmp, flags = 0; ++ ++ tmp = I915_READ(intel_hdmi->hdmi_reg); ++ ++ if (tmp & SDVO_HSYNC_ACTIVE_HIGH) ++ flags |= DRM_MODE_FLAG_PHSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NHSYNC; ++ ++ if (tmp & SDVO_VSYNC_ACTIVE_HIGH) ++ flags |= DRM_MODE_FLAG_PVSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NVSYNC; ++ ++ pipe_config->adjusted_mode.flags |= flags; ++} ++ + static void intel_enable_hdmi(struct intel_encoder *encoder) + { + struct drm_device *dev = encoder->base.dev; +@@ -1216,6 +1238,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) + intel_encoder->enable = intel_enable_hdmi; + intel_encoder->disable = intel_disable_hdmi; + intel_encoder->get_hw_state = intel_hdmi_get_hw_state; ++ intel_encoder->get_config = intel_hdmi_get_config; + if (IS_VALLEYVIEW(dev)) { + intel_encoder->pre_enable = intel_hdmi_pre_enable; + intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable; +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index fa7511143974..0b67e89cac9c 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -86,6 +86,31 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, + return true; + } + ++static void intel_lvds_get_config(struct intel_encoder *encoder, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ u32 lvds_reg, tmp, flags = 0; ++ ++ if (HAS_PCH_SPLIT(dev)) ++ lvds_reg = PCH_LVDS; ++ else ++ lvds_reg = LVDS; ++ ++ tmp = I915_READ(lvds_reg); ++ if (tmp & LVDS_HSYNC_POLARITY) ++ flags |= DRM_MODE_FLAG_NHSYNC; ++ else ++ flags |= DRM_MODE_FLAG_PHSYNC; ++ if (tmp & LVDS_VSYNC_POLARITY) ++ flags |= DRM_MODE_FLAG_NVSYNC; ++ else ++ flags |= DRM_MODE_FLAG_PVSYNC; ++ ++ pipe_config->adjusted_mode.flags |= flags; ++} ++ + /* The LVDS pin pair needs to be on before the DPLLs are enabled. + * This is an exception to the general rule that mode_set doesn't turn + * things on. +@@ -953,6 +978,7 @@ bool intel_lvds_init(struct drm_device *dev) + intel_encoder->compute_config = intel_lvds_compute_config; + intel_encoder->disable = intel_disable_lvds; + intel_encoder->get_hw_state = intel_lvds_get_hw_state; ++ intel_encoder->get_config = intel_lvds_get_config; + intel_connector->get_hw_state = intel_connector_get_hw_state; + + intel_connector_attach_encoder(intel_connector, intel_encoder); +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 474fa8addab1..f8ad93bd7d9b 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -712,6 +712,13 @@ static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd, + intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); + } + ++static bool intel_sdvo_get_timing(struct intel_sdvo *intel_sdvo, u8 cmd, ++ struct intel_sdvo_dtd *dtd) ++{ ++ return intel_sdvo_get_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) && ++ intel_sdvo_get_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); ++} ++ + static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, + struct intel_sdvo_dtd *dtd) + { +@@ -726,6 +733,13 @@ static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo, + SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); + } + ++static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo, ++ struct intel_sdvo_dtd *dtd) ++{ ++ return intel_sdvo_get_timing(intel_sdvo, ++ SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd); ++} ++ + static bool + intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, + uint16_t clock, +@@ -1295,6 +1309,33 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, + return true; + } + ++static void intel_sdvo_get_config(struct intel_encoder *encoder, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); ++ struct intel_sdvo_dtd dtd; ++ u32 flags = 0; ++ bool ret; ++ ++ ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); ++ if (!ret) { ++ DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n"); ++ return; ++ } ++ ++ if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) ++ flags |= DRM_MODE_FLAG_PHSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NHSYNC; ++ ++ if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) ++ flags |= DRM_MODE_FLAG_PVSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NVSYNC; ++ ++ pipe_config->adjusted_mode.flags |= flags; ++} ++ + static void intel_disable_sdvo(struct intel_encoder *encoder) + { + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; +@@ -2821,6 +2862,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) + intel_encoder->mode_set = intel_sdvo_mode_set; + intel_encoder->enable = intel_enable_sdvo; + intel_encoder->get_hw_state = intel_sdvo_get_hw_state; ++ intel_encoder->get_config = intel_sdvo_get_config; + + /* In default case sdvo lvds is false */ + if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0170-drm-i915-ILK-SNB-and-IVB-don-t-have-linetime-waterma.patch b/patches.baytrail/0170-drm-i915-ILK-SNB-and-IVB-don-t-have-linetime-waterma.patch new file mode 100644 index 000000000000..ab194e7db331 --- /dev/null +++ b/patches.baytrail/0170-drm-i915-ILK-SNB-and-IVB-don-t-have-linetime-waterma.patch @@ -0,0 +1,36 @@ +From 31c34ee116fd52a7461bba195c74d5bff1563774 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 3 May 2013 17:23:37 -0300 +Subject: drm/i915: ILK, SNB and IVB don't have linetime watermarks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +So don't call intel_update_linetime_watermarks from +ironlake_crtc_mode_set. Only Haswell has these watermarks. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 5a41254eac1137d0335c0aed7b00f1f3138ee9ca) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index d2a01268443b..95dc839be850 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5841,8 +5841,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + + intel_update_watermarks(dev); + +- intel_update_linetime_watermarks(dev, pipe, adjusted_mode); +- + return ret; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0171-drm-i915-remove-intel_update_linetime_watermarks.patch b/patches.baytrail/0171-drm-i915-remove-intel_update_linetime_watermarks.patch new file mode 100644 index 000000000000..10b2d65ca091 --- /dev/null +++ b/patches.baytrail/0171-drm-i915-remove-intel_update_linetime_watermarks.patch @@ -0,0 +1,160 @@ +From 67d7cd19116763b9de65ee81d1aeb3297bf970d7 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 9 May 2013 16:55:50 -0300 +Subject: drm/i915: remove intel_update_linetime_watermarks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The spec says the linetime watermarks must be programmed before +enabling any display low power watermarks, but we're currently +updating the linetime watermarks after we call intel_update_watermarks +(and only at crtc_mode_set, not at crtc_{enable,disable}). So IMHO the +best way guarantee the linetime watermarks will be updated before the +low power watermarks is inside the update_wm function, because it's +the function that enables low power watermarks. And since Haswell is +the only platform that has linetime watermarks, let's completely kill +the "intel_update_linetime_watermarks" abstraction and just use the +intel_update_watermarks abstraction by creating haswell_update_wm. + +For now haswell_update_wm is still calling sandybridge_update_wm, but +in the future I plan to implement a function specific to Haswell. + +v2: - Rename patch + - Disable LP watermarks before changing linetime WMs (Chris) + - Add a comment explaining that this is just temporary code. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 1011d8c4373b229012208b5aedad4f46396bdd94) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 -- + drivers/gpu/drm/i915/intel_display.c | 2 -- + drivers/gpu/drm/i915/intel_drv.h | 2 -- + drivers/gpu/drm/i915/intel_pm.c | 43 +++++++++++++++++++++++++----------- + 4 files changed, 30 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index dc2997828af1..4ab1e4266da0 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -316,8 +316,6 @@ struct drm_i915_display_funcs { + void (*update_wm)(struct drm_device *dev); + void (*update_sprite_wm)(struct drm_device *dev, int pipe, + uint32_t sprite_width, int pixel_size); +- void (*update_linetime_wm)(struct drm_device *dev, int pipe, +- struct drm_display_mode *mode); + void (*modeset_global_resources)(struct drm_device *dev); + /* Returns the active state of the crtc, and if the crtc is active, + * fills out the pipe-config with the hw state. */ +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 95dc839be850..e62a9770cf71 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -6008,8 +6008,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + + intel_update_watermarks(dev); + +- intel_update_linetime_watermarks(dev, pipe, adjusted_mode); +- + return ret; + } + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index f0cae755a0a6..a5ba33bb6c0d 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -732,8 +732,6 @@ extern void intel_update_watermarks(struct drm_device *dev); + extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, + uint32_t sprite_width, + int pixel_size); +-extern void intel_update_linetime_watermarks(struct drm_device *dev, int pipe, +- struct drm_display_mode *mode); + + extern unsigned long intel_gen4_compute_page_offset(int *x, int *y, + unsigned int tiling_mode, +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 71752d5cdaf4..e8505e8cd711 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2073,12 +2073,19 @@ static void ivybridge_update_wm(struct drm_device *dev) + } + + static void +-haswell_update_linetime_wm(struct drm_device *dev, int pipe, +- struct drm_display_mode *mode) ++haswell_update_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) + { + struct drm_i915_private *dev_priv = dev->dev_private; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ enum pipe pipe = intel_crtc->pipe; ++ struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode; + u32 temp; + ++ if (!intel_crtc_active(crtc)) { ++ I915_WRITE(PIPE_WM_LINETIME(pipe), 0); ++ return; ++ } ++ + temp = I915_READ(PIPE_WM_LINETIME(pipe)); + temp &= ~PIPE_WM_LINETIME_MASK; + +@@ -2099,6 +2106,26 @@ haswell_update_linetime_wm(struct drm_device *dev, int pipe, + I915_WRITE(PIPE_WM_LINETIME(pipe), temp); + } + ++static void haswell_update_wm(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_crtc *crtc; ++ enum pipe pipe; ++ ++ /* Disable the LP WMs before changine the linetime registers. This is ++ * just a temporary code that will be replaced soon. */ ++ I915_WRITE(WM3_LP_ILK, 0); ++ I915_WRITE(WM2_LP_ILK, 0); ++ I915_WRITE(WM1_LP_ILK, 0); ++ ++ for_each_pipe(pipe) { ++ crtc = dev_priv->pipe_to_crtc_mapping[pipe]; ++ haswell_update_linetime_wm(dev, crtc); ++ } ++ ++ sandybridge_update_wm(dev); ++} ++ + static bool + sandybridge_compute_sprite_wm(struct drm_device *dev, int plane, + uint32_t sprite_width, int pixel_size, +@@ -2294,15 +2321,6 @@ void intel_update_watermarks(struct drm_device *dev) + dev_priv->display.update_wm(dev); + } + +-void intel_update_linetime_watermarks(struct drm_device *dev, +- int pipe, struct drm_display_mode *mode) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- +- if (dev_priv->display.update_linetime_wm) +- dev_priv->display.update_linetime_wm(dev, pipe, mode); +-} +- + void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, + uint32_t sprite_width, int pixel_size) + { +@@ -4624,9 +4642,8 @@ void intel_init_pm(struct drm_device *dev) + dev_priv->display.init_clock_gating = ivybridge_init_clock_gating; + } else if (IS_HASWELL(dev)) { + if (SNB_READ_WM0_LATENCY()) { +- dev_priv->display.update_wm = sandybridge_update_wm; ++ dev_priv->display.update_wm = haswell_update_wm; + dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; +- dev_priv->display.update_linetime_wm = haswell_update_linetime_wm; + } else { + DRM_DEBUG_KMS("Failed to read display plane latency. " + "Disable CxSR\n"); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0172-drm-i915-use-the-mode-htotal-to-calculate-linetime-w.patch b/patches.baytrail/0172-drm-i915-use-the-mode-htotal-to-calculate-linetime-w.patch new file mode 100644 index 000000000000..947f32201518 --- /dev/null +++ b/patches.baytrail/0172-drm-i915-use-the-mode-htotal-to-calculate-linetime-w.patch @@ -0,0 +1,37 @@ +From a387a082e8b46f08ecdb3fc3f5c514a9c070e9f6 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 3 May 2013 17:23:39 -0300 +Subject: drm/i915: use the mode->htotal to calculate linetime watermarks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +... instead of mode->crtc_display. The spec says "pipe horizontal +total number of pixels" and the "Haswell Watermark Calculator" tool +uses the "Pipe H Total" instead of "Pipe H Src" as the value. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 7366937312d4e406539b1cf70e1562358bdd560e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index e8505e8cd711..9f336991fee7 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2093,7 +2093,7 @@ haswell_update_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) + * row at the given clock rate, multiplied by 8. + * */ + temp |= PIPE_WM_LINETIME_TIME( +- ((mode->crtc_hdisplay * 1000) / mode->clock) * 8); ++ ((mode->htotal * 1000) / mode->clock) * 8); + + /* IPS watermarks are only used by pipe A, and are ignored by + * pipes B and C. They are calculated similarly to the common +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0173-drm-i915-fix-haswell-linetime-watermarks-calculation.patch b/patches.baytrail/0173-drm-i915-fix-haswell-linetime-watermarks-calculation.patch new file mode 100644 index 000000000000..6428336fba60 --- /dev/null +++ b/patches.baytrail/0173-drm-i915-fix-haswell-linetime-watermarks-calculation.patch @@ -0,0 +1,37 @@ +From c13117d00b2dfb5b8ed8472a47bbd73418dd73b8 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 3 May 2013 17:23:40 -0300 +Subject: drm/i915: fix haswell linetime watermarks calculation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Move the "*8" calculation to the left side so we don't propagate +rounding errors. Also use DIV_ROUND_CLOSEST because that's what the +spec says we need to do. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit eaa591ec528ad75bb4c77606c5cb671f05e04db6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 9f336991fee7..84cc32643f63 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2093,7 +2093,7 @@ haswell_update_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) + * row at the given clock rate, multiplied by 8. + * */ + temp |= PIPE_WM_LINETIME_TIME( +- ((mode->htotal * 1000) / mode->clock) * 8); ++ DIV_ROUND_CLOSEST(mode->htotal * 1000 * 8, mode->clock)); + + /* IPS watermarks are only used by pipe A, and are ignored by + * pipes B and C. They are calculated similarly to the common +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0174-drm-i915-make-intel_ddi_get_cdclk_freq-return-values.patch b/patches.baytrail/0174-drm-i915-make-intel_ddi_get_cdclk_freq-return-values.patch new file mode 100644 index 000000000000..48dd34336c1d --- /dev/null +++ b/patches.baytrail/0174-drm-i915-make-intel_ddi_get_cdclk_freq-return-values.patch @@ -0,0 +1,101 @@ +From 4395f23a2af9250ec17528c7fbccdf7b3a16badc Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 3 May 2013 17:23:42 -0300 +Subject: drm/i915: make intel_ddi_get_cdclk_freq return values in KHz +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With this, that 338 can finally become the correct 337500. + +Due to the change we need to adjust the intel_dp_aux_ch function to +set the correct value, so adjust the division and also use +DIV_ROUND_CLOSEST instead of the old "round down" behavior because the +spec says the value "should be programmed to get as close as possible +to the ideal rate of 2MHz". + +Quoting Paulo's follow-up to a question from Chris Wilson to explain +what exactly will change: + +I use the 337500 value on the next patch, when setting the +ips_linetime value. The correct frequency is 337500, not 338000. + +ips_linetime = DIV_ROUND_CLOSEST(mode->htotal * 1000 * 8, +intel_ddi_get_cdclk_freq); +For a mode with htotal of 2640 [0] we'll have: (i) (2640 * 1000 * 8) / +338000 = 62.48, resulting in 62 and (ii) (2640 * 1000 * 8) / 337500 = +62.57 resulting in 63. + +For the case inside intel_dp.c: +Previously we were using 338. So with the old formula we were writing +338/2 = 169 to the register. And 337500 / 169 = 1997.04 (we use 337500 +here because it's the real clock value). With the new value of +337500/2000 we'll have 168.75, which is 168 on the round-down case and +169 on the round-closest case. If we write 168 to the register, 337500 +/ 168 = 2008.92, and 2008.92 is more distant from 2000 than 1997.04. +So with this patch we're changing the formula but still writing the +same correct value to the DP AUX register. + +[0]: That's 1920x1080@50Hz on my DP monitor. + +Signed-off-by: Paulo Zanoni +[danvet: Pimp the commit message with Paulo's follow-up.] +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter + +(cherry picked from commit b2b877ffe37d699f77f45e993590b66010491c52) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 10 +++++----- + drivers/gpu/drm/i915/intel_dp.c | 3 ++- + 2 files changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index af699def47f0..418b91c28ed6 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -1154,14 +1154,14 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) + int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) + { + if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) +- return 450; ++ return 450000; + else if ((I915_READ(LCPLL_CTL) & LCPLL_CLK_FREQ_MASK) == + LCPLL_CLK_FREQ_450) +- return 450; ++ return 450000; + else if (IS_ULT(dev_priv->dev)) +- return 338; ++ return 337500; + else +- return 540; ++ return 540000; + } + + void intel_ddi_pll_init(struct drm_device *dev) +@@ -1174,7 +1174,7 @@ void intel_ddi_pll_init(struct drm_device *dev) + * Don't even try to turn it on. + */ + +- DRM_DEBUG_KMS("CDCLK running at %dMHz\n", ++ DRM_DEBUG_KMS("CDCLK running at %dKHz\n", + intel_ddi_get_cdclk_freq(dev_priv)); + + if (val & LCPLL_CD_SOURCE_FCLK) +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 8c282c8af0ed..73b97a1b2143 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -319,7 +319,8 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, + */ + if (is_cpu_edp(intel_dp)) { + if (HAS_DDI(dev)) +- aux_clock_divider = intel_ddi_get_cdclk_freq(dev_priv) >> 1; ++ aux_clock_divider = DIV_ROUND_CLOSEST( ++ intel_ddi_get_cdclk_freq(dev_priv), 2000); + else if (IS_VALLEYVIEW(dev)) + aux_clock_divider = 100; + else if (IS_GEN6(dev) || IS_GEN7(dev)) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0175-drm-i915-set-the-IPS-linetime-watermark.patch b/patches.baytrail/0175-drm-i915-set-the-IPS-linetime-watermark.patch new file mode 100644 index 000000000000..2c87639b99b7 --- /dev/null +++ b/patches.baytrail/0175-drm-i915-set-the-IPS-linetime-watermark.patch @@ -0,0 +1,72 @@ +From 842f1bd6f12a539caed5337bff25eec9f27df39e Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 3 May 2013 17:23:43 -0300 +Subject: drm/i915: set the IPS linetime watermark +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Remove the "placeholder" comment and set the actual value described by +the specification. We still don't enable IPS, but it won't hurt to +already have the value set here. + +While at it, fully set the register value instead of just masking the +values we're changing. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ville Syrjälä +[danvet: Resolve conflict due to reordered patches.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 85a02deb4ca5a7e1e39e8538b6eb3c7066469720) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 22 +++++++--------------- + 1 file changed, 7 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 84cc32643f63..c121e516c2cc 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2079,31 +2079,23 @@ haswell_update_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + enum pipe pipe = intel_crtc->pipe; + struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode; +- u32 temp; ++ u32 linetime, ips_linetime; + + if (!intel_crtc_active(crtc)) { + I915_WRITE(PIPE_WM_LINETIME(pipe), 0); + return; + } + +- temp = I915_READ(PIPE_WM_LINETIME(pipe)); +- temp &= ~PIPE_WM_LINETIME_MASK; +- + /* The WM are computed with base on how long it takes to fill a single + * row at the given clock rate, multiplied by 8. + * */ +- temp |= PIPE_WM_LINETIME_TIME( +- DIV_ROUND_CLOSEST(mode->htotal * 1000 * 8, mode->clock)); +- +- /* IPS watermarks are only used by pipe A, and are ignored by +- * pipes B and C. They are calculated similarly to the common +- * linetime values, except that we are using CD clock frequency +- * in MHz instead of pixel rate for the division. +- * +- * This is a placeholder for the IPS watermark calculation code. +- */ ++ linetime = DIV_ROUND_CLOSEST(mode->htotal * 1000 * 8, mode->clock); ++ ips_linetime = DIV_ROUND_CLOSEST(mode->htotal * 1000 * 8, ++ intel_ddi_get_cdclk_freq(dev_priv)); + +- I915_WRITE(PIPE_WM_LINETIME(pipe), temp); ++ I915_WRITE(PIPE_WM_LINETIME(pipe), ++ PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) | ++ PIPE_WM_LINETIME_TIME(linetime)); + } + + static void haswell_update_wm(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0176-drm-i915-MCH_SSKPD-is-a-64-bit-register-on-Haswell.patch b/patches.baytrail/0176-drm-i915-MCH_SSKPD-is-a-64-bit-register-on-Haswell.patch new file mode 100644 index 000000000000..e2f91a0bac1a --- /dev/null +++ b/patches.baytrail/0176-drm-i915-MCH_SSKPD-is-a-64-bit-register-on-Haswell.patch @@ -0,0 +1,37 @@ +From d206a94de025497e11e0294766496b1bbf7e9919 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 3 May 2013 17:23:44 -0300 +Subject: drm/i915: MCH_SSKPD is a 64 bit register on Haswell +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +And the SNB_READ_WM0_LATENCY macro is not valid anymore because we +have the "New WM0" at 63:56, so the "Old WM0" could maybe be zero if +the new one is not zero. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 3e1f72664e0a8a31e9b90c48459deb6642fd52f3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index c121e516c2cc..42bc0a36caac 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4633,7 +4633,7 @@ void intel_init_pm(struct drm_device *dev) + } + dev_priv->display.init_clock_gating = ivybridge_init_clock_gating; + } else if (IS_HASWELL(dev)) { +- if (SNB_READ_WM0_LATENCY()) { ++ if (I915_READ64(MCH_SSKPD)) { + dev_priv->display.update_wm = haswell_update_wm; + dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; + } else { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0177-drm-i915-set-FORCE_ARB_IDLE_PLANES-workaround.patch b/patches.baytrail/0177-drm-i915-set-FORCE_ARB_IDLE_PLANES-workaround.patch new file mode 100644 index 000000000000..9ac18963d6dd --- /dev/null +++ b/patches.baytrail/0177-drm-i915-set-FORCE_ARB_IDLE_PLANES-workaround.patch @@ -0,0 +1,73 @@ +From ad3d17fd1ffb41255af37cbacf0b3602627ece21 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 3 May 2013 17:23:45 -0300 +Subject: drm/i915: set FORCE_ARB_IDLE_PLANES workaround +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 1544d9d57396d5c0c6b7644ed5ae1f4d6caad07a added a workaround +inside haswell_init_clock_gating and mentioned it is "a workaround for +early silicon revisions and should be removed later". This workaround +is documented in bit 31 of PRI_CTL. I asked Arthur and he mentioned +that setting FORCE_ARB_IDLE_PLANES replaces that workaround for the +newer machines. So use the new one. + +Also notice that there's still another workaround for PRI_CTL that +involves WM_DBG, but it's not the one we're reverting. And notice that +we were previously setting WM_DBG_DISALLOW_MULTIPIPE_LP which disables +the LP watermarks when more than one pipe is used, and we really don't +want this because we need the LP watermarks if we want to reach deeper +PC states. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ville Syrjälä +[danvet: Add a comment for the w/a name Ville dug out of Bspec.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 90a8864320b2a9f91e5b5d561924a4bb70b90dcc) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 3 +++ + drivers/gpu/drm/i915/intel_pm.c | 11 +++-------- + 2 files changed, 6 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 83cc2e5dbd79..669da48ecca8 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -3717,6 +3717,9 @@ + # define CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE (1 << 5) + # define CHICKEN3_DGMG_DONE_FIX_DISABLE (1 << 2) + ++#define CHICKEN_PAR1_1 0x42080 ++#define FORCE_ARB_IDLE_PLANES (1 << 14) ++ + #define DISP_ARB_CTL 0x45000 + #define DISP_TILE_SURFACE_SWIZZLING (1<<13) + #define DISP_FBC_WM_DIS (1<<15) +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 42bc0a36caac..f016998ca83c 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4172,14 +4172,9 @@ static void haswell_init_clock_gating(struct drm_device *dev) + /* WaSwitchSolVfFArbitrationPriority:hsw */ + I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); + +- /* XXX: This is a workaround for early silicon revisions and should be +- * removed later. +- */ +- I915_WRITE(WM_DBG, +- I915_READ(WM_DBG) | +- WM_DBG_DISALLOW_MULTIPLE_LP | +- WM_DBG_DISALLOW_SPRITE | +- WM_DBG_DISALLOW_MAXFIFO); ++ /* WaRsPkgCStateDisplayPMReq:hsw */ ++ I915_WRITE(CHICKEN_PAR1_1, ++ I915_READ(CHICKEN_PAR1_1) | FORCE_ARB_IDLE_PLANES); + + lpt_init_clock_gating(dev); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0178-drm-i915-Be-more-informative-when-reporting-too-larg.patch b/patches.baytrail/0178-drm-i915-Be-more-informative-when-reporting-too-larg.patch new file mode 100644 index 000000000000..ead49fa5bd21 --- /dev/null +++ b/patches.baytrail/0178-drm-i915-Be-more-informative-when-reporting-too-larg.patch @@ -0,0 +1,39 @@ +From c02628fc0cd3df67a39ce0ea2cb7dbfeaabbfd90 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Tue, 21 May 2013 16:58:49 +0100 +Subject: drm/i915: Be more informative when reporting "too large for aperture" + error + +This should help debugging the truly unexpected cases where it occurs - +in particular to see which value is garbage. + +References: https://bugzilla.kernel.org/show_bug.cgi?id=58511 +Signed-off-by: Chris Wilson +[danvet: s/%ld/%zd/ as spotted by Wu Fengguang's autobuilder.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit a36689cb771f06819c3fa8139c3d3716dfdf6d53) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 34a1d71655a3..33de1ead1f5d 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3007,7 +3007,10 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + */ + if (obj->base.size > + (map_and_fenceable ? dev_priv->gtt.mappable_end : dev_priv->gtt.total)) { +- DRM_ERROR("Attempting to bind an object larger than the aperture\n"); ++ DRM_ERROR("Attempting to bind an object larger than the aperture: object=%zd > %s aperture=%ld\n", ++ obj->base.size, ++ map_and_fenceable ? "mappable" : "total", ++ map_and_fenceable ? dev_priv->gtt.mappable_end : dev_priv->gtt.total); + return -E2BIG; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0179-drm-i915-Fix-WARN_ON-on-UP-machines.patch b/patches.baytrail/0179-drm-i915-Fix-WARN_ON-on-UP-machines.patch new file mode 100644 index 000000000000..21e815351c7c --- /dev/null +++ b/patches.baytrail/0179-drm-i915-Fix-WARN_ON-on-UP-machines.patch @@ -0,0 +1,44 @@ +From c54aea2e14d56b49663106bc6bd97fc46e893937 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 22 May 2013 11:36:40 +0300 +Subject: drm/i915: Fix WARN_ON() on UP machines +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +WARN_ON(!spin_is_locked()) is not a good idea on a UP system w/o +spinlock debugging. Use WARN_ON_SMP() instead. + +This check has been added in + +commit 8ba2d18520ce380cf572e9902d9b3b91ece6c2c0 +Author: Jani Nikula +Date: Fri Apr 12 15:18:37 2013 +0300 + + drm/i915: protect backlight registers and data with a spinlock + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit df0a67979543e716d411eb11406848dcb50abd0a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_panel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index 8cae635bb90a..01b5a519c43c 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -332,7 +332,7 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val; + +- WARN_ON(!spin_is_locked(&dev_priv->backlight.lock)); ++ WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight.lock)); + + /* Restore the CTL value if it lost, e.g. GPU reset */ + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0180-drm-i915-Workaround-incoherence-with-fence-updates-o.patch b/patches.baytrail/0180-drm-i915-Workaround-incoherence-with-fence-updates-o.patch new file mode 100644 index 000000000000..81129f1a9229 --- /dev/null +++ b/patches.baytrail/0180-drm-i915-Workaround-incoherence-with-fence-updates-o.patch @@ -0,0 +1,101 @@ +From 032d38bcda1684aac0ef54de8b6e9331735bd5f5 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 22 May 2013 17:08:06 +0100 +Subject: drm/i915: Workaround incoherence with fence updates on Valleyview + +In commit 25ff1195f8a0b3724541ae7bbe331b4296de9c06 +Author: Chris Wilson +Date: Thu Apr 4 21:31:03 2013 +0100 + + drm/i915: Workaround incoherence between fences and LLC across multiple CPUs + +we introduced an empirical workaround for memory corruption when using +fences from multiple CPUs. At the time, we did not have any results for +Valleyview, so the presumption was that it was limited to recent +generations using LLC. Now we have evidence that Valleyview also suffers +incoherence and requires a similar but different workaround. For +Valleyview, the wbinvd instruction is insufficient and we require the +serialising register write per-CPU. Conversely, that serialising +register write is not enough for SNB/IVB/HSW. To compromise and keep the +code relatively clean, employ both serialisation techniques in the same +workaround. + +Reported-by: Jon Bloomfield +Tested-by: Jon Bloomfield +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=62191 +Signed-off-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 2dc8aae06d53458dd3624dc0accd4f81100ee631) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 35 ++++++++++++++++++++++++++++------- + 1 file changed, 28 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 33de1ead1f5d..229089c83f25 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2725,18 +2725,33 @@ static inline int fence_number(struct drm_i915_private *dev_priv, + return fence - dev_priv->fence_regs; + } + ++struct write_fence { ++ struct drm_device *dev; ++ struct drm_i915_gem_object *obj; ++ int fence; ++}; ++ + static void i915_gem_write_fence__ipi(void *data) + { ++ struct write_fence *args = data; ++ ++ /* Required for SNB+ with LLC */ + wbinvd(); ++ ++ /* Required for VLV */ ++ i915_gem_write_fence(args->dev, args->fence, args->obj); + } + + static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, + struct drm_i915_fence_reg *fence, + bool enable) + { +- struct drm_device *dev = obj->base.dev; +- struct drm_i915_private *dev_priv = dev->dev_private; +- int fence_reg = fence_number(dev_priv, fence); ++ struct drm_i915_private *dev_priv = obj->base.dev->dev_private; ++ struct write_fence args = { ++ .dev = obj->base.dev, ++ .fence = fence_number(dev_priv, fence), ++ .obj = enable ? obj : NULL, ++ }; + + /* In order to fully serialize access to the fenced region and + * the update to the fence register we need to take extreme +@@ -2747,13 +2762,19 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, + * SNB+ we need to take a step further and emit an explicit wbinvd() + * on each processor in order to manually flush all memory + * transactions before updating the fence register. ++ * ++ * However, Valleyview complicates matter. There the wbinvd is ++ * insufficient and unlike SNB/IVB requires the serialising ++ * register write. (Note that that register write by itself is ++ * conversely not sufficient for SNB+.) To compromise, we do both. + */ +- if (HAS_LLC(obj->base.dev)) +- on_each_cpu(i915_gem_write_fence__ipi, NULL, 1); +- i915_gem_write_fence(dev, fence_reg, enable ? obj : NULL); ++ if (INTEL_INFO(args.dev)->gen >= 6) ++ on_each_cpu(i915_gem_write_fence__ipi, &args, 1); ++ else ++ i915_gem_write_fence(args.dev, args.fence, args.obj); + + if (enable) { +- obj->fence_reg = fence_reg; ++ obj->fence_reg = args.fence; + fence->obj = obj; + list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); + } else { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0181-drm-i915-Cocci-spatch-memdup.spatch.patch b/patches.baytrail/0181-drm-i915-Cocci-spatch-memdup.spatch.patch new file mode 100644 index 000000000000..3d0a1d9dbaff --- /dev/null +++ b/patches.baytrail/0181-drm-i915-Cocci-spatch-memdup.spatch.patch @@ -0,0 +1,33 @@ +From 2875f3868f69e8be973007bb5beba758e6ea215d Mon Sep 17 00:00:00 2001 +From: Thomas Meyer +Date: Wed, 22 May 2013 23:07:09 +0200 +Subject: drm/i915: Cocci spatch "memdup.spatch" + +Signed-off-by: Thomas Meyer +Signed-off-by: Daniel Vetter +(cherry picked from commit edbe1581c5f94f7fba39cd9a5b2facd624aab661) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 73b97a1b2143..093138c2f080 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -2531,11 +2531,10 @@ intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) + return NULL; + + size = (intel_connector->edid->extensions + 1) * EDID_LENGTH; +- edid = kmalloc(size, GFP_KERNEL); ++ edid = kmemdup(intel_connector->edid, size, GFP_KERNEL); + if (!edid) + return NULL; + +- memcpy(edid, intel_connector->edid, size); + return edid; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0182-drm-i915-avoid-big-kmallocs-on-reading-error-state.patch b/patches.baytrail/0182-drm-i915-avoid-big-kmallocs-on-reading-error-state.patch new file mode 100644 index 000000000000..7c60b13b812b --- /dev/null +++ b/patches.baytrail/0182-drm-i915-avoid-big-kmallocs-on-reading-error-state.patch @@ -0,0 +1,568 @@ +From c92e8eb4241bddd30dceb7414cca1689b690dc53 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Thu, 23 May 2013 13:55:35 +0300 +Subject: drm/i915: avoid big kmallocs on reading error state + +Sometimes when user is trying to get error state out from +debugfs after gpu hang, the memory is low and/or fragmented +enough that kmalloc in seq_file will fail. + +Prevent big kmalloc by avoiding seq_file and instead convert +error state to string in smaller chunks. + +v2: better alloc flags, better truncate, correct +locking, and error handling improvements (Chris Wilson) + +v3: printf annotations (Daniel Vetter) + +Signed-off-by: Mika Kuoppala +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit edc3d8848dc9fe2a470316363dab8ef211d77e01) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 242 ++++++++++++++++++++++++++--------- + drivers/gpu/drm/i915/i915_drv.h | 16 ++- + drivers/gpu/drm/i915/intel_display.c | 54 ++++---- + drivers/gpu/drm/i915/intel_overlay.c | 13 +- + 4 files changed, 232 insertions(+), 93 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index a55630a80f83..3a8409a31266 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -604,15 +604,80 @@ static const char *purgeable_flag(int purgeable) + return purgeable ? " purgeable" : ""; + } + +-static void print_error_buffers(struct seq_file *m, ++static void i915_error_vprintf(struct drm_i915_error_state_buf *e, ++ const char *f, va_list args) ++{ ++ unsigned len; ++ ++ if (!e->err && WARN(e->bytes > (e->size - 1), "overflow")) { ++ e->err = -ENOSPC; ++ return; ++ } ++ ++ if (e->bytes == e->size - 1 || e->err) ++ return; ++ ++ /* Seek the first printf which is hits start position */ ++ if (e->pos < e->start) { ++ len = vsnprintf(NULL, 0, f, args); ++ if (e->pos + len <= e->start) { ++ e->pos += len; ++ return; ++ } ++ ++ /* First vsnprintf needs to fit in full for memmove*/ ++ if (len >= e->size) { ++ e->err = -EIO; ++ return; ++ } ++ } ++ ++ len = vsnprintf(e->buf + e->bytes, e->size - e->bytes, f, args); ++ if (len >= e->size - e->bytes) ++ len = e->size - e->bytes - 1; ++ ++ /* If this is first printf in this window, adjust it so that ++ * start position matches start of the buffer ++ */ ++ if (e->pos < e->start) { ++ const size_t off = e->start - e->pos; ++ ++ /* Should not happen but be paranoid */ ++ if (off > len || e->bytes) { ++ e->err = -EIO; ++ return; ++ } ++ ++ memmove(e->buf, e->buf + off, len - off); ++ e->bytes = len - off; ++ e->pos = e->start; ++ return; ++ } ++ ++ e->bytes += len; ++ e->pos += len; ++} ++ ++void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...) ++{ ++ va_list args; ++ ++ va_start(args, f); ++ i915_error_vprintf(e, f, args); ++ va_end(args); ++} ++ ++#define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__) ++ ++static void print_error_buffers(struct drm_i915_error_state_buf *m, + const char *name, + struct drm_i915_error_buffer *err, + int count) + { +- seq_printf(m, "%s [%d]:\n", name, count); ++ err_printf(m, "%s [%d]:\n", name, count); + + while (count--) { +- seq_printf(m, " %08x %8u %02x %02x %x %x%s%s%s%s%s%s%s", ++ err_printf(m, " %08x %8u %02x %02x %x %x%s%s%s%s%s%s%s", + err->gtt_offset, + err->size, + err->read_domains, +@@ -627,50 +692,50 @@ static void print_error_buffers(struct seq_file *m, + cache_level_str(err->cache_level)); + + if (err->name) +- seq_printf(m, " (name: %d)", err->name); ++ err_printf(m, " (name: %d)", err->name); + if (err->fence_reg != I915_FENCE_REG_NONE) +- seq_printf(m, " (fence: %d)", err->fence_reg); ++ err_printf(m, " (fence: %d)", err->fence_reg); + +- seq_printf(m, "\n"); ++ err_printf(m, "\n"); + err++; + } + } + +-static void i915_ring_error_state(struct seq_file *m, ++static void i915_ring_error_state(struct drm_i915_error_state_buf *m, + struct drm_device *dev, + struct drm_i915_error_state *error, + unsigned ring) + { + BUG_ON(ring >= I915_NUM_RINGS); /* shut up confused gcc */ +- seq_printf(m, "%s command stream:\n", ring_str(ring)); +- seq_printf(m, " HEAD: 0x%08x\n", error->head[ring]); +- seq_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); +- seq_printf(m, " CTL: 0x%08x\n", error->ctl[ring]); +- seq_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); +- seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); +- seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); +- seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); ++ err_printf(m, "%s command stream:\n", ring_str(ring)); ++ err_printf(m, " HEAD: 0x%08x\n", error->head[ring]); ++ err_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); ++ err_printf(m, " CTL: 0x%08x\n", error->ctl[ring]); ++ err_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); ++ err_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); ++ err_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); ++ err_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); + if (ring == RCS && INTEL_INFO(dev)->gen >= 4) +- seq_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr); ++ err_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr); + + if (INTEL_INFO(dev)->gen >= 4) +- seq_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); +- seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); +- seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); ++ err_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); ++ err_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); ++ err_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); + if (INTEL_INFO(dev)->gen >= 6) { +- seq_printf(m, " RC PSMI: 0x%08x\n", error->rc_psmi[ring]); +- seq_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); +- seq_printf(m, " SYNC_0: 0x%08x [last synced 0x%08x]\n", ++ err_printf(m, " RC PSMI: 0x%08x\n", error->rc_psmi[ring]); ++ err_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); ++ err_printf(m, " SYNC_0: 0x%08x [last synced 0x%08x]\n", + error->semaphore_mboxes[ring][0], + error->semaphore_seqno[ring][0]); +- seq_printf(m, " SYNC_1: 0x%08x [last synced 0x%08x]\n", ++ err_printf(m, " SYNC_1: 0x%08x [last synced 0x%08x]\n", + error->semaphore_mboxes[ring][1], + error->semaphore_seqno[ring][1]); + } +- seq_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); +- seq_printf(m, " waiting: %s\n", yesno(error->waiting[ring])); +- seq_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]); +- seq_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); ++ err_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); ++ err_printf(m, " waiting: %s\n", yesno(error->waiting[ring])); ++ err_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]); ++ err_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); + } + + struct i915_error_state_file_priv { +@@ -678,9 +743,11 @@ struct i915_error_state_file_priv { + struct drm_i915_error_state *error; + }; + +-static int i915_error_state(struct seq_file *m, void *unused) ++ ++static int i915_error_state(struct i915_error_state_file_priv *error_priv, ++ struct drm_i915_error_state_buf *m) ++ + { +- struct i915_error_state_file_priv *error_priv = m->private; + struct drm_device *dev = error_priv->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_error_state *error = error_priv->error; +@@ -688,34 +755,35 @@ static int i915_error_state(struct seq_file *m, void *unused) + int i, j, page, offset, elt; + + if (!error) { +- seq_printf(m, "no error state collected\n"); ++ err_printf(m, "no error state collected\n"); + return 0; + } + +- seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, ++ err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, + error->time.tv_usec); +- seq_printf(m, "Kernel: " UTS_RELEASE "\n"); +- seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); +- seq_printf(m, "EIR: 0x%08x\n", error->eir); +- seq_printf(m, "IER: 0x%08x\n", error->ier); +- seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); +- seq_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake); +- seq_printf(m, "DERRMR: 0x%08x\n", error->derrmr); +- seq_printf(m, "CCID: 0x%08x\n", error->ccid); ++ err_printf(m, "Kernel: " UTS_RELEASE "\n"); ++ err_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); ++ err_printf(m, "EIR: 0x%08x\n", error->eir); ++ err_printf(m, "IER: 0x%08x\n", error->ier); ++ err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); ++ err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake); ++ err_printf(m, "DERRMR: 0x%08x\n", error->derrmr); ++ err_printf(m, "CCID: 0x%08x\n", error->ccid); + + for (i = 0; i < dev_priv->num_fence_regs; i++) +- seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); ++ err_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); + + for (i = 0; i < ARRAY_SIZE(error->extra_instdone); i++) +- seq_printf(m, " INSTDONE_%d: 0x%08x\n", i, error->extra_instdone[i]); ++ err_printf(m, " INSTDONE_%d: 0x%08x\n", i, ++ error->extra_instdone[i]); + + if (INTEL_INFO(dev)->gen >= 6) { +- seq_printf(m, "ERROR: 0x%08x\n", error->error); +- seq_printf(m, "DONE_REG: 0x%08x\n", error->done_reg); ++ err_printf(m, "ERROR: 0x%08x\n", error->error); ++ err_printf(m, "DONE_REG: 0x%08x\n", error->done_reg); + } + + if (INTEL_INFO(dev)->gen == 7) +- seq_printf(m, "ERR_INT: 0x%08x\n", error->err_int); ++ err_printf(m, "ERR_INT: 0x%08x\n", error->err_int); + + for_each_ring(ring, dev_priv, i) + i915_ring_error_state(m, dev, error, i); +@@ -734,24 +802,25 @@ static int i915_error_state(struct seq_file *m, void *unused) + struct drm_i915_error_object *obj; + + if ((obj = error->ring[i].batchbuffer)) { +- seq_printf(m, "%s --- gtt_offset = 0x%08x\n", ++ err_printf(m, "%s --- gtt_offset = 0x%08x\n", + dev_priv->ring[i].name, + obj->gtt_offset); + offset = 0; + for (page = 0; page < obj->page_count; page++) { + for (elt = 0; elt < PAGE_SIZE/4; elt++) { +- seq_printf(m, "%08x : %08x\n", offset, obj->pages[page][elt]); ++ err_printf(m, "%08x : %08x\n", offset, ++ obj->pages[page][elt]); + offset += 4; + } + } + } + + if (error->ring[i].num_requests) { +- seq_printf(m, "%s --- %d requests\n", ++ err_printf(m, "%s --- %d requests\n", + dev_priv->ring[i].name, + error->ring[i].num_requests); + for (j = 0; j < error->ring[i].num_requests; j++) { +- seq_printf(m, " seqno 0x%08x, emitted %ld, tail 0x%08x\n", ++ err_printf(m, " seqno 0x%08x, emitted %ld, tail 0x%08x\n", + error->ring[i].requests[j].seqno, + error->ring[i].requests[j].jiffies, + error->ring[i].requests[j].tail); +@@ -759,13 +828,13 @@ static int i915_error_state(struct seq_file *m, void *unused) + } + + if ((obj = error->ring[i].ringbuffer)) { +- seq_printf(m, "%s --- ringbuffer = 0x%08x\n", ++ err_printf(m, "%s --- ringbuffer = 0x%08x\n", + dev_priv->ring[i].name, + obj->gtt_offset); + offset = 0; + for (page = 0; page < obj->page_count; page++) { + for (elt = 0; elt < PAGE_SIZE/4; elt++) { +- seq_printf(m, "%08x : %08x\n", ++ err_printf(m, "%08x : %08x\n", + offset, + obj->pages[page][elt]); + offset += 4; +@@ -775,12 +844,12 @@ static int i915_error_state(struct seq_file *m, void *unused) + + obj = error->ring[i].ctx; + if (obj) { +- seq_printf(m, "%s --- HW Context = 0x%08x\n", ++ err_printf(m, "%s --- HW Context = 0x%08x\n", + dev_priv->ring[i].name, + obj->gtt_offset); + offset = 0; + for (elt = 0; elt < PAGE_SIZE/16; elt += 4) { +- seq_printf(m, "[%04x] %08x %08x %08x %08x\n", ++ err_printf(m, "[%04x] %08x %08x %08x %08x\n", + offset, + obj->pages[0][elt], + obj->pages[0][elt+1], +@@ -806,8 +875,7 @@ i915_error_state_write(struct file *filp, + size_t cnt, + loff_t *ppos) + { +- struct seq_file *m = filp->private_data; +- struct i915_error_state_file_priv *error_priv = m->private; ++ struct i915_error_state_file_priv *error_priv = filp->private_data; + struct drm_device *dev = error_priv->dev; + int ret; + +@@ -842,25 +910,81 @@ static int i915_error_state_open(struct inode *inode, struct file *file) + kref_get(&error_priv->error->ref); + spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); + +- return single_open(file, i915_error_state, error_priv); ++ file->private_data = error_priv; ++ ++ return 0; + } + + static int i915_error_state_release(struct inode *inode, struct file *file) + { +- struct seq_file *m = file->private_data; +- struct i915_error_state_file_priv *error_priv = m->private; ++ struct i915_error_state_file_priv *error_priv = file->private_data; + + if (error_priv->error) + kref_put(&error_priv->error->ref, i915_error_state_free); + kfree(error_priv); + +- return single_release(inode, file); ++ return 0; ++} ++ ++static ssize_t i915_error_state_read(struct file *file, char __user *userbuf, ++ size_t count, loff_t *pos) ++{ ++ struct i915_error_state_file_priv *error_priv = file->private_data; ++ struct drm_i915_error_state_buf error_str; ++ loff_t tmp_pos = 0; ++ ssize_t ret_count = 0; ++ int ret = 0; ++ ++ memset(&error_str, 0, sizeof(error_str)); ++ ++ /* We need to have enough room to store any i915_error_state printf ++ * so that we can move it to start position. ++ */ ++ error_str.size = count + 1 > PAGE_SIZE ? count + 1 : PAGE_SIZE; ++ error_str.buf = kmalloc(error_str.size, ++ GFP_TEMPORARY | __GFP_NORETRY | __GFP_NOWARN); ++ ++ if (error_str.buf == NULL) { ++ error_str.size = PAGE_SIZE; ++ error_str.buf = kmalloc(error_str.size, GFP_TEMPORARY); ++ } ++ ++ if (error_str.buf == NULL) { ++ error_str.size = 128; ++ error_str.buf = kmalloc(error_str.size, GFP_TEMPORARY); ++ } ++ ++ if (error_str.buf == NULL) ++ return -ENOMEM; ++ ++ error_str.start = *pos; ++ ++ ret = i915_error_state(error_priv, &error_str); ++ if (ret) ++ goto out; ++ ++ if (error_str.bytes == 0 && error_str.err) { ++ ret = error_str.err; ++ goto out; ++ } ++ ++ ret_count = simple_read_from_buffer(userbuf, count, &tmp_pos, ++ error_str.buf, ++ error_str.bytes); ++ ++ if (ret_count < 0) ++ ret = ret_count; ++ else ++ *pos = error_str.start + ret_count; ++out: ++ kfree(error_str.buf); ++ return ret ?: ret_count; + } + + static const struct file_operations i915_error_state_fops = { + .owner = THIS_MODULE, + .open = i915_error_state_open, +- .read = seq_read, ++ .read = i915_error_state_read, + .write = i915_error_state_write, + .llseek = default_llseek, + .release = i915_error_state_release, +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 4ab1e4266da0..e8c1ffbc9db3 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -827,6 +827,15 @@ struct i915_gem_mm { + u32 object_count; + }; + ++struct drm_i915_error_state_buf { ++ unsigned bytes; ++ unsigned size; ++ int err; ++ u8 *buf; ++ loff_t start; ++ loff_t pos; ++}; ++ + struct i915_gpu_error { + /* For hangcheck timer */ + #define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */ +@@ -1822,6 +1831,8 @@ void i915_gem_dump_object(struct drm_i915_gem_object *obj, int len, + /* i915_debugfs.c */ + int i915_debugfs_init(struct drm_minor *minor); + void i915_debugfs_cleanup(struct drm_minor *minor); ++__printf(2, 3) ++void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...); + + /* i915_suspend.c */ + extern int i915_save_state(struct drm_device *dev); +@@ -1903,10 +1914,11 @@ int i915_reg_read_ioctl(struct drm_device *dev, void *data, + /* overlay */ + #ifdef CONFIG_DEBUG_FS + extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); +-extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); ++extern void intel_overlay_print_error_state(struct drm_i915_error_state_buf *e, ++ struct intel_overlay_error_state *error); + + extern struct intel_display_error_state *intel_display_capture_error_state(struct drm_device *dev); +-extern void intel_display_print_error_state(struct seq_file *m, ++extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e, + struct drm_device *dev, + struct intel_display_error_state *error); + #endif +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index e62a9770cf71..121fc5d31c7d 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -9905,48 +9905,50 @@ intel_display_capture_error_state(struct drm_device *dev) + return error; + } + ++#define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__) ++ + void +-intel_display_print_error_state(struct seq_file *m, ++intel_display_print_error_state(struct drm_i915_error_state_buf *m, + struct drm_device *dev, + struct intel_display_error_state *error) + { + int i; + +- seq_printf(m, "Num Pipes: %d\n", INTEL_INFO(dev)->num_pipes); ++ err_printf(m, "Num Pipes: %d\n", INTEL_INFO(dev)->num_pipes); + if (HAS_POWER_WELL(dev)) +- seq_printf(m, "PWR_WELL_CTL2: %08x\n", ++ err_printf(m, "PWR_WELL_CTL2: %08x\n", + error->power_well_driver); + for_each_pipe(i) { +- seq_printf(m, "Pipe [%d]:\n", i); +- seq_printf(m, " CPU transcoder: %c\n", ++ err_printf(m, "Pipe [%d]:\n", i); ++ err_printf(m, " CPU transcoder: %c\n", + transcoder_name(error->pipe[i].cpu_transcoder)); +- seq_printf(m, " CONF: %08x\n", error->pipe[i].conf); +- seq_printf(m, " SRC: %08x\n", error->pipe[i].source); +- seq_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal); +- seq_printf(m, " HBLANK: %08x\n", error->pipe[i].hblank); +- seq_printf(m, " HSYNC: %08x\n", error->pipe[i].hsync); +- seq_printf(m, " VTOTAL: %08x\n", error->pipe[i].vtotal); +- seq_printf(m, " VBLANK: %08x\n", error->pipe[i].vblank); +- seq_printf(m, " VSYNC: %08x\n", error->pipe[i].vsync); +- +- seq_printf(m, "Plane [%d]:\n", i); +- seq_printf(m, " CNTR: %08x\n", error->plane[i].control); +- seq_printf(m, " STRIDE: %08x\n", error->plane[i].stride); ++ err_printf(m, " CONF: %08x\n", error->pipe[i].conf); ++ err_printf(m, " SRC: %08x\n", error->pipe[i].source); ++ err_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal); ++ err_printf(m, " HBLANK: %08x\n", error->pipe[i].hblank); ++ err_printf(m, " HSYNC: %08x\n", error->pipe[i].hsync); ++ err_printf(m, " VTOTAL: %08x\n", error->pipe[i].vtotal); ++ err_printf(m, " VBLANK: %08x\n", error->pipe[i].vblank); ++ err_printf(m, " VSYNC: %08x\n", error->pipe[i].vsync); ++ ++ err_printf(m, "Plane [%d]:\n", i); ++ err_printf(m, " CNTR: %08x\n", error->plane[i].control); ++ err_printf(m, " STRIDE: %08x\n", error->plane[i].stride); + if (INTEL_INFO(dev)->gen <= 3) { +- seq_printf(m, " SIZE: %08x\n", error->plane[i].size); +- seq_printf(m, " POS: %08x\n", error->plane[i].pos); ++ err_printf(m, " SIZE: %08x\n", error->plane[i].size); ++ err_printf(m, " POS: %08x\n", error->plane[i].pos); + } + if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) +- seq_printf(m, " ADDR: %08x\n", error->plane[i].addr); ++ err_printf(m, " ADDR: %08x\n", error->plane[i].addr); + if (INTEL_INFO(dev)->gen >= 4) { +- seq_printf(m, " SURF: %08x\n", error->plane[i].surface); +- seq_printf(m, " TILEOFF: %08x\n", error->plane[i].tile_offset); ++ err_printf(m, " SURF: %08x\n", error->plane[i].surface); ++ err_printf(m, " TILEOFF: %08x\n", error->plane[i].tile_offset); + } + +- seq_printf(m, "Cursor [%d]:\n", i); +- seq_printf(m, " CNTR: %08x\n", error->cursor[i].control); +- seq_printf(m, " POS: %08x\n", error->cursor[i].position); +- seq_printf(m, " BASE: %08x\n", error->cursor[i].base); ++ err_printf(m, "Cursor [%d]:\n", i); ++ err_printf(m, " CNTR: %08x\n", error->cursor[i].control); ++ err_printf(m, " POS: %08x\n", error->cursor[i].position); ++ err_printf(m, " BASE: %08x\n", error->cursor[i].base); + } + } + #endif +diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c +index 67a2501d519d..836794b68fc6 100644 +--- a/drivers/gpu/drm/i915/intel_overlay.c ++++ b/drivers/gpu/drm/i915/intel_overlay.c +@@ -1485,14 +1485,15 @@ err: + } + + void +-intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error) ++intel_overlay_print_error_state(struct drm_i915_error_state_buf *m, ++ struct intel_overlay_error_state *error) + { +- seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n", +- error->dovsta, error->isr); +- seq_printf(m, " Register file at 0x%08lx:\n", +- error->base); ++ i915_error_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n", ++ error->dovsta, error->isr); ++ i915_error_printf(m, " Register file at 0x%08lx:\n", ++ error->base); + +-#define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x) ++#define P(x) i915_error_printf(m, " " #x ": 0x%08x\n", error->regs.x) + P(OBUF_0Y); + P(OBUF_1Y); + P(OBUF_0U); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0183-drm-i915-group-sideband-register-accessors-to-a-new-.patch b/patches.baytrail/0183-drm-i915-group-sideband-register-accessors-to-a-new-.patch new file mode 100644 index 000000000000..ee647e663fdf --- /dev/null +++ b/patches.baytrail/0183-drm-i915-group-sideband-register-accessors-to-a-new-.patch @@ -0,0 +1,453 @@ +From 4ac209b0e285a218e0058390f2e31bae8bc04831 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Wed, 22 May 2013 15:36:16 +0300 +Subject: drm/i915: group sideband register accessors to a new file + +Group both the HSW/LPT SBI interface and VLV IOSF sideband register +accessor functions into a new file. No functional changes. + +v2: also move intel_sbi_{read,write} (Daniel) + +Signed-off-by: Jani Nikula +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 59de08136f0c8d91bfd607d03cf722c5b6c60d1b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/Makefile | 1 + + drivers/gpu/drm/i915/i915_drv.h | 8 ++ + drivers/gpu/drm/i915/intel_display.c | 98 ------------------ + drivers/gpu/drm/i915/intel_drv.h | 4 - + drivers/gpu/drm/i915/intel_pm.c | 60 ----------- + drivers/gpu/drm/i915/intel_sideband.c | 183 ++++++++++++++++++++++++++++++++++ + 6 files changed, 192 insertions(+), 162 deletions(-) + create mode 100644 drivers/gpu/drm/i915/intel_sideband.c + +diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile +index 91f3ac6cef35..40034ecefd3b 100644 +--- a/drivers/gpu/drm/i915/Makefile ++++ b/drivers/gpu/drm/i915/Makefile +@@ -36,6 +36,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ + intel_overlay.o \ + intel_sprite.o \ + intel_opregion.o \ ++ intel_sideband.o \ + dvo_ch7xxx.o \ + dvo_ch7017.o \ + dvo_ivch.o \ +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index e8c1ffbc9db3..0243cb0b2dee 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1933,9 +1933,17 @@ int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); + + int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val); + int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val); ++ ++/* intel_sideband.c */ + int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val); + int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val); + int valleyview_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val); ++u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg); ++void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val); ++u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg, ++ enum intel_sbi_destination destination); ++void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value, ++ enum intel_sbi_destination destination); + + int vlv_gpu_freq(int ddr_freq, int val); + int vlv_freq_opcode(int ddr_freq, int val); +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 121fc5d31c7d..613629ee81d9 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -381,43 +381,6 @@ static const intel_limit_t intel_limits_vlv_dp = { + .find_pll = intel_vlv_find_best_pll, + }; + +-u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg) +-{ +- WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); +- +- if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { +- DRM_ERROR("DPIO idle wait timed out\n"); +- return 0; +- } +- +- I915_WRITE(DPIO_REG, reg); +- I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_READ | DPIO_PORTID | +- DPIO_BYTE); +- if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { +- DRM_ERROR("DPIO read wait timed out\n"); +- return 0; +- } +- +- return I915_READ(DPIO_DATA); +-} +- +-void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val) +-{ +- WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); +- +- if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { +- DRM_ERROR("DPIO idle wait timed out\n"); +- return; +- } +- +- I915_WRITE(DPIO_DATA, val); +- I915_WRITE(DPIO_REG, reg); +- I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_WRITE | DPIO_PORTID | +- DPIO_BYTE); +- if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) +- DRM_ERROR("DPIO write wait timed out\n"); +-} +- + static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, + int refclk) + { +@@ -1404,67 +1367,6 @@ static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) + POSTING_READ(reg); + } + +-/* SBI access */ +-static void +-intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value, +- enum intel_sbi_destination destination) +-{ +- u32 tmp; +- +- WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); +- +- if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, +- 100)) { +- DRM_ERROR("timeout waiting for SBI to become ready\n"); +- return; +- } +- +- I915_WRITE(SBI_ADDR, (reg << 16)); +- I915_WRITE(SBI_DATA, value); +- +- if (destination == SBI_ICLK) +- tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR; +- else +- tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR; +- I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp); +- +- if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, +- 100)) { +- DRM_ERROR("timeout waiting for SBI to complete write transaction\n"); +- return; +- } +-} +- +-static u32 +-intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg, +- enum intel_sbi_destination destination) +-{ +- u32 value = 0; +- WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); +- +- if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, +- 100)) { +- DRM_ERROR("timeout waiting for SBI to become ready\n"); +- return 0; +- } +- +- I915_WRITE(SBI_ADDR, (reg << 16)); +- +- if (destination == SBI_ICLK) +- value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD; +- else +- value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD; +- I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY); +- +- if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, +- 100)) { +- DRM_ERROR("timeout waiting for SBI to complete read transaction\n"); +- return 0; +- } +- +- return I915_READ(SBI_DATA); +-} +- + void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port) + { + u32 port_mask; +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index a5ba33bb6c0d..928368a93f74 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -743,10 +743,6 @@ extern int intel_sprite_set_colorkey(struct drm_device *dev, void *data, + extern int intel_sprite_get_colorkey(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +-extern u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg); +-extern void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, +- u32 val); +- + /* Power-related functions, located in intel_pm.c */ + extern void intel_init_pm(struct drm_device *dev); + /* FBC */ +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index f016998ca83c..1b884359662a 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4991,66 +4991,6 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val) + return 0; + } + +-static int vlv_punit_rw(struct drm_i915_private *dev_priv, u32 port, u8 opcode, +- u8 addr, u32 *val) +-{ +- u32 cmd, devfn, be, bar; +- +- bar = 0; +- be = 0xf; +- devfn = PCI_DEVFN(2, 0); +- +- cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) | +- (port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) | +- (bar << IOSF_BAR_SHIFT); +- +- WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); +- +- if (I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) { +- DRM_DEBUG_DRIVER("warning: pcode (%s) mailbox access failed\n", +- opcode == PUNIT_OPCODE_REG_READ ? +- "read" : "write"); +- return -EAGAIN; +- } +- +- I915_WRITE(VLV_IOSF_ADDR, addr); +- if (opcode == PUNIT_OPCODE_REG_WRITE) +- I915_WRITE(VLV_IOSF_DATA, *val); +- I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd); +- +- if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, +- 5)) { +- DRM_ERROR("timeout waiting for pcode %s (%d) to finish\n", +- opcode == PUNIT_OPCODE_REG_READ ? "read" : "write", +- addr); +- return -ETIMEDOUT; +- } +- +- if (opcode == PUNIT_OPCODE_REG_READ) +- *val = I915_READ(VLV_IOSF_DATA); +- I915_WRITE(VLV_IOSF_DATA, 0); +- +- return 0; +-} +- +-int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) +-{ +- return vlv_punit_rw(dev_priv, IOSF_PORT_PUNIT, PUNIT_OPCODE_REG_READ, +- addr, val); +-} +- +-int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) +-{ +- return vlv_punit_rw(dev_priv, IOSF_PORT_PUNIT, PUNIT_OPCODE_REG_WRITE, +- addr, &val); +-} +- +-int valleyview_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) +-{ +- return vlv_punit_rw(dev_priv, IOSF_PORT_NC, PUNIT_OPCODE_REG_READ, +- addr, val); +-} +- + int vlv_gpu_freq(int ddr_freq, int val) + { + int mult, base; +diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c +new file mode 100644 +index 000000000000..81af8857857d +--- /dev/null ++++ b/drivers/gpu/drm/i915/intel_sideband.c +@@ -0,0 +1,183 @@ ++/* ++ * Copyright © 2013 Intel Corporation ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ * ++ */ ++ ++#include "i915_drv.h" ++#include "intel_drv.h" ++ ++/* IOSF sideband */ ++static int vlv_punit_rw(struct drm_i915_private *dev_priv, u32 port, u8 opcode, ++ u8 addr, u32 *val) ++{ ++ u32 cmd, devfn, be, bar; ++ ++ bar = 0; ++ be = 0xf; ++ devfn = PCI_DEVFN(2, 0); ++ ++ cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) | ++ (port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) | ++ (bar << IOSF_BAR_SHIFT); ++ ++ WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); ++ ++ if (I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) { ++ DRM_DEBUG_DRIVER("warning: pcode (%s) mailbox access failed\n", ++ opcode == PUNIT_OPCODE_REG_READ ? ++ "read" : "write"); ++ return -EAGAIN; ++ } ++ ++ I915_WRITE(VLV_IOSF_ADDR, addr); ++ if (opcode == PUNIT_OPCODE_REG_WRITE) ++ I915_WRITE(VLV_IOSF_DATA, *val); ++ I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd); ++ ++ if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, ++ 5)) { ++ DRM_ERROR("timeout waiting for pcode %s (%d) to finish\n", ++ opcode == PUNIT_OPCODE_REG_READ ? "read" : "write", ++ addr); ++ return -ETIMEDOUT; ++ } ++ ++ if (opcode == PUNIT_OPCODE_REG_READ) ++ *val = I915_READ(VLV_IOSF_DATA); ++ I915_WRITE(VLV_IOSF_DATA, 0); ++ ++ return 0; ++} ++ ++int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) ++{ ++ return vlv_punit_rw(dev_priv, IOSF_PORT_PUNIT, PUNIT_OPCODE_REG_READ, ++ addr, val); ++} ++ ++int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) ++{ ++ return vlv_punit_rw(dev_priv, IOSF_PORT_PUNIT, PUNIT_OPCODE_REG_WRITE, ++ addr, &val); ++} ++ ++int valleyview_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) ++{ ++ return vlv_punit_rw(dev_priv, IOSF_PORT_NC, PUNIT_OPCODE_REG_READ, ++ addr, val); ++} ++ ++u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg) ++{ ++ WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); ++ ++ if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { ++ DRM_ERROR("DPIO idle wait timed out\n"); ++ return 0; ++ } ++ ++ I915_WRITE(DPIO_REG, reg); ++ I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_READ | DPIO_PORTID | ++ DPIO_BYTE); ++ if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { ++ DRM_ERROR("DPIO read wait timed out\n"); ++ return 0; ++ } ++ ++ return I915_READ(DPIO_DATA); ++} ++ ++void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val) ++{ ++ WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); ++ ++ if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { ++ DRM_ERROR("DPIO idle wait timed out\n"); ++ return; ++ } ++ ++ I915_WRITE(DPIO_DATA, val); ++ I915_WRITE(DPIO_REG, reg); ++ I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_WRITE | DPIO_PORTID | ++ DPIO_BYTE); ++ if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) ++ DRM_ERROR("DPIO write wait timed out\n"); ++} ++ ++/* SBI access */ ++u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg, ++ enum intel_sbi_destination destination) ++{ ++ u32 value = 0; ++ WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); ++ ++ if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, ++ 100)) { ++ DRM_ERROR("timeout waiting for SBI to become ready\n"); ++ return 0; ++ } ++ ++ I915_WRITE(SBI_ADDR, (reg << 16)); ++ ++ if (destination == SBI_ICLK) ++ value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD; ++ else ++ value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD; ++ I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY); ++ ++ if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, ++ 100)) { ++ DRM_ERROR("timeout waiting for SBI to complete read transaction\n"); ++ return 0; ++ } ++ ++ return I915_READ(SBI_DATA); ++} ++ ++void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value, ++ enum intel_sbi_destination destination) ++{ ++ u32 tmp; ++ ++ WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); ++ ++ if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, ++ 100)) { ++ DRM_ERROR("timeout waiting for SBI to become ready\n"); ++ return; ++ } ++ ++ I915_WRITE(SBI_ADDR, (reg << 16)); ++ I915_WRITE(SBI_DATA, value); ++ ++ if (destination == SBI_ICLK) ++ tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR; ++ else ++ tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR; ++ I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp); ++ ++ if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, ++ 100)) { ++ DRM_ERROR("timeout waiting for SBI to complete write transaction\n"); ++ return; ++ } ++} +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0184-drm-i915-refactor-VLV-IOSF-sideband-accessors-to-use.patch b/patches.baytrail/0184-drm-i915-refactor-VLV-IOSF-sideband-accessors-to-use.patch new file mode 100644 index 000000000000..62f28978374e --- /dev/null +++ b/patches.baytrail/0184-drm-i915-refactor-VLV-IOSF-sideband-accessors-to-use.patch @@ -0,0 +1,304 @@ +From 957854930e3f56e214953ec6f22ecea76d782a3c Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Wed, 22 May 2013 15:36:17 +0300 +Subject: drm/i915: refactor VLV IOSF sideband accessors to use one helper + +Both the intel_dpio_{read,write} and valleyview_{punit,nc}_{read,write} +use the IOSF sideband interface. They access the same registers and do +mostly the same stuff, but no shared code. There are even duplicate +register defines for the same registers. Both have locking, but the +former use dpio_lock and the latter rps.hw_lock. It's racy. + +This patch refactors the sideband access to a single function that +expects dpio_lock to be held. The dpio_lock is only used for sideband +stuff, so it's a better match than rps.hw_lock for the purpose. The rps +stuff still needs rps.hw_lock, since it's used to protect more than just +the register access, so rps code will need to hold both locks. + +Based on the work by Shobhit Kumar and Yogesh +Mohan Marimuthu . + +Signed-off-by: Jani Nikula +Acked-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 5a09ae9fd509d7dded34e0d599e1afa5142c6987) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 93 ++++++++++++++----------------- + drivers/gpu/drm/i915/intel_sideband.c | 102 +++++++++++++++++----------------- + 2 files changed, 93 insertions(+), 102 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 669da48ecca8..e29e9b17690c 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -342,27 +342,54 @@ + #define DEBUG_RESET_DISPLAY (1<<9) + + /* +- * DPIO - a special bus for various display related registers to hide behind: +- * 0x800c: m1, m2, n, p1, p2, k dividers +- * 0x8014: REF and SFR select +- * 0x8014: N divider, VCO select +- * 0x801c/3c: core clock bits +- * 0x8048/68: low pass filter coefficients +- * 0x8100: fast clock controls ++ * IOSF sideband ++ */ ++#define VLV_IOSF_DOORBELL_REQ (VLV_DISPLAY_BASE + 0x2100) ++#define IOSF_DEVFN_SHIFT 24 ++#define IOSF_OPCODE_SHIFT 16 ++#define IOSF_PORT_SHIFT 8 ++#define IOSF_BYTE_ENABLES_SHIFT 4 ++#define IOSF_BAR_SHIFT 1 ++#define IOSF_SB_BUSY (1<<0) ++#define IOSF_PORT_PUNIT 0x4 ++#define IOSF_PORT_NC 0x11 ++#define IOSF_PORT_DPIO 0x12 ++#define VLV_IOSF_DATA (VLV_DISPLAY_BASE + 0x2104) ++#define VLV_IOSF_ADDR (VLV_DISPLAY_BASE + 0x2108) ++ ++#define PUNIT_OPCODE_REG_READ 6 ++#define PUNIT_OPCODE_REG_WRITE 7 ++ ++#define PUNIT_REG_GPU_LFM 0xd3 ++#define PUNIT_REG_GPU_FREQ_REQ 0xd4 ++#define PUNIT_REG_GPU_FREQ_STS 0xd8 ++#define PUNIT_REG_MEDIA_TURBO_FREQ_REQ 0xdc ++ ++#define PUNIT_FUSE_BUS2 0xf6 /* bits 47:40 */ ++#define PUNIT_FUSE_BUS1 0xf5 /* bits 55:48 */ ++ ++#define IOSF_NC_FB_GFX_FREQ_FUSE 0x1c ++#define FB_GFX_MAX_FREQ_FUSE_SHIFT 3 ++#define FB_GFX_MAX_FREQ_FUSE_MASK 0x000007f8 ++#define FB_GFX_FGUARANTEED_FREQ_FUSE_SHIFT 11 ++#define FB_GFX_FGUARANTEED_FREQ_FUSE_MASK 0x0007f800 ++#define IOSF_NC_FB_GFX_FMAX_FUSE_HI 0x34 ++#define FB_FMAX_VMIN_FREQ_HI_MASK 0x00000007 ++#define IOSF_NC_FB_GFX_FMAX_FUSE_LO 0x30 ++#define FB_FMAX_VMIN_FREQ_LO_SHIFT 27 ++#define FB_FMAX_VMIN_FREQ_LO_MASK 0xf8000000 ++ ++/* ++ * DPIO - a special bus for various display related registers to hide behind + * + * DPIO is VLV only. + * + * Note: digital port B is DDI0, digital pot C is DDI1 + */ +-#define DPIO_PKT (VLV_DISPLAY_BASE + 0x2100) +-#define DPIO_RID (0<<24) +-#define DPIO_OP_WRITE (1<<16) +-#define DPIO_OP_READ (0<<16) +-#define DPIO_PORTID (0x12<<8) +-#define DPIO_BYTE (0xf<<4) +-#define DPIO_BUSY (1<<0) /* status only */ +-#define DPIO_DATA (VLV_DISPLAY_BASE + 0x2104) +-#define DPIO_REG (VLV_DISPLAY_BASE + 0x2108) ++#define DPIO_DEVFN 0 ++#define DPIO_OPCODE_REG_WRITE 1 ++#define DPIO_OPCODE_REG_READ 0 ++ + #define DPIO_CTL (VLV_DISPLAY_BASE + 0x2110) + #define DPIO_MODSEL1 (1<<3) /* if ref clk b == 27 */ + #define DPIO_MODSEL0 (1<<2) /* if ref clk a == 27 */ +@@ -4547,40 +4574,6 @@ + #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 + #define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 + +-#define VLV_IOSF_DOORBELL_REQ 0x182100 +-#define IOSF_DEVFN_SHIFT 24 +-#define IOSF_OPCODE_SHIFT 16 +-#define IOSF_PORT_SHIFT 8 +-#define IOSF_BYTE_ENABLES_SHIFT 4 +-#define IOSF_BAR_SHIFT 1 +-#define IOSF_SB_BUSY (1<<0) +-#define IOSF_PORT_PUNIT 0x4 +-#define IOSF_PORT_NC 0x11 +-#define VLV_IOSF_DATA 0x182104 +-#define VLV_IOSF_ADDR 0x182108 +- +-#define PUNIT_OPCODE_REG_READ 6 +-#define PUNIT_OPCODE_REG_WRITE 7 +- +-#define PUNIT_REG_GPU_LFM 0xd3 +-#define PUNIT_REG_GPU_FREQ_REQ 0xd4 +-#define PUNIT_REG_GPU_FREQ_STS 0xd8 +-#define PUNIT_REG_MEDIA_TURBO_FREQ_REQ 0xdc +- +-#define PUNIT_FUSE_BUS2 0xf6 /* bits 47:40 */ +-#define PUNIT_FUSE_BUS1 0xf5 /* bits 55:48 */ +- +-#define IOSF_NC_FB_GFX_FREQ_FUSE 0x1c +-#define FB_GFX_MAX_FREQ_FUSE_SHIFT 3 +-#define FB_GFX_MAX_FREQ_FUSE_MASK 0x000007f8 +-#define FB_GFX_FGUARANTEED_FREQ_FUSE_SHIFT 11 +-#define FB_GFX_FGUARANTEED_FREQ_FUSE_MASK 0x0007f800 +-#define IOSF_NC_FB_GFX_FMAX_FUSE_HI 0x34 +-#define FB_FMAX_VMIN_FREQ_HI_MASK 0x00000007 +-#define IOSF_NC_FB_GFX_FMAX_FUSE_LO 0x30 +-#define FB_FMAX_VMIN_FREQ_LO_SHIFT 27 +-#define FB_FMAX_VMIN_FREQ_LO_MASK 0xf8000000 +- + #define GEN6_GT_CORE_STATUS 0x138060 + #define GEN6_CORE_CPD_STATE_MASK (7<<4) + #define GEN6_RCn_MASK 7 +diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c +index 81af8857857d..a7c4b61e9c30 100644 +--- a/drivers/gpu/drm/i915/intel_sideband.c ++++ b/drivers/gpu/drm/i915/intel_sideband.c +@@ -26,42 +26,37 @@ + #include "intel_drv.h" + + /* IOSF sideband */ +-static int vlv_punit_rw(struct drm_i915_private *dev_priv, u32 port, u8 opcode, +- u8 addr, u32 *val) ++static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn, ++ u32 port, u32 opcode, u32 addr, u32 *val) + { +- u32 cmd, devfn, be, bar; +- +- bar = 0; +- be = 0xf; +- devfn = PCI_DEVFN(2, 0); ++ u32 cmd, be = 0xf, bar = 0; ++ bool is_read = (opcode == PUNIT_OPCODE_REG_READ || ++ opcode == DPIO_OPCODE_REG_READ); + + cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) | + (port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) | + (bar << IOSF_BAR_SHIFT); + +- WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); ++ WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); + +- if (I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) { +- DRM_DEBUG_DRIVER("warning: pcode (%s) mailbox access failed\n", +- opcode == PUNIT_OPCODE_REG_READ ? +- "read" : "write"); ++ if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) { ++ DRM_DEBUG_DRIVER("IOSF sideband idle wait (%s) timed out\n", ++ is_read ? "read" : "write"); + return -EAGAIN; + } + + I915_WRITE(VLV_IOSF_ADDR, addr); +- if (opcode == PUNIT_OPCODE_REG_WRITE) ++ if (!is_read) + I915_WRITE(VLV_IOSF_DATA, *val); + I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd); + +- if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, +- 5)) { +- DRM_ERROR("timeout waiting for pcode %s (%d) to finish\n", +- opcode == PUNIT_OPCODE_REG_READ ? "read" : "write", +- addr); ++ if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) { ++ DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n", ++ is_read ? "read" : "write"); + return -ETIMEDOUT; + } + +- if (opcode == PUNIT_OPCODE_REG_READ) ++ if (is_read) + *val = I915_READ(VLV_IOSF_DATA); + I915_WRITE(VLV_IOSF_DATA, 0); + +@@ -70,57 +65,60 @@ static int vlv_punit_rw(struct drm_i915_private *dev_priv, u32 port, u8 opcode, + + int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) + { +- return vlv_punit_rw(dev_priv, IOSF_PORT_PUNIT, PUNIT_OPCODE_REG_READ, +- addr, val); ++ int ret; ++ ++ WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); ++ ++ mutex_lock(&dev_priv->dpio_lock); ++ ret = vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT, ++ PUNIT_OPCODE_REG_READ, addr, val); ++ mutex_unlock(&dev_priv->dpio_lock); ++ ++ return ret; + } + + int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) + { +- return vlv_punit_rw(dev_priv, IOSF_PORT_PUNIT, PUNIT_OPCODE_REG_WRITE, +- addr, &val); ++ int ret; ++ ++ WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); ++ ++ mutex_lock(&dev_priv->dpio_lock); ++ ret = vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT, ++ PUNIT_OPCODE_REG_WRITE, addr, &val); ++ mutex_unlock(&dev_priv->dpio_lock); ++ ++ return ret; + } + + int valleyview_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) + { +- return vlv_punit_rw(dev_priv, IOSF_PORT_NC, PUNIT_OPCODE_REG_READ, +- addr, val); ++ int ret; ++ ++ WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); ++ ++ mutex_lock(&dev_priv->dpio_lock); ++ ret = vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_NC, ++ PUNIT_OPCODE_REG_READ, addr, val); ++ mutex_unlock(&dev_priv->dpio_lock); ++ ++ return ret; + } + + u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg) + { +- WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); ++ u32 val = 0; + +- if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { +- DRM_ERROR("DPIO idle wait timed out\n"); +- return 0; +- } ++ vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_DPIO, ++ DPIO_OPCODE_REG_READ, reg, &val); + +- I915_WRITE(DPIO_REG, reg); +- I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_READ | DPIO_PORTID | +- DPIO_BYTE); +- if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { +- DRM_ERROR("DPIO read wait timed out\n"); +- return 0; +- } +- +- return I915_READ(DPIO_DATA); ++ return val; + } + + void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val) + { +- WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); +- +- if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { +- DRM_ERROR("DPIO idle wait timed out\n"); +- return; +- } +- +- I915_WRITE(DPIO_DATA, val); +- I915_WRITE(DPIO_REG, reg); +- I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_WRITE | DPIO_PORTID | +- DPIO_BYTE); +- if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) +- DRM_ERROR("DPIO write wait timed out\n"); ++ vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_DPIO, ++ DPIO_OPCODE_REG_WRITE, reg, &val); + } + + /* SBI access */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0185-drm-i915-drop-redundant-warnings-on-not-holding-dpio.patch b/patches.baytrail/0185-drm-i915-drop-redundant-warnings-on-not-holding-dpio.patch new file mode 100644 index 000000000000..b10934c7acdb --- /dev/null +++ b/patches.baytrail/0185-drm-i915-drop-redundant-warnings-on-not-holding-dpio.patch @@ -0,0 +1,73 @@ +From 5eccf5a47761f220e88e8fcc3672f6b80a911272 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Wed, 22 May 2013 15:36:18 +0300 +Subject: drm/i915: drop redundant warnings on not holding dpio_lock + +The lower level sideband read/write functions already do this. + +Signed-off-by: Jani Nikula +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit a1ca802d98acbc5fd87cc399b6aaf38f54be33e1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 6 ------ + drivers/gpu/drm/i915/intel_hdmi.c | 4 ---- + 2 files changed, 10 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 093138c2f080..02e98fac18e5 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1462,8 +1462,6 @@ static void intel_pre_enable_dp(struct intel_encoder *encoder) + int pipe = intel_crtc->pipe; + u32 val; + +- WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); +- + val = intel_dpio_read(dev_priv, DPIO_DATA_LANE_A(port)); + val = 0; + if (pipe) +@@ -1490,8 +1488,6 @@ static void intel_dp_pre_pll_enable(struct intel_encoder *encoder) + if (!IS_VALLEYVIEW(dev)) + return; + +- WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); +- + /* Program Tx lane resets to default */ + intel_dpio_write(dev_priv, DPIO_PCS_TX(port), + DPIO_PCS_TX_LANE2_RESET | +@@ -1642,8 +1638,6 @@ static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp) + uint8_t train_set = intel_dp->train_set[0]; + int port = vlv_dport_to_channel(dport); + +- WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); +- + switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { + case DP_TRAIN_PRE_EMPHASIS_0: + preemph_reg_value = 0x0004000; +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 18f8ce0404c6..83b63d72af83 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -1018,8 +1018,6 @@ static void intel_hdmi_pre_enable(struct intel_encoder *encoder) + if (!IS_VALLEYVIEW(dev)) + return; + +- WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); +- + /* Enable clock channels for this port */ + val = intel_dpio_read(dev_priv, DPIO_DATA_LANE_A(port)); + val = 0; +@@ -1063,8 +1061,6 @@ static void intel_hdmi_pre_pll_enable(struct intel_encoder *encoder) + if (!IS_VALLEYVIEW(dev)) + return; + +- WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); +- + /* Program Tx lane resets to default */ + intel_dpio_write(dev_priv, DPIO_PCS_TX(port), + DPIO_PCS_TX_LANE2_RESET | +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0186-drm-i915-rename-VLV-IOSF-sideband-functions-logicall.patch b/patches.baytrail/0186-drm-i915-rename-VLV-IOSF-sideband-functions-logicall.patch new file mode 100644 index 000000000000..95fb2d79c6f3 --- /dev/null +++ b/patches.baytrail/0186-drm-i915-rename-VLV-IOSF-sideband-functions-logicall.patch @@ -0,0 +1,520 @@ +From 2b1355f668812ec8cabbbfe6c4dbd23b0cf2f51f Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Wed, 22 May 2013 15:36:19 +0300 +Subject: drm/i915: rename VLV IOSF sideband functions logically + +Rename all VLV IOSF sideband register accessor functions to +vlv__{read,write}. No functional changes. + +Signed-off-by: Jani Nikula +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit ae99258f02fe189c008af94f26140ed691258e9f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 24 +++++++++--------- + drivers/gpu/drm/i915/i915_drv.h | 10 ++++---- + drivers/gpu/drm/i915/i915_sysfs.c | 2 +- + drivers/gpu/drm/i915/intel_display.c | 46 +++++++++++++++++------------------ + drivers/gpu/drm/i915/intel_dp.c | 32 ++++++++++++------------ + drivers/gpu/drm/i915/intel_hdmi.c | 42 ++++++++++++++++---------------- + drivers/gpu/drm/i915/intel_pm.c | 16 ++++++------ + drivers/gpu/drm/i915/intel_sideband.c | 10 ++++---- + 8 files changed, 91 insertions(+), 91 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 3a8409a31266..bc0f6a55c74b 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1137,16 +1137,16 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) + u32 freq_sts, val; + + mutex_lock(&dev_priv->rps.hw_lock); +- valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, ++ vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, + &freq_sts); + seq_printf(m, "PUNIT_REG_GPU_FREQ_STS: 0x%08x\n", freq_sts); + seq_printf(m, "DDR freq: %d MHz\n", dev_priv->mem_freq); + +- valleyview_punit_read(dev_priv, PUNIT_FUSE_BUS1, &val); ++ vlv_punit_read(dev_priv, PUNIT_FUSE_BUS1, &val); + seq_printf(m, "max GPU freq: %d MHz\n", + vlv_gpu_freq(dev_priv->mem_freq, val)); + +- valleyview_punit_read(dev_priv, PUNIT_REG_GPU_LFM, &val); ++ vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM, &val); + seq_printf(m, "min GPU freq: %d MHz\n", + vlv_gpu_freq(dev_priv->mem_freq, val)); + +@@ -1787,27 +1787,27 @@ static int i915_dpio_info(struct seq_file *m, void *data) + seq_printf(m, "DPIO_CTL: 0x%08x\n", I915_READ(DPIO_CTL)); + + seq_printf(m, "DPIO_DIV_A: 0x%08x\n", +- intel_dpio_read(dev_priv, _DPIO_DIV_A)); ++ vlv_dpio_read(dev_priv, _DPIO_DIV_A)); + seq_printf(m, "DPIO_DIV_B: 0x%08x\n", +- intel_dpio_read(dev_priv, _DPIO_DIV_B)); ++ vlv_dpio_read(dev_priv, _DPIO_DIV_B)); + + seq_printf(m, "DPIO_REFSFR_A: 0x%08x\n", +- intel_dpio_read(dev_priv, _DPIO_REFSFR_A)); ++ vlv_dpio_read(dev_priv, _DPIO_REFSFR_A)); + seq_printf(m, "DPIO_REFSFR_B: 0x%08x\n", +- intel_dpio_read(dev_priv, _DPIO_REFSFR_B)); ++ vlv_dpio_read(dev_priv, _DPIO_REFSFR_B)); + + seq_printf(m, "DPIO_CORE_CLK_A: 0x%08x\n", +- intel_dpio_read(dev_priv, _DPIO_CORE_CLK_A)); ++ vlv_dpio_read(dev_priv, _DPIO_CORE_CLK_A)); + seq_printf(m, "DPIO_CORE_CLK_B: 0x%08x\n", +- intel_dpio_read(dev_priv, _DPIO_CORE_CLK_B)); ++ vlv_dpio_read(dev_priv, _DPIO_CORE_CLK_B)); + + seq_printf(m, "DPIO_LFP_COEFF_A: 0x%08x\n", +- intel_dpio_read(dev_priv, _DPIO_LFP_COEFF_A)); ++ vlv_dpio_read(dev_priv, _DPIO_LFP_COEFF_A)); + seq_printf(m, "DPIO_LFP_COEFF_B: 0x%08x\n", +- intel_dpio_read(dev_priv, _DPIO_LFP_COEFF_B)); ++ vlv_dpio_read(dev_priv, _DPIO_LFP_COEFF_B)); + + seq_printf(m, "DPIO_FASTCLK_DISABLE: 0x%08x\n", +- intel_dpio_read(dev_priv, DPIO_FASTCLK_DISABLE)); ++ vlv_dpio_read(dev_priv, DPIO_FASTCLK_DISABLE)); + + mutex_unlock(&dev_priv->dpio_lock); + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 0243cb0b2dee..57911d47072e 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1935,11 +1935,11 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) + int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val); + + /* intel_sideband.c */ +-int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val); +-int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val); +-int valleyview_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val); +-u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg); +-void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val); ++int vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val); ++int vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val); ++int vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val); ++u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg); ++void vlv_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val); + u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg, + enum intel_sbi_destination destination); + void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value, +diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c +index c0d7875b475c..588fa00e6938 100644 +--- a/drivers/gpu/drm/i915/i915_sysfs.c ++++ b/drivers/gpu/drm/i915/i915_sysfs.c +@@ -214,7 +214,7 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev, + mutex_lock(&dev_priv->rps.hw_lock); + if (IS_VALLEYVIEW(dev_priv->dev)) { + u32 freq; +- valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &freq); ++ vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &freq); + ret = vlv_gpu_freq(dev_priv->mem_freq, (freq >> 8) & 0xff); + } else { + ret = dev_priv->rps.cur_delay * GT_FREQUENCY_MULTIPLIER; +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 613629ee81d9..0159fe522d0d 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4241,24 +4241,24 @@ static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv) + * PLLB opamp always calibrates to max value of 0x3f, force enable it + * and set it to a reasonable value instead. + */ +- reg_val = intel_dpio_read(dev_priv, DPIO_IREF(1)); ++ reg_val = vlv_dpio_read(dev_priv, DPIO_IREF(1)); + reg_val &= 0xffffff00; + reg_val |= 0x00000030; +- intel_dpio_write(dev_priv, DPIO_IREF(1), reg_val); ++ vlv_dpio_write(dev_priv, DPIO_IREF(1), reg_val); + +- reg_val = intel_dpio_read(dev_priv, DPIO_CALIBRATION); ++ reg_val = vlv_dpio_read(dev_priv, DPIO_CALIBRATION); + reg_val &= 0x8cffffff; + reg_val = 0x8c000000; +- intel_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val); ++ vlv_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val); + +- reg_val = intel_dpio_read(dev_priv, DPIO_IREF(1)); ++ reg_val = vlv_dpio_read(dev_priv, DPIO_IREF(1)); + reg_val &= 0xffffff00; +- intel_dpio_write(dev_priv, DPIO_IREF(1), reg_val); ++ vlv_dpio_write(dev_priv, DPIO_IREF(1), reg_val); + +- reg_val = intel_dpio_read(dev_priv, DPIO_CALIBRATION); ++ reg_val = vlv_dpio_read(dev_priv, DPIO_CALIBRATION); + reg_val &= 0x00ffffff; + reg_val |= 0xb0000000; +- intel_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val); ++ vlv_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val); + } + + static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc, +@@ -4333,15 +4333,15 @@ static void vlv_update_pll(struct intel_crtc *crtc) + vlv_pllb_recal_opamp(dev_priv); + + /* Set up Tx target for periodic Rcomp update */ +- intel_dpio_write(dev_priv, DPIO_IREF_BCAST, 0x0100000f); ++ vlv_dpio_write(dev_priv, DPIO_IREF_BCAST, 0x0100000f); + + /* Disable target IRef on PLL */ +- reg_val = intel_dpio_read(dev_priv, DPIO_IREF_CTL(pipe)); ++ reg_val = vlv_dpio_read(dev_priv, DPIO_IREF_CTL(pipe)); + reg_val &= 0x00ffffff; +- intel_dpio_write(dev_priv, DPIO_IREF_CTL(pipe), reg_val); ++ vlv_dpio_write(dev_priv, DPIO_IREF_CTL(pipe), reg_val); + + /* Disable fast lock */ +- intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x610); ++ vlv_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x610); + + /* Set idtafcrecal before PLL is enabled */ + mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK)); +@@ -4355,47 +4355,47 @@ static void vlv_update_pll(struct intel_crtc *crtc) + * Note: don't use the DAC post divider as it seems unstable. + */ + mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT); +- intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); ++ vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); + + mdiv |= DPIO_ENABLE_CALIBRATION; +- intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); ++ vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); + + /* Set HBR and RBR LPF coefficients */ + if (adjusted_mode->clock == 162000 || + intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI)) +- intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), ++ vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), + 0x005f0021); + else +- intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), ++ vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), + 0x00d0000f); + + if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) || + intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)) { + /* Use SSC source */ + if (!pipe) +- intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), ++ vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe), + 0x0df40000); + else +- intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), ++ vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe), + 0x0df70000); + } else { /* HDMI or VGA */ + /* Use bend source */ + if (!pipe) +- intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), ++ vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe), + 0x0df70000); + else +- intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), ++ vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe), + 0x0df40000); + } + +- coreclk = intel_dpio_read(dev_priv, DPIO_CORE_CLK(pipe)); ++ coreclk = vlv_dpio_read(dev_priv, DPIO_CORE_CLK(pipe)); + coreclk = (coreclk & 0x0000ff00) | 0x01c00000; + if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT) || + intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP)) + coreclk |= 0x01000000; +- intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), coreclk); ++ vlv_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), coreclk); + +- intel_dpio_write(dev_priv, DPIO_PLL_CML(pipe), 0x87871000); ++ vlv_dpio_write(dev_priv, DPIO_PLL_CML(pipe), 0x87871000); + + for_each_encoder_on_crtc(dev, &crtc->base, encoder) + if (encoder->pre_pll_enable) +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 02e98fac18e5..e21d98621078 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1462,18 +1462,18 @@ static void intel_pre_enable_dp(struct intel_encoder *encoder) + int pipe = intel_crtc->pipe; + u32 val; + +- val = intel_dpio_read(dev_priv, DPIO_DATA_LANE_A(port)); ++ val = vlv_dpio_read(dev_priv, DPIO_DATA_LANE_A(port)); + val = 0; + if (pipe) + val |= (1<<21); + else + val &= ~(1<<21); + val |= 0x001000c4; +- intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val); ++ vlv_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val); + +- intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port), ++ vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port), + 0x00760018); +- intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port), ++ vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port), + 0x00400888); + } + } +@@ -1489,19 +1489,19 @@ static void intel_dp_pre_pll_enable(struct intel_encoder *encoder) + return; + + /* Program Tx lane resets to default */ +- intel_dpio_write(dev_priv, DPIO_PCS_TX(port), ++ vlv_dpio_write(dev_priv, DPIO_PCS_TX(port), + DPIO_PCS_TX_LANE2_RESET | + DPIO_PCS_TX_LANE1_RESET); +- intel_dpio_write(dev_priv, DPIO_PCS_CLK(port), ++ vlv_dpio_write(dev_priv, DPIO_PCS_CLK(port), + DPIO_PCS_CLK_CRI_RXEB_EIOS_EN | + DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN | + (1<dpio_lock); +- intel_dpio_write(dev_priv, DPIO_PCS_TX(port), 0x00000000); +- intel_dpio_write(dev_priv, DPIO_PCS_CLK(port), 0x00e00060); ++ vlv_dpio_write(dev_priv, DPIO_PCS_TX(port), 0x00000000); ++ vlv_dpio_write(dev_priv, DPIO_PCS_CLK(port), 0x00e00060); + mutex_unlock(&dev_priv->dpio_lock); + } + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 1b884359662a..d158a34037ac 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2566,10 +2566,10 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) + if (val == dev_priv->rps.cur_delay) + return; + +- valleyview_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); ++ vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); + + do { +- valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &pval); ++ vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &pval); + if (time_after(jiffies, timeout)) { + DRM_DEBUG_DRIVER("timed out waiting for Punit\n"); + break; +@@ -2577,7 +2577,7 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) + udelay(10); + } while (pval & 1); + +- valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &pval); ++ vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &pval); + if ((pval >> 8) != val) + DRM_DEBUG_DRIVER("punit overrode freq: %d requested, but got %d\n", + val, pval >> 8); +@@ -2882,7 +2882,7 @@ int valleyview_rps_max_freq(struct drm_i915_private *dev_priv) + { + u32 val, rp0; + +- valleyview_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE, &val); ++ vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE, &val); + + rp0 = (val & FB_GFX_MAX_FREQ_FUSE_MASK) >> FB_GFX_MAX_FREQ_FUSE_SHIFT; + /* Clamp to max */ +@@ -2895,9 +2895,9 @@ static int valleyview_rps_rpe_freq(struct drm_i915_private *dev_priv) + { + u32 val, rpe; + +- valleyview_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_LO, &val); ++ vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_LO, &val); + rpe = (val & FB_FMAX_VMIN_FREQ_LO_MASK) >> FB_FMAX_VMIN_FREQ_LO_SHIFT; +- valleyview_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_HI, &val); ++ vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_HI, &val); + rpe |= (val & FB_FMAX_VMIN_FREQ_HI_MASK) << 5; + + return rpe; +@@ -2907,7 +2907,7 @@ int valleyview_rps_min_freq(struct drm_i915_private *dev_priv) + { + u32 val; + +- valleyview_punit_read(dev_priv, PUNIT_REG_GPU_LFM, &val); ++ vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM, &val); + + return val & 0xff; + } +@@ -3018,7 +3018,7 @@ static void valleyview_enable_rps(struct drm_device *dev) + I915_WRITE(GEN6_RC_CONTROL, + GEN7_RC_CTL_TO_MODE); + +- valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &val); ++ vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &val); + switch ((val >> 6) & 3) { + case 0: + case 1: +diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c +index a7c4b61e9c30..d150972da048 100644 +--- a/drivers/gpu/drm/i915/intel_sideband.c ++++ b/drivers/gpu/drm/i915/intel_sideband.c +@@ -63,7 +63,7 @@ static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn, + return 0; + } + +-int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) ++int vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) + { + int ret; + +@@ -77,7 +77,7 @@ int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) + return ret; + } + +-int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) ++int vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) + { + int ret; + +@@ -91,7 +91,7 @@ int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) + return ret; + } + +-int valleyview_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) ++int vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) + { + int ret; + +@@ -105,7 +105,7 @@ int valleyview_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) + return ret; + } + +-u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg) ++u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg) + { + u32 val = 0; + +@@ -115,7 +115,7 @@ u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg) + return val; + } + +-void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val) ++void vlv_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val) + { + vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_DPIO, + DPIO_OPCODE_REG_WRITE, reg, &val); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0187-drm-i915-change-VLV-IOSF-sideband-accessors-to-not-r.patch b/patches.baytrail/0187-drm-i915-change-VLV-IOSF-sideband-accessors-to-not-r.patch new file mode 100644 index 000000000000..3c0fb6b04e23 --- /dev/null +++ b/patches.baytrail/0187-drm-i915-change-VLV-IOSF-sideband-accessors-to-not-r.patch @@ -0,0 +1,207 @@ +From 16d8b3d29023040d295f6c6c26228560b8a8d242 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Wed, 22 May 2013 15:36:20 +0300 +Subject: drm/i915: change VLV IOSF sideband accessors to not return error code + +We never check the return values, and there's not much we could do on +errors anyway. Just simplify the signatures. No functional changes. + +Signed-off-by: Jani Nikula +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 64936258d7e426bee5f2392269b1b20172db9ffb) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 7 +++---- + drivers/gpu/drm/i915/i915_drv.h | 6 +++--- + drivers/gpu/drm/i915/i915_sysfs.c | 2 +- + drivers/gpu/drm/i915/intel_pm.c | 18 +++++++----------- + drivers/gpu/drm/i915/intel_sideband.c | 30 +++++++++++++----------------- + 5 files changed, 27 insertions(+), 36 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index bc0f6a55c74b..2eb572afbcd3 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1137,16 +1137,15 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) + u32 freq_sts, val; + + mutex_lock(&dev_priv->rps.hw_lock); +- vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, +- &freq_sts); ++ freq_sts = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); + seq_printf(m, "PUNIT_REG_GPU_FREQ_STS: 0x%08x\n", freq_sts); + seq_printf(m, "DDR freq: %d MHz\n", dev_priv->mem_freq); + +- vlv_punit_read(dev_priv, PUNIT_FUSE_BUS1, &val); ++ val = vlv_punit_read(dev_priv, PUNIT_FUSE_BUS1); + seq_printf(m, "max GPU freq: %d MHz\n", + vlv_gpu_freq(dev_priv->mem_freq, val)); + +- vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM, &val); ++ val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM); + seq_printf(m, "min GPU freq: %d MHz\n", + vlv_gpu_freq(dev_priv->mem_freq, val)); + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 57911d47072e..5161c2c7487f 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1935,9 +1935,9 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) + int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val); + + /* intel_sideband.c */ +-int vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val); +-int vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val); +-int vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val); ++u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr); ++void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val); ++u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr); + u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg); + void vlv_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val); + u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg, +diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c +index 588fa00e6938..6875b5654c63 100644 +--- a/drivers/gpu/drm/i915/i915_sysfs.c ++++ b/drivers/gpu/drm/i915/i915_sysfs.c +@@ -214,7 +214,7 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev, + mutex_lock(&dev_priv->rps.hw_lock); + if (IS_VALLEYVIEW(dev_priv->dev)) { + u32 freq; +- vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &freq); ++ freq = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); + ret = vlv_gpu_freq(dev_priv->mem_freq, (freq >> 8) & 0xff); + } else { + ret = dev_priv->rps.cur_delay * GT_FREQUENCY_MULTIPLIER; +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index d158a34037ac..914257501006 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2569,7 +2569,7 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) + vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); + + do { +- vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &pval); ++ pval = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); + if (time_after(jiffies, timeout)) { + DRM_DEBUG_DRIVER("timed out waiting for Punit\n"); + break; +@@ -2577,7 +2577,7 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) + udelay(10); + } while (pval & 1); + +- vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &pval); ++ pval = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); + if ((pval >> 8) != val) + DRM_DEBUG_DRIVER("punit overrode freq: %d requested, but got %d\n", + val, pval >> 8); +@@ -2882,7 +2882,7 @@ int valleyview_rps_max_freq(struct drm_i915_private *dev_priv) + { + u32 val, rp0; + +- vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE, &val); ++ val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE); + + rp0 = (val & FB_GFX_MAX_FREQ_FUSE_MASK) >> FB_GFX_MAX_FREQ_FUSE_SHIFT; + /* Clamp to max */ +@@ -2895,9 +2895,9 @@ static int valleyview_rps_rpe_freq(struct drm_i915_private *dev_priv) + { + u32 val, rpe; + +- vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_LO, &val); ++ val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_LO); + rpe = (val & FB_FMAX_VMIN_FREQ_LO_MASK) >> FB_FMAX_VMIN_FREQ_LO_SHIFT; +- vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_HI, &val); ++ val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_HI); + rpe |= (val & FB_FMAX_VMIN_FREQ_HI_MASK) << 5; + + return rpe; +@@ -2905,11 +2905,7 @@ static int valleyview_rps_rpe_freq(struct drm_i915_private *dev_priv) + + int valleyview_rps_min_freq(struct drm_i915_private *dev_priv) + { +- u32 val; +- +- vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM, &val); +- +- return val & 0xff; ++ return vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff; + } + + static void vlv_rps_timer_work(struct work_struct *work) +@@ -3018,7 +3014,7 @@ static void valleyview_enable_rps(struct drm_device *dev) + I915_WRITE(GEN6_RC_CONTROL, + GEN7_RC_CTL_TO_MODE); + +- vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &val); ++ val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); + switch ((val >> 6) & 3) { + case 0: + case 1: +diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c +index d150972da048..9a0e6c5ea540 100644 +--- a/drivers/gpu/drm/i915/intel_sideband.c ++++ b/drivers/gpu/drm/i915/intel_sideband.c +@@ -63,46 +63,42 @@ static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn, + return 0; + } + +-int vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) ++u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr) + { +- int ret; ++ u32 val = 0; + + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + + mutex_lock(&dev_priv->dpio_lock); +- ret = vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT, +- PUNIT_OPCODE_REG_READ, addr, val); ++ vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT, ++ PUNIT_OPCODE_REG_READ, addr, &val); + mutex_unlock(&dev_priv->dpio_lock); + +- return ret; ++ return val; + } + +-int vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) ++void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) + { +- int ret; +- + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + + mutex_lock(&dev_priv->dpio_lock); +- ret = vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT, +- PUNIT_OPCODE_REG_WRITE, addr, &val); ++ vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT, ++ PUNIT_OPCODE_REG_WRITE, addr, &val); + mutex_unlock(&dev_priv->dpio_lock); +- +- return ret; + } + +-int vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) ++u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr) + { +- int ret; ++ u32 val = 0; + + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + + mutex_lock(&dev_priv->dpio_lock); +- ret = vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_NC, +- PUNIT_OPCODE_REG_READ, addr, val); ++ vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_NC, ++ PUNIT_OPCODE_REG_READ, addr, &val); + mutex_unlock(&dev_priv->dpio_lock); + +- return ret; ++ return val; + } + + u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0188-drm-i915-add-enable-argument-to-intel_update_sprite_.patch b/patches.baytrail/0188-drm-i915-add-enable-argument-to-intel_update_sprite_.patch new file mode 100644 index 000000000000..4670c7744c6c --- /dev/null +++ b/patches.baytrail/0188-drm-i915-add-enable-argument-to-intel_update_sprite_.patch @@ -0,0 +1,142 @@ +From 41752b19eecbd28f97f57d19cf6d08415bbd3e45 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 24 May 2013 11:59:17 -0300 +Subject: drm/i915: add "enable" argument to intel_update_sprite_watermarks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Because we want to call it from the "sprite disable" paths, since on +Haswell we need to update the sprite watermarks when we disable +sprites. + +For now, all this patch does is to add the "enable" argument and call +intel_update_sprite_watermarks from inside ivb_disable_plane. This +shouldn't change how the code behaves because on +sandybridge_update_sprite_wm we just ignore the "!enable" case. The +patches that implement Haswell watermarks will make use of the changes +introduced by this patch. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 4c4ff43a692b44c6e326f9f28208f3d78ea51f7e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 3 ++- + drivers/gpu/drm/i915/intel_drv.h | 2 +- + drivers/gpu/drm/i915/intel_pm.c | 11 ++++++++--- + drivers/gpu/drm/i915/intel_sprite.c | 8 +++++--- + 4 files changed, 16 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 5161c2c7487f..db0a41cf0d49 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -315,7 +315,8 @@ struct drm_i915_display_funcs { + int (*get_fifo_size)(struct drm_device *dev, int plane); + void (*update_wm)(struct drm_device *dev); + void (*update_sprite_wm)(struct drm_device *dev, int pipe, +- uint32_t sprite_width, int pixel_size); ++ uint32_t sprite_width, int pixel_size, ++ bool enable); + void (*modeset_global_resources)(struct drm_device *dev); + /* Returns the active state of the crtc, and if the crtc is active, + * fills out the pipe-config with the hw state. */ +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 928368a93f74..cfc24a2257f4 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -731,7 +731,7 @@ extern void intel_ddi_init(struct drm_device *dev, enum port port); + extern void intel_update_watermarks(struct drm_device *dev); + extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, + uint32_t sprite_width, +- int pixel_size); ++ int pixel_size, bool enable); + + extern unsigned long intel_gen4_compute_page_offset(int *x, int *y, + unsigned int tiling_mode, +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 914257501006..0273da696394 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2195,7 +2195,8 @@ sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane, + } + + static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, +- uint32_t sprite_width, int pixel_size) ++ uint32_t sprite_width, int pixel_size, ++ bool enable) + { + struct drm_i915_private *dev_priv = dev->dev_private; + int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ +@@ -2203,6 +2204,9 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, + int sprite_wm, reg; + int ret; + ++ if (!enable) ++ return; ++ + switch (pipe) { + case 0: + reg = WM0_PIPEA_ILK; +@@ -2314,13 +2318,14 @@ void intel_update_watermarks(struct drm_device *dev) + } + + void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, +- uint32_t sprite_width, int pixel_size) ++ uint32_t sprite_width, int pixel_size, ++ bool enable) + { + struct drm_i915_private *dev_priv = dev->dev_private; + + if (dev_priv->display.update_sprite_wm) + dev_priv->display.update_sprite_wm(dev, pipe, sprite_width, +- pixel_size); ++ pixel_size, enable); + } + + static struct drm_i915_gem_object * +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index 19b9cb961b5a..04d38d4d811a 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -114,7 +114,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb, + crtc_w--; + crtc_h--; + +- intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); ++ intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true); + + I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); + I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); +@@ -268,7 +268,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, + crtc_w--; + crtc_h--; + +- intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); ++ intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true); + + /* + * IVB workaround: must disable low power watermarks for at least +@@ -335,6 +335,8 @@ ivb_disable_plane(struct drm_plane *plane) + + dev_priv->sprite_scaling_enabled &= ~(1 << pipe); + ++ intel_update_sprite_watermarks(dev, pipe, 0, 0, false); ++ + /* potentially re-enable LP watermarks */ + if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) + intel_update_watermarks(dev); +@@ -453,7 +455,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, + crtc_w--; + crtc_h--; + +- intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); ++ intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true); + + dvsscale = 0; + if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0189-drm-i915-add-haswell_update_sprite_wm.patch b/patches.baytrail/0189-drm-i915-add-haswell_update_sprite_wm.patch new file mode 100644 index 000000000000..01dbff9d5c6b --- /dev/null +++ b/patches.baytrail/0189-drm-i915-add-haswell_update_sprite_wm.patch @@ -0,0 +1,98 @@ +From ea067f886b0f3014da486f0714f394e88999835c Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 24 May 2013 11:59:18 -0300 +Subject: drm/i915: add haswell_update_sprite_wm +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On Haswell, whenever we change the sprites we need to completely +recalculate all the watermarks, because the sprites are one of the +parameters to the LP watermarks, so a change on the sprites may +trigger a change on which LP levels are enabled. + +So on this commit we store all the parameters we need to store for +proper recalculation of the Haswell WMs and then call +haswell_update_wm. + +Notice that for now our haswell_update_wm function is not really using +these parameters we're storing, but on the next commits we'll use +these parameters. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 526682e9fabf22e82a02383e8f864a7330b73b25) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_drv.h | 12 ++++++++++++ + drivers/gpu/drm/i915/intel_pm.c | 23 ++++++++++++++++++++++- + 2 files changed, 34 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index cfc24a2257f4..c02bc97e350d 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -326,6 +326,18 @@ struct intel_plane { + unsigned int crtc_w, crtc_h; + uint32_t src_x, src_y; + uint32_t src_w, src_h; ++ ++ /* Since we need to change the watermarks before/after ++ * enabling/disabling the planes, we need to store the parameters here ++ * as the other pieces of the struct may not reflect the values we want ++ * for the watermark calculations. Currently only Haswell uses this. ++ */ ++ struct { ++ bool enable; ++ uint8_t bytes_per_pixel; ++ uint32_t horiz_pixels; ++ } wm; ++ + void (*update_plane)(struct drm_plane *plane, + struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj, +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 0273da696394..6d189cde8591 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2118,6 +2118,26 @@ static void haswell_update_wm(struct drm_device *dev) + sandybridge_update_wm(dev); + } + ++static void haswell_update_sprite_wm(struct drm_device *dev, int pipe, ++ uint32_t sprite_width, int pixel_size, ++ bool enable) ++{ ++ struct drm_plane *plane; ++ ++ list_for_each_entry(plane, &dev->mode_config.plane_list, head) { ++ struct intel_plane *intel_plane = to_intel_plane(plane); ++ ++ if (intel_plane->pipe == pipe) { ++ intel_plane->wm.enable = enable; ++ intel_plane->wm.horiz_pixels = sprite_width + 1; ++ intel_plane->wm.bytes_per_pixel = pixel_size; ++ break; ++ } ++ } ++ ++ haswell_update_wm(dev); ++} ++ + static bool + sandybridge_compute_sprite_wm(struct drm_device *dev, int plane, + uint32_t sprite_width, int pixel_size, +@@ -4631,7 +4651,8 @@ void intel_init_pm(struct drm_device *dev) + } else if (IS_HASWELL(dev)) { + if (I915_READ64(MCH_SSKPD)) { + dev_priv->display.update_wm = haswell_update_wm; +- dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; ++ dev_priv->display.update_sprite_wm = ++ haswell_update_sprite_wm; + } else { + DRM_DEBUG_KMS("Failed to read display plane latency. " + "Disable CxSR\n"); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0190-drm-i915-pass-seqno-to-i915_hangcheck_ring_idle.patch b/patches.baytrail/0190-drm-i915-pass-seqno-to-i915_hangcheck_ring_idle.patch new file mode 100644 index 000000000000..7411a19e7e4f --- /dev/null +++ b/patches.baytrail/0190-drm-i915-pass-seqno-to-i915_hangcheck_ring_idle.patch @@ -0,0 +1,52 @@ +From 2c68ed1c6ef46f4c22bb63215d63e284f59243be Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Mon, 13 May 2013 16:32:09 +0300 +Subject: drm/i915: pass seqno to i915_hangcheck_ring_idle + +In preparation for next commit, pass seqno as a parameter +to i915_hangcheck_ring_idle as it will be used inside +i915_hangcheck_elapsed. + +Signed-off-by: Mika Kuoppala +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 79ee20dc85072b0edfb5e461799d192a9cc9d422) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 6b9bc815cc70..3920c26d56ca 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2311,11 +2311,11 @@ ring_last_seqno(struct intel_ring_buffer *ring) + struct drm_i915_gem_request, list)->seqno; + } + +-static bool i915_hangcheck_ring_idle(struct intel_ring_buffer *ring, bool *err) ++static bool i915_hangcheck_ring_idle(struct intel_ring_buffer *ring, ++ u32 ring_seqno, bool *err) + { + if (list_empty(&ring->request_list) || +- i915_seqno_passed(ring->get_seqno(ring, false), +- ring_last_seqno(ring))) { ++ i915_seqno_passed(ring_seqno, ring_last_seqno(ring))) { + /* Issue a wake-up to catch stuck h/w. */ + if (waitqueue_active(&ring->irq_queue)) { + DRM_ERROR("Hangcheck timer elapsed... %s idle\n", +@@ -2432,7 +2432,10 @@ void i915_hangcheck_elapsed(unsigned long data) + memset(acthd, 0, sizeof(acthd)); + idle = true; + for_each_ring(ring, dev_priv, i) { +- idle &= i915_hangcheck_ring_idle(ring, &err); ++ u32 seqno; ++ ++ seqno = ring->get_seqno(ring, false); ++ idle &= i915_hangcheck_ring_idle(ring, seqno, &err); + acthd[i] = intel_ring_get_active_head(ring); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0191-drm-i915-track-ring-progression-using-seqnos.patch b/patches.baytrail/0191-drm-i915-track-ring-progression-using-seqnos.patch new file mode 100644 index 000000000000..99eb266ee345 --- /dev/null +++ b/patches.baytrail/0191-drm-i915-track-ring-progression-using-seqnos.patch @@ -0,0 +1,137 @@ +From 9f3f987cb1f2ebc32e2442b63a4b0e75c648f45f Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Fri, 24 May 2013 17:16:07 +0300 +Subject: drm/i915: track ring progression using seqnos + +Instead of relying in acthd, track ring seqno progression +to detect if ring has hung. + +v2: put hangcheck stuff inside struct (Chris Wilson) + +v3: initialize hangcheck.seqno (Ben Widawsky) + +Signed-off-by: Mika Kuoppala +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 92cab7345131db7af18f630a799ce6b2e8e624c5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 -- + drivers/gpu/drm/i915/i915_irq.c | 30 +++++++++++++----------------- + drivers/gpu/drm/i915/intel_ringbuffer.c | 1 + + drivers/gpu/drm/i915/intel_ringbuffer.h | 6 ++++++ + 4 files changed, 20 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index db0a41cf0d49..16a69b82e865 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -843,8 +843,6 @@ struct i915_gpu_error { + #define DRM_I915_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD) + struct timer_list hangcheck_timer; + int hangcheck_count; +- uint32_t last_acthd[I915_NUM_RINGS]; +- uint32_t prev_instdone[I915_NUM_INSTDONE_REG]; + + /* For reset and error_state handling. */ + spinlock_t lock; +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 3920c26d56ca..ef31d00fbf1e 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2421,22 +2421,19 @@ void i915_hangcheck_elapsed(unsigned long data) + { + struct drm_device *dev = (struct drm_device *)data; + drm_i915_private_t *dev_priv = dev->dev_private; +- uint32_t acthd[I915_NUM_RINGS], instdone[I915_NUM_INSTDONE_REG]; + struct intel_ring_buffer *ring; + bool err = false, idle; + int i; ++ u32 seqno[I915_NUM_RINGS]; ++ bool work_done; + + if (!i915_enable_hangcheck) + return; + +- memset(acthd, 0, sizeof(acthd)); + idle = true; + for_each_ring(ring, dev_priv, i) { +- u32 seqno; +- +- seqno = ring->get_seqno(ring, false); +- idle &= i915_hangcheck_ring_idle(ring, seqno, &err); +- acthd[i] = intel_ring_get_active_head(ring); ++ seqno[i] = ring->get_seqno(ring, false); ++ idle &= i915_hangcheck_ring_idle(ring, seqno[i], &err); + } + + /* If all work is done then ACTHD clearly hasn't advanced. */ +@@ -2452,20 +2449,19 @@ void i915_hangcheck_elapsed(unsigned long data) + return; + } + +- i915_get_extra_instdone(dev, instdone); +- if (memcmp(dev_priv->gpu_error.last_acthd, acthd, +- sizeof(acthd)) == 0 && +- memcmp(dev_priv->gpu_error.prev_instdone, instdone, +- sizeof(instdone)) == 0) { ++ work_done = false; ++ for_each_ring(ring, dev_priv, i) { ++ if (ring->hangcheck.seqno != seqno[i]) { ++ work_done = true; ++ ring->hangcheck.seqno = seqno[i]; ++ } ++ } ++ ++ if (!work_done) { + if (i915_hangcheck_hung(dev)) + return; + } else { + dev_priv->gpu_error.hangcheck_count = 0; +- +- memcpy(dev_priv->gpu_error.last_acthd, acthd, +- sizeof(acthd)); +- memcpy(dev_priv->gpu_error.prev_instdone, instdone, +- sizeof(instdone)); + } + + repeat: +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index d99ff99b07b2..df0b7c7ac166 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -1513,6 +1513,7 @@ void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno) + } + + ring->set_seqno(ring, seqno); ++ ring->hangcheck.seqno = seqno; + } + + void intel_ring_advance(struct intel_ring_buffer *ring) +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index dac1614a1bca..ef374a892105 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -37,6 +37,10 @@ struct intel_hw_status_page { + #define I915_READ_SYNC_0(ring) I915_READ(RING_SYNC_0((ring)->mmio_base)) + #define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base)) + ++struct intel_ring_hangcheck { ++ u32 seqno; ++}; ++ + struct intel_ring_buffer { + const char *name; + enum intel_ring_id { +@@ -137,6 +141,8 @@ struct intel_ring_buffer { + struct i915_hw_context *default_context; + struct i915_hw_context *last_context; + ++ struct intel_ring_hangcheck hangcheck; ++ + void *private; + }; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0192-drm-i915-introduce-i915_hangcheck_ring_hung.patch b/patches.baytrail/0192-drm-i915-introduce-i915_hangcheck_ring_hung.patch new file mode 100644 index 000000000000..27328f06cf4e --- /dev/null +++ b/patches.baytrail/0192-drm-i915-introduce-i915_hangcheck_ring_hung.patch @@ -0,0 +1,72 @@ +From 5dc06cf1f4a0e0ece5e4920226210238cc9c2e77 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Mon, 13 May 2013 16:32:11 +0300 +Subject: drm/i915: introduce i915_hangcheck_ring_hung + +In preparation to track per ring progress in hangcheck, +add i915_hangcheck_ring_hung. + +v2: omit dev parameter (Ben Widawsky) + +Signed-off-by: Mika Kuoppala +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit ed5cbb0355779dc5516b2f7b62cedce185b00439) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 29 +++++++++++++++++------------ + 1 file changed, 17 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index ef31d00fbf1e..427cf89923aa 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2382,28 +2382,33 @@ static bool kick_ring(struct intel_ring_buffer *ring) + return false; + } + ++static bool i915_hangcheck_ring_hung(struct intel_ring_buffer *ring) ++{ ++ if (IS_GEN2(ring->dev)) ++ return false; ++ ++ /* Is the chip hanging on a WAIT_FOR_EVENT? ++ * If so we can simply poke the RB_WAIT bit ++ * and break the hang. This should work on ++ * all but the second generation chipsets. ++ */ ++ return !kick_ring(ring); ++} ++ + static bool i915_hangcheck_hung(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; + + if (dev_priv->gpu_error.hangcheck_count++ > 1) { + bool hung = true; ++ struct intel_ring_buffer *ring; ++ int i; + + DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); + i915_handle_error(dev, true); + +- if (!IS_GEN2(dev)) { +- struct intel_ring_buffer *ring; +- int i; +- +- /* Is the chip hanging on a WAIT_FOR_EVENT? +- * If so we can simply poke the RB_WAIT bit +- * and break the hang. This should work on +- * all but the second generation chipsets. +- */ +- for_each_ring(ring, dev_priv, i) +- hung &= !kick_ring(ring); +- } ++ for_each_ring(ring, dev_priv, i) ++ hung &= i915_hangcheck_ring_hung(ring); + + return hung; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0193-drm-i915-Fix-error-state-memory-leaks.patch b/patches.baytrail/0193-drm-i915-Fix-error-state-memory-leaks.patch new file mode 100644 index 000000000000..c4dfb7d7e8df --- /dev/null +++ b/patches.baytrail/0193-drm-i915-Fix-error-state-memory-leaks.patch @@ -0,0 +1,36 @@ +From c9f4de633274816bd2d74bfd4702cd96398f9e66 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Sat, 25 May 2013 14:42:54 -0700 +Subject: drm/i915: Fix error state memory leaks + +Found with kmemleak. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 7ed73da0eac4e2e06c06e8baf518e124fc1f6a17) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 427cf89923aa..e8b5d548230e 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1589,11 +1589,13 @@ i915_error_state_free(struct kref *error_ref) + for (i = 0; i < ARRAY_SIZE(error->ring); i++) { + i915_error_object_free(error->ring[i].batchbuffer); + i915_error_object_free(error->ring[i].ringbuffer); ++ i915_error_object_free(error->ring[i].ctx); + kfree(error->ring[i].requests); + } + + kfree(error->active_bo); + kfree(error->overlay); ++ kfree(error->display); + kfree(error); + } + static void capture_bo(struct drm_i915_error_buffer *err, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0194-drm-i915-pre-fixes-for-checkpatch.patch b/patches.baytrail/0194-drm-i915-pre-fixes-for-checkpatch.patch new file mode 100644 index 000000000000..266da726bc5f --- /dev/null +++ b/patches.baytrail/0194-drm-i915-pre-fixes-for-checkpatch.patch @@ -0,0 +1,69 @@ +From ae75c68006432d74c83d2f50d8cd4c9038a249b0 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Sat, 25 May 2013 12:26:35 -0700 +Subject: drm/i915: pre-fixes for checkpatch + +Since I'll need to modify i915_gem_object_bind_to_gtt(), fix the errors +now to get checkpatch to not complain. + +Signed-off-by: Ben Widawsky +[danvet: Resolve conflict with Chris' improved debug output, and +bikeshed the new variable with s/max/gtt_max/ a bit while at it.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 0a9ae0d7f8249da5906c8cac7d56768975c38de4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 229089c83f25..03103eb57e32 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3000,6 +3000,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + struct drm_mm_node *node; + u32 size, fence_size, fence_alignment, unfenced_alignment; + bool mappable, fenceable; ++ size_t gtt_max = map_and_fenceable ? ++ dev_priv->gtt.mappable_end : dev_priv->gtt.total; + int ret; + + fence_size = i915_gem_get_gtt_size(dev, +@@ -3026,12 +3028,11 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + /* If the object is bigger than the entire aperture, reject it early + * before evicting everything in a vain attempt to find space. + */ +- if (obj->base.size > +- (map_and_fenceable ? dev_priv->gtt.mappable_end : dev_priv->gtt.total)) { ++ if (obj->base.size > gtt_max) { + DRM_ERROR("Attempting to bind an object larger than the aperture: object=%zd > %s aperture=%ld\n", + obj->base.size, + map_and_fenceable ? "mappable" : "total", +- map_and_fenceable ? dev_priv->gtt.mappable_end : dev_priv->gtt.total); ++ gtt_max); + return -E2BIG; + } + +@@ -3047,14 +3048,10 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + return -ENOMEM; + } + +- search_free: +- if (map_and_fenceable) +- ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space, node, +- size, alignment, obj->cache_level, +- 0, dev_priv->gtt.mappable_end); +- else +- ret = drm_mm_insert_node_generic(&dev_priv->mm.gtt_space, node, +- size, alignment, obj->cache_level); ++search_free: ++ ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space, node, ++ size, alignment, ++ obj->cache_level, 0, gtt_max); + if (ret) { + ret = i915_gem_evict_something(dev, size, alignment, + obj->cache_level, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0195-drm-i915-use-mappable-size-for-fb-kickout.patch b/patches.baytrail/0195-drm-i915-use-mappable-size-for-fb-kickout.patch new file mode 100644 index 000000000000..fdd1d5ca3ede --- /dev/null +++ b/patches.baytrail/0195-drm-i915-use-mappable-size-for-fb-kickout.patch @@ -0,0 +1,45 @@ +From 20c2d0a631c088478598f0e4c8790f5a129a22cf Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Sat, 25 May 2013 12:26:36 -0700 +Subject: drm/i915: use mappable size for fb kickout + +The GTT start is either 0 in the KMS case, or some value which is set +only after the init IOCTL in the UMS case. In both cases, we don't have +this information until after we've tried to kick out the firmware fb. + +This patch should have no functional change since we kzalloc the GTT +struct anyway. It only clarifies the situation for people who end up +having to look at that code. + +This weirdness was introduced in: + +commit 93d187993b783c68383a884091a600d9ad499ea6 +Author: Ben Widawsky +Date: Thu Jan 17 12:45:17 2013 -0800 + + drm/i915: Remove use of gtt_mappable_entries + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit f64e29227d80cc15c37c7dbf7030ffc8c415cbd4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 29bb1303e662..09233f9c5640 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1407,7 +1407,7 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) + return; + + ap->ranges[0].base = dev_priv->gtt.mappable_base; +- ap->ranges[0].size = dev_priv->gtt.mappable_end - dev_priv->gtt.start; ++ ap->ranges[0].size = dev_priv->gtt.mappable_end; + + primary = + pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0196-drm-i915-use-drm_mm_takedown.patch b/patches.baytrail/0196-drm-i915-use-drm_mm_takedown.patch new file mode 100644 index 000000000000..19b33c92b22d --- /dev/null +++ b/patches.baytrail/0196-drm-i915-use-drm_mm_takedown.patch @@ -0,0 +1,39 @@ +From ad96fe201090c5d229cf892258fc504496513f14 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Sat, 25 May 2013 12:26:37 -0700 +Subject: drm/i915: use drm_mm_takedown + +I noticed this while doing the VMA abstraction. AFAICT, it won't +actually fix anything, but it is the correct thing to do. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit dd62eabd1d54336a2d5d3758ab4393cd13254102) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 09233f9c5640..d9ee7e82a4a1 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1360,6 +1360,7 @@ cleanup_gem: + i915_gem_cleanup_ringbuffer(dev); + mutex_unlock(&dev->struct_mutex); + i915_gem_cleanup_aliasing_ppgtt(dev); ++ drm_mm_takedown(&dev_priv->mm.gtt_space); + cleanup_irq: + drm_irq_uninstall(dev); + cleanup_gem_stolen: +@@ -1746,6 +1747,7 @@ int i915_driver_unload(struct drm_device *dev) + i915_free_hws(dev); + } + ++ drm_mm_takedown(&dev_priv->mm.gtt_space); + if (dev_priv->regs != NULL) + pci_iounmap(dev->pdev, dev_priv->regs); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0197-drm-i915-context-debug-messages.patch b/patches.baytrail/0197-drm-i915-context-debug-messages.patch new file mode 100644 index 000000000000..3b0dc93a2b94 --- /dev/null +++ b/patches.baytrail/0197-drm-i915-context-debug-messages.patch @@ -0,0 +1,82 @@ +From a6993f7806610ac625570222337c16a91951decc Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Sat, 25 May 2013 12:26:38 -0700 +Subject: drm/i915: context debug messages + +Add some debug messages to help figure out what goes wrong on context +initialization. + +Later in the PPGTT series, I ended up having a lot of failures after +reset. In many cases it was extra difficult to debug because I hadn't +even realized that contexts failed to reinitialize after reset (again an +artifact of some later patches). + +This fairly benign patch does help debug some potential issues which +arise later. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit bb0364130fb0d272c838149b2ffe698a6c7afbfc) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_context.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index 59b536a7f773..b3be2946e6db 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -156,7 +156,8 @@ create_hw_context(struct drm_device *dev, + if (INTEL_INFO(dev)->gen >= 7) { + ret = i915_gem_object_set_cache_level(ctx->obj, + I915_CACHE_LLC_MLC); +- if (ret) ++ /* Failure shouldn't ever happen this early */ ++ if (WARN_ON(ret)) + goto err_out; + } + +@@ -214,12 +215,16 @@ static int create_default_context(struct drm_i915_private *dev_priv) + */ + dev_priv->ring[RCS].default_context = ctx; + ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false, false); +- if (ret) ++ if (ret) { ++ DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret); + goto err_destroy; ++ } + + ret = do_switch(ctx); +- if (ret) ++ if (ret) { ++ DRM_DEBUG_DRIVER("Switch failed %d\n", ret); + goto err_unpin; ++ } + + DRM_DEBUG_DRIVER("Default HW context loaded\n"); + return 0; +@@ -237,6 +242,7 @@ void i915_gem_context_init(struct drm_device *dev) + + if (!HAS_HW_CONTEXTS(dev)) { + dev_priv->hw_contexts_disabled = true; ++ DRM_DEBUG_DRIVER("Disabling HW Contexts; old hardware\n"); + return; + } + +@@ -249,11 +255,13 @@ void i915_gem_context_init(struct drm_device *dev) + + if (dev_priv->hw_context_size > (1<<20)) { + dev_priv->hw_contexts_disabled = true; ++ DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size\n"); + return; + } + + if (create_default_context(dev_priv)) { + dev_priv->hw_contexts_disabled = true; ++ DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed\n"); + return; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0198-drm-i915-Call-context-fini-at-cleanup.patch b/patches.baytrail/0198-drm-i915-Call-context-fini-at-cleanup.patch new file mode 100644 index 000000000000..77cbcc20aa20 --- /dev/null +++ b/patches.baytrail/0198-drm-i915-Call-context-fini-at-cleanup.patch @@ -0,0 +1,36 @@ +From 75ee4b5cd86b57376566578871801ab841293b76 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Sat, 25 May 2013 12:26:39 -0700 +Subject: drm/i915: Call context fini at cleanup + +If contexts were actually initialized, and we fail somewhere later during +init this would possibly leak memory, and lead to some error messages +about unclean takedown. As the odds of this occurring, and someone +actually caring/noticing are pretty slim, the patch isn't terribly +important. + +Found by code inspection while working on something else. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 55d23285745b1be7bd25a2a4ba5ba79e05ab843a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index d9ee7e82a4a1..57198f4bdf2c 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1358,6 +1358,7 @@ static int i915_load_modeset_init(struct drm_device *dev) + cleanup_gem: + mutex_lock(&dev->struct_mutex); + i915_gem_cleanup_ringbuffer(dev); ++ i915_gem_context_fini(dev); + mutex_unlock(&dev->struct_mutex); + i915_gem_cleanup_aliasing_ppgtt(dev); + drm_mm_takedown(&dev_priv->mm.gtt_space); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0199-drm-i915-release-scratch-page-at-module-unload.patch b/patches.baytrail/0199-drm-i915-release-scratch-page-at-module-unload.patch new file mode 100644 index 000000000000..5a7777c86eb5 --- /dev/null +++ b/patches.baytrail/0199-drm-i915-release-scratch-page-at-module-unload.patch @@ -0,0 +1,30 @@ +From 855063179f42046e992a4c9be21c7d524c6c33f6 Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Wed, 22 May 2013 17:47:13 +0300 +Subject: drm/i915: release scratch page at module unload + +Signed-off-by: Imre Deak +Acked-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 6640aab6f2aed89470bc44c7450b7573659e651e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 57198f4bdf2c..0a61f6f6948d 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1758,6 +1758,8 @@ int i915_driver_unload(struct drm_device *dev) + destroy_workqueue(dev_priv->wq); + pm_qos_remove_request(&dev_priv->pm_qos); + ++ dev_priv->gtt.gtt_remove(dev); ++ + if (dev_priv->slab) + kmem_cache_destroy(dev_priv->slab); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0200-drm-i915-stop-using-is_cpu_edp-in-intel_disable-post.patch b/patches.baytrail/0200-drm-i915-stop-using-is_cpu_edp-in-intel_disable-post.patch new file mode 100644 index 000000000000..baccb7c57ce5 --- /dev/null +++ b/patches.baytrail/0200-drm-i915-stop-using-is_cpu_edp-in-intel_disable-post.patch @@ -0,0 +1,64 @@ +From 129dee5cd83f425ca16f18ac329b626f18711625 Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Thu, 23 May 2013 19:39:40 +0300 +Subject: drm/i915: stop using is_cpu_edp() in intel_disable/post_disable_dp + +Based on 3739850b46f - "drm/i915: disable the cpu edp port after the +cpu pipe" and the bspec disabling sequence for IVB and older it seems we +have to distinguish only the CPU vs. PCH port case, whether it's a DP or +eDP doesn't seem to matter. For IVB and older on the CPU side we can +only have eDP on port A, DP ports can only be on the PCH side. On VLV we +have only CPU side eDP/DP ports, no PCH. So the condition for the +disabling sequence we need for CPU ports is port == A || IS_VLV. + +This allows us to remove is_cpu_edp() completely in a later patch. + +v2: +- simplify (and fix) the condition for CPU side ports and adjust the + commit message accordingly (Daniel) + +Signed-off-by: Imre Deak +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 982a38667dd9f175f8dd8a78651426ae6baac463) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index e21d98621078..af8bca7f1745 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1392,6 +1392,8 @@ static void intel_dp_get_config(struct intel_encoder *encoder, + static void intel_disable_dp(struct intel_encoder *encoder) + { + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); ++ enum port port = dp_to_dig_port(intel_dp)->port; ++ struct drm_device *dev = encoder->base.dev; + + /* Make sure the panel is off before trying to change the mode. But also + * ensure that we have vdd while we switch off the panel. */ +@@ -1401,16 +1403,17 @@ static void intel_disable_dp(struct intel_encoder *encoder) + ironlake_edp_panel_off(intel_dp); + + /* cpu edp my only be disable _after_ the cpu pipe/plane is disabled. */ +- if (!is_cpu_edp(intel_dp)) ++ if (!(port == PORT_A || IS_VALLEYVIEW(dev))) + intel_dp_link_down(intel_dp); + } + + static void intel_post_disable_dp(struct intel_encoder *encoder) + { + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); ++ enum port port = dp_to_dig_port(intel_dp)->port; + struct drm_device *dev = encoder->base.dev; + +- if (is_cpu_edp(intel_dp)) { ++ if (port == PORT_A || IS_VALLEYVIEW(dev)) { + intel_dp_link_down(intel_dp); + if (!IS_VALLEYVIEW(dev)) + ironlake_edp_pll_off(intel_dp); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0201-drm-i915-merge-VLV-eDP-and-DP-AUX-clock-divider-calc.patch b/patches.baytrail/0201-drm-i915-merge-VLV-eDP-and-DP-AUX-clock-divider-calc.patch new file mode 100644 index 000000000000..5a73badf80fa --- /dev/null +++ b/patches.baytrail/0201-drm-i915-merge-VLV-eDP-and-DP-AUX-clock-divider-calc.patch @@ -0,0 +1,42 @@ +From 6bee0308a9bc75184521e11ae551a11d670f1ede Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Thu, 16 May 2013 14:40:35 +0300 +Subject: drm/i915: merge VLV eDP and DP AUX clock divider calculation + +On ValleyView for both eDP and DP the AUX input clock is 200MHz, so we +can calculate for both the clock divider for the 2MHz target rate at the +same place. Afterwards we can also replace the is_cpu_edp() check with a +check for port A. + +Signed-off-by: Imre Deak +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit a62d0834dee83994e41fcd0e5b7f10aad3d80de0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index af8bca7f1745..e1d39f2c70fe 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -317,12 +317,12 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, + * Note that PCH attached eDP panels should use a 125MHz input + * clock divider. + */ +- if (is_cpu_edp(intel_dp)) { ++ if (IS_VALLEYVIEW(dev)) { ++ aux_clock_divider = 100; ++ } else if (intel_dig_port->port == PORT_A) { + if (HAS_DDI(dev)) + aux_clock_divider = DIV_ROUND_CLOSEST( + intel_ddi_get_cdclk_freq(dev_priv), 2000); +- else if (IS_VALLEYVIEW(dev)) +- aux_clock_divider = 100; + else if (IS_GEN6(dev) || IS_GEN7(dev)) + aux_clock_divider = 200; /* SNB & IVB eDP input clock at 400Mhz */ + else +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0202-drm-i915-replace-is_cpu_edp-with-a-check-for-port-A.patch b/patches.baytrail/0202-drm-i915-replace-is_cpu_edp-with-a-check-for-port-A.patch new file mode 100644 index 000000000000..7f83d54ebec6 --- /dev/null +++ b/patches.baytrail/0202-drm-i915-replace-is_cpu_edp-with-a-check-for-port-A.patch @@ -0,0 +1,227 @@ +From 836f214d6b146aad6223fd821f97f214ccff155c Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Thu, 16 May 2013 14:40:36 +0300 +Subject: drm/i915: replace is_cpu_edp() with a check for port A + +The patch changes all remaining is_cpu_edp() check with a check for port +A. We can do this, since in all these cases ValleyView is handled +separately and port A is always a CPU side eDP port. + +Signed-off-by: Imre Deak +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit bc7d38a43ab1af4cad1c235c3aa30426b6c7d6c5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 49 +++++++++++++++++++++++------------------ + 1 file changed, 27 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index e1d39f2c70fe..63fa72d4a4c6 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -696,6 +696,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); ++ enum port port = dp_to_dig_port(intel_dp)->port; + struct intel_crtc *intel_crtc = encoder->new_crtc; + struct intel_connector *intel_connector = intel_dp->attached_connector; + int lane_count, clock; +@@ -705,7 +706,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, + static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; + int target_clock, link_avail, link_clock; + +- if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && !is_cpu_edp(intel_dp)) ++ if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A) + pipe_config->has_pch_encoder = true; + + pipe_config->has_dp_encoder = true; +@@ -848,6 +849,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); ++ enum port port = dp_to_dig_port(intel_dp)->port; + struct drm_crtc *crtc = encoder->crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + +@@ -888,7 +890,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + + /* Split out the IBX/CPU vs CPT settings */ + +- if (is_cpu_edp(intel_dp) && IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) { ++ if (port == PORT_A && IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) { + if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) + intel_dp->DP |= DP_SYNC_HS_HIGH; + if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) +@@ -905,7 +907,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + intel_dp->DP |= DP_PLL_FREQ_160MHZ; + else + intel_dp->DP |= DP_PLL_FREQ_270MHZ; +- } else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) { ++ } else if (!HAS_PCH_CPT(dev) || port == PORT_A) { + if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev)) + intel_dp->DP |= intel_dp->color_range; + +@@ -921,7 +923,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + if (intel_crtc->pipe == 1) + intel_dp->DP |= DP_PIPEB_SELECT; + +- if (is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) { ++ if (port == PORT_A && !IS_VALLEYVIEW(dev)) { + /* don't miss out required setting for eDP */ + if (adjusted_mode->clock < 200000) + intel_dp->DP |= DP_PLL_FREQ_160MHZ; +@@ -932,7 +934,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; + } + +- if (is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) ++ if (port == PORT_A && !IS_VALLEYVIEW(dev)) + ironlake_set_pll_edp(crtc, adjusted_mode->clock); + } + +@@ -1322,6 +1324,7 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, + enum pipe *pipe) + { + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); ++ enum port port = dp_to_dig_port(intel_dp)->port; + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 tmp = I915_READ(intel_dp->output_reg); +@@ -1329,9 +1332,9 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, + if (!(tmp & DP_PORT_EN)) + return false; + +- if (is_cpu_edp(intel_dp) && IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) { ++ if (port == PORT_A && IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) { + *pipe = PORT_TO_PIPE_CPT(tmp); +- } else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) { ++ } else if (!HAS_PCH_CPT(dev) || port == PORT_A) { + *pipe = PORT_TO_PIPE(tmp); + } else { + u32 trans_sel; +@@ -1451,14 +1454,14 @@ static void intel_enable_dp(struct intel_encoder *encoder) + static void intel_pre_enable_dp(struct intel_encoder *encoder) + { + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); ++ struct intel_digital_port *dport = dp_to_dig_port(intel_dp); + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + +- if (is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) ++ if (dport->port == PORT_A && !IS_VALLEYVIEW(dev)) + ironlake_edp_pll_on(intel_dp); + + if (IS_VALLEYVIEW(dev)) { +- struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); + struct intel_crtc *intel_crtc = + to_intel_crtc(encoder->base.crtc); + int port = vlv_dport_to_channel(dport); +@@ -1566,12 +1569,13 @@ static uint8_t + intel_dp_voltage_max(struct intel_dp *intel_dp) + { + struct drm_device *dev = intel_dp_to_dev(intel_dp); ++ enum port port = dp_to_dig_port(intel_dp)->port; + + if (IS_VALLEYVIEW(dev)) + return DP_TRAIN_VOLTAGE_SWING_1200; +- else if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) ++ else if (IS_GEN7(dev) && port == PORT_A) + return DP_TRAIN_VOLTAGE_SWING_800; +- else if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) ++ else if (HAS_PCH_CPT(dev) && port != PORT_A) + return DP_TRAIN_VOLTAGE_SWING_1200; + else + return DP_TRAIN_VOLTAGE_SWING_800; +@@ -1581,6 +1585,7 @@ static uint8_t + intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing) + { + struct drm_device *dev = intel_dp_to_dev(intel_dp); ++ enum port port = dp_to_dig_port(intel_dp)->port; + + if (HAS_DDI(dev)) { + switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { +@@ -1606,7 +1611,7 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing) + default: + return DP_TRAIN_PRE_EMPHASIS_0; + } +- } else if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) { ++ } else if (IS_GEN7(dev) && port == PORT_A) { + switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { + case DP_TRAIN_VOLTAGE_SWING_400: + return DP_TRAIN_PRE_EMPHASIS_6; +@@ -1893,6 +1898,7 @@ static void + intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP) + { + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); ++ enum port port = intel_dig_port->port; + struct drm_device *dev = intel_dig_port->base.base.dev; + uint32_t signal_levels, mask; + uint8_t train_set = intel_dp->train_set[0]; +@@ -1903,10 +1909,10 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP) + } else if (IS_VALLEYVIEW(dev)) { + signal_levels = intel_vlv_signal_levels(intel_dp); + mask = 0; +- } else if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) { ++ } else if (IS_GEN7(dev) && port == PORT_A) { + signal_levels = intel_gen7_edp_signal_levels(train_set); + mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB; +- } else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { ++ } else if (IS_GEN6(dev) && port == PORT_A) { + signal_levels = intel_gen6_edp_signal_levels(train_set); + mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB; + } else { +@@ -1956,8 +1962,7 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, + } + I915_WRITE(DP_TP_CTL(port), temp); + +- } else if (HAS_PCH_CPT(dev) && +- (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) { ++ } else if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || port != PORT_A)) { + dp_reg_value &= ~DP_LINK_TRAIN_MASK_CPT; + + switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { +@@ -2208,6 +2213,7 @@ static void + intel_dp_link_down(struct intel_dp *intel_dp) + { + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); ++ enum port port = intel_dig_port->port; + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = +@@ -2237,7 +2243,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) + + DRM_DEBUG_KMS("\n"); + +- if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) { ++ if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || port != PORT_A)) { + DP &= ~DP_LINK_TRAIN_MASK_CPT; + I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); + } else { +@@ -2964,9 +2970,6 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, + pp_div_reg = PIPEA_PP_DIVISOR; + } + +- if (IS_VALLEYVIEW(dev)) +- port_sel = I915_READ(pp_on_reg) & 0xc0000000; +- + /* And finally store the new values in the power sequencer. */ + pp_on = (seq->t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) | + (seq->t8 << PANEL_LIGHT_ON_DELAY_SHIFT); +@@ -2980,8 +2983,10 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, + + /* Haswell doesn't have any port selection bits for the panel + * power sequencer any more. */ +- if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) { +- if (is_cpu_edp(intel_dp)) ++ if (IS_VALLEYVIEW(dev)) { ++ port_sel = I915_READ(pp_on_reg) & 0xc0000000; ++ } else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) { ++ if (dp_to_dig_port(intel_dp)->port == PORT_A) + port_sel = PANEL_POWER_PORT_DP_A; + else + port_sel = PANEL_POWER_PORT_DP_D; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0203-drm-i915-remove-unused-is_cpu_edp.patch b/patches.baytrail/0203-drm-i915-remove-unused-is_cpu_edp.patch new file mode 100644 index 000000000000..547d4fa930ed --- /dev/null +++ b/patches.baytrail/0203-drm-i915-remove-unused-is_cpu_edp.patch @@ -0,0 +1,44 @@ +From 30435b091bdc92ea845f44db5ae794ce577b1d7a Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Thu, 16 May 2013 14:40:37 +0300 +Subject: drm/i915: remove unused is_cpu_edp() + +Signed-off-by: Imre Deak +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 55aab33e898eb61d6187b18c2446e2cb1b06b910) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 16 ---------------- + 1 file changed, 16 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 63fa72d4a4c6..be862039eeab 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -59,22 +59,6 @@ static struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp) + return intel_dig_port->base.base.dev; + } + +-/** +- * is_cpu_edp - is the port on the CPU and attached to an eDP panel? +- * @intel_dp: DP struct +- * +- * Returns true if the given DP struct corresponds to a CPU eDP port. +- */ +-static bool is_cpu_edp(struct intel_dp *intel_dp) +-{ +- struct drm_device *dev = intel_dp_to_dev(intel_dp); +- struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); +- enum port port = intel_dig_port->port; +- +- return is_edp(intel_dp) && +- (port == PORT_A || (port == PORT_C && IS_VALLEYVIEW(dev))); +-} +- + static struct intel_dp *intel_attached_dp(struct drm_connector *connector) + { + return enc_to_intel_dp(&intel_attached_encoder(connector)->base); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0204-drm-i915-fixup-i915_pipe_enabled-check-in-i915_irq.c.patch b/patches.baytrail/0204-drm-i915-fixup-i915_pipe_enabled-check-in-i915_irq.c.patch new file mode 100644 index 000000000000..c5d114c22327 --- /dev/null +++ b/patches.baytrail/0204-drm-i915-fixup-i915_pipe_enabled-check-in-i915_irq.c.patch @@ -0,0 +1,74 @@ +From 2267c95ec73c45ff5cd2749df882bcfb3d20c8c2 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 22 May 2013 00:50:23 +0200 +Subject: drm/i915: fixup i915_pipe_enabled check in i915_irq.c + +Well, as well as we can without completely revamping the drm vblank +code. The issue are that +- The vblank code needs to work on both ums and kms. +- It deals always deals with pipes. +- It doesn't take any of the kms locks. + +The last part is not really fixable without revamping the drm vblank +code, since the drm core <-> driver interactions is a veritable pile +of spaghettis. But the other pieces can be fixed by switching on the +MODESET driver flag and either checking the hw state directly (ums +case) or just querying our sw tracking (with broken locking, but +that's not worse than what we've had). + +Note that this essentially reverts + +commit 702e7a56af3780d8b3a717f698209bef44187bb0 +Author: Paulo Zanoni +Date: Tue Oct 23 18:29:59 2012 -0200 + + drm/i915: convert PIPECONF to use transcoder instead of pipe + +for the ums case, which will fix a NULL deref (since we really don't +have any crtcs set up). + +But the real reason to do this is to drop our reliance on the +cpu_transcoder: By only checking intel_crtc->active we don't need to +make sure that the pipe_config (or at least the cpu_transcoder) +contain safe values even when the pipe is off. + +Cc: Paulo Zanoni +Cc: Damien Lespiau +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit a01025afa89ccaf1b0521f5862cbfcc73f970481) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index e8b5d548230e..c0d9f876a690 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -372,14 +372,16 @@ static int + i915_pipe_enabled(struct drm_device *dev, int pipe) + { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +- enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, +- pipe); + +- if (!intel_display_power_enabled(dev, +- POWER_DOMAIN_TRANSCODER(cpu_transcoder))) +- return false; ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ /* Locking is horribly broken here, but whatever. */ ++ struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + +- return I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE; ++ return intel_crtc->active; ++ } else { ++ return I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE; ++ } + } + + /* Called from drm generic code, passed a 'crtc', which +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0205-drm-i915-hw-state-readout-check-support-for-cpu_tran.patch b/patches.baytrail/0205-drm-i915-hw-state-readout-check-support-for-cpu_tran.patch new file mode 100644 index 000000000000..47ff673d6850 --- /dev/null +++ b/patches.baytrail/0205-drm-i915-hw-state-readout-check-support-for-cpu_tran.patch @@ -0,0 +1,266 @@ +From febaa9a7bcf2b55e774a617e247cff437b25999f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 22 May 2013 00:50:22 +0200 +Subject: drm/i915: hw state readout&check support for cpu_transcoder + +This allows us to drop a bunch of ugly hacks and finally implement +what + +commit cc464b2a17c59adedbdc02cc54341d630354edc3 +Author: Paulo Zanoni +Date: Fri Jan 25 16:59:16 2013 -0200 + + drm/i915: set TRANSCODER_EDP even earlier + +tried to achieve, but that was reverted again in + +commit bba2181c49f1dddf8b592804a1b53cc1a3cf408a +Author: Daniel Vetter +Date: Fri Mar 22 10:53:40 2013 +0100 + + Revert "drm/i915: set TRANSCODER_EDP even earlier" + +Now we should always have a consistent cpu_transcoder in the +pipe_config. + +v2: Fix up the code as spotted by Paulo: +- read the register for real +- assign the right pipes +- break out if the hw state doesn't make sense + +v3: Shut up gcc. + +Cc: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit eccb140bca6727f2ef849e8811d5fe4c9fbfd5dd) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 4 ++ + drivers/gpu/drm/i915/intel_display.c | 90 +++++++++++++----------------------- + 2 files changed, 37 insertions(+), 57 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 418b91c28ed6..74b372dc14a4 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -1292,9 +1292,13 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) + { + int type = encoder->type; ++ int port = intel_ddi_get_encoder_port(encoder); + + WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); + ++ if (port == PORT_A) ++ pipe_config->cpu_transcoder = TRANSCODER_EDP; ++ + if (type == INTEL_OUTPUT_HDMI) + return intel_hdmi_compute_config(encoder, pipe_config); + else +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 0159fe522d0d..371cd327b6ea 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3469,12 +3469,6 @@ static void ironlake_crtc_off(struct drm_crtc *crtc) + + static void haswell_crtc_off(struct drm_crtc *crtc) + { +- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- +- /* Stop saying we're using TRANSCODER_EDP because some other CRTC might +- * start using it. */ +- intel_crtc->config.cpu_transcoder = (enum transcoder) intel_crtc->pipe; +- + intel_ddi_put_crtc_pll(crtc); + } + +@@ -4925,6 +4919,8 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t tmp; + ++ pipe_config->cpu_transcoder = crtc->pipe; ++ + tmp = I915_READ(PIPECONF(crtc->pipe)); + if (!(tmp & PIPECONF_ENABLE)) + return false; +@@ -5647,8 +5643,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)), + "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev)); + +- intel_crtc->config.cpu_transcoder = pipe; +- + ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock, + &has_reduced_clock, &reduced_clock); + if (!ok) { +@@ -5784,6 +5778,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t tmp; + ++ pipe_config->cpu_transcoder = crtc->pipe; ++ + tmp = I915_READ(PIPECONF(crtc->pipe)); + if (!(tmp & PIPECONF_ENABLE)) + return false; +@@ -5860,11 +5856,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + num_connectors++; + } + +- if (is_cpu_edp) +- intel_crtc->config.cpu_transcoder = TRANSCODER_EDP; +- else +- intel_crtc->config.cpu_transcoder = pipe; +- + /* We are not sure yet this won't happen. */ + WARN(!HAS_PCH_LPT(dev), "Unexpected PCH type %d\n", + INTEL_PCH_TYPE(dev)); +@@ -5918,15 +5909,37 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + { + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- enum transcoder cpu_transcoder = crtc->config.cpu_transcoder; + enum intel_display_power_domain pfit_domain; + uint32_t tmp; + ++ pipe_config->cpu_transcoder = crtc->pipe; ++ tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); ++ if (tmp & TRANS_DDI_FUNC_ENABLE) { ++ enum pipe trans_edp_pipe; ++ switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { ++ default: ++ WARN(1, "unknown pipe linked to edp transcoder\n"); ++ case TRANS_DDI_EDP_INPUT_A_ONOFF: ++ case TRANS_DDI_EDP_INPUT_A_ON: ++ trans_edp_pipe = PIPE_A; ++ break; ++ case TRANS_DDI_EDP_INPUT_B_ONOFF: ++ trans_edp_pipe = PIPE_B; ++ break; ++ case TRANS_DDI_EDP_INPUT_C_ONOFF: ++ trans_edp_pipe = PIPE_C; ++ break; ++ } ++ ++ if (trans_edp_pipe == crtc->pipe) ++ pipe_config->cpu_transcoder = TRANSCODER_EDP; ++ } ++ + if (!intel_display_power_enabled(dev, +- POWER_DOMAIN_TRANSCODER(cpu_transcoder))) ++ POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder))) + return false; + +- tmp = I915_READ(PIPECONF(cpu_transcoder)); ++ tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder)); + if (!(tmp & PIPECONF_ENABLE)) + return false; + +@@ -5935,7 +5948,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + * DDI E. So just check whether this pipe is wired to DDI E and whether + * the PCH transcoder is on. + */ +- tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); ++ tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder)); + if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(PORT_E) && + I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) { + pipe_config->has_pch_encoder = true; +@@ -7694,6 +7707,7 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, + + drm_mode_copy(&pipe_config->adjusted_mode, mode); + drm_mode_copy(&pipe_config->requested_mode, mode); ++ pipe_config->cpu_transcoder = to_intel_crtc(crtc)->pipe; + + plane_bpp = pipe_config_set_bpp(crtc, fb, pipe_config); + if (plane_bpp < 0) +@@ -7944,6 +7958,8 @@ intel_pipe_config_compare(struct drm_device *dev, + return false; \ + } + ++ PIPE_CONF_CHECK_I(cpu_transcoder); ++ + PIPE_CONF_CHECK_I(has_pch_encoder); + PIPE_CONF_CHECK_I(fdi_lanes); + PIPE_CONF_CHECK_I(fdi_m_n.gmch_m); +@@ -8095,7 +8111,6 @@ intel_modeset_check_state(struct drm_device *dev) + "crtc's computed enabled state doesn't match tracked enabled state " + "(expected %i, found %i)\n", enabled, crtc->base.enabled); + +- pipe_config.cpu_transcoder = crtc->config.cpu_transcoder; + active = dev_priv->display.get_pipe_config(crtc, + &pipe_config); + +@@ -8163,12 +8178,10 @@ static int __intel_set_mode(struct drm_crtc *crtc, + * to set it here already despite that we pass it down the callchain. + */ + if (modeset_pipes) { +- enum transcoder tmp = to_intel_crtc(crtc)->config.cpu_transcoder; + crtc->mode = *mode; + /* mode_set/enable/disable functions rely on a correct pipe + * config. */ + to_intel_crtc(crtc)->config = *pipe_config; +- to_intel_crtc(crtc)->config.cpu_transcoder = tmp; + } + + /* Only after disabling all output pipelines that will be changed can we +@@ -8597,7 +8610,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) + /* Swap pipes & planes for FBC on pre-965 */ + intel_crtc->pipe = pipe; + intel_crtc->plane = pipe; +- intel_crtc->config.cpu_transcoder = pipe; + if (IS_MOBILE(dev) && IS_GEN3(dev)) { + DRM_DEBUG_KMS("swapping pipes & planes for FBC\n"); + intel_crtc->plane = !pipe; +@@ -9483,50 +9495,14 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, + { + struct drm_i915_private *dev_priv = dev->dev_private; + enum pipe pipe; +- u32 tmp; + struct drm_plane *plane; + struct intel_crtc *crtc; + struct intel_encoder *encoder; + struct intel_connector *connector; + +- if (HAS_DDI(dev)) { +- tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); +- +- if (tmp & TRANS_DDI_FUNC_ENABLE) { +- switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { +- case TRANS_DDI_EDP_INPUT_A_ON: +- case TRANS_DDI_EDP_INPUT_A_ONOFF: +- pipe = PIPE_A; +- break; +- case TRANS_DDI_EDP_INPUT_B_ONOFF: +- pipe = PIPE_B; +- break; +- case TRANS_DDI_EDP_INPUT_C_ONOFF: +- pipe = PIPE_C; +- break; +- default: +- /* A bogus value has been programmed, disable +- * the transcoder */ +- WARN(1, "Bogus eDP source %08x\n", tmp); +- intel_ddi_disable_transcoder_func(dev_priv, +- TRANSCODER_EDP); +- goto setup_pipes; +- } +- +- crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); +- crtc->config.cpu_transcoder = TRANSCODER_EDP; +- +- DRM_DEBUG_KMS("Pipe %c using transcoder EDP\n", +- pipe_name(pipe)); +- } +- } +- +-setup_pipes: + list_for_each_entry(crtc, &dev->mode_config.crtc_list, + base.head) { +- enum transcoder tmp = crtc->config.cpu_transcoder; + memset(&crtc->config, 0, sizeof(crtc->config)); +- crtc->config.cpu_transcoder = tmp; + + crtc->active = dev_priv->display.get_pipe_config(crtc, + &crtc->config); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0206-drm-i915-document-why-dvo-sdvo-crt-need-a-special-dp.patch b/patches.baytrail/0206-drm-i915-document-why-dvo-sdvo-crt-need-a-special-dp.patch new file mode 100644 index 000000000000..1e47f30bfd04 --- /dev/null +++ b/patches.baytrail/0206-drm-i915-document-why-dvo-sdvo-crt-need-a-special-dp.patch @@ -0,0 +1,89 @@ +From 00e7394f71082ea6359da0cea8cbd461bfaf0bb3 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 28 May 2013 12:35:02 +0300 +Subject: drm/i915: document why dvo/sdvo/crt need a special dpms function + +In the cloned case, changing just one output but keeping the other, the +pipe state won't change and intel_crtc_update_dpms will be a nop, but we +still need to update the dpms state of the output being changed. + +Only dvo, sdvo and crt are cloneable, so only those three have special +dpms functions. + +Signed-off-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 6b1c087ba5789aceb25a2170b217055ce2476f67) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_crt.c | 4 +++- + drivers/gpu/drm/i915/intel_dvo.c | 3 +++ + drivers/gpu/drm/i915/intel_sdvo.c | 3 +++ + 3 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c +index 5e9f93e53255..3acec8c48166 100644 +--- a/drivers/gpu/drm/i915/intel_crt.c ++++ b/drivers/gpu/drm/i915/intel_crt.c +@@ -149,7 +149,7 @@ static void intel_enable_crt(struct intel_encoder *encoder) + intel_crt_set_dpms(encoder, crt->connector->base.dpms); + } + +- ++/* Special dpms function to support cloning between dvo/sdvo/crt. */ + static void intel_crt_dpms(struct drm_connector *connector, int mode) + { + struct drm_device *dev = connector->dev; +@@ -180,6 +180,8 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode) + else + encoder->connectors_active = true; + ++ /* We call connector dpms manually below in case pipe dpms doesn't ++ * change due to cloning. */ + if (mode < old_dpms) { + /* From off to on, enable the pipe first. */ + intel_crtc_update_dpms(crtc); +diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c +index 9e80d487b5cb..eb2020eb2b7e 100644 +--- a/drivers/gpu/drm/i915/intel_dvo.c ++++ b/drivers/gpu/drm/i915/intel_dvo.c +@@ -180,6 +180,7 @@ static void intel_enable_dvo(struct intel_encoder *encoder) + intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true); + } + ++/* Special dpms function to support cloning between dvo/sdvo/crt. */ + static void intel_dvo_dpms(struct drm_connector *connector, int mode) + { + struct intel_dvo *intel_dvo = intel_attached_dvo(connector); +@@ -201,6 +202,8 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode) + return; + } + ++ /* We call connector dpms manually below in case pipe dpms doesn't ++ * change due to cloning. */ + if (mode == DRM_MODE_DPMS_ON) { + intel_dvo->base.connectors_active = true; + +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index f8ad93bd7d9b..c55841937705 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1416,6 +1416,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder) + intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); + } + ++/* Special dpms function to support cloning between dvo/sdvo/crt. */ + static void intel_sdvo_dpms(struct drm_connector *connector, int mode) + { + struct drm_crtc *crtc; +@@ -1437,6 +1438,8 @@ static void intel_sdvo_dpms(struct drm_connector *connector, int mode) + return; + } + ++ /* We set active outputs manually below in case pipe dpms doesn't change ++ * due to cloning. */ + if (mode != DRM_MODE_DPMS_ON) { + intel_sdvo_set_active_outputs(intel_sdvo, 0); + if (0) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0207-drm-i915-fix-error-return-code-in-init_pipe_control.patch b/patches.baytrail/0207-drm-i915-fix-error-return-code-in-init_pipe_control.patch new file mode 100644 index 000000000000..c76f37481971 --- /dev/null +++ b/patches.baytrail/0207-drm-i915-fix-error-return-code-in-init_pipe_control.patch @@ -0,0 +1,37 @@ +From b3cc024df0a7453c1488487b84bd3008975cc068 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Tue, 28 May 2013 17:51:44 +0800 +Subject: drm/i915: fix error return code in init_pipe_control() + +Fix to return -ENOMEM in the kmap() error handling case +instead of 0, as done elsewhere in this function. + +Signed-off-by: Wei Yongjun +Signed-off-by: Daniel Vetter +(cherry picked from commit 56b085a01befc7907d270e9acb349580015e7bad) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ringbuffer.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index df0b7c7ac166..4295400a39ac 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -464,9 +464,11 @@ init_pipe_control(struct intel_ring_buffer *ring) + goto err_unref; + + pc->gtt_offset = obj->gtt_offset; +- pc->cpu_page = kmap(sg_page(obj->pages->sgl)); +- if (pc->cpu_page == NULL) ++ pc->cpu_page = kmap(sg_page(obj->pages->sgl)); ++ if (pc->cpu_page == NULL) { ++ ret = -ENOMEM; + goto err_unpin; ++ } + + DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n", + ring->name, pc->gtt_offset); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0208-drm-i915-add-basic-pipe-config-dump-support.patch b/patches.baytrail/0208-drm-i915-add-basic-pipe-config-dump-support.patch new file mode 100644 index 000000000000..8f2a56ace559 --- /dev/null +++ b/patches.baytrail/0208-drm-i915-add-basic-pipe-config-dump-support.patch @@ -0,0 +1,183 @@ +From c93c0760b4b29502316c5e76138699cdb6e5644e Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 28 May 2013 12:05:54 +0200 +Subject: drm/i915: add basic pipe config dump support + +All this pipe config abstraction adds another layer of complexity, so +it's good to have better visibility into what's going on exactly. +Doesn't dump out everything yet, and some bits are a bit duplicated +but this should be a good start. + +Note that at boot-up a lot of the fields are 0 even for enabled pipes, +this is simply because our hw state readout code doesn't support +everything. + +v2: Remove a few more now redudant debug output lines. + +v3: Review from Paulo +- use transcoder_name +- fix up format specifiers +- add missing ':' in debug output + +Cc: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit c0b0341121f2e2b329e60986aee766e4d1d80fde) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 74 +++++++++++++++++++++--------------- + 1 file changed, 44 insertions(+), 30 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 371cd327b6ea..c953cc46f208 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3523,18 +3523,12 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc) + if (!crtc->config.gmch_pfit.control) + return; + +- WARN_ON(I915_READ(PFIT_CONTROL) & PFIT_ENABLE); +- assert_pipe_disabled(dev_priv, crtc->pipe); +- + /* +- * Enable automatic panel scaling so that non-native modes +- * fill the screen. The panel fitter should only be +- * adjusted whilst the pipe is disabled, according to +- * register description and PRM. ++ * The panel fitter should only be adjusted whilst the pipe is disabled, ++ * according to register description and PRM. + */ +- DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", +- pipe_config->gmch_pfit.control, +- pipe_config->gmch_pfit.pgm_ratios); ++ WARN_ON(I915_READ(PFIT_CONTROL) & PFIT_ENABLE); ++ assert_pipe_disabled(dev_priv, crtc->pipe); + + I915_WRITE(PFIT_PGM_RATIOS, pipe_config->gmch_pfit.pgm_ratios); + I915_WRITE(PFIT_CONTROL, pipe_config->gmch_pfit.control); +@@ -4857,9 +4851,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + dspcntr |= DISPPLANE_SEL_PIPE_B; + } + +- DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe_name(pipe)); +- drm_mode_debug_printmodeline(mode); +- + intel_set_pipe_timings(intel_crtc, mode, adjusted_mode); + + /* pipesrc and dspsize control the size that is scaled from, +@@ -5661,9 +5652,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + /* Ensure that the cursor is valid for the new mode before changing... */ + intel_crtc_update_cursor(crtc, true); + +- DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe_name(pipe)); +- drm_mode_debug_printmodeline(mode); +- + /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ + if (intel_crtc->config.has_pch_encoder) { + struct intel_pch_pll *pll; +@@ -5874,9 +5862,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + /* Ensure that the cursor is valid for the new mode before changing... */ + intel_crtc_update_cursor(crtc, true); + +- DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe_name(pipe)); +- drm_mode_debug_printmodeline(mode); +- + if (intel_crtc->config.has_dp_encoder) + intel_dp_set_m_n(intel_crtc); + +@@ -7689,6 +7674,35 @@ pipe_config_set_bpp(struct drm_crtc *crtc, + return bpp; + } + ++static void intel_dump_pipe_config(struct intel_crtc *crtc, ++ struct intel_crtc_config *pipe_config, ++ const char *context) ++{ ++ DRM_DEBUG_KMS("[CRTC:%d]%s config for pipe %c\n", crtc->base.base.id, ++ context, pipe_name(crtc->pipe)); ++ ++ DRM_DEBUG_KMS("cpu_transcoder: %c\n", transcoder_name(pipe_config->cpu_transcoder)); ++ DRM_DEBUG_KMS("pipe bpp: %i, dithering: %i\n", ++ pipe_config->pipe_bpp, pipe_config->dither); ++ DRM_DEBUG_KMS("fdi/pch: %i, lanes: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n", ++ pipe_config->has_pch_encoder, ++ pipe_config->fdi_lanes, ++ pipe_config->fdi_m_n.gmch_m, pipe_config->fdi_m_n.gmch_n, ++ pipe_config->fdi_m_n.link_m, pipe_config->fdi_m_n.link_n, ++ pipe_config->fdi_m_n.tu); ++ DRM_DEBUG_KMS("requested mode:\n"); ++ drm_mode_debug_printmodeline(&pipe_config->requested_mode); ++ DRM_DEBUG_KMS("adjusted mode:\n"); ++ drm_mode_debug_printmodeline(&pipe_config->adjusted_mode); ++ DRM_DEBUG_KMS("gmch pfit: control: 0x%08x, ratios: 0x%08x, lvds border: 0x%08x\n", ++ pipe_config->gmch_pfit.control, ++ pipe_config->gmch_pfit.pgm_ratios, ++ pipe_config->gmch_pfit.lvds_border_bits); ++ DRM_DEBUG_KMS("pch pfit: pos: 0x%08x, size: 0x%08x\n", ++ pipe_config->pch_pfit.pos, ++ pipe_config->pch_pfit.size); ++} ++ + static struct intel_crtc_config * + intel_modeset_pipe_config(struct drm_crtc *crtc, + struct drm_framebuffer *fb, +@@ -7759,8 +7773,6 @@ encoder_retry: + goto encoder_retry; + } + +- DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); +- + pipe_config->dither = pipe_config->pipe_bpp != plane_bpp; + DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n", + plane_bpp, pipe_config->pipe_bpp, pipe_config->dither); +@@ -8122,9 +8134,14 @@ intel_modeset_check_state(struct drm_device *dev) + "crtc active state doesn't match with hw state " + "(expected %i, found %i)\n", crtc->active, active); + +- WARN(active && +- !intel_pipe_config_compare(dev, &crtc->config, &pipe_config), +- "pipe state doesn't match!\n"); ++ if (active && ++ !intel_pipe_config_compare(dev, &crtc->config, &pipe_config)) { ++ WARN(1, "pipe state doesn't match!\n"); ++ intel_dump_pipe_config(crtc, &pipe_config, ++ "[hw state]"); ++ intel_dump_pipe_config(crtc, &crtc->config, ++ "[sw state]"); ++ } + } + } + +@@ -8164,6 +8181,8 @@ static int __intel_set_mode(struct drm_crtc *crtc, + + goto out; + } ++ intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, ++ "[modeset]"); + } + + for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc) +@@ -8523,12 +8542,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set) + goto fail; + + if (config->mode_changed) { +- if (set->mode) { +- DRM_DEBUG_KMS("attempting to set mode from" +- " userspace\n"); +- drm_mode_debug_printmodeline(set->mode); +- } +- + ret = intel_set_mode(set->crtc, set->mode, + set->x, set->y, set->fb); + } else if (config->fb_changed) { +@@ -9563,6 +9576,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, + for_each_pipe(pipe) { + crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); + intel_sanitize_crtc(crtc); ++ intel_dump_pipe_config(crtc, &crtc->config, "[setup_hw_state]"); + } + + if (force_restore) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0209-drm-i915-drop-a-few-really-redundant-WARNs-in-hsw-mo.patch b/patches.baytrail/0209-drm-i915-drop-a-few-really-redundant-WARNs-in-hsw-mo.patch new file mode 100644 index 000000000000..f8d129940533 --- /dev/null +++ b/patches.baytrail/0209-drm-i915-drop-a-few-really-redundant-WARNs-in-hsw-mo.patch @@ -0,0 +1,46 @@ +From 32790092e61aa6de3df314cc35a74f524ac314e1 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 28 May 2013 16:28:55 +0200 +Subject: drm/i915: drop a few really redundant WARNs in hsw mode_set + +- Correct cpu->pch display matching is already check when we detect + the PCH type at driver load. +- Plane/pipe state is already checked both when a) enabling, b) + disabling and in c) the modeset state checker. No need to go + overboard and also check it in in between a) and b). + +Cc: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 64eae94134d2fd0a0f1cf2162fb91e46da4ec75f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index c953cc46f208..77f6784e2128 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5844,18 +5844,9 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + num_connectors++; + } + +- /* We are not sure yet this won't happen. */ +- WARN(!HAS_PCH_LPT(dev), "Unexpected PCH type %d\n", +- INTEL_PCH_TYPE(dev)); +- + WARN(num_connectors != 1, "%d connectors attached to pipe %c\n", + num_connectors, pipe_name(pipe)); + +- WARN_ON(I915_READ(PIPECONF(intel_crtc->config.cpu_transcoder)) & +- (PIPECONF_ENABLE | I965_PIPECONF_ACTIVE)); +- +- WARN_ON(I915_READ(DSPCNTR(plane)) & DISPLAY_PLANE_ENABLE); +- + if (!intel_ddi_pll_mode_set(crtc, adjusted_mode->clock)) + return -EINVAL; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0210-drm-i915-Avoid-promoting-a-simulated-hang-to-wedged.patch b/patches.baytrail/0210-drm-i915-Avoid-promoting-a-simulated-hang-to-wedged.patch new file mode 100644 index 000000000000..051703d85ba6 --- /dev/null +++ b/patches.baytrail/0210-drm-i915-Avoid-promoting-a-simulated-hang-to-wedged.patch @@ -0,0 +1,111 @@ +From 01654de70fb4664215a98b55e0d8746cd81aa08e Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Tue, 28 May 2013 10:38:44 +0100 +Subject: drm/i915: Avoid promoting a simulated hang to 'wedged' + +It appears that a beneficial side-effect of Mika's more accurate hangman +work is to speed up hang detection and execution. This exposes a bug in +the reset code that then treats repeated simulated hangs as an +indication that the machine is wedged. Jiggle the code around so that we +only do the simulation processing from the hangcheck and avoid confusing +it with a real hang. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65060 +Signed-off-by: Chris Wilson +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 2e7c8ee7a6bf3440478120f14cbf597d416f88b2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 55 +++++++++++++++++------------------------ + 1 file changed, 23 insertions(+), 32 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index daf727e79ded..94492d1cdb0c 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -863,37 +863,14 @@ static int gen6_do_reset(struct drm_device *dev) + + int intel_gpu_reset(struct drm_device *dev) + { +- struct drm_i915_private *dev_priv = dev->dev_private; +- int ret = -ENODEV; +- + switch (INTEL_INFO(dev)->gen) { + case 7: +- case 6: +- ret = gen6_do_reset(dev); +- break; +- case 5: +- ret = ironlake_do_reset(dev); +- break; +- case 4: +- ret = i965_do_reset(dev); +- break; +- case 2: +- ret = i8xx_do_reset(dev); +- break; +- } +- +- /* Also reset the gpu hangman. */ +- if (dev_priv->gpu_error.stop_rings) { +- DRM_INFO("Simulated gpu hang, resetting stop_rings\n"); +- dev_priv->gpu_error.stop_rings = 0; +- if (ret == -ENODEV) { +- DRM_ERROR("Reset not implemented, but ignoring " +- "error for simulated gpu hangs\n"); +- ret = 0; +- } ++ case 6: return gen6_do_reset(dev); ++ case 5: return ironlake_do_reset(dev); ++ case 4: return i965_do_reset(dev); ++ case 2: return i8xx_do_reset(dev); ++ default: return -ENODEV; + } +- +- return ret; + } + + /** +@@ -914,6 +891,7 @@ int intel_gpu_reset(struct drm_device *dev) + int i915_reset(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; ++ bool simulated; + int ret; + + if (!i915_try_reset) +@@ -923,13 +901,26 @@ int i915_reset(struct drm_device *dev) + + i915_gem_reset(dev); + +- ret = -ENODEV; +- if (get_seconds() - dev_priv->gpu_error.last_reset < 5) ++ simulated = dev_priv->gpu_error.stop_rings != 0; ++ ++ if (!simulated && get_seconds() - dev_priv->gpu_error.last_reset < 5) { + DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); +- else ++ ret = -ENODEV; ++ } else { + ret = intel_gpu_reset(dev); + +- dev_priv->gpu_error.last_reset = get_seconds(); ++ /* Also reset the gpu hangman. */ ++ if (simulated) { ++ DRM_INFO("Simulated gpu hang, resetting stop_rings\n"); ++ dev_priv->gpu_error.stop_rings = 0; ++ if (ret == -ENODEV) { ++ DRM_ERROR("Reset not implemented, but ignoring " ++ "error for simulated gpu hangs\n"); ++ ret = 0; ++ } ++ } else ++ dev_priv->gpu_error.last_reset = get_seconds(); ++ } + if (ret) { + DRM_ERROR("Failed to reset chip.\n"); + mutex_unlock(&dev->struct_mutex); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0211-drm-i915-release-cursor-when-crtc-is-destroyed.patch b/patches.baytrail/0211-drm-i915-release-cursor-when-crtc-is-destroyed.patch new file mode 100644 index 000000000000..6612d90d79dc --- /dev/null +++ b/patches.baytrail/0211-drm-i915-release-cursor-when-crtc-is-destroyed.patch @@ -0,0 +1,57 @@ +From 725a57ca50b050fa405c96ae6b8e61e13f07f6cf Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Tue, 23 Apr 2013 17:27:08 +0300 +Subject: drm/i915: release cursor when crtc is destroyed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +crtc is holding a reference to a cursor bo and it needs +to be released when crtc is destroyed so that we don't leak +the cursor bo. + +v2: Enhance set and move cursor so that disabled +cursor is handled correctly (Ville Syrjälä) + +Signed-off-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 40ccc72b84a848e6fcbdb38fe716f0ac6939609e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 77f6784e2128..959ebc7a8283 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -6513,7 +6513,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, + intel_crtc->cursor_width = width; + intel_crtc->cursor_height = height; + +- intel_crtc_update_cursor(crtc, true); ++ intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL); + + return 0; + fail_unpin: +@@ -6532,7 +6532,7 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) + intel_crtc->cursor_x = x; + intel_crtc->cursor_y = y; + +- intel_crtc_update_cursor(crtc, true); ++ intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL); + + return 0; + } +@@ -7046,6 +7046,8 @@ static void intel_crtc_destroy(struct drm_crtc *crtc) + kfree(work); + } + ++ intel_crtc_cursor_set(crtc, NULL, 0, 0, 0); ++ + drm_crtc_cleanup(crtc); + + kfree(intel_crtc); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0212-drm-i915-Comments-for-semaphore-clarification.patch b/patches.baytrail/0212-drm-i915-Comments-for-semaphore-clarification.patch new file mode 100644 index 000000000000..cda2ca5645e3 --- /dev/null +++ b/patches.baytrail/0212-drm-i915-Comments-for-semaphore-clarification.patch @@ -0,0 +1,111 @@ +From 5220eb4fdd65f13a5012aa077214ae80604e8467 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:17 -0700 +Subject: drm/i915: Comments for semaphore clarification + +Semaphores are tied very closely to the rings in the GPU. Trivial patch +adds comments to the existing code so that when we add new rings we can +include comments there as well. It also helps distinguish the ring to +semaphore mailbox interactions by using the ringname in the semaphore +data structures. + +This patch should have no functional impact. + +v2: The English parts (as opposed to register names) of the comments +were reversed. (Damien) + +Signed-off-by: Ben Widawsky +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 5586181fce2b2e89a0e281d78ffbdfa103bb0dde) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 12 ++++++------ + drivers/gpu/drm/i915/intel_ringbuffer.c | 18 +++++++++--------- + drivers/gpu/drm/i915/intel_ringbuffer.h | 4 ++-- + 3 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index e29e9b17690c..f56c30ef40c8 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -265,12 +265,12 @@ + #define MI_SEMAPHORE_UPDATE (1<<21) + #define MI_SEMAPHORE_COMPARE (1<<20) + #define MI_SEMAPHORE_REGISTER (1<<18) +-#define MI_SEMAPHORE_SYNC_RV (2<<16) +-#define MI_SEMAPHORE_SYNC_RB (0<<16) +-#define MI_SEMAPHORE_SYNC_VR (0<<16) +-#define MI_SEMAPHORE_SYNC_VB (2<<16) +-#define MI_SEMAPHORE_SYNC_BR (2<<16) +-#define MI_SEMAPHORE_SYNC_BV (0<<16) ++#define MI_SEMAPHORE_SYNC_RB (0<<16) /* BCS wait for RCS (BRSYNC) */ ++#define MI_SEMAPHORE_SYNC_RV (2<<16) /* VCS wait for RCS (VRSYNC) */ ++#define MI_SEMAPHORE_SYNC_VR (0<<16) /* RCS wait for VCS (RVSYNC) */ ++#define MI_SEMAPHORE_SYNC_VB (2<<16) /* BCS wait for VCS (BVSYNC) */ ++#define MI_SEMAPHORE_SYNC_BV (0<<16) /* VCS wait for BCS (VBSYNC) */ ++#define MI_SEMAPHORE_SYNC_BR (2<<16) /* RCS wait for BCS (RBSYNC) */ + #define MI_SEMAPHORE_SYNC_INVALID (1<<0) + /* + * 3D instructions used by the kernel +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 4295400a39ac..ef64bb3e847c 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -1682,9 +1682,9 @@ int intel_init_render_ring_buffer(struct drm_device *dev) + ring->get_seqno = gen6_ring_get_seqno; + ring->set_seqno = ring_set_seqno; + ring->sync_to = gen6_ring_sync; +- ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_INVALID; +- ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_RV; +- ring->semaphore_register[2] = MI_SEMAPHORE_SYNC_RB; ++ ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_INVALID; ++ ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_RV; ++ ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_RB; + ring->signal_mbox[0] = GEN6_VRSYNC; + ring->signal_mbox[1] = GEN6_BRSYNC; + } else if (IS_GEN5(dev)) { +@@ -1841,9 +1841,9 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) + ring->irq_put = gen6_ring_put_irq; + ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; + ring->sync_to = gen6_ring_sync; +- ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_VR; +- ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_INVALID; +- ring->semaphore_register[2] = MI_SEMAPHORE_SYNC_VB; ++ ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VR; ++ ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_INVALID; ++ ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_VB; + ring->signal_mbox[0] = GEN6_RVSYNC; + ring->signal_mbox[1] = GEN6_BVSYNC; + } else { +@@ -1887,9 +1887,9 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) + ring->irq_put = gen6_ring_put_irq; + ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; + ring->sync_to = gen6_ring_sync; +- ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_BR; +- ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_BV; +- ring->semaphore_register[2] = MI_SEMAPHORE_SYNC_INVALID; ++ ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_BR; ++ ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_BV; ++ ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_INVALID; + ring->signal_mbox[0] = GEN6_RBSYNC; + ring->signal_mbox[1] = GEN6_VBSYNC; + ring->init = init_ring_common; +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index ef374a892105..24268fbe6855 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -105,8 +105,8 @@ struct intel_ring_buffer { + int (*sync_to)(struct intel_ring_buffer *ring, + struct intel_ring_buffer *to, + u32 seqno); +- +- u32 semaphore_register[3]; /*our mbox written by others */ ++ /* our mbox written by others */ ++ u32 semaphore_register[I915_NUM_RINGS]; + u32 signal_mbox[2]; /* mboxes this ring signals to */ + /** + * List of objects currently involved in rendering from the +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0213-drm-i915-Semaphore-MBOX-update-generalization.patch b/patches.baytrail/0213-drm-i915-Semaphore-MBOX-update-generalization.patch new file mode 100644 index 000000000000..3f8028dfccee --- /dev/null +++ b/patches.baytrail/0213-drm-i915-Semaphore-MBOX-update-generalization.patch @@ -0,0 +1,151 @@ +From d2dfc993a86c85fda98e8aae9de0a8e7afb891cc Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:18 -0700 +Subject: drm/i915: Semaphore MBOX update generalization + +This replaces the existing MBOX update code with a more generalized +calculation for emitting mbox updates. We also create a sentinel for +doing the updates so we can more abstractly deal with the rings. + +When doing MBOX updates the code must be aware of the /other/ rings. +Until now the platforms which supported semaphores had a fixed number of +rings and so it made sense for the code to be very specialized +(hardcoded). + +The patch does contain a functional change, but should have no +behavioral changes. + +Signed-off-by: Ben Widawsky +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit ad776f8b09d66e0145479fdbde2a710e5892441f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 1 + + drivers/gpu/drm/i915/intel_ringbuffer.c | 43 ++++++++++++++++++++++----------- + drivers/gpu/drm/i915/intel_ringbuffer.h | 5 +++- + 3 files changed, 34 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index f56c30ef40c8..77e201b7bfda 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -593,6 +593,7 @@ + #define GEN6_VRSYNC (RING_SYNC_1(GEN6_BSD_RING_BASE)) + #define GEN6_VBSYNC (RING_SYNC_0(GEN6_BSD_RING_BASE)) + #define GEN6_BRSYNC (RING_SYNC_0(BLT_RING_BASE)) ++#define GEN6_NOSYNC 0 + #define GEN6_BVSYNC (RING_SYNC_1(BLT_RING_BASE)) + #define RING_MAX_IDLE(base) ((base)+0x54) + #define RING_HWS_PGA(base) ((base)+0x80) +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index ef64bb3e847c..97555b7d4d0c 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -581,9 +581,16 @@ static void + update_mboxes(struct intel_ring_buffer *ring, + u32 mmio_offset) + { ++/* NB: In order to be able to do semaphore MBOX updates for varying number ++ * of rings, it's easiest if we round up each individual update to a ++ * multiple of 2 (since ring updates must always be a multiple of 2) ++ * even though the actual update only requires 3 dwords. ++ */ ++#define MBOX_UPDATE_DWORDS 4 + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(ring, mmio_offset); + intel_ring_emit(ring, ring->outstanding_lazy_request); ++ intel_ring_emit(ring, MI_NOOP); + } + + /** +@@ -598,19 +605,24 @@ update_mboxes(struct intel_ring_buffer *ring, + static int + gen6_add_request(struct intel_ring_buffer *ring) + { +- u32 mbox1_reg; +- u32 mbox2_reg; +- int ret; ++ struct drm_device *dev = ring->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct intel_ring_buffer *useless; ++ int i, ret; + +- ret = intel_ring_begin(ring, 10); ++ ret = intel_ring_begin(ring, ((I915_NUM_RINGS-1) * ++ MBOX_UPDATE_DWORDS) + ++ 4); + if (ret) + return ret; ++#undef MBOX_UPDATE_DWORDS + +- mbox1_reg = ring->signal_mbox[0]; +- mbox2_reg = ring->signal_mbox[1]; ++ for_each_ring(useless, dev_priv, i) { ++ u32 mbox_reg = ring->signal_mbox[i]; ++ if (mbox_reg != GEN6_NOSYNC) ++ update_mboxes(ring, mbox_reg); ++ } + +- update_mboxes(ring, mbox1_reg); +- update_mboxes(ring, mbox2_reg); + intel_ring_emit(ring, MI_STORE_DWORD_INDEX); + intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(ring, ring->outstanding_lazy_request); +@@ -1685,8 +1697,9 @@ int intel_init_render_ring_buffer(struct drm_device *dev) + ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_INVALID; + ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_RV; + ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_RB; +- ring->signal_mbox[0] = GEN6_VRSYNC; +- ring->signal_mbox[1] = GEN6_BRSYNC; ++ ring->signal_mbox[RCS] = GEN6_NOSYNC; ++ ring->signal_mbox[VCS] = GEN6_VRSYNC; ++ ring->signal_mbox[BCS] = GEN6_BRSYNC; + } else if (IS_GEN5(dev)) { + ring->add_request = pc_render_add_request; + ring->flush = gen4_render_ring_flush; +@@ -1844,8 +1857,9 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) + ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VR; + ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_INVALID; + ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_VB; +- ring->signal_mbox[0] = GEN6_RVSYNC; +- ring->signal_mbox[1] = GEN6_BVSYNC; ++ ring->signal_mbox[RCS] = GEN6_RVSYNC; ++ ring->signal_mbox[VCS] = GEN6_NOSYNC; ++ ring->signal_mbox[BCS] = GEN6_BVSYNC; + } else { + ring->mmio_base = BSD_RING_BASE; + ring->flush = bsd_ring_flush; +@@ -1890,8 +1904,9 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) + ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_BR; + ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_BV; + ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_INVALID; +- ring->signal_mbox[0] = GEN6_RBSYNC; +- ring->signal_mbox[1] = GEN6_VBSYNC; ++ ring->signal_mbox[RCS] = GEN6_RBSYNC; ++ ring->signal_mbox[VCS] = GEN6_VBSYNC; ++ ring->signal_mbox[BCS] = GEN6_NOSYNC; + ring->init = init_ring_common; + + return intel_init_ring_buffer(dev, ring); +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index 24268fbe6855..f55d92eb6c2a 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -105,9 +105,12 @@ struct intel_ring_buffer { + int (*sync_to)(struct intel_ring_buffer *ring, + struct intel_ring_buffer *to, + u32 seqno); ++ + /* our mbox written by others */ + u32 semaphore_register[I915_NUM_RINGS]; +- u32 signal_mbox[2]; /* mboxes this ring signals to */ ++ /* mboxes this ring signals to */ ++ u32 signal_mbox[I915_NUM_RINGS]; ++ + /** + * List of objects currently involved in rendering from the + * ringbuffer. +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0214-drm-i915-Introduce-VECS-the-4th-ring.patch b/patches.baytrail/0214-drm-i915-Introduce-VECS-the-4th-ring.patch new file mode 100644 index 000000000000..a6804ad8c48d --- /dev/null +++ b/patches.baytrail/0214-drm-i915-Introduce-VECS-the-4th-ring.patch @@ -0,0 +1,55 @@ +From 8b47e7d28bf88e4bedf76827a06aad825b94f91f Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:19 -0700 +Subject: drm/i915: Introduce VECS: the 4th ring + +The video enhancement command streamer is a new ring on HSW which does +what it sounds like it does. This patch provides the most minimal +inception of the ring. + +In order to support a new ring, we need to bump the number. The patch +may look trivial to the untrained eye, but bumping the number of rings +is a bit scary. As such the patch is not terribly useful by itself, but +a pretty nice place to find issues during a bisection. + +Reviewed-by: Damien Lespiau +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 4a3dd19d94c65323d71b2ffc7e63940f00acfb47) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ringbuffer.c | 2 ++ + drivers/gpu/drm/i915/intel_ringbuffer.h | 3 ++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 97555b7d4d0c..4f51e8da8dfe 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -914,6 +914,8 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring) + case VCS: + mmio = BSD_HWS_PGA_GEN7; + break; ++ case VECS: ++ BUG(); + } + } else if (IS_GEN6(ring->dev)) { + mmio = RING_HWS_PGA_GEN6(ring->mmio_base); +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index f55d92eb6c2a..73619cb34631 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -47,8 +47,9 @@ struct intel_ring_buffer { + RCS = 0x0, + VCS, + BCS, ++ VECS, + } id; +-#define I915_NUM_RINGS 3 ++#define I915_NUM_RINGS 4 + u32 mmio_base; + void __iomem *virtual_start; + struct drm_device *dev; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0215-drm-i915-Add-VECS-semaphore-bits.patch b/patches.baytrail/0215-drm-i915-Add-VECS-semaphore-bits.patch new file mode 100644 index 000000000000..8574c03bda77 --- /dev/null +++ b/patches.baytrail/0215-drm-i915-Add-VECS-semaphore-bits.patch @@ -0,0 +1,134 @@ +From 894554d1cc2a1ec72c3f24a7f1dccbeb7288bc20 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:20 -0700 +Subject: drm/i915: Add VECS semaphore bits + +Like the other rings, the VECS supports semaphores. The semaphore stuff +is a bit wonky so this patch on it's own should be nice for review. + +This patch should have no functional impact. + +v2: Fix the English parts of clarification (again, register names were +right, text was reversed) (Damien) +Restore the still valid invariant. (Damien) +The bsd semaphore register should be MI_SEMAPHORE_SYNC_VVE (Damien) + +Signed-off-by: Ben Widawsky +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 1950de14fd1b8ea27a411929156c7eccee2ad7c3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 40 ++++++++++++++++++++++----------- + drivers/gpu/drm/i915/intel_ringbuffer.c | 6 +++++ + 2 files changed, 33 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 77e201b7bfda..cad62c893fa9 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -265,13 +265,19 @@ + #define MI_SEMAPHORE_UPDATE (1<<21) + #define MI_SEMAPHORE_COMPARE (1<<20) + #define MI_SEMAPHORE_REGISTER (1<<18) +-#define MI_SEMAPHORE_SYNC_RB (0<<16) /* BCS wait for RCS (BRSYNC) */ +-#define MI_SEMAPHORE_SYNC_RV (2<<16) /* VCS wait for RCS (VRSYNC) */ +-#define MI_SEMAPHORE_SYNC_VR (0<<16) /* RCS wait for VCS (RVSYNC) */ +-#define MI_SEMAPHORE_SYNC_VB (2<<16) /* BCS wait for VCS (BVSYNC) */ +-#define MI_SEMAPHORE_SYNC_BV (0<<16) /* VCS wait for BCS (VBSYNC) */ +-#define MI_SEMAPHORE_SYNC_BR (2<<16) /* RCS wait for BCS (RBSYNC) */ +-#define MI_SEMAPHORE_SYNC_INVALID (1<<0) ++#define MI_SEMAPHORE_SYNC_VR (0<<16) /* RCS wait for VCS (RVSYNC) */ ++#define MI_SEMAPHORE_SYNC_VER (1<<16) /* RCS wait for VECS (RVESYNC) */ ++#define MI_SEMAPHORE_SYNC_BR (2<<16) /* RCS wait for BCS (RBSYNC) */ ++#define MI_SEMAPHORE_SYNC_BV (0<<16) /* VCS wait for BCS (VBSYNC) */ ++#define MI_SEMAPHORE_SYNC_VEV (1<<16) /* VCS wait for VECS (VVESYNC) */ ++#define MI_SEMAPHORE_SYNC_RV (2<<16) /* VCS wait for RCS (VRSYNC) */ ++#define MI_SEMAPHORE_SYNC_RB (0<<16) /* BCS wait for RCS (BRSYNC) */ ++#define MI_SEMAPHORE_SYNC_VEB (1<<16) /* BCS wait for VECS (BVESYNC) */ ++#define MI_SEMAPHORE_SYNC_VB (2<<16) /* BCS wait for VCS (BVSYNC) */ ++#define MI_SEMAPHORE_SYNC_BVE (0<<16) /* VECS wait for BCS (VEBSYNC) */ ++#define MI_SEMAPHORE_SYNC_VVE (1<<16) /* VECS wait for VCS (VEVSYNC) */ ++#define MI_SEMAPHORE_SYNC_RVE (2<<16) /* VECS wait for RCS (VERSYNC) */ ++#define MI_SEMAPHORE_SYNC_INVALID (3<<16) + /* + * 3D instructions used by the kernel + */ +@@ -581,6 +587,7 @@ + #define RENDER_RING_BASE 0x02000 + #define BSD_RING_BASE 0x04000 + #define GEN6_BSD_RING_BASE 0x12000 ++#define VEBOX_RING_BASE 0x1a000 + #define BLT_RING_BASE 0x22000 + #define RING_TAIL(base) ((base)+0x30) + #define RING_HEAD(base) ((base)+0x34) +@@ -588,13 +595,20 @@ + #define RING_CTL(base) ((base)+0x3c) + #define RING_SYNC_0(base) ((base)+0x40) + #define RING_SYNC_1(base) ((base)+0x44) +-#define GEN6_RVSYNC (RING_SYNC_0(RENDER_RING_BASE)) +-#define GEN6_RBSYNC (RING_SYNC_1(RENDER_RING_BASE)) +-#define GEN6_VRSYNC (RING_SYNC_1(GEN6_BSD_RING_BASE)) +-#define GEN6_VBSYNC (RING_SYNC_0(GEN6_BSD_RING_BASE)) +-#define GEN6_BRSYNC (RING_SYNC_0(BLT_RING_BASE)) ++#define RING_SYNC_2(base) ((base)+0x48) ++#define GEN6_RVSYNC (RING_SYNC_0(RENDER_RING_BASE)) ++#define GEN6_RBSYNC (RING_SYNC_1(RENDER_RING_BASE)) ++#define GEN6_RVESYNC (RING_SYNC_2(RENDER_RING_BASE)) ++#define GEN6_VBSYNC (RING_SYNC_0(GEN6_BSD_RING_BASE)) ++#define GEN6_VRSYNC (RING_SYNC_1(GEN6_BSD_RING_BASE)) ++#define GEN6_VVESYNC (RING_SYNC_2(GEN6_BSD_RING_BASE)) ++#define GEN6_BRSYNC (RING_SYNC_0(BLT_RING_BASE)) ++#define GEN6_BVSYNC (RING_SYNC_1(BLT_RING_BASE)) ++#define GEN6_BVESYNC (RING_SYNC_2(BLT_RING_BASE)) ++#define GEN6_VEBSYNC (RING_SYNC_0(VEBOX_RING_BASE)) ++#define GEN6_VERSYNC (RING_SYNC_1(VEBOX_RING_BASE)) ++#define GEN6_VEVSYNC (RING_SYNC_2(VEBOX_RING_BASE)) + #define GEN6_NOSYNC 0 +-#define GEN6_BVSYNC (RING_SYNC_1(BLT_RING_BASE)) + #define RING_MAX_IDLE(base) ((base)+0x54) + #define RING_HWS_PGA(base) ((base)+0x80) + #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 4f51e8da8dfe..7a716ec8695d 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -1699,9 +1699,11 @@ int intel_init_render_ring_buffer(struct drm_device *dev) + ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_INVALID; + ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_RV; + ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_RB; ++ ring->semaphore_register[VECS] = MI_SEMAPHORE_SYNC_RVE; + ring->signal_mbox[RCS] = GEN6_NOSYNC; + ring->signal_mbox[VCS] = GEN6_VRSYNC; + ring->signal_mbox[BCS] = GEN6_BRSYNC; ++ ring->signal_mbox[VECS] = GEN6_VERSYNC; + } else if (IS_GEN5(dev)) { + ring->add_request = pc_render_add_request; + ring->flush = gen4_render_ring_flush; +@@ -1859,9 +1861,11 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) + ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VR; + ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_INVALID; + ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_VB; ++ ring->semaphore_register[VECS] = MI_SEMAPHORE_SYNC_VVE; + ring->signal_mbox[RCS] = GEN6_RVSYNC; + ring->signal_mbox[VCS] = GEN6_NOSYNC; + ring->signal_mbox[BCS] = GEN6_BVSYNC; ++ ring->signal_mbox[VECS] = GEN6_VEVSYNC; + } else { + ring->mmio_base = BSD_RING_BASE; + ring->flush = bsd_ring_flush; +@@ -1906,9 +1910,11 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) + ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_BR; + ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_BV; + ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_INVALID; ++ ring->semaphore_register[VECS] = MI_SEMAPHORE_SYNC_BVE; + ring->signal_mbox[RCS] = GEN6_RBSYNC; + ring->signal_mbox[VCS] = GEN6_VBSYNC; + ring->signal_mbox[BCS] = GEN6_NOSYNC; ++ ring->signal_mbox[VECS] = GEN6_VEBSYNC; + ring->init = init_ring_common; + + return intel_init_ring_buffer(dev, ring); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0216-drm-i915-Rename-ring-flush-functions.patch b/patches.baytrail/0216-drm-i915-Rename-ring-flush-functions.patch new file mode 100644 index 000000000000..31b58a5fe45f --- /dev/null +++ b/patches.baytrail/0216-drm-i915-Rename-ring-flush-functions.patch @@ -0,0 +1,71 @@ +From 23a0013dedffc706c22105480f50489de98d6c00 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:21 -0700 +Subject: drm/i915: Rename ring flush functions + +Historically we considered the render ring to have special flush +semantics and everything else to fall under a more general umbrella. +Probably by coincidence more than anything we decided to make the bsd +ring have the default *other* flush. As the new vebox ring exposes, the +bsd ring is actually the weird one. Doing this allows us to call +gen6_ring_flush for the vebox because calling blt_ring_flush would be +weird... + +This patch should have no functional change. + +Reviewed-by: Damien Lespiau +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit ea251324cac6c1e0402db073e5193f33aedd94f3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ringbuffer.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 7a716ec8695d..40bf9e699599 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -1576,8 +1576,8 @@ static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, + _MASKED_BIT_DISABLE(GEN6_BSD_SLEEP_MSG_DISABLE)); + } + +-static int gen6_ring_flush(struct intel_ring_buffer *ring, +- u32 invalidate, u32 flush) ++static int gen6_bsd_ring_flush(struct intel_ring_buffer *ring, ++ u32 invalidate, u32 flush) + { + uint32_t cmd; + int ret; +@@ -1648,8 +1648,8 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, + + /* Blitter support (SandyBridge+) */ + +-static int blt_ring_flush(struct intel_ring_buffer *ring, +- u32 invalidate, u32 flush) ++static int gen6_ring_flush(struct intel_ring_buffer *ring, ++ u32 invalidate, u32 flush) + { + uint32_t cmd; + int ret; +@@ -1849,7 +1849,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) + /* gen6 bsd needs a special wa for tail updates */ + if (IS_GEN6(dev)) + ring->write_tail = gen6_bsd_ring_write_tail; +- ring->flush = gen6_ring_flush; ++ ring->flush = gen6_bsd_ring_flush; + ring->add_request = gen6_add_request; + ring->get_seqno = gen6_ring_get_seqno; + ring->set_seqno = ring_set_seqno; +@@ -1898,7 +1898,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) + + ring->mmio_base = BLT_RING_BASE; + ring->write_tail = ring_write_tail; +- ring->flush = blt_ring_flush; ++ ring->flush = gen6_ring_flush; + ring->add_request = gen6_add_request; + ring->get_seqno = gen6_ring_get_seqno; + ring->set_seqno = ring_set_seqno; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0217-drm-i915-add-HAS_VEBOX.patch b/patches.baytrail/0217-drm-i915-add-HAS_VEBOX.patch new file mode 100644 index 000000000000..bacdcc636fed --- /dev/null +++ b/patches.baytrail/0217-drm-i915-add-HAS_VEBOX.patch @@ -0,0 +1,65 @@ +From 8e7b8296771e2e0f1eece8977aa5d84be8c4d9c0 Mon Sep 17 00:00:00 2001 +From: "Xiang, Haihao" +Date: Tue, 28 May 2013 19:22:22 -0700 +Subject: drm/i915: add HAS_VEBOX + +The flag will be useful to help share code between IVB, and HSW as the +programming is similar in many places with this as one of the major +differences. + +Signed-off-by: Xiang, Haihao +[Commit message + small fix by] +Reviewed-by: Damien Lespiau +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter + +(cherry picked from commit f72a1183b31cd1bebf926f904c1f025a90d153a1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 2 ++ + drivers/gpu/drm/i915/i915_drv.h | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 94492d1cdb0c..9136fcdcd24a 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -311,6 +311,7 @@ static const struct intel_device_info intel_haswell_d_info = { + .is_haswell = 1, + .has_ddi = 1, + .has_fpga_dbg = 1, ++ .has_vebox_ring = 1, + }; + + static const struct intel_device_info intel_haswell_m_info = { +@@ -320,6 +321,7 @@ static const struct intel_device_info intel_haswell_m_info = { + .has_ddi = 1, + .has_fpga_dbg = 1, + .has_fbc = 1, ++ .has_vebox_ring = 1, + }; + + static const struct pci_device_id pciidlist[] = { /* aka */ +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 16a69b82e865..ae8b9668b8ff 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -374,6 +374,7 @@ struct drm_i915_gt_funcs { + func(supports_tv) sep \ + func(has_bsd_ring) sep \ + func(has_blt_ring) sep \ ++ func(has_vebox_ring) sep \ + func(has_llc) sep \ + func(has_ddi) sep \ + func(has_fpga_dbg) +@@ -1374,6 +1375,7 @@ struct drm_i915_file_private { + + #define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring) + #define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) ++#define HAS_VEBOX(dev) (INTEL_INFO(dev)->has_vebox_ring) + #define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) + #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0218-drm-i915-Vebox-ringbuffer-init.patch b/patches.baytrail/0218-drm-i915-Vebox-ringbuffer-init.patch new file mode 100644 index 000000000000..3979fa93a613 --- /dev/null +++ b/patches.baytrail/0218-drm-i915-Vebox-ringbuffer-init.patch @@ -0,0 +1,127 @@ +From df17af4a02da8dc65abe33d9517038e2482adbb5 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:23 -0700 +Subject: drm/i915: Vebox ringbuffer init + +v2: Add set_seqno which didn't exist before rebase (Haihao) + +Signed-off-by: Ben Widawsky +Reviewed-by: Damien Lespiau +Signed-off-by: Xiang, Haihao +Signed-off-by: Daniel Vetter +(cherry picked from commit 9a8a2213a778509b724c8fda04be70528a1f7130) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 11 ++++++++++- + drivers/gpu/drm/i915/i915_reg.h | 1 + + drivers/gpu/drm/i915/intel_ringbuffer.c | 35 ++++++++++++++++++++++++++++++++- + drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + + 4 files changed, 46 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 03103eb57e32..25f327cc1127 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -4043,12 +4043,21 @@ static int i915_gem_init_rings(struct drm_device *dev) + goto cleanup_bsd_ring; + } + ++ if (HAS_VEBOX(dev)) { ++ ret = intel_init_vebox_ring_buffer(dev); ++ if (ret) ++ goto cleanup_blt_ring; ++ } ++ ++ + ret = i915_gem_set_seqno(dev, ((u32)~0 - 0x1000)); + if (ret) +- goto cleanup_blt_ring; ++ goto cleanup_vebox_ring; + + return 0; + ++cleanup_vebox_ring: ++ intel_cleanup_ring_buffer(&dev_priv->ring[VECS]); + cleanup_blt_ring: + intel_cleanup_ring_buffer(&dev_priv->ring[BCS]); + cleanup_bsd_ring: +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index cad62c893fa9..4b25cbafc4f2 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -620,6 +620,7 @@ + #define DONE_REG 0x40b0 + #define BSD_HWS_PGA_GEN7 (0x04180) + #define BLT_HWS_PGA_GEN7 (0x04280) ++#define VEBOX_HWS_PGA_GEN7 (0x04380) + #define RING_ACTHD(base) ((base)+0x74) + #define RING_NOPID(base) ((base)+0x94) + #define RING_IMR(base) ((base)+0xa8) +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 40bf9e699599..c626a943d9c2 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -915,7 +915,8 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring) + mmio = BSD_HWS_PGA_GEN7; + break; + case VECS: +- BUG(); ++ mmio = VEBOX_HWS_PGA_GEN7; ++ break; + } + } else if (IS_GEN6(ring->dev)) { + mmio = RING_HWS_PGA_GEN6(ring->mmio_base); +@@ -1920,6 +1921,38 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) + return intel_init_ring_buffer(dev, ring); + } + ++int intel_init_vebox_ring_buffer(struct drm_device *dev) ++{ ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ struct intel_ring_buffer *ring = &dev_priv->ring[VECS]; ++ ++ ring->name = "video enhancement ring"; ++ ring->id = VECS; ++ ++ ring->mmio_base = VEBOX_RING_BASE; ++ ring->write_tail = ring_write_tail; ++ ring->flush = gen6_ring_flush; ++ ring->add_request = gen6_add_request; ++ ring->get_seqno = gen6_ring_get_seqno; ++ ring->set_seqno = ring_set_seqno; ++ ring->irq_enable_mask = 0; ++ ring->irq_get = NULL; ++ ring->irq_put = NULL; ++ ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; ++ ring->sync_to = gen6_ring_sync; ++ ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VER; ++ ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_VEV; ++ ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_VEB; ++ ring->semaphore_register[VECS] = MI_SEMAPHORE_SYNC_INVALID; ++ ring->signal_mbox[RCS] = GEN6_RVESYNC; ++ ring->signal_mbox[VCS] = GEN6_VVESYNC; ++ ring->signal_mbox[BCS] = GEN6_BVESYNC; ++ ring->signal_mbox[VECS] = GEN6_NOSYNC; ++ ring->init = init_ring_common; ++ ++ return intel_init_ring_buffer(dev, ring); ++} ++ + int + intel_ring_flush_all_caches(struct intel_ring_buffer *ring) + { +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index 73619cb34631..1c79520c7e45 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -234,6 +234,7 @@ int intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring); + int intel_init_render_ring_buffer(struct drm_device *dev); + int intel_init_bsd_ring_buffer(struct drm_device *dev); + int intel_init_blt_ring_buffer(struct drm_device *dev); ++int intel_init_vebox_ring_buffer(struct drm_device *dev); + + u32 intel_ring_get_active_head(struct intel_ring_buffer *ring); + void intel_ring_setup_status_page(struct intel_ring_buffer *ring); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0219-drm-i915-fix-pch_nop-support.patch b/patches.baytrail/0219-drm-i915-fix-pch_nop-support.patch new file mode 100644 index 000000000000..b1bff9107cd8 --- /dev/null +++ b/patches.baytrail/0219-drm-i915-fix-pch_nop-support.patch @@ -0,0 +1,51 @@ +From 56a3329380e6430d74d338bfcedda84951e80784 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 29 May 2013 21:43:05 +0200 +Subject: drm/i915: fix pch_nop support + +This was accidentally broken in the south error interrupt handling +work: + +commit 8664281b64c457705db72fc60143d03827e75ca9 +Author: Paulo Zanoni +Date: Fri Apr 12 17:57:57 2013 -0300 + + drm/i915: report Gen5+ CPU and PCH FIFO underruns + +Cc: Paulo Zanoni +Cc: Ben Widawsky +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 692a04cf77e6073a60a9eaa87b7c409b6cf0283b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index c0d9f876a690..77baf991499b 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2588,6 +2588,9 @@ static void ibx_irq_postinstall(struct drm_device *dev) + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u32 mask; + ++ if (HAS_PCH_NOP(dev)) ++ return; ++ + if (HAS_PCH_IBX(dev)) { + mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER | + SDE_TRANSA_FIFO_UNDER | SDE_POISON; +@@ -2597,9 +2600,6 @@ static void ibx_irq_postinstall(struct drm_device *dev) + I915_WRITE(SERR_INT, I915_READ(SERR_INT)); + } + +- if (HAS_PCH_NOP(dev)) +- return; +- + I915_WRITE(SDEIIR, I915_READ(SDEIIR)); + I915_WRITE(SDEIMR, ~mask); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0220-drm-i915-properly-set-HSW-WM_PIPE-registers.patch b/patches.baytrail/0220-drm-i915-properly-set-HSW-WM_PIPE-registers.patch new file mode 100644 index 000000000000..dcef57249e38 --- /dev/null +++ b/patches.baytrail/0220-drm-i915-properly-set-HSW-WM_PIPE-registers.patch @@ -0,0 +1,433 @@ +From 9e5631af96314147533b47ba2c7c0a3f54b7db9d Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 31 May 2013 10:08:35 -0300 +Subject: drm/i915: properly set HSW WM_PIPE registers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We were previously calling sandybridge_update_wm on HSW, but the SNB +function didn't really match the HSW specification, so we were just +writing the wrong values. + +With this patch, the haswell_update_wm function will set the correct +values for the WM_PIPE registers, but it will still keep all the LP +watermarks disabled. + +The patch may look a little bit over-complicated for now, but it's +because much of the infrastructure for setting the LP watermarks is +already in place, so we won't have too much code churn on the patch +that sets the LP watermarks. + +v2: - Fix pixel_rate on panel fitter case (Ville) + - Try to not overflow (Ville) + - Remove useless variable (Ville) + - Fix p->pri_horiz_pixels (Paulo) +v3: - Fix rounding errors on hsw_wm_method2 (Ville) +v4: - Fix memcmp bug (Paulo) + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 801bcfffbb0721d7131e930f9a46103e539c43a4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 3 + + drivers/gpu/drm/i915/intel_pm.c | 342 +++++++++++++++++++++++++++++++++++++--- + 2 files changed, 327 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 4b25cbafc4f2..a2a4bc6dfe57 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -4953,6 +4953,9 @@ + #define SFUSE_STRAP_DDIC_DETECTED (1<<1) + #define SFUSE_STRAP_DDID_DETECTED (1<<0) + ++#define WM_MISC 0x45260 ++#define WM_MISC_DATA_PARTITION_5_6 (1 << 0) ++ + #define WM_DBG 0x45280 + #define WM_DBG_DISALLOW_MULTIPLE_LP (1<<0) + #define WM_DBG_DISALLOW_MAXFIFO (1<<1) +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 6d189cde8591..bbd2a06718b1 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2072,19 +2072,170 @@ static void ivybridge_update_wm(struct drm_device *dev) + cursor_wm); + } + +-static void +-haswell_update_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) ++static uint32_t hsw_wm_get_pixel_rate(struct drm_device *dev, ++ struct drm_crtc *crtc) ++{ ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ uint32_t pixel_rate, pfit_size; ++ ++ if (intel_crtc->config.pixel_target_clock) ++ pixel_rate = intel_crtc->config.pixel_target_clock; ++ else ++ pixel_rate = intel_crtc->config.adjusted_mode.clock; ++ ++ /* We only use IF-ID interlacing. If we ever use PF-ID we'll need to ++ * adjust the pixel_rate here. */ ++ ++ pfit_size = intel_crtc->config.pch_pfit.size; ++ if (pfit_size) { ++ uint64_t pipe_w, pipe_h, pfit_w, pfit_h; ++ ++ pipe_w = intel_crtc->config.requested_mode.hdisplay; ++ pipe_h = intel_crtc->config.requested_mode.vdisplay; ++ pfit_w = (pfit_size >> 16) & 0xFFFF; ++ pfit_h = pfit_size & 0xFFFF; ++ if (pipe_w < pfit_w) ++ pipe_w = pfit_w; ++ if (pipe_h < pfit_h) ++ pipe_h = pfit_h; ++ ++ pixel_rate = div_u64((uint64_t) pixel_rate * pipe_w * pipe_h, ++ pfit_w * pfit_h); ++ } ++ ++ return pixel_rate; ++} ++ ++static uint32_t hsw_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel, ++ uint32_t latency) ++{ ++ uint64_t ret; ++ ++ ret = (uint64_t) pixel_rate * bytes_per_pixel * latency; ++ ret = DIV_ROUND_UP_ULL(ret, 64 * 10000) + 2; ++ ++ return ret; ++} ++ ++static uint32_t hsw_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, ++ uint32_t horiz_pixels, uint8_t bytes_per_pixel, ++ uint32_t latency) ++{ ++ uint32_t ret; ++ ++ ret = (latency * pixel_rate) / (pipe_htotal * 10000); ++ ret = (ret + 1) * horiz_pixels * bytes_per_pixel; ++ ret = DIV_ROUND_UP(ret, 64) + 2; ++ return ret; ++} ++ ++struct hsw_pipe_wm_parameters { ++ bool active; ++ bool sprite_enabled; ++ uint8_t pri_bytes_per_pixel; ++ uint8_t spr_bytes_per_pixel; ++ uint8_t cur_bytes_per_pixel; ++ uint32_t pri_horiz_pixels; ++ uint32_t spr_horiz_pixels; ++ uint32_t cur_horiz_pixels; ++ uint32_t pipe_htotal; ++ uint32_t pixel_rate; ++}; ++ ++struct hsw_wm_values { ++ uint32_t wm_pipe[3]; ++ uint32_t wm_lp[3]; ++ uint32_t wm_lp_spr[3]; ++ uint32_t wm_linetime[3]; ++}; ++ ++enum hsw_data_buf_partitioning { ++ HSW_DATA_BUF_PART_1_2, ++ HSW_DATA_BUF_PART_5_6, ++}; ++ ++/* Only for WM_PIPE. */ ++static uint32_t hsw_compute_pri_wm_pipe(struct hsw_pipe_wm_parameters *params, ++ uint32_t mem_value) ++{ ++ /* TODO: for now, assume the primary plane is always enabled. */ ++ if (!params->active) ++ return 0; ++ ++ return hsw_wm_method1(params->pixel_rate, ++ params->pri_bytes_per_pixel, ++ mem_value); ++} ++ ++/* For both WM_PIPE and WM_LP. */ ++static uint32_t hsw_compute_spr_wm(struct hsw_pipe_wm_parameters *params, ++ uint32_t mem_value) ++{ ++ uint32_t method1, method2; ++ ++ if (!params->active || !params->sprite_enabled) ++ return 0; ++ ++ method1 = hsw_wm_method1(params->pixel_rate, ++ params->spr_bytes_per_pixel, ++ mem_value); ++ method2 = hsw_wm_method2(params->pixel_rate, ++ params->pipe_htotal, ++ params->spr_horiz_pixels, ++ params->spr_bytes_per_pixel, ++ mem_value); ++ return min(method1, method2); ++} ++ ++/* For both WM_PIPE and WM_LP. */ ++static uint32_t hsw_compute_cur_wm(struct hsw_pipe_wm_parameters *params, ++ uint32_t mem_value) ++{ ++ if (!params->active) ++ return 0; ++ ++ return hsw_wm_method2(params->pixel_rate, ++ params->pipe_htotal, ++ params->cur_horiz_pixels, ++ params->cur_bytes_per_pixel, ++ mem_value); ++} ++ ++static uint32_t hsw_compute_wm_pipe(struct drm_i915_private *dev_priv, ++ uint32_t mem_value, enum pipe pipe, ++ struct hsw_pipe_wm_parameters *params) ++{ ++ uint32_t pri_val, cur_val, spr_val; ++ ++ pri_val = hsw_compute_pri_wm_pipe(params, mem_value); ++ spr_val = hsw_compute_spr_wm(params, mem_value); ++ cur_val = hsw_compute_cur_wm(params, mem_value); ++ ++ WARN(pri_val > 127, ++ "Primary WM error, mode not supported for pipe %c\n", ++ pipe_name(pipe)); ++ WARN(spr_val > 127, ++ "Sprite WM error, mode not supported for pipe %c\n", ++ pipe_name(pipe)); ++ WARN(cur_val > 63, ++ "Cursor WM error, mode not supported for pipe %c\n", ++ pipe_name(pipe)); ++ ++ return (pri_val << WM0_PIPE_PLANE_SHIFT) | ++ (spr_val << WM0_PIPE_SPRITE_SHIFT) | ++ cur_val; ++} ++ ++static uint32_t ++hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- enum pipe pipe = intel_crtc->pipe; + struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode; + u32 linetime, ips_linetime; + +- if (!intel_crtc_active(crtc)) { +- I915_WRITE(PIPE_WM_LINETIME(pipe), 0); +- return; +- } ++ if (!intel_crtc_active(crtc)) ++ return 0; + + /* The WM are computed with base on how long it takes to fill a single + * row at the given clock rate, multiplied by 8. +@@ -2093,29 +2244,184 @@ haswell_update_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) + ips_linetime = DIV_ROUND_CLOSEST(mode->htotal * 1000 * 8, + intel_ddi_get_cdclk_freq(dev_priv)); + +- I915_WRITE(PIPE_WM_LINETIME(pipe), +- PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) | +- PIPE_WM_LINETIME_TIME(linetime)); ++ return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) | ++ PIPE_WM_LINETIME_TIME(linetime); + } + +-static void haswell_update_wm(struct drm_device *dev) ++static void hsw_compute_wm_parameters(struct drm_device *dev, ++ struct hsw_pipe_wm_parameters *params, ++ uint32_t *wm) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; ++ struct drm_plane *plane; ++ uint64_t sskpd = I915_READ64(MCH_SSKPD); + enum pipe pipe; + +- /* Disable the LP WMs before changine the linetime registers. This is +- * just a temporary code that will be replaced soon. */ +- I915_WRITE(WM3_LP_ILK, 0); +- I915_WRITE(WM2_LP_ILK, 0); +- I915_WRITE(WM1_LP_ILK, 0); ++ if ((sskpd >> 56) & 0xFF) ++ wm[0] = (sskpd >> 56) & 0xFF; ++ else ++ wm[0] = sskpd & 0xF; ++ wm[1] = ((sskpd >> 4) & 0xFF) * 5; ++ wm[2] = ((sskpd >> 12) & 0xFF) * 5; ++ wm[3] = ((sskpd >> 20) & 0x1FF) * 5; ++ wm[4] = ((sskpd >> 32) & 0x1FF) * 5; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ struct hsw_pipe_wm_parameters *p; ++ ++ pipe = intel_crtc->pipe; ++ p = ¶ms[pipe]; ++ ++ p->active = intel_crtc_active(crtc); ++ if (!p->active) ++ continue; ++ ++ p->pipe_htotal = intel_crtc->config.adjusted_mode.htotal; ++ p->pixel_rate = hsw_wm_get_pixel_rate(dev, crtc); ++ p->pri_bytes_per_pixel = crtc->fb->bits_per_pixel / 8; ++ p->cur_bytes_per_pixel = 4; ++ p->pri_horiz_pixels = ++ intel_crtc->config.requested_mode.hdisplay; ++ p->cur_horiz_pixels = 64; ++ } ++ ++ list_for_each_entry(plane, &dev->mode_config.plane_list, head) { ++ struct intel_plane *intel_plane = to_intel_plane(plane); ++ struct hsw_pipe_wm_parameters *p; ++ ++ pipe = intel_plane->pipe; ++ p = ¶ms[pipe]; ++ ++ p->sprite_enabled = intel_plane->wm.enable; ++ p->spr_bytes_per_pixel = intel_plane->wm.bytes_per_pixel; ++ p->spr_horiz_pixels = intel_plane->wm.horiz_pixels; ++ } ++} ++ ++static void hsw_compute_wm_results(struct drm_device *dev, ++ struct hsw_pipe_wm_parameters *params, ++ uint32_t *wm, ++ struct hsw_wm_values *results) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_crtc *crtc; ++ enum pipe pipe; ++ ++ /* No support for LP WMs yet. */ ++ results->wm_lp[2] = 0; ++ results->wm_lp[1] = 0; ++ results->wm_lp[0] = 0; ++ results->wm_lp_spr[2] = 0; ++ results->wm_lp_spr[1] = 0; ++ results->wm_lp_spr[0] = 0; ++ ++ for_each_pipe(pipe) ++ results->wm_pipe[pipe] = hsw_compute_wm_pipe(dev_priv, wm[0], ++ pipe, ++ ¶ms[pipe]); + + for_each_pipe(pipe) { + crtc = dev_priv->pipe_to_crtc_mapping[pipe]; +- haswell_update_linetime_wm(dev, crtc); ++ results->wm_linetime[pipe] = hsw_compute_linetime_wm(dev, crtc); + } ++} ++ ++/* ++ * The spec says we shouldn't write when we don't need, because every write ++ * causes WMs to be re-evaluated, expending some power. ++ */ ++static void hsw_write_wm_values(struct drm_i915_private *dev_priv, ++ struct hsw_wm_values *results, ++ enum hsw_data_buf_partitioning partitioning) ++{ ++ struct hsw_wm_values previous; ++ uint32_t val; ++ enum hsw_data_buf_partitioning prev_partitioning; ++ ++ previous.wm_pipe[0] = I915_READ(WM0_PIPEA_ILK); ++ previous.wm_pipe[1] = I915_READ(WM0_PIPEB_ILK); ++ previous.wm_pipe[2] = I915_READ(WM0_PIPEC_IVB); ++ previous.wm_lp[0] = I915_READ(WM1_LP_ILK); ++ previous.wm_lp[1] = I915_READ(WM2_LP_ILK); ++ previous.wm_lp[2] = I915_READ(WM3_LP_ILK); ++ previous.wm_lp_spr[0] = I915_READ(WM1S_LP_ILK); ++ previous.wm_lp_spr[1] = I915_READ(WM2S_LP_IVB); ++ previous.wm_lp_spr[2] = I915_READ(WM3S_LP_IVB); ++ previous.wm_linetime[0] = I915_READ(PIPE_WM_LINETIME(PIPE_A)); ++ previous.wm_linetime[1] = I915_READ(PIPE_WM_LINETIME(PIPE_B)); ++ previous.wm_linetime[2] = I915_READ(PIPE_WM_LINETIME(PIPE_C)); ++ ++ prev_partitioning = (I915_READ(WM_MISC) & WM_MISC_DATA_PARTITION_5_6) ? ++ HSW_DATA_BUF_PART_5_6 : HSW_DATA_BUF_PART_1_2; ++ ++ if (memcmp(results->wm_pipe, previous.wm_pipe, ++ sizeof(results->wm_pipe)) == 0 && ++ memcmp(results->wm_lp, previous.wm_lp, ++ sizeof(results->wm_lp)) == 0 && ++ memcmp(results->wm_lp_spr, previous.wm_lp_spr, ++ sizeof(results->wm_lp_spr)) == 0 && ++ memcmp(results->wm_linetime, previous.wm_linetime, ++ sizeof(results->wm_linetime)) == 0 && ++ partitioning == prev_partitioning) ++ return; ++ ++ if (previous.wm_lp[2] != 0) ++ I915_WRITE(WM3_LP_ILK, 0); ++ if (previous.wm_lp[1] != 0) ++ I915_WRITE(WM2_LP_ILK, 0); ++ if (previous.wm_lp[0] != 0) ++ I915_WRITE(WM1_LP_ILK, 0); ++ ++ if (previous.wm_pipe[0] != results->wm_pipe[0]) ++ I915_WRITE(WM0_PIPEA_ILK, results->wm_pipe[0]); ++ if (previous.wm_pipe[1] != results->wm_pipe[1]) ++ I915_WRITE(WM0_PIPEB_ILK, results->wm_pipe[1]); ++ if (previous.wm_pipe[2] != results->wm_pipe[2]) ++ I915_WRITE(WM0_PIPEC_IVB, results->wm_pipe[2]); ++ ++ if (previous.wm_linetime[0] != results->wm_linetime[0]) ++ I915_WRITE(PIPE_WM_LINETIME(PIPE_A), results->wm_linetime[0]); ++ if (previous.wm_linetime[1] != results->wm_linetime[1]) ++ I915_WRITE(PIPE_WM_LINETIME(PIPE_B), results->wm_linetime[1]); ++ if (previous.wm_linetime[2] != results->wm_linetime[2]) ++ I915_WRITE(PIPE_WM_LINETIME(PIPE_C), results->wm_linetime[2]); ++ ++ if (prev_partitioning != partitioning) { ++ val = I915_READ(WM_MISC); ++ if (partitioning == HSW_DATA_BUF_PART_1_2) ++ val &= ~WM_MISC_DATA_PARTITION_5_6; ++ else ++ val |= WM_MISC_DATA_PARTITION_5_6; ++ I915_WRITE(WM_MISC, val); ++ } ++ ++ if (previous.wm_lp_spr[0] != results->wm_lp_spr[0]) ++ I915_WRITE(WM1S_LP_ILK, results->wm_lp_spr[0]); ++ if (previous.wm_lp_spr[1] != results->wm_lp_spr[1]) ++ I915_WRITE(WM2S_LP_IVB, results->wm_lp_spr[1]); ++ if (previous.wm_lp_spr[2] != results->wm_lp_spr[2]) ++ I915_WRITE(WM3S_LP_IVB, results->wm_lp_spr[2]); ++ ++ if (results->wm_lp[0] != 0) ++ I915_WRITE(WM1_LP_ILK, results->wm_lp[0]); ++ if (results->wm_lp[1] != 0) ++ I915_WRITE(WM2_LP_ILK, results->wm_lp[1]); ++ if (results->wm_lp[2] != 0) ++ I915_WRITE(WM3_LP_ILK, results->wm_lp[2]); ++} ++ ++static void haswell_update_wm(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct hsw_pipe_wm_parameters params[3]; ++ struct hsw_wm_values results; ++ uint32_t wm[5]; + +- sandybridge_update_wm(dev); ++ hsw_compute_wm_parameters(dev, params, wm); ++ hsw_compute_wm_results(dev, params, wm, &results); ++ hsw_write_wm_values(dev_priv, &results, HSW_DATA_BUF_PART_1_2); + } + + static void haswell_update_sprite_wm(struct drm_device *dev, int pipe, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0221-drm-i915-properly-set-HSW-WM_LP-watermarks.patch b/patches.baytrail/0221-drm-i915-properly-set-HSW-WM_LP-watermarks.patch new file mode 100644 index 000000000000..b72c5f47d4e2 --- /dev/null +++ b/patches.baytrail/0221-drm-i915-properly-set-HSW-WM_LP-watermarks.patch @@ -0,0 +1,352 @@ +From f242679dccec06216bfe835ee7daa6cdff6afb0d Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 31 May 2013 11:45:06 -0300 +Subject: drm/i915: properly set HSW WM_LP watermarks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We were previously only setting the WM_PIPE registers, now we are +setting the LP watermark registers. This should allow deeper PC +states, resulting in power savings. + +We're only using 1/2 data buffer partitioning for now. + +v2: Merge both hsw_compute_pri_wm_* functions (Ville) +v3: - Simplify hsw_compute_wm_results (Ville) + - Rebase due to changes on the previous patch +v4: Unconfuse wm_lp/level (Ville) + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit cca32e9ad372172c808b93eebff536459ce37d85) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 4 + + drivers/gpu/drm/i915/intel_pm.c | 179 ++++++++++++++++++++++++++++++++++++---- + 2 files changed, 165 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index a2a4bc6dfe57..8fdafd4619ae 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -3106,6 +3106,10 @@ + #define WM3S_LP_IVB 0x45128 + #define WM1S_LP_EN (1<<31) + ++#define HSW_WM_LP_VAL(lat, fbc, pri, cur) \ ++ (WM3_LP_EN | ((lat) << WM1_LP_LATENCY_SHIFT) | \ ++ ((fbc) << WM1_LP_FBC_SHIFT) | ((pri) << WM1_LP_SR_SHIFT) | (cur)) ++ + /* Memory latency timer register */ + #define MLTR_ILK 0x11222 + #define MLTR_WM1_SHIFT 0 +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index bbd2a06718b1..bc476bc15916 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2129,6 +2129,12 @@ static uint32_t hsw_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, + return ret; + } + ++static uint32_t hsw_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels, ++ uint8_t bytes_per_pixel) ++{ ++ return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2; ++} ++ + struct hsw_pipe_wm_parameters { + bool active; + bool sprite_enabled; +@@ -2142,11 +2148,28 @@ struct hsw_pipe_wm_parameters { + uint32_t pixel_rate; + }; + ++struct hsw_wm_maximums { ++ uint16_t pri; ++ uint16_t spr; ++ uint16_t cur; ++ uint16_t fbc; ++}; ++ ++struct hsw_lp_wm_result { ++ bool enable; ++ bool fbc_enable; ++ uint32_t pri_val; ++ uint32_t spr_val; ++ uint32_t cur_val; ++ uint32_t fbc_val; ++}; ++ + struct hsw_wm_values { + uint32_t wm_pipe[3]; + uint32_t wm_lp[3]; + uint32_t wm_lp_spr[3]; + uint32_t wm_linetime[3]; ++ bool enable_fbc_wm; + }; + + enum hsw_data_buf_partitioning { +@@ -2154,17 +2177,31 @@ enum hsw_data_buf_partitioning { + HSW_DATA_BUF_PART_5_6, + }; + +-/* Only for WM_PIPE. */ +-static uint32_t hsw_compute_pri_wm_pipe(struct hsw_pipe_wm_parameters *params, +- uint32_t mem_value) ++/* For both WM_PIPE and WM_LP. */ ++static uint32_t hsw_compute_pri_wm(struct hsw_pipe_wm_parameters *params, ++ uint32_t mem_value, ++ bool is_lp) + { ++ uint32_t method1, method2; ++ + /* TODO: for now, assume the primary plane is always enabled. */ + if (!params->active) + return 0; + +- return hsw_wm_method1(params->pixel_rate, +- params->pri_bytes_per_pixel, +- mem_value); ++ method1 = hsw_wm_method1(params->pixel_rate, ++ params->pri_bytes_per_pixel, ++ mem_value); ++ ++ if (!is_lp) ++ return method1; ++ ++ method2 = hsw_wm_method2(params->pixel_rate, ++ params->pipe_htotal, ++ params->pri_horiz_pixels, ++ params->pri_bytes_per_pixel, ++ mem_value); ++ ++ return min(method1, method2); + } + + /* For both WM_PIPE and WM_LP. */ +@@ -2201,13 +2238,60 @@ static uint32_t hsw_compute_cur_wm(struct hsw_pipe_wm_parameters *params, + mem_value); + } + ++/* Only for WM_LP. */ ++static uint32_t hsw_compute_fbc_wm(struct hsw_pipe_wm_parameters *params, ++ uint32_t pri_val, ++ uint32_t mem_value) ++{ ++ if (!params->active) ++ return 0; ++ ++ return hsw_wm_fbc(pri_val, ++ params->pri_horiz_pixels, ++ params->pri_bytes_per_pixel); ++} ++ ++static bool hsw_compute_lp_wm(uint32_t mem_value, struct hsw_wm_maximums *max, ++ struct hsw_pipe_wm_parameters *params, ++ struct hsw_lp_wm_result *result) ++{ ++ enum pipe pipe; ++ uint32_t pri_val[3], spr_val[3], cur_val[3], fbc_val[3]; ++ ++ for (pipe = PIPE_A; pipe <= PIPE_C; pipe++) { ++ struct hsw_pipe_wm_parameters *p = ¶ms[pipe]; ++ ++ pri_val[pipe] = hsw_compute_pri_wm(p, mem_value, true); ++ spr_val[pipe] = hsw_compute_spr_wm(p, mem_value); ++ cur_val[pipe] = hsw_compute_cur_wm(p, mem_value); ++ fbc_val[pipe] = hsw_compute_fbc_wm(p, pri_val[pipe], mem_value); ++ } ++ ++ result->pri_val = max3(pri_val[0], pri_val[1], pri_val[2]); ++ result->spr_val = max3(spr_val[0], spr_val[1], spr_val[2]); ++ result->cur_val = max3(cur_val[0], cur_val[1], cur_val[2]); ++ result->fbc_val = max3(fbc_val[0], fbc_val[1], fbc_val[2]); ++ ++ if (result->fbc_val > max->fbc) { ++ result->fbc_enable = false; ++ result->fbc_val = 0; ++ } else { ++ result->fbc_enable = true; ++ } ++ ++ result->enable = result->pri_val <= max->pri && ++ result->spr_val <= max->spr && ++ result->cur_val <= max->cur; ++ return result->enable; ++} ++ + static uint32_t hsw_compute_wm_pipe(struct drm_i915_private *dev_priv, + uint32_t mem_value, enum pipe pipe, + struct hsw_pipe_wm_parameters *params) + { + uint32_t pri_val, cur_val, spr_val; + +- pri_val = hsw_compute_pri_wm_pipe(params, mem_value); ++ pri_val = hsw_compute_pri_wm(params, mem_value, false); + spr_val = hsw_compute_spr_wm(params, mem_value); + cur_val = hsw_compute_cur_wm(params, mem_value); + +@@ -2250,13 +2334,15 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) + + static void hsw_compute_wm_parameters(struct drm_device *dev, + struct hsw_pipe_wm_parameters *params, +- uint32_t *wm) ++ uint32_t *wm, ++ struct hsw_wm_maximums *lp_max_1_2) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + struct drm_plane *plane; + uint64_t sskpd = I915_READ64(MCH_SSKPD); + enum pipe pipe; ++ int pipes_active = 0, sprites_enabled = 0; + + if ((sskpd >> 56) & 0xFF) + wm[0] = (sskpd >> 56) & 0xFF; +@@ -2278,6 +2364,8 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, + if (!p->active) + continue; + ++ pipes_active++; ++ + p->pipe_htotal = intel_crtc->config.adjusted_mode.htotal; + p->pixel_rate = hsw_wm_get_pixel_rate(dev, crtc); + p->pri_bytes_per_pixel = crtc->fb->bits_per_pixel / 8; +@@ -2297,25 +2385,66 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, + p->sprite_enabled = intel_plane->wm.enable; + p->spr_bytes_per_pixel = intel_plane->wm.bytes_per_pixel; + p->spr_horiz_pixels = intel_plane->wm.horiz_pixels; ++ ++ if (p->sprite_enabled) ++ sprites_enabled++; ++ } ++ ++ if (pipes_active > 1) { ++ lp_max_1_2->pri = sprites_enabled ? 128 : 256; ++ lp_max_1_2->spr = 128; ++ lp_max_1_2->cur = 64; ++ } else { ++ lp_max_1_2->pri = sprites_enabled ? 384 : 768; ++ lp_max_1_2->spr = 384; ++ lp_max_1_2->cur = 255; + } ++ lp_max_1_2->fbc = 15; + } + + static void hsw_compute_wm_results(struct drm_device *dev, + struct hsw_pipe_wm_parameters *params, + uint32_t *wm, ++ struct hsw_wm_maximums *lp_maximums, + struct hsw_wm_values *results) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; ++ struct hsw_lp_wm_result lp_results[4] = {}; + enum pipe pipe; ++ int level, max_level, wm_lp; ++ ++ for (level = 1; level <= 4; level++) ++ if (!hsw_compute_lp_wm(wm[level], lp_maximums, params, ++ &lp_results[level - 1])) ++ break; ++ max_level = level - 1; ++ ++ /* The spec says it is preferred to disable FBC WMs instead of disabling ++ * a WM level. */ ++ results->enable_fbc_wm = true; ++ for (level = 1; level <= max_level; level++) { ++ if (!lp_results[level - 1].fbc_enable) { ++ results->enable_fbc_wm = false; ++ break; ++ } ++ } ++ ++ memset(results, 0, sizeof(*results)); ++ for (wm_lp = 1; wm_lp <= 3; wm_lp++) { ++ const struct hsw_lp_wm_result *r; + +- /* No support for LP WMs yet. */ +- results->wm_lp[2] = 0; +- results->wm_lp[1] = 0; +- results->wm_lp[0] = 0; +- results->wm_lp_spr[2] = 0; +- results->wm_lp_spr[1] = 0; +- results->wm_lp_spr[0] = 0; ++ level = (max_level == 4 && wm_lp > 1) ? wm_lp + 1 : wm_lp; ++ if (level > max_level) ++ break; ++ ++ r = &lp_results[level - 1]; ++ results->wm_lp[wm_lp - 1] = HSW_WM_LP_VAL(level * 2, ++ r->fbc_val, ++ r->pri_val, ++ r->cur_val); ++ results->wm_lp_spr[wm_lp - 1] = r->spr_val; ++ } + + for_each_pipe(pipe) + results->wm_pipe[pipe] = hsw_compute_wm_pipe(dev_priv, wm[0], +@@ -2339,6 +2468,7 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv, + struct hsw_wm_values previous; + uint32_t val; + enum hsw_data_buf_partitioning prev_partitioning; ++ bool prev_enable_fbc_wm; + + previous.wm_pipe[0] = I915_READ(WM0_PIPEA_ILK); + previous.wm_pipe[1] = I915_READ(WM0_PIPEB_ILK); +@@ -2356,6 +2486,8 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv, + prev_partitioning = (I915_READ(WM_MISC) & WM_MISC_DATA_PARTITION_5_6) ? + HSW_DATA_BUF_PART_5_6 : HSW_DATA_BUF_PART_1_2; + ++ prev_enable_fbc_wm = !(I915_READ(DISP_ARB_CTL) & DISP_FBC_WM_DIS); ++ + if (memcmp(results->wm_pipe, previous.wm_pipe, + sizeof(results->wm_pipe)) == 0 && + memcmp(results->wm_lp, previous.wm_lp, +@@ -2364,7 +2496,8 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv, + sizeof(results->wm_lp_spr)) == 0 && + memcmp(results->wm_linetime, previous.wm_linetime, + sizeof(results->wm_linetime)) == 0 && +- partitioning == prev_partitioning) ++ partitioning == prev_partitioning && ++ results->enable_fbc_wm == prev_enable_fbc_wm) + return; + + if (previous.wm_lp[2] != 0) +@@ -2397,6 +2530,15 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv, + I915_WRITE(WM_MISC, val); + } + ++ if (prev_enable_fbc_wm != results->enable_fbc_wm) { ++ val = I915_READ(DISP_ARB_CTL); ++ if (results->enable_fbc_wm) ++ val &= ~DISP_FBC_WM_DIS; ++ else ++ val |= DISP_FBC_WM_DIS; ++ I915_WRITE(DISP_ARB_CTL, val); ++ } ++ + if (previous.wm_lp_spr[0] != results->wm_lp_spr[0]) + I915_WRITE(WM1S_LP_ILK, results->wm_lp_spr[0]); + if (previous.wm_lp_spr[1] != results->wm_lp_spr[1]) +@@ -2415,12 +2557,13 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv, + static void haswell_update_wm(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; ++ struct hsw_wm_maximums lp_max_1_2; + struct hsw_pipe_wm_parameters params[3]; + struct hsw_wm_values results; + uint32_t wm[5]; + +- hsw_compute_wm_parameters(dev, params, wm); +- hsw_compute_wm_results(dev, params, wm, &results); ++ hsw_compute_wm_parameters(dev, params, wm, &lp_max_1_2); ++ hsw_compute_wm_results(dev, params, wm, &lp_max_1_2, &results); + hsw_write_wm_values(dev_priv, &results, HSW_DATA_BUF_PART_1_2); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0222-drm-i915-add-support-for-5-6-data-buffer-partitionin.patch b/patches.baytrail/0222-drm-i915-add-support-for-5-6-data-buffer-partitionin.patch new file mode 100644 index 000000000000..e254eeaafb0a --- /dev/null +++ b/patches.baytrail/0222-drm-i915-add-support-for-5-6-data-buffer-partitionin.patch @@ -0,0 +1,133 @@ +From 101aa5ff33bb6e6195eadd076bbb54c545b4163a Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 31 May 2013 10:19:21 -0300 +Subject: drm/i915: add support for 5/6 data buffer partitioning on Haswell +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Now we compute the results for both 1/2 and 5/6 partitioning and then +use hsw_find_best_result to choose which one to use. + +With this patch, Haswell watermarks support should be in good shape. +The only improvement we're missing is the case where the primary plane +is disabled: we always assume it's enabled, so we take it into +consideration when calculating the watermarks. + +v2: - Check the latency when finding the best result + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 861f3389c6627460bcd19d1442eb650001f15c9b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 64 ++++++++++++++++++++++++++++++++++------- + 1 file changed, 53 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index bc476bc15916..80294f285467 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2335,7 +2335,8 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) + static void hsw_compute_wm_parameters(struct drm_device *dev, + struct hsw_pipe_wm_parameters *params, + uint32_t *wm, +- struct hsw_wm_maximums *lp_max_1_2) ++ struct hsw_wm_maximums *lp_max_1_2, ++ struct hsw_wm_maximums *lp_max_5_6) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; +@@ -2391,15 +2392,17 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, + } + + if (pipes_active > 1) { +- lp_max_1_2->pri = sprites_enabled ? 128 : 256; +- lp_max_1_2->spr = 128; +- lp_max_1_2->cur = 64; ++ lp_max_1_2->pri = lp_max_5_6->pri = sprites_enabled ? 128 : 256; ++ lp_max_1_2->spr = lp_max_5_6->spr = 128; ++ lp_max_1_2->cur = lp_max_5_6->cur = 64; + } else { + lp_max_1_2->pri = sprites_enabled ? 384 : 768; ++ lp_max_5_6->pri = sprites_enabled ? 128 : 768; + lp_max_1_2->spr = 384; +- lp_max_1_2->cur = 255; ++ lp_max_5_6->spr = 640; ++ lp_max_1_2->cur = lp_max_5_6->cur = 255; + } +- lp_max_1_2->fbc = 15; ++ lp_max_1_2->fbc = lp_max_5_6->fbc = 15; + } + + static void hsw_compute_wm_results(struct drm_device *dev, +@@ -2457,6 +2460,32 @@ static void hsw_compute_wm_results(struct drm_device *dev, + } + } + ++/* Find the result with the highest level enabled. Check for enable_fbc_wm in ++ * case both are at the same level. Prefer r1 in case they're the same. */ ++struct hsw_wm_values *hsw_find_best_result(struct hsw_wm_values *r1, ++ struct hsw_wm_values *r2) ++{ ++ int i, val_r1 = 0, val_r2 = 0; ++ ++ for (i = 0; i < 3; i++) { ++ if (r1->wm_lp[i] & WM3_LP_EN) ++ val_r1 = r1->wm_lp[i] & WM1_LP_LATENCY_MASK; ++ if (r2->wm_lp[i] & WM3_LP_EN) ++ val_r2 = r2->wm_lp[i] & WM1_LP_LATENCY_MASK; ++ } ++ ++ if (val_r1 == val_r2) { ++ if (r2->enable_fbc_wm && !r1->enable_fbc_wm) ++ return r2; ++ else ++ return r1; ++ } else if (val_r1 > val_r2) { ++ return r1; ++ } else { ++ return r2; ++ } ++} ++ + /* + * The spec says we shouldn't write when we don't need, because every write + * causes WMs to be re-evaluated, expending some power. +@@ -2557,14 +2586,27 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv, + static void haswell_update_wm(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- struct hsw_wm_maximums lp_max_1_2; ++ struct hsw_wm_maximums lp_max_1_2, lp_max_5_6; + struct hsw_pipe_wm_parameters params[3]; +- struct hsw_wm_values results; ++ struct hsw_wm_values results_1_2, results_5_6, *best_results; + uint32_t wm[5]; ++ enum hsw_data_buf_partitioning partitioning; ++ ++ hsw_compute_wm_parameters(dev, params, wm, &lp_max_1_2, &lp_max_5_6); ++ ++ hsw_compute_wm_results(dev, params, wm, &lp_max_1_2, &results_1_2); ++ if (lp_max_1_2.pri != lp_max_5_6.pri) { ++ hsw_compute_wm_results(dev, params, wm, &lp_max_5_6, ++ &results_5_6); ++ best_results = hsw_find_best_result(&results_1_2, &results_5_6); ++ } else { ++ best_results = &results_1_2; ++ } ++ ++ partitioning = (best_results == &results_1_2) ? ++ HSW_DATA_BUF_PART_1_2 : HSW_DATA_BUF_PART_5_6; + +- hsw_compute_wm_parameters(dev, params, wm, &lp_max_1_2); +- hsw_compute_wm_results(dev, params, wm, &lp_max_1_2, &results); +- hsw_write_wm_values(dev_priv, &results, HSW_DATA_BUF_PART_1_2); ++ hsw_write_wm_values(dev_priv, best_results, partitioning); + } + + static void haswell_update_sprite_wm(struct drm_device *dev, int pipe, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0223-drm-i915-Create-a-more-generic-pm-handler-for-hsw.patch b/patches.baytrail/0223-drm-i915-Create-a-more-generic-pm-handler-for-hsw.patch new file mode 100644 index 000000000000..b50d6b3a22f6 --- /dev/null +++ b/patches.baytrail/0223-drm-i915-Create-a-more-generic-pm-handler-for-hsw.patch @@ -0,0 +1,80 @@ +From b933565650c82ce49fbc4eb152834d9f6bad4001 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:24 -0700 +Subject: drm/i915: Create a more generic pm handler for hsw+ + +HSW has some special requirements for the VEBOX. Splitting out the +interrupt handler will make the code a bit nicer and less error prone +when we begin to handle those. + +The slight functional change in this patch (queueing work while holding +the spinlock) is intentional as it makes a subsequent patch a bit nicer. +The change should also only effect HSW platforms. + +Reviewed-by: Damien Lespiau +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit baf02a1fb0485b0cca8666241577b4ef87914d87) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 30 +++++++++++++++++++++++++++++- + 1 file changed, 29 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 77baf991499b..85149d27f9e1 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -833,6 +833,7 @@ static void snb_gt_irq_handler(struct drm_device *dev, + ivybridge_handle_parity_error(dev); + } + ++/* Legacy way of handling PM interrupts */ + static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, + u32 pm_iir) + { +@@ -912,6 +913,31 @@ static void dp_aux_irq_handler(struct drm_device *dev) + wake_up_all(&dev_priv->gmbus_wait_queue); + } + ++/* Unlike gen6_queue_rps_work() from which this function is originally derived, ++ * we must be able to deal with other PM interrupts. This is complicated because ++ * of the way in which we use the masks to defer the RPS work (which for ++ * posterity is necessary because of forcewake). ++ */ ++static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv, ++ u32 pm_iir) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev_priv->rps.lock, flags); ++ dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_DEFERRED_EVENTS; ++ if (dev_priv->rps.pm_iir) { ++ I915_WRITE(GEN6_PMIMR, dev_priv->rps.pm_iir); ++ /* never want to mask useful interrupts. (also posting read) */ ++ WARN_ON(I915_READ_NOTRACE(GEN6_PMIMR) & ~GEN6_PM_DEFERRED_EVENTS); ++ /* TODO: if queue_work is slow, move it out of the spinlock */ ++ queue_work(dev_priv->wq, &dev_priv->rps.work); ++ } ++ spin_unlock_irqrestore(&dev_priv->rps.lock, flags); ++ ++ if (pm_iir & ~GEN6_PM_DEFERRED_EVENTS) ++ DRM_ERROR("Unexpected PM interrupted\n"); ++} ++ + static irqreturn_t valleyview_irq_handler(int irq, void *arg) + { + struct drm_device *dev = (struct drm_device *) arg; +@@ -1222,7 +1248,9 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + + pm_iir = I915_READ(GEN6_PMIIR); + if (pm_iir) { +- if (pm_iir & GEN6_PM_DEFERRED_EVENTS) ++ if (IS_HASWELL(dev)) ++ hsw_pm_irq_handler(dev_priv, pm_iir); ++ else if (pm_iir & GEN6_PM_DEFERRED_EVENTS) + gen6_queue_rps_work(dev_priv, pm_iir); + I915_WRITE(GEN6_PMIIR, pm_iir); + ret = IRQ_HANDLED; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0224-drm-i915-Create-an-ivybridge_irq_preinstall.patch b/patches.baytrail/0224-drm-i915-Create-an-ivybridge_irq_preinstall.patch new file mode 100644 index 000000000000..68b9f5f614ee --- /dev/null +++ b/patches.baytrail/0224-drm-i915-Create-an-ivybridge_irq_preinstall.patch @@ -0,0 +1,78 @@ +From 2b144769b8d88652ed455bd426084f2e4f667452 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:25 -0700 +Subject: drm/i915: Create an ivybridge_irq_preinstall + +Just duplicates ironlake_irq_preinstall for now. + +v2: Add new PCH_NOP check (Damien) +Add SDEIMR comment (Damien) + +Signed-off-by: Ben Widawsky +Reviewed-by: Damien Lespiau +[danvet: Update now outdated comment.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 7d99163da69e04ccae0b52093f716167ed71d66d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 35 +++++++++++++++++++++++++++++++++-- + 1 file changed, 33 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 85149d27f9e1..f490d54f4726 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2528,6 +2528,37 @@ static void ironlake_irq_preinstall(struct drm_device *dev) + I915_WRITE(GTIER, 0x0); + POSTING_READ(GTIER); + ++ /* south display irq */ ++ I915_WRITE(SDEIMR, 0xffffffff); ++ /* ++ * SDEIER is also touched by the interrupt handler to work around missed ++ * PCH interrupts. Hence we can't update it after the interrupt handler ++ * is enabled - instead we unconditionally enable all PCH interrupt ++ * sources here, but then only unmask them as needed with SDEIMR. ++ */ ++ I915_WRITE(SDEIER, 0xffffffff); ++ POSTING_READ(SDEIER); ++} ++ ++static void ivybridge_irq_preinstall(struct drm_device *dev) ++{ ++ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; ++ ++ atomic_set(&dev_priv->irq_received, 0); ++ ++ I915_WRITE(HWSTAM, 0xeffe); ++ ++ /* XXX hotplug from PCH */ ++ ++ I915_WRITE(DEIMR, 0xffffffff); ++ I915_WRITE(DEIER, 0x0); ++ POSTING_READ(DEIER); ++ ++ /* and GT */ ++ I915_WRITE(GTIMR, 0xffffffff); ++ I915_WRITE(GTIER, 0x0); ++ POSTING_READ(GTIER); ++ + if (HAS_PCH_NOP(dev)) + return; + +@@ -3531,9 +3562,9 @@ void intel_irq_init(struct drm_device *dev) + dev->driver->disable_vblank = valleyview_disable_vblank; + dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; + } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { +- /* Share pre & uninstall handlers with ILK/SNB */ ++ /* Share uninstall handlers with ILK/SNB */ + dev->driver->irq_handler = ivybridge_irq_handler; +- dev->driver->irq_preinstall = ironlake_irq_preinstall; ++ dev->driver->irq_preinstall = ivybridge_irq_preinstall; + dev->driver->irq_postinstall = ivybridge_irq_postinstall; + dev->driver->irq_uninstall = ironlake_irq_uninstall; + dev->driver->enable_vblank = ivybridge_enable_vblank; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0225-drm-i915-Add-PM-regs-to-pre-post-install.patch b/patches.baytrail/0225-drm-i915-Add-PM-regs-to-pre-post-install.patch new file mode 100644 index 000000000000..e09fd89852d8 --- /dev/null +++ b/patches.baytrail/0225-drm-i915-Add-PM-regs-to-pre-post-install.patch @@ -0,0 +1,80 @@ +From 52b9a7ae4e27b821aaf99d0fd54a3e9a603a42d4 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:26 -0700 +Subject: drm/i915: Add PM regs to pre/post install + +At the moment, these values are wiped out anyway by the rps +enable/disable. That will be changed in the next patch though. + +v2: Add post install setup to address issue found by Damien in the next +patch. +replaced +WARN_ON(dev_priv->rps.pm_iir != 0); +with rps.pm_iir = 0; + +With the v2 of this patch and the deferred pm enabling (which changed +since the original patches) we're now able to get PM interrupts before +we've brought up enabled rps. At this point in boot, we don't want to do +anything about it, so we simply ignore it. Since writing the original +assertion, the code has changed quite a bit, and I believe removing this +assertion is perfectly safe. + +Signed-off-by: Ben Widawsky +Reviewed-by: Damien Lespiau +[danvet: I don't agree with the justification to drop the WARN and +added a FIXME to that effect.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit eda63ffb906c2fb3b609a0e87aeb63c0f25b9e6b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 10 ++++++++++ + drivers/gpu/drm/i915/intel_pm.c | 4 +++- + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index f490d54f4726..c150f90b5770 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2559,6 +2559,11 @@ static void ivybridge_irq_preinstall(struct drm_device *dev) + I915_WRITE(GTIER, 0x0); + POSTING_READ(GTIER); + ++ /* Power management */ ++ I915_WRITE(GEN6_PMIMR, 0xffffffff); ++ I915_WRITE(GEN6_PMIER, 0x0); ++ POSTING_READ(GEN6_PMIER); ++ + if (HAS_PCH_NOP(dev)) + return; + +@@ -2747,6 +2752,11 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) + I915_WRITE(GTIER, render_irqs); + POSTING_READ(GTIER); + ++ /* Power management */ ++ I915_WRITE(GEN6_PMIMR, ~GEN6_PM_DEFERRED_EVENTS); ++ I915_WRITE(GEN6_PMIER, GEN6_PM_DEFERRED_EVENTS); ++ POSTING_READ(GEN6_PMIMR); ++ + ibx_irq_postinstall(dev); + + return 0; +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 80294f285467..5890c610db3c 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3309,7 +3309,9 @@ static void gen6_enable_rps(struct drm_device *dev) + /* requires MSI enabled */ + I915_WRITE(GEN6_PMIER, GEN6_PM_DEFERRED_EVENTS); + spin_lock_irq(&dev_priv->rps.lock); +- WARN_ON(dev_priv->rps.pm_iir != 0); ++ /* FIXME: Our interrupt enabling sequence is bonghits. ++ * dev_priv->rps.pm_iir really should be 0 here. */ ++ dev_priv->rps.pm_iir = 0; + I915_WRITE(GEN6_PMIMR, 0); + spin_unlock_irq(&dev_priv->rps.lock); + /* enable all PM interrupts */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0226-drm-i915-make-PM-interrupt-writes-non-destructive.patch b/patches.baytrail/0226-drm-i915-make-PM-interrupt-writes-non-destructive.patch new file mode 100644 index 000000000000..07446d483d24 --- /dev/null +++ b/patches.baytrail/0226-drm-i915-make-PM-interrupt-writes-non-destructive.patch @@ -0,0 +1,196 @@ +From ea23acc752f131163b7b23c06453f478e5991981 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:27 -0700 +Subject: drm/i915: make PM interrupt writes non-destructive + +PM interrupts have an expanded role on HSW. It helps route the EBOX +interrupts. This patch is necessary to make the existing code which +touches the mask, and enable registers more friendly to other code paths +that also will need these registers. + +To be more explicit: +At preinstall all interrupts are masked and disabled. This implies that +preinstall should always happen before any enabling/disabling of RPS or +other interrupts. + +The PMIMR is touched by the workqueue, so enable/disable touch IER and +IIR. Similarly, the code currently expects IMR has no use outside of the +RPS related interrupts so they unconditionally set 0, or ~0. We could +use IER in the workqueue, and IMR elsewhere, but since the workqueue +use-case is more transient the existing usage makes sense. + +Disable RPS events: +IER := IER & ~GEN6_PM_RPS_EVENTS // Disable RPS related interrupts +IIR := GEN6_PM_RPS_EVENTS // Disable any outstanding interrupts + +Enable RPS events: +IER := IER | GEN6_PM_RPS_EVENTS // Enable the RPS related interrupts +IIR := GEN6_PM_RPS_EVENTS // Make sure there were no leftover events +(really shouldn't happen) + +v2: Shouldn't destroy PMIIR or PMIMR VEBOX interrupt state in +enable/disable rps functions (Haihao) + +v3: Bug found by Chris where we were clearing the wrong bits at rps +disable. + expanded commit message + +v4: v3 was based off the wrong branch + +v5: Added the setting of PMIMR because of previous patch update + +CC: Chris Wilson +Signed-off-by: Ben Widawsky +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 4848405cced3b46f4ec7d404b8ed5873171ae10a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 21 +++++++++++---------- + drivers/gpu/drm/i915/i915_reg.h | 2 +- + drivers/gpu/drm/i915/intel_pm.c | 13 +++++++------ + 3 files changed, 19 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index c150f90b5770..19734c719ef8 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -691,10 +691,11 @@ static void gen6_pm_rps_work(struct work_struct *work) + pm_iir = dev_priv->rps.pm_iir; + dev_priv->rps.pm_iir = 0; + pm_imr = I915_READ(GEN6_PMIMR); +- I915_WRITE(GEN6_PMIMR, 0); ++ /* Make sure not to corrupt PMIMR state used by ringbuffer code */ ++ I915_WRITE(GEN6_PMIMR, pm_imr & ~GEN6_PM_RPS_EVENTS); + spin_unlock_irq(&dev_priv->rps.lock); + +- if ((pm_iir & GEN6_PM_DEFERRED_EVENTS) == 0) ++ if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0) + return; + + mutex_lock(&dev_priv->rps.hw_lock); +@@ -924,17 +925,17 @@ static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv, + unsigned long flags; + + spin_lock_irqsave(&dev_priv->rps.lock, flags); +- dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_DEFERRED_EVENTS; ++ dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS; + if (dev_priv->rps.pm_iir) { + I915_WRITE(GEN6_PMIMR, dev_priv->rps.pm_iir); + /* never want to mask useful interrupts. (also posting read) */ +- WARN_ON(I915_READ_NOTRACE(GEN6_PMIMR) & ~GEN6_PM_DEFERRED_EVENTS); ++ WARN_ON(I915_READ_NOTRACE(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS); + /* TODO: if queue_work is slow, move it out of the spinlock */ + queue_work(dev_priv->wq, &dev_priv->rps.work); + } + spin_unlock_irqrestore(&dev_priv->rps.lock, flags); + +- if (pm_iir & ~GEN6_PM_DEFERRED_EVENTS) ++ if (pm_iir & ~GEN6_PM_RPS_EVENTS) + DRM_ERROR("Unexpected PM interrupted\n"); + } + +@@ -1009,7 +1010,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) + if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS) + gmbus_irq_handler(dev); + +- if (pm_iir & GEN6_PM_DEFERRED_EVENTS) ++ if (pm_iir & GEN6_PM_RPS_EVENTS) + gen6_queue_rps_work(dev_priv, pm_iir); + + I915_WRITE(GTIIR, gt_iir); +@@ -1250,7 +1251,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + if (pm_iir) { + if (IS_HASWELL(dev)) + hsw_pm_irq_handler(dev_priv, pm_iir); +- else if (pm_iir & GEN6_PM_DEFERRED_EVENTS) ++ else if (pm_iir & GEN6_PM_RPS_EVENTS) + gen6_queue_rps_work(dev_priv, pm_iir); + I915_WRITE(GEN6_PMIIR, pm_iir); + ret = IRQ_HANDLED; +@@ -1365,7 +1366,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + if (IS_GEN5(dev) && de_iir & DE_PCU_EVENT) + ironlake_handle_rps_change(dev); + +- if (IS_GEN6(dev) && pm_iir & GEN6_PM_DEFERRED_EVENTS) ++ if (IS_GEN6(dev) && pm_iir & GEN6_PM_RPS_EVENTS) + gen6_queue_rps_work(dev_priv, pm_iir); + + I915_WRITE(GTIIR, gt_iir); +@@ -2753,8 +2754,8 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) + POSTING_READ(GTIER); + + /* Power management */ +- I915_WRITE(GEN6_PMIMR, ~GEN6_PM_DEFERRED_EVENTS); +- I915_WRITE(GEN6_PMIER, GEN6_PM_DEFERRED_EVENTS); ++ I915_WRITE(GEN6_PMIMR, ~GEN6_PM_RPS_EVENTS); ++ I915_WRITE(GEN6_PMIER, GEN6_PM_RPS_EVENTS); + POSTING_READ(GEN6_PMIMR); + + ibx_irq_postinstall(dev); +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 8fdafd4619ae..30f6cfe91d1b 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -4572,7 +4572,7 @@ + #define GEN6_PM_RP_DOWN_THRESHOLD (1<<4) + #define GEN6_PM_RP_UP_EI_EXPIRED (1<<2) + #define GEN6_PM_RP_DOWN_EI_EXPIRED (1<<1) +-#define GEN6_PM_DEFERRED_EVENTS (GEN6_PM_RP_UP_THRESHOLD | \ ++#define GEN6_PM_RPS_EVENTS (GEN6_PM_RP_UP_THRESHOLD | \ + GEN6_PM_RP_DOWN_THRESHOLD | \ + GEN6_PM_RP_DOWN_TIMEOUT) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 5890c610db3c..8af5c12e944d 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3116,7 +3116,7 @@ static void gen6_disable_rps(struct drm_device *dev) + I915_WRITE(GEN6_RC_CONTROL, 0); + I915_WRITE(GEN6_RPNSWREQ, 1 << 31); + I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); +- I915_WRITE(GEN6_PMIER, 0); ++ I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) & ~GEN6_PM_RPS_EVENTS); + /* Complete PM interrupt masking here doesn't race with the rps work + * item again unmasking PM interrupts because that is using a different + * register (PMIMR) to mask PM interrupts. The only risk is in leaving +@@ -3126,7 +3126,7 @@ static void gen6_disable_rps(struct drm_device *dev) + dev_priv->rps.pm_iir = 0; + spin_unlock_irq(&dev_priv->rps.lock); + +- I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); ++ I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); + } + + static void valleyview_disable_rps(struct drm_device *dev) +@@ -3307,14 +3307,15 @@ static void gen6_enable_rps(struct drm_device *dev) + gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8); + + /* requires MSI enabled */ +- I915_WRITE(GEN6_PMIER, GEN6_PM_DEFERRED_EVENTS); ++ I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) | GEN6_PM_RPS_EVENTS); + spin_lock_irq(&dev_priv->rps.lock); + /* FIXME: Our interrupt enabling sequence is bonghits. + * dev_priv->rps.pm_iir really should be 0 here. */ + dev_priv->rps.pm_iir = 0; +- I915_WRITE(GEN6_PMIMR, 0); ++ I915_WRITE(GEN6_PMIMR, I915_READ(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS); ++ I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); + spin_unlock_irq(&dev_priv->rps.lock); +- /* enable all PM interrupts */ ++ /* unmask all PM interrupts */ + I915_WRITE(GEN6_PMINTRMSK, 0); + + rc6vids = 0; +@@ -3577,7 +3578,7 @@ static void valleyview_enable_rps(struct drm_device *dev) + valleyview_set_rps(dev_priv->dev, rpe); + + /* requires MSI enabled */ +- I915_WRITE(GEN6_PMIER, GEN6_PM_DEFERRED_EVENTS); ++ I915_WRITE(GEN6_PMIER, GEN6_PM_RPS_EVENTS); + spin_lock_irq(&dev_priv->rps.lock); + WARN_ON(dev_priv->rps.pm_iir != 0); + I915_WRITE(GEN6_PMIMR, 0); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0227-drm-i915-Convert-irq_refounct-to-struct.patch b/patches.baytrail/0227-drm-i915-Convert-irq_refounct-to-struct.patch new file mode 100644 index 000000000000..4ee723c8970c --- /dev/null +++ b/patches.baytrail/0227-drm-i915-Convert-irq_refounct-to-struct.patch @@ -0,0 +1,111 @@ +From 79ebbcfe0b10e4ec570759644c30e7376b7bda0b Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:28 -0700 +Subject: drm/i915: Convert irq_refounct to struct + +It's overkill on older gens, but it's useful for newer gens. + +Reviewed-by: Damien Lespiau +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit aeb0659338793746b8a4e482fa588ba1dd9ee559) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ringbuffer.c | 16 ++++++++-------- + drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +++- + 2 files changed, 11 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index c626a943d9c2..8246213ffada 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -794,7 +794,7 @@ gen5_ring_get_irq(struct intel_ring_buffer *ring) + return false; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (ring->irq_refcount++ == 0) { ++ if (ring->irq_refcount.gt++ == 0) { + dev_priv->gt_irq_mask &= ~ring->irq_enable_mask; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + POSTING_READ(GTIMR); +@@ -812,7 +812,7 @@ gen5_ring_put_irq(struct intel_ring_buffer *ring) + unsigned long flags; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (--ring->irq_refcount == 0) { ++ if (--ring->irq_refcount.gt == 0) { + dev_priv->gt_irq_mask |= ring->irq_enable_mask; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + POSTING_READ(GTIMR); +@@ -831,7 +831,7 @@ i9xx_ring_get_irq(struct intel_ring_buffer *ring) + return false; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (ring->irq_refcount++ == 0) { ++ if (ring->irq_refcount.gt++ == 0) { + dev_priv->irq_mask &= ~ring->irq_enable_mask; + I915_WRITE(IMR, dev_priv->irq_mask); + POSTING_READ(IMR); +@@ -849,7 +849,7 @@ i9xx_ring_put_irq(struct intel_ring_buffer *ring) + unsigned long flags; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (--ring->irq_refcount == 0) { ++ if (--ring->irq_refcount.gt == 0) { + dev_priv->irq_mask |= ring->irq_enable_mask; + I915_WRITE(IMR, dev_priv->irq_mask); + POSTING_READ(IMR); +@@ -868,7 +868,7 @@ i8xx_ring_get_irq(struct intel_ring_buffer *ring) + return false; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (ring->irq_refcount++ == 0) { ++ if (ring->irq_refcount.gt++ == 0) { + dev_priv->irq_mask &= ~ring->irq_enable_mask; + I915_WRITE16(IMR, dev_priv->irq_mask); + POSTING_READ16(IMR); +@@ -886,7 +886,7 @@ i8xx_ring_put_irq(struct intel_ring_buffer *ring) + unsigned long flags; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (--ring->irq_refcount == 0) { ++ if (--ring->irq_refcount.gt == 0) { + dev_priv->irq_mask |= ring->irq_enable_mask; + I915_WRITE16(IMR, dev_priv->irq_mask); + POSTING_READ16(IMR); +@@ -991,7 +991,7 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring) + gen6_gt_force_wake_get(dev_priv); + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (ring->irq_refcount++ == 0) { ++ if (ring->irq_refcount.gt++ == 0) { + if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS) + I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | + GEN6_RENDER_L3_PARITY_ERROR)); +@@ -1014,7 +1014,7 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring) + unsigned long flags; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (--ring->irq_refcount == 0) { ++ if (--ring->irq_refcount.gt == 0) { + if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS) + I915_WRITE_IMR(ring, ~GEN6_RENDER_L3_PARITY_ERROR); + else +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index 1c79520c7e45..153b87f67aae 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -72,7 +72,9 @@ struct intel_ring_buffer { + */ + u32 last_retired_head; + +- u32 irq_refcount; /* protected by dev_priv->irq_lock */ ++ struct { ++ u32 gt; ++ } irq_refcount; /* protected by dev_priv->irq_lock */ + u32 irq_enable_mask; /* bitmask to enable ring interrupt */ + u32 trace_irq_seqno; + u32 sync_seqno[I915_NUM_RINGS-1]; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0228-drm-i915-consolidate-interrupt-naming-scheme.patch b/patches.baytrail/0228-drm-i915-consolidate-interrupt-naming-scheme.patch new file mode 100644 index 000000000000..0be817f8ee79 --- /dev/null +++ b/patches.baytrail/0228-drm-i915-consolidate-interrupt-naming-scheme.patch @@ -0,0 +1,402 @@ +From 3aafcac2d475ed673c184ebfaa1351c8274e9f74 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:29 -0700 +Subject: drm/i915: consolidate interrupt naming scheme + +The motivation here is we're going to add some new interrupt definitions +and handling outside of the GT interrupts which is all we've managed so +far (with some RPS exceptions). By consolidating the names in the future +we can make thing a bit cleaner as we don't need to define register +names twice, and we can leverage pretty decent overlap in HW registers +since ILK. + +To explain briefly what is in the comments: there are two sets of +interrupt masking/enabling registers. At least so far, the definitions +of the two sets overlap. The old code setup distinct names for +interrupts in each set, ie. one for global, and one for ring. This made +things confusing when using the wrong defines in the wrong places. + +rebase: Modified VLV bits + +v2: Renamed GT_RENDER_MASTER to GT_RENDER_CS_MASTER (Damien) + +Reviewed-by: Damien Lespiau +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit cc609d5da5c78c92a2e2565604b2603a0965b494) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 61 ++++++++++--------- + drivers/gpu/drm/i915/i915_reg.h | 101 ++++++++++++++------------------ + drivers/gpu/drm/i915/intel_ringbuffer.c | 21 ++++--- + 3 files changed, 85 insertions(+), 98 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 19734c719ef8..7eabe79680c7 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -771,7 +771,7 @@ static void ivybridge_parity_work(struct work_struct *work) + I915_WRITE(GEN7_MISCCPCTL, misccpctl); + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- dev_priv->gt_irq_mask &= ~GT_GEN7_L3_PARITY_ERROR_INTERRUPT; ++ dev_priv->gt_irq_mask &= ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + +@@ -803,7 +803,7 @@ static void ivybridge_handle_parity_error(struct drm_device *dev) + return; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- dev_priv->gt_irq_mask |= GT_GEN7_L3_PARITY_ERROR_INTERRUPT; ++ dev_priv->gt_irq_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + +@@ -815,22 +815,22 @@ static void snb_gt_irq_handler(struct drm_device *dev, + u32 gt_iir) + { + +- if (gt_iir & (GEN6_RENDER_USER_INTERRUPT | +- GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT)) ++ if (gt_iir & ++ (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT)) + notify_ring(dev, &dev_priv->ring[RCS]); +- if (gt_iir & GEN6_BSD_USER_INTERRUPT) ++ if (gt_iir & GT_BSD_USER_INTERRUPT) + notify_ring(dev, &dev_priv->ring[VCS]); +- if (gt_iir & GEN6_BLITTER_USER_INTERRUPT) ++ if (gt_iir & GT_BLT_USER_INTERRUPT) + notify_ring(dev, &dev_priv->ring[BCS]); + +- if (gt_iir & (GT_GEN6_BLT_CS_ERROR_INTERRUPT | +- GT_GEN6_BSD_CS_ERROR_INTERRUPT | +- GT_RENDER_CS_ERROR_INTERRUPT)) { ++ if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT | ++ GT_BSD_CS_ERROR_INTERRUPT | ++ GT_RENDER_CS_MASTER_ERROR_INTERRUPT)) { + DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir); + i915_handle_error(dev, false); + } + +- if (gt_iir & GT_GEN7_L3_PARITY_ERROR_INTERRUPT) ++ if (gt_iir & GT_RENDER_L3_PARITY_ERROR_INTERRUPT) + ivybridge_handle_parity_error(dev); + } + +@@ -1274,9 +1274,10 @@ static void ilk_gt_irq_handler(struct drm_device *dev, + struct drm_i915_private *dev_priv, + u32 gt_iir) + { +- if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) ++ if (gt_iir & ++ (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT)) + notify_ring(dev, &dev_priv->ring[RCS]); +- if (gt_iir & GT_BSD_USER_INTERRUPT) ++ if (gt_iir & ILK_BSD_USER_INTERRUPT) + notify_ring(dev, &dev_priv->ring[VCS]); + } + +@@ -2677,7 +2678,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) + DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | + DE_AUX_CHANNEL_A | DE_PIPEB_FIFO_UNDERRUN | + DE_PIPEA_FIFO_UNDERRUN | DE_POISON; +- u32 render_irqs; ++ u32 gt_irqs; + + dev_priv->irq_mask = ~display_mask; + +@@ -2692,17 +2693,15 @@ static int ironlake_irq_postinstall(struct drm_device *dev) + I915_WRITE(GTIIR, I915_READ(GTIIR)); + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + ++ gt_irqs = GT_RENDER_USER_INTERRUPT; ++ + if (IS_GEN6(dev)) +- render_irqs = +- GT_USER_INTERRUPT | +- GEN6_BSD_USER_INTERRUPT | +- GEN6_BLITTER_USER_INTERRUPT; ++ gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT; + else +- render_irqs = +- GT_USER_INTERRUPT | +- GT_PIPE_NOTIFY | +- GT_BSD_USER_INTERRUPT; +- I915_WRITE(GTIER, render_irqs); ++ gt_irqs |= GT_RENDER_PIPECTL_NOTIFY_INTERRUPT | ++ ILK_BSD_USER_INTERRUPT; ++ ++ I915_WRITE(GTIER, gt_irqs); + POSTING_READ(GTIER); + + ibx_irq_postinstall(dev); +@@ -2728,7 +2727,7 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) + DE_PLANEA_FLIP_DONE_IVB | + DE_AUX_CHANNEL_A_IVB | + DE_ERR_INT_IVB; +- u32 render_irqs; ++ u32 gt_irqs; + + dev_priv->irq_mask = ~display_mask; + +@@ -2743,14 +2742,14 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) + DE_PIPEA_VBLANK_IVB); + POSTING_READ(DEIER); + +- dev_priv->gt_irq_mask = ~GT_GEN7_L3_PARITY_ERROR_INTERRUPT; ++ dev_priv->gt_irq_mask = ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT; + + I915_WRITE(GTIIR, I915_READ(GTIIR)); + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + +- render_irqs = GT_USER_INTERRUPT | GEN6_BSD_USER_INTERRUPT | +- GEN6_BLITTER_USER_INTERRUPT | GT_GEN7_L3_PARITY_ERROR_INTERRUPT; +- I915_WRITE(GTIER, render_irqs); ++ gt_irqs = GT_RENDER_USER_INTERRUPT | GT_BSD_USER_INTERRUPT | ++ GT_BLT_USER_INTERRUPT | GT_RENDER_L3_PARITY_ERROR_INTERRUPT; ++ I915_WRITE(GTIER, gt_irqs); + POSTING_READ(GTIER); + + /* Power management */ +@@ -2766,9 +2765,9 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) + static int valleyview_irq_postinstall(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; ++ u32 gt_irqs; + u32 enable_mask; + u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV; +- u32 render_irqs; + + enable_mask = I915_DISPLAY_PORT_INTERRUPT; + enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | +@@ -2804,9 +2803,9 @@ static int valleyview_irq_postinstall(struct drm_device *dev) + I915_WRITE(GTIIR, I915_READ(GTIIR)); + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + +- render_irqs = GT_USER_INTERRUPT | GEN6_BSD_USER_INTERRUPT | +- GEN6_BLITTER_USER_INTERRUPT; +- I915_WRITE(GTIER, render_irqs); ++ gt_irqs = GT_RENDER_USER_INTERRUPT | GT_BSD_USER_INTERRUPT | ++ GT_BLT_USER_INTERRUPT; ++ I915_WRITE(GTIER, gt_irqs); + POSTING_READ(GTIER); + + /* ack & enable invalid PTE error interrupts */ +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 30f6cfe91d1b..ef1c471b1909 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -742,24 +742,6 @@ + #define VLV_IMR (VLV_DISPLAY_BASE + 0x20a8) + #define VLV_ISR (VLV_DISPLAY_BASE + 0x20ac) + #define VLV_PCBR (VLV_DISPLAY_BASE + 0x2120) +-#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) +-#define I915_DISPLAY_PORT_INTERRUPT (1<<17) +-#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15) +-#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14) /* p-state */ +-#define I915_HWB_OOM_INTERRUPT (1<<13) +-#define I915_SYNC_STATUS_INTERRUPT (1<<12) +-#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11) +-#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10) +-#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9) +-#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8) +-#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7) +-#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6) +-#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5) +-#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4) +-#define I915_DEBUG_INTERRUPT (1<<2) +-#define I915_USER_INTERRUPT (1<<1) +-#define I915_ASLE_INTERRUPT (1<<0) +-#define I915_BSD_USER_INTERRUPT (1<<25) + #define DISPLAY_PLANE_FLIP_PENDING(plane) (1<<(11-(plane))) /* A and B only */ + #define EIR 0x020b0 + #define EMR 0x020b4 +@@ -873,28 +855,6 @@ + #define CACHE_MODE_1 0x7004 /* IVB+ */ + #define PIXEL_SUBSPAN_COLLECT_OPT_DISABLE (1<<6) + +-/* GEN6 interrupt control +- * Note that the per-ring interrupt bits do alias with the global interrupt bits +- * in GTIMR. */ +-#define GEN6_RENDER_HWSTAM 0x2098 +-#define GEN6_RENDER_IMR 0x20a8 +-#define GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT (1 << 8) +-#define GEN6_RENDER_PPGTT_PAGE_FAULT (1 << 7) +-#define GEN6_RENDER_TIMEOUT_COUNTER_EXPIRED (1 << 6) +-#define GEN6_RENDER_L3_PARITY_ERROR (1 << 5) +-#define GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT (1 << 4) +-#define GEN6_RENDER_COMMAND_PARSER_MASTER_ERROR (1 << 3) +-#define GEN6_RENDER_SYNC_STATUS (1 << 2) +-#define GEN6_RENDER_DEBUG_INTERRUPT (1 << 1) +-#define GEN6_RENDER_USER_INTERRUPT (1 << 0) +- +-#define GEN6_BLITTER_HWSTAM 0x22098 +-#define GEN6_BLITTER_IMR 0x220a8 +-#define GEN6_BLITTER_MI_FLUSH_DW_NOTIFY_INTERRUPT (1 << 26) +-#define GEN6_BLITTER_COMMAND_PARSER_MASTER_ERROR (1 << 25) +-#define GEN6_BLITTER_SYNC_STATUS (1 << 24) +-#define GEN6_BLITTER_USER_INTERRUPT (1 << 22) +- + #define GEN6_BLITTER_ECOSKPD 0x221d0 + #define GEN6_BLITTER_LOCK_SHIFT 16 + #define GEN6_BLITTER_FBC_NOTIFY (1<<3) +@@ -905,9 +865,49 @@ + #define GEN6_BSD_SLEEP_INDICATOR (1 << 3) + #define GEN6_BSD_GO_INDICATOR (1 << 4) + +-#define GEN6_BSD_HWSTAM 0x12098 +-#define GEN6_BSD_IMR 0x120a8 +-#define GEN6_BSD_USER_INTERRUPT (1 << 12) ++/* On modern GEN architectures interrupt control consists of two sets ++ * of registers. The first set pertains to the ring generating the ++ * interrupt. The second control is for the functional block generating the ++ * interrupt. These are PM, GT, DE, etc. ++ * ++ * Luckily *knocks on wood* all the ring interrupt bits match up with the ++ * GT interrupt bits, so we don't need to duplicate the defines. ++ * ++ * These defines should cover us well from SNB->HSW with minor exceptions ++ * it can also work on ILK. ++ */ ++#define GT_BLT_FLUSHDW_NOTIFY_INTERRUPT (1 << 26) ++#define GT_BLT_CS_ERROR_INTERRUPT (1 << 25) ++#define GT_BLT_USER_INTERRUPT (1 << 22) ++#define GT_BSD_CS_ERROR_INTERRUPT (1 << 15) ++#define GT_BSD_USER_INTERRUPT (1 << 12) ++#define GT_RENDER_L3_PARITY_ERROR_INTERRUPT (1 << 5) /* !snb */ ++#define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT (1 << 4) ++#define GT_RENDER_CS_MASTER_ERROR_INTERRUPT (1 << 3) ++#define GT_RENDER_SYNC_STATUS_INTERRUPT (1 << 2) ++#define GT_RENDER_DEBUG_INTERRUPT (1 << 1) ++#define GT_RENDER_USER_INTERRUPT (1 << 0) ++ ++/* These are all the "old" interrupts */ ++#define ILK_BSD_USER_INTERRUPT (1<<5) ++#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) ++#define I915_DISPLAY_PORT_INTERRUPT (1<<17) ++#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15) ++#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14) /* p-state */ ++#define I915_HWB_OOM_INTERRUPT (1<<13) ++#define I915_SYNC_STATUS_INTERRUPT (1<<12) ++#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11) ++#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10) ++#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9) ++#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8) ++#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7) ++#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6) ++#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5) ++#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4) ++#define I915_DEBUG_INTERRUPT (1<<2) ++#define I915_USER_INTERRUPT (1<<1) ++#define I915_ASLE_INTERRUPT (1<<0) ++#define I915_BSD_USER_INTERRUPT (1 << 25) + + #define GEN6_BSD_RNCID 0x12198 + +@@ -3720,21 +3720,6 @@ + #define DEIIR 0x44008 + #define DEIER 0x4400c + +-/* GT interrupt. +- * Note that for gen6+ the ring-specific interrupt bits do alias with the +- * corresponding bits in the per-ring interrupt control registers. */ +-#define GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT (1 << 26) +-#define GT_GEN6_BLT_CS_ERROR_INTERRUPT (1 << 25) +-#define GT_GEN6_BLT_USER_INTERRUPT (1 << 22) +-#define GT_GEN6_BSD_CS_ERROR_INTERRUPT (1 << 15) +-#define GT_GEN6_BSD_USER_INTERRUPT (1 << 12) +-#define GT_BSD_USER_INTERRUPT (1 << 5) /* ilk only */ +-#define GT_GEN7_L3_PARITY_ERROR_INTERRUPT (1 << 5) +-#define GT_PIPE_NOTIFY (1 << 4) +-#define GT_RENDER_CS_ERROR_INTERRUPT (1 << 3) +-#define GT_SYNC_STATUS (1 << 2) +-#define GT_USER_INTERRUPT (1 << 0) +- + #define GTISR 0x44010 + #define GTIMR 0x44014 + #define GTIIR 0x44018 +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 8246213ffada..5ce12be4faeb 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -556,7 +556,7 @@ static int init_render_ring(struct intel_ring_buffer *ring) + I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); + + if (HAS_L3_GPU_CACHE(dev)) +- I915_WRITE_IMR(ring, ~GEN6_RENDER_L3_PARITY_ERROR); ++ I915_WRITE_IMR(ring, ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT); + + return ret; + } +@@ -993,8 +993,9 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring) + spin_lock_irqsave(&dev_priv->irq_lock, flags); + if (ring->irq_refcount.gt++ == 0) { + if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS) +- I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | +- GEN6_RENDER_L3_PARITY_ERROR)); ++ I915_WRITE_IMR(ring, ++ ~(ring->irq_enable_mask | ++ GT_RENDER_L3_PARITY_ERROR_INTERRUPT)); + else + I915_WRITE_IMR(ring, ~ring->irq_enable_mask); + dev_priv->gt_irq_mask &= ~ring->irq_enable_mask; +@@ -1016,7 +1017,8 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring) + spin_lock_irqsave(&dev_priv->irq_lock, flags); + if (--ring->irq_refcount.gt == 0) { + if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS) +- I915_WRITE_IMR(ring, ~GEN6_RENDER_L3_PARITY_ERROR); ++ I915_WRITE_IMR(ring, ++ ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT); + else + I915_WRITE_IMR(ring, ~0); + dev_priv->gt_irq_mask |= ring->irq_enable_mask; +@@ -1693,7 +1695,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) + ring->flush = gen6_render_ring_flush; + ring->irq_get = gen6_ring_get_irq; + ring->irq_put = gen6_ring_put_irq; +- ring->irq_enable_mask = GT_USER_INTERRUPT; ++ ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT; + ring->get_seqno = gen6_ring_get_seqno; + ring->set_seqno = ring_set_seqno; + ring->sync_to = gen6_ring_sync; +@@ -1712,7 +1714,8 @@ int intel_init_render_ring_buffer(struct drm_device *dev) + ring->set_seqno = pc_render_set_seqno; + ring->irq_get = gen5_ring_get_irq; + ring->irq_put = gen5_ring_put_irq; +- ring->irq_enable_mask = GT_USER_INTERRUPT | GT_PIPE_NOTIFY; ++ ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT | ++ GT_RENDER_PIPECTL_NOTIFY_INTERRUPT; + } else { + ring->add_request = i9xx_add_request; + if (INTEL_INFO(dev)->gen < 4) +@@ -1854,7 +1857,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) + ring->add_request = gen6_add_request; + ring->get_seqno = gen6_ring_get_seqno; + ring->set_seqno = ring_set_seqno; +- ring->irq_enable_mask = GEN6_BSD_USER_INTERRUPT; ++ ring->irq_enable_mask = GT_BSD_USER_INTERRUPT; + ring->irq_get = gen6_ring_get_irq; + ring->irq_put = gen6_ring_put_irq; + ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; +@@ -1874,7 +1877,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) + ring->get_seqno = ring_get_seqno; + ring->set_seqno = ring_set_seqno; + if (IS_GEN5(dev)) { +- ring->irq_enable_mask = GT_BSD_USER_INTERRUPT; ++ ring->irq_enable_mask = ILK_BSD_USER_INTERRUPT; + ring->irq_get = gen5_ring_get_irq; + ring->irq_put = gen5_ring_put_irq; + } else { +@@ -1903,7 +1906,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) + ring->add_request = gen6_add_request; + ring->get_seqno = gen6_ring_get_seqno; + ring->set_seqno = ring_set_seqno; +- ring->irq_enable_mask = GEN6_BLITTER_USER_INTERRUPT; ++ ring->irq_enable_mask = GT_BLT_USER_INTERRUPT; + ring->irq_get = gen6_ring_get_irq; + ring->irq_put = gen6_ring_put_irq; + ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0229-drm-i915-vebox-interrupt-get-put.patch b/patches.baytrail/0229-drm-i915-vebox-interrupt-get-put.patch new file mode 100644 index 000000000000..f57b076a1dd2 --- /dev/null +++ b/patches.baytrail/0229-drm-i915-vebox-interrupt-get-put.patch @@ -0,0 +1,102 @@ +From 47d9c22e933d7fd7308b8184939d9e1f88437393 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:30 -0700 +Subject: drm/i915: vebox interrupt get/put + +v2: Use the correct lock to protect PM interrupt regs, this was +accidentally lost from earlier (Haihao) +Fix return types (Ben) + +Reviewed-by: Damien Lespiau +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit a19d2933cbc4c7b8e3d72e9fd2d48847c25bb41d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ringbuffer.c | 46 +++++++++++++++++++++++++++++++-- + drivers/gpu/drm/i915/intel_ringbuffer.h | 5 ++-- + 2 files changed, 47 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 5ce12be4faeb..81a397bb2424 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -1030,6 +1030,48 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring) + gen6_gt_force_wake_put(dev_priv); + } + ++static bool ++hsw_vebox_get_irq(struct intel_ring_buffer *ring) ++{ ++ struct drm_device *dev = ring->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ unsigned long flags; ++ ++ if (!dev->irq_enabled) ++ return false; ++ ++ spin_lock_irqsave(&dev_priv->rps.lock, flags); ++ if (ring->irq_refcount.pm++ == 0) { ++ u32 pm_imr = I915_READ(GEN6_PMIMR); ++ I915_WRITE_IMR(ring, ~ring->irq_enable_mask); ++ I915_WRITE(GEN6_PMIMR, pm_imr & ~ring->irq_enable_mask); ++ POSTING_READ(GEN6_PMIMR); ++ } ++ spin_unlock_irqrestore(&dev_priv->rps.lock, flags); ++ ++ return true; ++} ++ ++static void ++hsw_vebox_put_irq(struct intel_ring_buffer *ring) ++{ ++ struct drm_device *dev = ring->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ unsigned long flags; ++ ++ if (!dev->irq_enabled) ++ return; ++ ++ spin_lock_irqsave(&dev_priv->rps.lock, flags); ++ if (--ring->irq_refcount.pm == 0) { ++ u32 pm_imr = I915_READ(GEN6_PMIMR); ++ I915_WRITE_IMR(ring, ~0); ++ I915_WRITE(GEN6_PMIMR, pm_imr | ring->irq_enable_mask); ++ POSTING_READ(GEN6_PMIMR); ++ } ++ spin_unlock_irqrestore(&dev_priv->rps.lock, flags); ++} ++ + static int + i965_dispatch_execbuffer(struct intel_ring_buffer *ring, + u32 offset, u32 length, +@@ -1939,8 +1981,8 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) + ring->get_seqno = gen6_ring_get_seqno; + ring->set_seqno = ring_set_seqno; + ring->irq_enable_mask = 0; +- ring->irq_get = NULL; +- ring->irq_put = NULL; ++ ring->irq_get = hsw_vebox_get_irq; ++ ring->irq_put = hsw_vebox_put_irq; + ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; + ring->sync_to = gen6_ring_sync; + ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VER; +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index 153b87f67aae..022d07e43d12 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -73,8 +73,9 @@ struct intel_ring_buffer { + u32 last_retired_head; + + struct { +- u32 gt; +- } irq_refcount; /* protected by dev_priv->irq_lock */ ++ u32 gt; /* protected by dev_priv->irq_lock */ ++ u32 pm; /* protected by dev_priv->rps.lock (sucks) */ ++ } irq_refcount; + u32 irq_enable_mask; /* bitmask to enable ring interrupt */ + u32 trace_irq_seqno; + u32 sync_seqno[I915_NUM_RINGS-1]; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0230-drm-i915-Enable-vebox-interrupts.patch b/patches.baytrail/0230-drm-i915-Enable-vebox-interrupts.patch new file mode 100644 index 000000000000..66cf2db00d29 --- /dev/null +++ b/patches.baytrail/0230-drm-i915-Enable-vebox-interrupts.patch @@ -0,0 +1,113 @@ +From 925cdffd7db75dc492ed4600bd0b9e20e98ad1c3 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 28 May 2013 19:22:31 -0700 +Subject: drm/i915: Enable vebox interrupts + +Similar to a patch originally written by: + +v2: Reversed the meanings of masked and enabled (Haihao) +Made non-destructive writes in case enable/disabler rps runs first +(Haihao) + +v3: Reword error message (Damien) +Modify postinstall to do the right thing based on previous fixup. (Ben) + +CC: Xiang, Haihao +Reviewed-by: Damien Lespiau +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 12638c57f31952127c734c26315e1348fa1334c2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 31 +++++++++++++++++++++++++------ + drivers/gpu/drm/i915/i915_reg.h | 3 +++ + drivers/gpu/drm/i915/intel_ringbuffer.c | 3 ++- + 3 files changed, 30 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 7eabe79680c7..ea396518baab 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -935,8 +935,15 @@ static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv, + } + spin_unlock_irqrestore(&dev_priv->rps.lock, flags); + +- if (pm_iir & ~GEN6_PM_RPS_EVENTS) +- DRM_ERROR("Unexpected PM interrupted\n"); ++ if (pm_iir & ~GEN6_PM_RPS_EVENTS) { ++ if (pm_iir & PM_VEBOX_USER_INTERRUPT) ++ notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); ++ ++ if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) { ++ DRM_ERROR("VEBOX CS error interrupt 0x%08x\n", pm_iir); ++ i915_handle_error(dev_priv->dev, false); ++ } ++ } + } + + static irqreturn_t valleyview_irq_handler(int irq, void *arg) +@@ -2727,6 +2734,7 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) + DE_PLANEA_FLIP_DONE_IVB | + DE_AUX_CHANNEL_A_IVB | + DE_ERR_INT_IVB; ++ u32 pm_irqs = GEN6_PM_RPS_EVENTS; + u32 gt_irqs; + + dev_priv->irq_mask = ~display_mask; +@@ -2752,10 +2760,21 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) + I915_WRITE(GTIER, gt_irqs); + POSTING_READ(GTIER); + +- /* Power management */ +- I915_WRITE(GEN6_PMIMR, ~GEN6_PM_RPS_EVENTS); +- I915_WRITE(GEN6_PMIER, GEN6_PM_RPS_EVENTS); +- POSTING_READ(GEN6_PMIMR); ++ I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); ++ if (HAS_VEBOX(dev)) ++ pm_irqs |= PM_VEBOX_USER_INTERRUPT | ++ PM_VEBOX_CS_ERROR_INTERRUPT; ++ ++ /* Our enable/disable rps functions may touch these registers so ++ * make sure to set a known state for only the non-RPS bits. ++ * The RMW is extra paranoia since this should be called after being set ++ * to a known state in preinstall. ++ * */ ++ I915_WRITE(GEN6_PMIMR, ++ (I915_READ(GEN6_PMIMR) | ~GEN6_PM_RPS_EVENTS) & ~pm_irqs); ++ I915_WRITE(GEN6_PMIER, ++ (I915_READ(GEN6_PMIER) & GEN6_PM_RPS_EVENTS) | pm_irqs); ++ POSTING_READ(GEN6_PMIER); + + ibx_irq_postinstall(dev); + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index ef1c471b1909..aabc67104272 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -888,6 +888,9 @@ + #define GT_RENDER_DEBUG_INTERRUPT (1 << 1) + #define GT_RENDER_USER_INTERRUPT (1 << 0) + ++#define PM_VEBOX_CS_ERROR_INTERRUPT (1 << 12) /* hsw+ */ ++#define PM_VEBOX_USER_INTERRUPT (1 << 10) /* hsw+ */ ++ + /* These are all the "old" interrupts */ + #define ILK_BSD_USER_INTERRUPT (1<<5) + #define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 81a397bb2424..cd2daf2f5dd7 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -1980,7 +1980,8 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) + ring->add_request = gen6_add_request; + ring->get_seqno = gen6_ring_get_seqno; + ring->set_seqno = ring_set_seqno; +- ring->irq_enable_mask = 0; ++ ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT | ++ PM_VEBOX_CS_ERROR_INTERRUPT; + ring->irq_get = hsw_vebox_get_irq; + ring->irq_put = hsw_vebox_put_irq; + ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0231-drm-i915-add-VEBOX-into-debugfs.patch b/patches.baytrail/0231-drm-i915-add-VEBOX-into-debugfs.patch new file mode 100644 index 000000000000..f7ca63bd7ac1 --- /dev/null +++ b/patches.baytrail/0231-drm-i915-add-VEBOX-into-debugfs.patch @@ -0,0 +1,45 @@ +From 10fa3bda880c59f074f87063893c6144a5180160 Mon Sep 17 00:00:00 2001 +From: "Xiang, Haihao" +Date: Wed, 29 May 2013 09:22:36 -0700 +Subject: drm/i915: add VEBOX into debugfs + +v2: Removed rebase relic VECS ring from i915_gem_request_info (Damien) + +v3: s/hsw/hws in debugfs which I introduced in v2 (Jon) + +Signed-off-by: Xiang, Haihao +[Order changed, and modified by] +CC: "Bloomfield, Jon" +Signed-off-by: Ben Widawsky +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter + +(cherry picked from commit 9010ebfd2b803ebab6c2fc70b9004b2a59e7937a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 2eb572afbcd3..2b4a6fa6350e 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -570,6 +570,7 @@ static const char *ring_str(int ring) + case RCS: return "render"; + case VCS: return "bsd"; + case BCS: return "blt"; ++ case VECS: return "vebox"; + default: return ""; + } + } +@@ -2222,6 +2223,7 @@ static struct drm_info_list i915_debugfs_list[] = { + {"i915_gem_hws", i915_hws_info, 0, (void *)RCS}, + {"i915_gem_hws_blt", i915_hws_info, 0, (void *)BCS}, + {"i915_gem_hws_bsd", i915_hws_info, 0, (void *)VCS}, ++ {"i915_gem_hws_vebox", i915_hws_info, 0, (void *)VECS}, + {"i915_rstdby_delays", i915_rstdby_delays, 0}, + {"i915_cur_delayinfo", i915_cur_delayinfo, 0}, + {"i915_delayfreq_table", i915_delayfreq_table, 0}, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0232-drm-i915-add-I915_EXEC_VEBOX-to-i915_gem_do_execbuff.patch b/patches.baytrail/0232-drm-i915-add-I915_EXEC_VEBOX-to-i915_gem_do_execbuff.patch new file mode 100644 index 000000000000..c6d87cd7722c --- /dev/null +++ b/patches.baytrail/0232-drm-i915-add-I915_EXEC_VEBOX-to-i915_gem_do_execbuff.patch @@ -0,0 +1,53 @@ +From 5c5cf6265426c14439c7fcd37443709567808f58 Mon Sep 17 00:00:00 2001 +From: "Xiang, Haihao" +Date: Tue, 28 May 2013 19:22:33 -0700 +Subject: drm/i915: add I915_EXEC_VEBOX to i915_gem_do_execbuffer() + +A user can run batchbuffer via VEBOX ring. + +Signed-off-by: Xiang, Haihao +Reviewed-by: Damien Lespiau +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 82f91b6e93e2138c7e02b5a866f63d04cf040c86) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 9 +++++++++ + include/uapi/drm/i915_drm.h | 1 + + 2 files changed, 10 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 117ce3813681..a8bb62ca8756 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -885,6 +885,15 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + return -EPERM; + } + break; ++ case I915_EXEC_VEBOX: ++ ring = &dev_priv->ring[VECS]; ++ if (ctx_id != 0) { ++ DRM_DEBUG("Ring %s doesn't support contexts\n", ++ ring->name); ++ return -EPERM; ++ } ++ break; ++ + default: + DRM_DEBUG("execbuf with unknown ring: %d\n", + (int)(args->flags & I915_EXEC_RING_MASK)); +diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h +index 07d59419fe6b..81b99817198e 100644 +--- a/include/uapi/drm/i915_drm.h ++++ b/include/uapi/drm/i915_drm.h +@@ -660,6 +660,7 @@ struct drm_i915_gem_execbuffer2 { + #define I915_EXEC_RENDER (1<<0) + #define I915_EXEC_BSD (2<<0) + #define I915_EXEC_BLT (3<<0) ++#define I915_EXEC_VEBOX (4<<0) + + /* Used for switching the constants addressing mode on gen4+ RENDER ring. + * Gen6+ only supports relative addressing to dynamic state (default) and +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0233-drm-i915-add-I915_PARAM_HAS_VEBOX-to-i915_getparam.patch b/patches.baytrail/0233-drm-i915-add-I915_PARAM_HAS_VEBOX-to-i915_getparam.patch new file mode 100644 index 000000000000..a3170676b8c7 --- /dev/null +++ b/patches.baytrail/0233-drm-i915-add-I915_PARAM_HAS_VEBOX-to-i915_getparam.patch @@ -0,0 +1,49 @@ +From b63204214b602f8ae8373aaac21b68178caa1eb5 Mon Sep 17 00:00:00 2001 +From: "Xiang, Haihao" +Date: Tue, 28 May 2013 19:22:34 -0700 +Subject: drm/i915: add I915_PARAM_HAS_VEBOX to i915_getparam + +This will let userland only try to use the new ring +when the appropriate kernel is present + +Signed-off-by: Xiang, Haihao +Reviewed-by: Damien Lespiau +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit a1f2cc73c762868435ae6ec9126bb2240337c61c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 3 +++ + include/uapi/drm/i915_drm.h | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 0a61f6f6948d..d392d8fb146e 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -955,6 +955,9 @@ static int i915_getparam(struct drm_device *dev, void *data, + case I915_PARAM_HAS_BLT: + value = intel_ring_initialized(&dev_priv->ring[BCS]); + break; ++ case I915_PARAM_HAS_VEBOX: ++ value = intel_ring_initialized(&dev_priv->ring[VECS]); ++ break; + case I915_PARAM_HAS_RELAXED_FENCING: + value = 1; + break; +diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h +index 81b99817198e..923ed7fe5775 100644 +--- a/include/uapi/drm/i915_drm.h ++++ b/include/uapi/drm/i915_drm.h +@@ -305,7 +305,7 @@ typedef struct drm_i915_irq_wait { + #define I915_PARAM_HAS_WAIT_TIMEOUT 19 + #define I915_PARAM_HAS_SEMAPHORES 20 + #define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21 +-#define I915_PARAM_RSVD_FOR_FUTURE_USE 22 ++#define I915_PARAM_HAS_VEBOX 22 + #define I915_PARAM_HAS_SECURE_BATCHES 23 + #define I915_PARAM_HAS_PINNED_BATCHES 24 + #define I915_PARAM_HAS_EXEC_NO_RELOC 25 +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0234-drm-i915-fix-up-the-edp-power-well-check.patch b/patches.baytrail/0234-drm-i915-fix-up-the-edp-power-well-check.patch new file mode 100644 index 000000000000..0bbb4e410827 --- /dev/null +++ b/patches.baytrail/0234-drm-i915-fix-up-the-edp-power-well-check.patch @@ -0,0 +1,70 @@ +From 5a53a12165befa51a0a7c6def19ce1f856b1c73a Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 31 May 2013 17:49:17 +0200 +Subject: drm/i915: fix up the edp power well check + +Now that we track the cpu transcoder we need accurately in the pipe +config we can finally fix up the transcoder check. With the current +code eDP on port D will be broken since we'd errornously cut the +power. + +For reference see + +commit 2124b72e6283c4e84a55e71077fee91793f4c801 +Author: Paulo Zanoni +Date: Fri Mar 22 14:07:23 2013 -0300 + + drm/i915: don't disable the power well yet + +v2: +- Kill the now outdated comment (Paulo) +- Add the missing crtc->base.enabled check and consolidate it (Paulo) +- Smash all checks together, looks neater that way. + +v3: Kill the unused encoder variable. + +Cc: Takashi Iwai +Cc: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit e7a639c445e1f7c44adc1665539fa8e3af0b8e30) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 18 ++++-------------- + 1 file changed, 4 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 959ebc7a8283..b16c95720f7b 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5793,23 +5793,13 @@ static void haswell_modeset_global_resources(struct drm_device *dev) + { + bool enable = false; + struct intel_crtc *crtc; +- struct intel_encoder *encoder; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { +- if (crtc->pipe != PIPE_A && crtc->base.enabled) +- enable = true; +- /* XXX: Should check for edp transcoder here, but thanks to init +- * sequence that's not yet available. Just in case desktop eDP +- * on PORT D is possible on haswell, too. */ +- /* Even the eDP panel fitter is outside the always-on well. */ +- if (crtc->config.pch_pfit.size && crtc->base.enabled) +- enable = true; +- } ++ if (!crtc->base.enabled) ++ continue; + +- list_for_each_entry(encoder, &dev->mode_config.encoder_list, +- base.head) { +- if (encoder->type != INTEL_OUTPUT_EDP && +- encoder->connectors_active) ++ if (crtc->pipe != PIPE_A || crtc->config.pch_pfit.size || ++ crtc->config.cpu_transcoder != TRANSCODER_EDP) + enable = true; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0235-drm-i915-implement-IPS-feature.patch b/patches.baytrail/0235-drm-i915-implement-IPS-feature.patch new file mode 100644 index 000000000000..54864070847d --- /dev/null +++ b/patches.baytrail/0235-drm-i915-implement-IPS-feature.patch @@ -0,0 +1,244 @@ +From b404317dbebe844ac7ca6bfa2d6ac34f4380f69b Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 31 May 2013 16:33:22 -0300 +Subject: drm/i915: implement IPS feature + +Intermediate Pixel Storage is a feature that should reduce the number +of times the display engine wakes up memory to read pixels, so it +should allow deeper PC states. IPS can only be enabled on ULT pipe A +with 8:8:8 pipe pixel formats. + +With eDP 1920x1080 and correct watermarks but without FBC this moves +my PC7 residency from 2.5% to around 38%. + +v2: - It's tied to pipe A, not port A + - Add pipe_config support (Chris) + - Add some assertions (Chris) + - Rebase against latest dinq +v3: - Don't ever set ips_enabled to false (Daniel) + - Only check for ips_enabled at hsw_disable_ips (Daniel) +v4: - Add hsw_compute_ips_config (Daniel) + - Use the new dump_pipe_config (Daniel) + +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 42db64efcd95014570835c7b0a08277c60486f07) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 11 +++++ + drivers/gpu/drm/i915/intel_display.c | 78 ++++++++++++++++++++++++++++++++++-- + drivers/gpu/drm/i915/intel_drv.h | 2 + + 3 files changed, 88 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index aabc67104272..13d4d5e21ce0 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -1025,6 +1025,8 @@ + /* Framebuffer compression for Ivybridge */ + #define IVB_FBC_RT_BASE 0x7020 + ++#define IPS_CTL 0x43408 ++#define IPS_ENABLE (1 << 31) + + #define _HSW_PIPE_SLICE_CHICKEN_1_A 0x420B0 + #define _HSW_PIPE_SLICE_CHICKEN_1_B 0x420B4 +@@ -3672,6 +3674,15 @@ + #define _LGC_PALETTE_B 0x4a800 + #define LGC_PALETTE(pipe) _PIPE(pipe, _LGC_PALETTE_A, _LGC_PALETTE_B) + ++#define _GAMMA_MODE_A 0x4a480 ++#define _GAMMA_MODE_B 0x4ac80 ++#define GAMMA_MODE(pipe) _PIPE(pipe, _GAMMA_MODE_A, _GAMMA_MODE_B) ++#define GAMMA_MODE_MODE_MASK (3 << 0) ++#define GAMMA_MODE_MODE_8bit (0 << 0) ++#define GAMMA_MODE_MODE_10bit (1 << 0) ++#define GAMMA_MODE_MODE_12bit (2 << 0) ++#define GAMMA_MODE_MODE_SPLIT (3 << 0) ++ + /* interrupts */ + #define DE_MASTER_IRQ_CONTROL (1 << 31) + #define DE_SPRITEB_FLIP_DONE (1 << 29) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index b16c95720f7b..20fa85137060 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3242,6 +3242,42 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + intel_wait_for_vblank(dev, intel_crtc->pipe); + } + ++/* IPS only exists on ULT machines and is tied to pipe A. */ ++static bool hsw_crtc_supports_ips(struct intel_crtc *crtc) ++{ ++ return IS_ULT(crtc->base.dev) && crtc->pipe == PIPE_A; ++} ++ ++static void hsw_enable_ips(struct intel_crtc *crtc) ++{ ++ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; ++ ++ if (!crtc->config.ips_enabled) ++ return; ++ ++ /* We can only enable IPS after we enable a plane and wait for a vblank. ++ * We guarantee that the plane is enabled by calling intel_enable_ips ++ * only after intel_enable_plane. And intel_enable_plane already waits ++ * for a vblank, so all we need to do here is to enable the IPS bit. */ ++ assert_plane_enabled(dev_priv, crtc->plane); ++ I915_WRITE(IPS_CTL, IPS_ENABLE); ++} ++ ++static void hsw_disable_ips(struct intel_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (!crtc->config.ips_enabled) ++ return; ++ ++ assert_plane_enabled(dev_priv, crtc->plane); ++ I915_WRITE(IPS_CTL, 0); ++ ++ /* We need to wait for a vblank before we can disable the plane. */ ++ intel_wait_for_vblank(dev, crtc->pipe); ++} ++ + static void haswell_crtc_enable(struct drm_crtc *crtc) + { + struct drm_device *dev = crtc->dev; +@@ -3289,6 +3325,8 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) + intel_crtc->config.has_pch_encoder); + intel_enable_plane(dev_priv, plane, pipe); + ++ hsw_enable_ips(intel_crtc); ++ + if (intel_crtc->config.has_pch_encoder) + lpt_pch_enable(crtc); + +@@ -3431,6 +3469,8 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) + if (dev_priv->cfb_plane == plane) + intel_disable_fbc(dev); + ++ hsw_disable_ips(intel_crtc); ++ + intel_disable_plane(dev_priv, plane, pipe); + + if (intel_crtc->config.has_pch_encoder) +@@ -3987,11 +4027,19 @@ retry: + return setup_ok ? 0 : -EINVAL; + } + ++static void hsw_compute_ips_config(struct intel_crtc *crtc, ++ struct intel_crtc_config *pipe_config) ++{ ++ pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) && ++ pipe_config->pipe_bpp == 24; ++} ++ + static int intel_crtc_compute_config(struct drm_crtc *crtc, + struct intel_crtc_config *pipe_config) + { + struct drm_device *dev = crtc->dev; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + if (HAS_PCH_SPLIT(dev)) { + /* FDI link clock is fixed at 2.7G */ +@@ -4021,8 +4069,11 @@ static int intel_crtc_compute_config(struct drm_crtc *crtc, + pipe_config->pipe_bpp = 8*3; + } + ++ if (IS_HASWELL(dev)) ++ hsw_compute_ips_config(intel_crtc, pipe_config); ++ + if (pipe_config->has_pch_encoder) +- return ironlake_fdi_compute_config(to_intel_crtc(crtc), pipe_config); ++ return ironlake_fdi_compute_config(intel_crtc, pipe_config); + + return 0; + } +@@ -5932,6 +5983,9 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + if (intel_display_power_enabled(dev, pfit_domain)) + ironlake_get_pfit_config(crtc, pipe_config); + ++ pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) && ++ (I915_READ(IPS_CTL) & IPS_ENABLE); ++ + return true; + } + +@@ -6236,8 +6290,10 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- int palreg = PALETTE(intel_crtc->pipe); ++ enum pipe pipe = intel_crtc->pipe; ++ int palreg = PALETTE(pipe); + int i; ++ bool reenable_ips = false; + + /* The clocks have to be on to load the palette. */ + if (!crtc->enabled || !intel_crtc->active) +@@ -6245,7 +6301,17 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) + + /* use legacy palette for Ironlake */ + if (HAS_PCH_SPLIT(dev)) +- palreg = LGC_PALETTE(intel_crtc->pipe); ++ palreg = LGC_PALETTE(pipe); ++ ++ /* Workaround : Do not read or write the pipe palette/gamma data while ++ * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled. ++ */ ++ if (intel_crtc->config.ips_enabled && ++ ((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) == ++ GAMMA_MODE_MODE_SPLIT)) { ++ hsw_disable_ips(intel_crtc); ++ reenable_ips = true; ++ } + + for (i = 0; i < 256; i++) { + I915_WRITE(palreg + 4 * i, +@@ -6253,6 +6319,9 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) + (intel_crtc->lut_g[i] << 8) | + intel_crtc->lut_b[i]); + } ++ ++ if (reenable_ips) ++ hsw_enable_ips(intel_crtc); + } + + static void i845_update_cursor(struct drm_crtc *crtc, u32 base) +@@ -7684,6 +7753,7 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, + DRM_DEBUG_KMS("pch pfit: pos: 0x%08x, size: 0x%08x\n", + pipe_config->pch_pfit.pos, + pipe_config->pch_pfit.size); ++ DRM_DEBUG_KMS("ips: %i\n", pipe_config->ips_enabled); + } + + static struct intel_crtc_config * +@@ -8000,6 +8070,8 @@ intel_pipe_config_compare(struct drm_device *dev, + PIPE_CONF_CHECK_I(pch_pfit.pos); + PIPE_CONF_CHECK_I(pch_pfit.size); + ++ PIPE_CONF_CHECK_I(ips_enabled); ++ + #undef PIPE_CONF_CHECK_I + #undef PIPE_CONF_CHECK_FLAGS + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index c02bc97e350d..b81cc4512c0a 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -268,6 +268,8 @@ struct intel_crtc_config { + /* FDI configuration, only valid if has_pch_encoder is set. */ + int fdi_lanes; + struct intel_link_m_n fdi_m_n; ++ ++ bool ips_enabled; + }; + + struct intel_crtc { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0236-drm-i915-add-enable_ips-module-option.patch b/patches.baytrail/0236-drm-i915-add-enable_ips-module-option.patch new file mode 100644 index 000000000000..2b57f44f3ccf --- /dev/null +++ b/patches.baytrail/0236-drm-i915-add-enable_ips-module-option.patch @@ -0,0 +1,71 @@ +From 8157c06d90041377493b7d8c9298fdaa05347039 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 31 May 2013 16:33:23 -0300 +Subject: drm/i915: add enable_ips module option + +IPS is still enabled by default. Feature requested by the power +management team. + +This should also help testing the feature on some early pre-production +hardware where there were relationship problems between IPS and PSR. + +v2: Rebase on top of the newest IPS implementation. +v3: Check i915_enable_ips at compute_config, not supports_ips, so the + kernel parameter will be ignored at haswell_get_pipe_config. + +Requested-by: Kristen Accardi +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 3c4ca58c12a3bf71433425df534dfbb85d8a5dc5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 4 ++++ + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/intel_display.c | 3 ++- + 3 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 9136fcdcd24a..4ae308e845d4 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -128,6 +128,10 @@ module_param_named(disable_power_well, i915_disable_power_well, int, 0600); + MODULE_PARM_DESC(disable_power_well, + "Disable the power well when possible (default: false)"); + ++int i915_enable_ips __read_mostly = 1; ++module_param_named(enable_ips, i915_enable_ips, int, 0600); ++MODULE_PARM_DESC(enable_ips, "Enable IPS (default: true)"); ++ + static struct drm_driver driver; + extern int intel_agp_enabled; + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index ae8b9668b8ff..4eed8559fa90 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1471,6 +1471,7 @@ extern bool i915_enable_hangcheck __read_mostly; + extern int i915_enable_ppgtt __read_mostly; + extern unsigned int i915_preliminary_hw_support __read_mostly; + extern int i915_disable_power_well __read_mostly; ++extern int i915_enable_ips __read_mostly; + + extern int i915_suspend(struct drm_device *dev, pm_message_t state); + extern int i915_resume(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 20fa85137060..b26c3a08d8e1 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4030,7 +4030,8 @@ retry: + static void hsw_compute_ips_config(struct intel_crtc *crtc, + struct intel_crtc_config *pipe_config) + { +- pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) && ++ pipe_config->ips_enabled = i915_enable_ips && ++ hsw_crtc_supports_ips(crtc) && + pipe_config->pipe_bpp == 24; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0237-drm-i915-add-i915_ips_status-debugfs-entry.patch b/patches.baytrail/0237-drm-i915-add-i915_ips_status-debugfs-entry.patch new file mode 100644 index 000000000000..7aee79ac7c7f --- /dev/null +++ b/patches.baytrail/0237-drm-i915-add-i915_ips_status-debugfs-entry.patch @@ -0,0 +1,61 @@ +From b3d96bf0c2c11911f7edf146e34f5d366e0a5082 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 31 May 2013 16:33:24 -0300 +Subject: drm/i915: add i915_ips_status debugfs entry + +It just prints whether it's supported/enabled/disabled. Feature +requested by the power management team. + +v2: Checkpatch started complaining about seq_printf with 1 argument. + +Requested-by: Kristen Accardi +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 92d44621ad2d083bc03920c904ca0a5eb10d9ded) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 2b4a6fa6350e..76255a69752a 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1435,6 +1435,25 @@ static int i915_fbc_status(struct seq_file *m, void *unused) + return 0; + } + ++static int i915_ips_status(struct seq_file *m, void *unused) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (!IS_ULT(dev)) { ++ seq_puts(m, "not supported\n"); ++ return 0; ++ } ++ ++ if (I915_READ(IPS_CTL) & IPS_ENABLE) ++ seq_puts(m, "enabled\n"); ++ else ++ seq_puts(m, "disabled\n"); ++ ++ return 0; ++} ++ + static int i915_sr_status(struct seq_file *m, void *unused) + { + struct drm_info_node *node = (struct drm_info_node *) m->private; +@@ -2233,6 +2252,7 @@ static struct drm_info_list i915_debugfs_list[] = { + {"i915_ring_freq_table", i915_ring_freq_table, 0}, + {"i915_gfxec", i915_gfxec, 0}, + {"i915_fbc_status", i915_fbc_status, 0}, ++ {"i915_ips_status", i915_ips_status, 0}, + {"i915_sr_status", i915_sr_status, 0}, + {"i915_opregion", i915_opregion, 0}, + {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0238-drm-i915-Drop-bogus-fbdev-sprite-disable-code.patch b/patches.baytrail/0238-drm-i915-Drop-bogus-fbdev-sprite-disable-code.patch new file mode 100644 index 000000000000..2c906bf3a569 --- /dev/null +++ b/patches.baytrail/0238-drm-i915-Drop-bogus-fbdev-sprite-disable-code.patch @@ -0,0 +1,48 @@ +From 3437a0f608f9c36c1fc289628202ddc4827921ee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Mon, 3 Jun 2013 16:11:41 +0300 +Subject: drm/i915: Drop bogus fbdev sprite disable code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +plane->enabled is never set, so this code didn't do anything. + +Also drm_fb_helper_restore_fbdev_mode() will now disable all cursors +and sprites for us, so we don't have to bother anymore. + +Signed-off-by: Ville Syrjälä +Signed-off-by: Dave Airlie +(cherry picked from commit b72447cdf1298b46af87d754bfb5d3db6eb7dbfe) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_fb.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c +index 6b7c3ca2c035..3b03c3c6cc5d 100644 +--- a/drivers/gpu/drm/i915/intel_fb.c ++++ b/drivers/gpu/drm/i915/intel_fb.c +@@ -292,8 +292,6 @@ void intel_fb_restore_mode(struct drm_device *dev) + { + int ret; + drm_i915_private_t *dev_priv = dev->dev_private; +- struct drm_mode_config *config = &dev->mode_config; +- struct drm_plane *plane; + + if (INTEL_INFO(dev)->num_pipes == 0) + return; +@@ -304,10 +302,5 @@ void intel_fb_restore_mode(struct drm_device *dev) + if (ret) + DRM_DEBUG("failed to restore crtc mode\n"); + +- /* Be sure to shut off any planes that may be active */ +- list_for_each_entry(plane, &config->plane_list, head) +- if (plane->enabled) +- plane->funcs->disable_plane(plane); +- + drm_modeset_unlock_all(dev); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0239-drm-i915-Demote-unknown-param-to-DRM_DEBUG.patch b/patches.baytrail/0239-drm-i915-Demote-unknown-param-to-DRM_DEBUG.patch new file mode 100644 index 000000000000..6ce398e8ca73 --- /dev/null +++ b/patches.baytrail/0239-drm-i915-Demote-unknown-param-to-DRM_DEBUG.patch @@ -0,0 +1,35 @@ +From 6316ab13178e4a5ce7897eba035b1286ccee440c Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Fri, 31 May 2013 11:28:45 -0700 +Subject: drm/i915: Demote unknown param to DRM_DEBUG + +It's not terribly interesting to know that a parameter doesn't exist, +and it can get in the way of interesting messages, especially with the +staggered VECS merging as we've done. + +Signed-off-by: Ben Widawsky +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit e29c32da531dfd94cffb150fd69760605739fb3a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index d392d8fb146e..cd2a5f3f7db6 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1001,8 +1001,7 @@ static int i915_getparam(struct drm_device *dev, void *data, + value = 1; + break; + default: +- DRM_DEBUG_DRIVER("Unknown parameter %d\n", +- param->param); ++ DRM_DEBUG("Unknown parameter %d\n", param->param); + return -EINVAL; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0240-drm-i915-Make-stolen-use-pin-pages.patch b/patches.baytrail/0240-drm-i915-Make-stolen-use-pin-pages.patch new file mode 100644 index 000000000000..d32616962ac9 --- /dev/null +++ b/patches.baytrail/0240-drm-i915-Make-stolen-use-pin-pages.patch @@ -0,0 +1,31 @@ +From 180938694fb4ff6714d2aca947d68f4dc596ffaf Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Fri, 31 May 2013 14:46:19 -0700 +Subject: drm/i915: Make stolen use pin pages + +This makes it easier to catch leaks. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit dd53e1b0ed82ba72b2e9f11ae9c3d38bb82113cc) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_stolen.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 89cbfab9570e..bc593e353576 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -279,7 +279,7 @@ _i915_gem_object_create_stolen(struct drm_device *dev, + goto cleanup; + + obj->has_dma_mapping = true; +- obj->pages_pin_count = 1; ++ i915_gem_object_pin_pages(obj); + obj->stolen = stolen; + + obj->base.write_domain = I915_GEM_DOMAIN_GTT; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0241-drm-i915-Unpin-stolen-pages.patch b/patches.baytrail/0241-drm-i915-Unpin-stolen-pages.patch new file mode 100644 index 000000000000..1f15280a751f --- /dev/null +++ b/patches.baytrail/0241-drm-i915-Unpin-stolen-pages.patch @@ -0,0 +1,39 @@ +From 8ef8ec6911e8776c8cbcdc516007803a5c8d92bd Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Fri, 31 May 2013 14:46:20 -0700 +Subject: drm/i915: Unpin stolen pages + +The way the stolen handling works is we take a pin on the backing pages, +but we never actually get a reference to the bo. On freeing objects +allocated with stolen memory, the final unref will end up freeing the +object with pinned pages count left. To enable an assertion to catch +bugs in this code path, this patch cleans up that remaining pin. + +Signed-off-by: Ben Widawsky +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 1d64ae719b436f2a5f8f5da801b4c560bf24aaa9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 25f327cc1127..fdb203fb5cb1 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3892,6 +3892,11 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) + dev_priv->mm.interruptible = was_interruptible; + } + ++ /* Stolen objects don't hold a ref, but do hold pin count. Fix that up ++ * before progressing. */ ++ if (obj->stolen) ++ i915_gem_object_unpin_pages(obj); ++ + obj->pages_pin_count = 0; + i915_gem_object_put_pages(obj); + i915_gem_object_free_mmap_offset(obj); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0242-drm-i915-unpin-pages-at-unbind.patch b/patches.baytrail/0242-drm-i915-unpin-pages-at-unbind.patch new file mode 100644 index 000000000000..e6d4ffc3a80d --- /dev/null +++ b/patches.baytrail/0242-drm-i915-unpin-pages-at-unbind.patch @@ -0,0 +1,54 @@ +From 10fc4a8c0bb80e95b2fb3d272cdf3b602b9d50d5 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Fri, 31 May 2013 11:28:47 -0700 +Subject: drm/i915: unpin pages at unbind + +If we properly keep track of the pages_pin_count, then when we later add +multiple address spaces, the put_pages doesn't need any special checks +to be able to perform it's job. + +CC: Chris Wilson +Signed-off-by: Ben Widawsky +Reviewed-by: Chris Wilson +[danvet: Rebased on top of the fix for stolen memory pinning.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 401c29f607702864fd00b6154325f7570ebaba4f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index fdb203fb5cb1..4c01b1b3d902 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2521,6 +2521,7 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) + obj->has_aliasing_ppgtt_mapping = 0; + } + i915_gem_gtt_finish_object(obj); ++ i915_gem_object_unpin_pages(obj); + + list_del(&obj->mm_list); + list_move_tail(&obj->gtt_list, &dev_priv->mm.unbound_list); +@@ -3092,7 +3093,6 @@ search_free: + + obj->map_and_fenceable = mappable && fenceable; + +- i915_gem_object_unpin_pages(obj); + trace_i915_gem_object_bind(obj, map_and_fenceable); + i915_gem_verify_gtt(dev); + return 0; +@@ -3897,7 +3897,8 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) + if (obj->stolen) + i915_gem_object_unpin_pages(obj); + +- obj->pages_pin_count = 0; ++ if (WARN_ON(obj->pages_pin_count)) ++ obj->pages_pin_count = 0; + i915_gem_object_put_pages(obj); + i915_gem_object_free_mmap_offset(obj); + i915_gem_object_release_stolen(obj); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0243-drm-i915-Rename-the-gtt_list-to-global_list.patch b/patches.baytrail/0243-drm-i915-Rename-the-gtt_list-to-global_list.patch new file mode 100644 index 000000000000..6f008d5d947b --- /dev/null +++ b/patches.baytrail/0243-drm-i915-Rename-the-gtt_list-to-global_list.patch @@ -0,0 +1,256 @@ +From 3c99a2602793537216ffb67e68f7cec221c9ed14 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Fri, 31 May 2013 11:28:48 -0700 +Subject: drm/i915: Rename the gtt_list to global_list + +Since it will be used for the global bound/unbound list with full PPGTT, +this helps clarify things for upcoming code rework. + +Recommended-by: Chris Wilson +Signed-off-by: Ben Widawsky +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 35c20a60c7549b11fd1d8c5d5d7ab5b6b54d6ff9) +[dbasehore: Fixed conflict that seems to be due to incorrect ordering +of CLs] +Signed-off-by: Derek Basehore + +Conflicts: + drivers/gpu/drm/i915/i915_gem.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 11 ++++++----- + drivers/gpu/drm/i915/i915_drv.h | 2 +- + drivers/gpu/drm/i915/i915_gem.c | 21 +++++++++++---------- + drivers/gpu/drm/i915/i915_gem_gtt.c | 4 ++-- + drivers/gpu/drm/i915/i915_gem_stolen.c | 2 +- + drivers/gpu/drm/i915/i915_irq.c | 6 +++--- + 6 files changed, 24 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 76255a69752a..0e7e3c04d939 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -215,7 +215,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data) + dev_priv->mm.object_memory); + + size = count = mappable_size = mappable_count = 0; +- count_objects(&dev_priv->mm.bound_list, gtt_list); ++ count_objects(&dev_priv->mm.bound_list, global_list); + seq_printf(m, "%u [%u] objects, %zu [%zu] bytes in gtt\n", + count, mappable_count, size, mappable_size); + +@@ -230,7 +230,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data) + count, mappable_count, size, mappable_size); + + size = count = purgeable_size = purgeable_count = 0; +- list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list) { ++ list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) { + size += obj->base.size, ++count; + if (obj->madv == I915_MADV_DONTNEED) + purgeable_size += obj->base.size, ++purgeable_count; +@@ -238,7 +238,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data) + seq_printf(m, "%u unbound objects, %zu bytes\n", count, size); + + size = count = mappable_size = mappable_count = 0; +- list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) { ++ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { + if (obj->fault_mappable) { + size += obj->gtt_space->size; + ++count; +@@ -283,7 +283,7 @@ static int i915_gem_gtt_info(struct seq_file *m, void* data) + return ret; + + total_obj_size = total_gtt_size = count = 0; +- list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) { ++ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { + if (list == PINNED_LIST && obj->pin_count == 0) + continue; + +@@ -1944,7 +1944,8 @@ i915_drop_caches_set(void *data, u64 val) + } + + if (val & DROP_UNBOUND) { +- list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list, gtt_list) ++ list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list, ++ global_list) + if (obj->pages_pin_count == 0) { + ret = i915_gem_object_put_pages(obj); + if (ret) +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 4eed8559fa90..36ed6041a259 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1155,7 +1155,7 @@ struct drm_i915_gem_object { + struct drm_mm_node *gtt_space; + /** Stolen memory for this object, instead of being backed by shmem. */ + struct drm_mm_node *stolen; +- struct list_head gtt_list; ++ struct list_head global_list; + + /** This object's place on the active/inactive lists */ + struct list_head ring_list; +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 4c01b1b3d902..694af6db61a2 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -176,7 +176,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, + + pinned = 0; + mutex_lock(&dev->struct_mutex); +- list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) ++ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) + if (obj->pin_count) + pinned += obj->gtt_space->size; + mutex_unlock(&dev->struct_mutex); +@@ -1677,7 +1677,7 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj) + /* ->put_pages might need to allocate memory for the bit17 swizzle + * array, hence protect them from being reaped by removing them from gtt + * lists early. */ +- list_del(&obj->gtt_list); ++ list_del(&obj->global_list); + + ops->put_pages(obj); + obj->pages = NULL; +@@ -1697,7 +1697,7 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, + + list_for_each_entry_safe(obj, next, + &dev_priv->mm.unbound_list, +- gtt_list) { ++ global_list) { + if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) && + i915_gem_object_put_pages(obj) == 0) { + count += obj->base.size >> PAGE_SHIFT; +@@ -1734,7 +1734,8 @@ i915_gem_shrink_all(struct drm_i915_private *dev_priv) + + i915_gem_evict_everything(dev_priv->dev); + +- list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list, gtt_list) ++ list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list, ++ global_list) + i915_gem_object_put_pages(obj); + } + +@@ -1868,7 +1869,7 @@ i915_gem_object_get_pages(struct drm_i915_gem_object *obj) + if (ret) + return ret; + +- list_add_tail(&obj->gtt_list, &dev_priv->mm.unbound_list); ++ list_add_tail(&obj->global_list, &dev_priv->mm.unbound_list); + return 0; + } + +@@ -2524,7 +2525,7 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) + i915_gem_object_unpin_pages(obj); + + list_del(&obj->mm_list); +- list_move_tail(&obj->gtt_list, &dev_priv->mm.unbound_list); ++ list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list); + /* Avoid an unnecessary call to unbind on rebind. */ + obj->map_and_fenceable = true; + +@@ -2954,7 +2955,7 @@ static void i915_gem_verify_gtt(struct drm_device *dev) + struct drm_i915_gem_object *obj; + int err = 0; + +- list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { ++ list_for_each_entry(obj, &dev_priv->mm.gtt_list, global_list) { + if (obj->gtt_space == NULL) { + printk(KERN_ERR "object found on GTT list with no space reserved\n"); + err++; +@@ -3078,7 +3079,7 @@ search_free: + return ret; + } + +- list_move_tail(&obj->gtt_list, &dev_priv->mm.bound_list); ++ list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); + list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); + + obj->gtt_space = node; +@@ -3792,7 +3793,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, + const struct drm_i915_gem_object_ops *ops) + { + INIT_LIST_HEAD(&obj->mm_list); +- INIT_LIST_HEAD(&obj->gtt_list); ++ INIT_LIST_HEAD(&obj->global_list); + INIT_LIST_HEAD(&obj->ring_list); + INIT_LIST_HEAD(&obj->exec_list); + +@@ -4538,7 +4539,7 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) + } + + cnt = 0; +- list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list) ++ list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) + if (obj->pages_pin_count == 0) + cnt += obj->base.size >> PAGE_SHIFT; + list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 1bddf477304a..95acae13b059 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -439,7 +439,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) + dev_priv->gtt.gtt_clear_range(dev, dev_priv->gtt.start / PAGE_SIZE, + dev_priv->gtt.total / PAGE_SIZE); + +- list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) { ++ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { + i915_gem_clflush_object(obj); + i915_gem_gtt_bind_object(obj, obj->cache_level); + } +@@ -631,7 +631,7 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + dev_priv->mm.gtt_space.color_adjust = i915_gtt_color_adjust; + + /* Mark any preallocated objects as occupied */ +- list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) { ++ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { + DRM_DEBUG_KMS("reserving preallocated space: %x + %zx\n", + obj->gtt_offset, obj->base.size); + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index bc593e353576..f713294618fe 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -383,7 +383,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + obj->gtt_offset = gtt_offset; + obj->has_global_gtt_mapping = 1; + +- list_add_tail(&obj->gtt_list, &dev_priv->mm.bound_list); ++ list_add_tail(&obj->global_list, &dev_priv->mm.bound_list); + list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); + + return obj; +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index ea396518baab..2ecf66cb26f3 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1681,7 +1681,7 @@ static u32 capture_pinned_bo(struct drm_i915_error_buffer *err, + struct drm_i915_gem_object *obj; + int i = 0; + +- list_for_each_entry(obj, head, gtt_list) { ++ list_for_each_entry(obj, head, global_list) { + if (obj->pin_count == 0) + continue; + +@@ -1823,7 +1823,7 @@ static void i915_gem_record_active_context(struct intel_ring_buffer *ring, + if (ring->id != RCS || !error->ccid) + return; + +- list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) { ++ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { + if ((error->ccid & PAGE_MASK) == obj->gtt_offset) { + ering->ctx = i915_error_object_create_sized(dev_priv, + obj, 1); +@@ -1960,7 +1960,7 @@ static void i915_capture_error_state(struct drm_device *dev) + list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) + i++; + error->active_bo_count = i; +- list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) ++ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) + if (obj->pin_count) + i++; + error->pinned_bo_count = i - error->active_bo_count; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0244-drm-i915-detect-hang-using-per-ring-hangcheck_score.patch b/patches.baytrail/0244-drm-i915-detect-hang-using-per-ring-hangcheck_score.patch new file mode 100644 index 000000000000..b78c8a18387f --- /dev/null +++ b/patches.baytrail/0244-drm-i915-detect-hang-using-per-ring-hangcheck_score.patch @@ -0,0 +1,188 @@ +From f31ffe1f1f0f76084f88564bcd0b8cd97068eca0 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Thu, 30 May 2013 09:04:29 +0300 +Subject: drm/i915: detect hang using per ring hangcheck_score + +Keep track of ring seqno progress and if there are no +progress detected, declare hang. Use actual head (acthd) +to distinguish between ring stuck and batchbuffer looping +situation. Stuck ring will be kicked to trigger progress. + +This commit adds a hard limit for batchbuffer completion time. +If batchbuffer completion time is more than 4.5 seconds, +the gpu will be declared hung. + +Review comment from Ben which nicely clarifies the semantic change: + +"Maybe I'm just stating the functional changes of the patch, but in case +they were unintended here is what I see as potential issues: + +1. "If ring B is waiting on ring A via semaphore, and ring A is making + progress, albeit slowly - the hangcheck will fire. The check will + determine that A is moving, however ring B will appear hung because + the ACTHD doesn't move. I honestly can't say if that's actually a + realistic problem to hit it probably implies the timeout value is too + low. + +2. "There's also another corner case on the kick. If the seqno = 2 + (though not stuck), and on the 3rd hangcheck, the ring is stuck, and + we try to kick it... we don't actually try to find out if the kick + helped" + +v2: use atchd to detect stuck ring from loop (Ben Widawsky) + +v3: Use acthd to check when ring needs kicking. +Declare hang on third time in order to give time for +kick_ring to take effect. + +v4: Update commit msg + +Signed-off-by: Mika Kuoppala +Reviewed-by: Ben Widawsky +[danvet: Paste in Ben's review comment.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 05407ff889ceebe383aa5907219f86582ef96b72) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 80 +++++++++++++++++++-------------- + drivers/gpu/drm/i915/intel_ringbuffer.h | 2 + + 2 files changed, 49 insertions(+), 33 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 2ecf66cb26f3..e213bd71524e 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -674,7 +674,6 @@ static void notify_ring(struct drm_device *dev, + + wake_up_all(&ring->irq_queue); + if (i915_enable_hangcheck) { +- dev_priv->gpu_error.hangcheck_count = 0; + mod_timer(&dev_priv->gpu_error.hangcheck_timer, + round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES)); + } +@@ -2459,61 +2458,76 @@ static bool i915_hangcheck_hung(struct drm_device *dev) + + /** + * This is called when the chip hasn't reported back with completed +- * batchbuffers in a long time. The first time this is called we simply record +- * ACTHD. If ACTHD hasn't changed by the time the hangcheck timer elapses +- * again, we assume the chip is wedged and try to fix it. ++ * batchbuffers in a long time. We keep track per ring seqno progress and ++ * if there are no progress, hangcheck score for that ring is increased. ++ * Further, acthd is inspected to see if the ring is stuck. On stuck case ++ * we kick the ring. If we see no progress on three subsequent calls ++ * we assume chip is wedged and try to fix it by resetting the chip. + */ + void i915_hangcheck_elapsed(unsigned long data) + { + struct drm_device *dev = (struct drm_device *)data; + drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring; +- bool err = false, idle; + int i; +- u32 seqno[I915_NUM_RINGS]; +- bool work_done; ++ int busy_count = 0, rings_hung = 0; ++ bool stuck[I915_NUM_RINGS]; + + if (!i915_enable_hangcheck) + return; + +- idle = true; + for_each_ring(ring, dev_priv, i) { +- seqno[i] = ring->get_seqno(ring, false); +- idle &= i915_hangcheck_ring_idle(ring, seqno[i], &err); +- } ++ u32 seqno, acthd; ++ bool idle, err = false; ++ ++ seqno = ring->get_seqno(ring, false); ++ acthd = intel_ring_get_active_head(ring); ++ idle = i915_hangcheck_ring_idle(ring, seqno, &err); ++ stuck[i] = ring->hangcheck.acthd == acthd; ++ ++ if (idle) { ++ if (err) ++ ring->hangcheck.score += 2; ++ else ++ ring->hangcheck.score = 0; ++ } else { ++ busy_count++; + +- /* If all work is done then ACTHD clearly hasn't advanced. */ +- if (idle) { +- if (err) { +- if (i915_hangcheck_hung(dev)) +- return; ++ if (ring->hangcheck.seqno == seqno) { ++ ring->hangcheck.score++; + +- goto repeat; ++ /* Kick ring if stuck*/ ++ if (stuck[i]) ++ i915_hangcheck_ring_hung(ring); ++ } else { ++ ring->hangcheck.score = 0; ++ } + } + +- dev_priv->gpu_error.hangcheck_count = 0; +- return; ++ ring->hangcheck.seqno = seqno; ++ ring->hangcheck.acthd = acthd; + } + +- work_done = false; + for_each_ring(ring, dev_priv, i) { +- if (ring->hangcheck.seqno != seqno[i]) { +- work_done = true; +- ring->hangcheck.seqno = seqno[i]; ++ if (ring->hangcheck.score > 2) { ++ rings_hung++; ++ DRM_ERROR("%s: %s on %s 0x%x\n", ring->name, ++ stuck[i] ? "stuck" : "no progress", ++ stuck[i] ? "addr" : "seqno", ++ stuck[i] ? ring->hangcheck.acthd & HEAD_ADDR : ++ ring->hangcheck.seqno); + } + } + +- if (!work_done) { +- if (i915_hangcheck_hung(dev)) +- return; +- } else { +- dev_priv->gpu_error.hangcheck_count = 0; +- } ++ if (rings_hung) ++ return i915_handle_error(dev, true); + +-repeat: +- /* Reset timer case chip hangs without another request being added */ +- mod_timer(&dev_priv->gpu_error.hangcheck_timer, +- round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES)); ++ if (busy_count) ++ /* Reset timer case chip hangs without another request ++ * being added */ ++ mod_timer(&dev_priv->gpu_error.hangcheck_timer, ++ round_jiffies_up(jiffies + ++ DRM_I915_HANGCHECK_JIFFIES)); + } + + /* drm_dma.h hooks +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index 022d07e43d12..4c7e103e6fa4 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -39,6 +39,8 @@ struct intel_hw_status_page { + + struct intel_ring_hangcheck { + u32 seqno; ++ u32 acthd; ++ int score; + }; + + struct intel_ring_buffer { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0245-drm-i915-remove-i915_hangcheck_hung.patch b/patches.baytrail/0245-drm-i915-remove-i915_hangcheck_hung.patch new file mode 100644 index 000000000000..4c4be5857954 --- /dev/null +++ b/patches.baytrail/0245-drm-i915-remove-i915_hangcheck_hung.patch @@ -0,0 +1,64 @@ +From 2dafb7e8f861588146d496267825941169efe20d Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Mon, 13 May 2013 16:32:13 +0300 +Subject: drm/i915: remove i915_hangcheck_hung + +Rework of per ring hangcheck made this obsolete. + +Signed-off-by: Mika Kuoppala +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 96a764d983647636b39c462ea14cd1f588f6c0bd) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 1 - + drivers/gpu/drm/i915/i915_irq.c | 21 --------------------- + 2 files changed, 22 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 36ed6041a259..92a0f5e42aca 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -843,7 +843,6 @@ struct i915_gpu_error { + #define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */ + #define DRM_I915_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD) + struct timer_list hangcheck_timer; +- int hangcheck_count; + + /* For reset and error_state handling. */ + spinlock_t lock; +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index e213bd71524e..2eaae3211553 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2435,27 +2435,6 @@ static bool i915_hangcheck_ring_hung(struct intel_ring_buffer *ring) + return !kick_ring(ring); + } + +-static bool i915_hangcheck_hung(struct drm_device *dev) +-{ +- drm_i915_private_t *dev_priv = dev->dev_private; +- +- if (dev_priv->gpu_error.hangcheck_count++ > 1) { +- bool hung = true; +- struct intel_ring_buffer *ring; +- int i; +- +- DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); +- i915_handle_error(dev, true); +- +- for_each_ring(ring, dev_priv, i) +- hung &= i915_hangcheck_ring_hung(ring); +- +- return hung; +- } +- +- return false; +-} +- + /** + * This is called when the chip hasn't reported back with completed + * batchbuffers in a long time. We keep track per ring seqno progress and +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0246-drm-i915-Use-container_of-in-the-fbdev-code.patch b/patches.baytrail/0246-drm-i915-Use-container_of-in-the-fbdev-code.patch new file mode 100644 index 000000000000..8211eed3a083 --- /dev/null +++ b/patches.baytrail/0246-drm-i915-Use-container_of-in-the-fbdev-code.patch @@ -0,0 +1,54 @@ +From 1d8b3fd87e153e799ccf8dbd41583d21121958ea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 31 May 2013 20:07:05 +0300 +Subject: drm/i915: Use container_of() in the fbdev code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use container_of() instead of a cast to get struct intel_fbdev +from struct drm_fb_helper. + +Also populate the fb_info->par correctly with the drm_fb_helper pointer +instead of the intel_fbdev pointer. + +There's no actual functional change since the drm_fb_helper happens to +be the first member inside intel_fbdev. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 3430824b4ba9f8b658d5503d390ce9a7286b0b4a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_fb.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c +index 3b03c3c6cc5d..9061edcf4b74 100644 +--- a/drivers/gpu/drm/i915/intel_fb.c ++++ b/drivers/gpu/drm/i915/intel_fb.c +@@ -60,8 +60,9 @@ static struct fb_ops intelfb_ops = { + static int intelfb_create(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes) + { +- struct intel_fbdev *ifbdev = (struct intel_fbdev *)helper; +- struct drm_device *dev = ifbdev->helper.dev; ++ struct intel_fbdev *ifbdev = ++ container_of(helper, struct intel_fbdev, helper); ++ struct drm_device *dev = helper->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct fb_info *info; + struct drm_framebuffer *fb; +@@ -108,7 +109,7 @@ static int intelfb_create(struct drm_fb_helper *helper, + goto out_unpin; + } + +- info->par = ifbdev; ++ info->par = helper; + + ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj); + if (ret) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0247-drm-i915-s-drm_i915_private_t-struct-drm_i915_privat.patch b/patches.baytrail/0247-drm-i915-s-drm_i915_private_t-struct-drm_i915_privat.patch new file mode 100644 index 000000000000..6df60dd810ce --- /dev/null +++ b/patches.baytrail/0247-drm-i915-s-drm_i915_private_t-struct-drm_i915_privat.patch @@ -0,0 +1,82 @@ +From 17a448203ff89adab92129c42c49490cd5d667dc Mon Sep 17 00:00:00 2001 +From: James Ausmus +Date: Mon, 23 Sep 2013 16:52:19 -0700 +Subject: drm/i915: s/drm_i915_private_t/struct drm_i915_private/ +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +People don't like typedefs these days. Eliminate their use from intel_fb.c. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit b51b32cde1757cd0f3f75bc15d5e0e98c3007dff) + +Conflicts: + drivers/gpu/drm/i915/intel_fb.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_fb.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c +index 9061edcf4b74..7f3ac54b56e9 100644 +--- a/drivers/gpu/drm/i915/intel_fb.c ++++ b/drivers/gpu/drm/i915/intel_fb.c +@@ -218,7 +218,7 @@ static void intel_fbdev_destroy(struct drm_device *dev, + int intel_fbdev_init(struct drm_device *dev) + { + struct intel_fbdev *ifbdev; +- drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = dev->dev_private; + int ret; + + ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL); +@@ -243,7 +243,7 @@ int intel_fbdev_init(struct drm_device *dev) + + void intel_fbdev_initial_config(struct drm_device *dev) + { +- drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = dev->dev_private; + + /* Due to peculiar init order wrt to hpd handling this is separate. */ + drm_fb_helper_initial_config(&dev_priv->fbdev->helper, 32); +@@ -251,7 +251,7 @@ void intel_fbdev_initial_config(struct drm_device *dev) + + void intel_fbdev_fini(struct drm_device *dev) + { +- drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = dev->dev_private; + if (!dev_priv->fbdev) + return; + +@@ -262,7 +262,7 @@ void intel_fbdev_fini(struct drm_device *dev) + + void intel_fbdev_set_suspend(struct drm_device *dev, int state) + { +- drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_fbdev *ifbdev = dev_priv->fbdev; + struct fb_info *info; + +@@ -285,14 +285,14 @@ MODULE_LICENSE("GPL and additional rights"); + + void intel_fb_output_poll_changed(struct drm_device *dev) + { +- drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = dev->dev_private; + drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); + } + + void intel_fb_restore_mode(struct drm_device *dev) + { + int ret; +- drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = dev->dev_private; + + if (INTEL_INFO(dev)->num_pipes == 0) + return; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0248-drm-i915-optimize-vblank-waits-in-set_base_atomic.patch b/patches.baytrail/0248-drm-i915-optimize-vblank-waits-in-set_base_atomic.patch new file mode 100644 index 000000000000..ce54777e7134 --- /dev/null +++ b/patches.baytrail/0248-drm-i915-optimize-vblank-waits-in-set_base_atomic.patch @@ -0,0 +1,36 @@ +From 3d97fe8c502a307b76e4c6dc967c88b4aefc3a2f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 2 Jun 2013 17:23:01 +0200 +Subject: drm/i915: optimize vblank waits in set_base_atomic + +We only need to do them if the pipe is actually running and if the +framebuffers have changed. Removes two "wait for vblank timed out" +messages when doing a suspend/resume cycle on my i855gm. + +v2: s/to_intel_ctrc(crtc)/intel_crtc/ spotted by Chris. + +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit d7697eea3eec74c561d12887d892c53ac4380c00) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index b26c3a08d8e1..799f2bd36aee 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2212,7 +2212,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, + crtc->y = y; + + if (old_fb) { +- intel_wait_for_vblank(dev, intel_crtc->pipe); ++ if (intel_crtc->active && old_fb != fb) ++ intel_wait_for_vblank(dev, intel_crtc->pipe); + intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0249-drm-i915-refactor-sink-bpp-clamping.patch b/patches.baytrail/0249-drm-i915-refactor-sink-bpp-clamping.patch new file mode 100644 index 000000000000..42d5d9acebb8 --- /dev/null +++ b/patches.baytrail/0249-drm-i915-refactor-sink-bpp-clamping.patch @@ -0,0 +1,120 @@ +From df3d709ec0bcc8cf08f8e2ad4ea50ce6fcec71b6 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 2 Jun 2013 13:26:23 +0200 +Subject: drm/i915: refactor sink bpp clamping + +As a prep work to fix it up: +- Use intel_connector instead of drm_connector to avoid too much + upcasting in the bugfix patch. +- Extract the connector bpp clamping from the loop-over-connectors + logic. +- Bikeshed function names (to make it clearer that + acompute_baseline_pipe_bpp runs in the compute stage of the modeset + sequence) and add a comment to make it clearer what it does. + +No functional change in this patch. + +Cc: Chris Wilson +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 050f7aeb129c1b9fb63dd523ca9bc1101bbae6cc) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 63 +++++++++++++++++++++++------------- + 1 file changed, 41 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 799f2bd36aee..e51b59cdee23 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -7656,13 +7656,39 @@ static void intel_modeset_commit_output_state(struct drm_device *dev) + } + } + ++static void ++connected_sink_compute_bpp(struct intel_connector * connector, ++ struct intel_crtc_config *pipe_config) ++{ ++ int bpp = pipe_config->pipe_bpp; ++ ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] checking for sink bpp constrains\n", ++ connector->base.base.id, ++ drm_get_connector_name(&connector->base)); ++ ++ /* Don't use an invalid EDID bpc value */ ++ if (connector->base.display_info.bpc && ++ connector->base.display_info.bpc * 3 < bpp) { ++ DRM_DEBUG_KMS("clamping display bpp (was %d) to EDID reported max of %d\n", ++ bpp, connector->base.display_info.bpc*3); ++ pipe_config->pipe_bpp = connector->base.display_info.bpc*3; ++ } ++ ++ /* Clamp bpp to 8 on screens without EDID 1.4 */ ++ if (connector->base.display_info.bpc == 0 && bpp > 24) { ++ DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of 24\n", ++ bpp); ++ pipe_config->pipe_bpp = 24; ++ } ++} ++ + static int +-pipe_config_set_bpp(struct drm_crtc *crtc, +- struct drm_framebuffer *fb, +- struct intel_crtc_config *pipe_config) ++compute_baseline_pipe_bpp(struct intel_crtc *crtc, ++ struct drm_framebuffer *fb, ++ struct intel_crtc_config *pipe_config) + { +- struct drm_device *dev = crtc->dev; +- struct drm_connector *connector; ++ struct drm_device *dev = crtc->base.dev; ++ struct intel_connector *connector; + int bpp; + + switch (fb->pixel_format) { +@@ -7705,24 +7731,12 @@ pipe_config_set_bpp(struct drm_crtc *crtc, + + /* Clamp display bpp to EDID value */ + list_for_each_entry(connector, &dev->mode_config.connector_list, +- head) { +- if (connector->encoder && connector->encoder->crtc != crtc) ++ base.head) { ++ if (connector->base.encoder && ++ connector->base.encoder->crtc != crtc) + continue; + +- /* Don't use an invalid EDID bpc value */ +- if (connector->display_info.bpc && +- connector->display_info.bpc * 3 < bpp) { +- DRM_DEBUG_KMS("clamping display bpp (was %d) to EDID reported max of %d\n", +- bpp, connector->display_info.bpc*3); +- pipe_config->pipe_bpp = connector->display_info.bpc*3; +- } +- +- /* Clamp bpp to 8 on screens without EDID 1.4 */ +- if (connector->display_info.bpc == 0 && bpp > 24) { +- DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of 24\n", +- bpp); +- pipe_config->pipe_bpp = 24; +- } ++ connected_sink_compute_bpp(connector, pipe_config); + } + + return bpp; +@@ -7778,7 +7792,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, + drm_mode_copy(&pipe_config->requested_mode, mode); + pipe_config->cpu_transcoder = to_intel_crtc(crtc)->pipe; + +- plane_bpp = pipe_config_set_bpp(crtc, fb, pipe_config); ++ /* Compute a starting value for pipe_config->pipe_bpp taking the source ++ * plane pixel format and any sink constraints into account. Returns the ++ * source plane bpp so that dithering can be selected on mismatches ++ * after encoders and crtc also have had their say. */ ++ plane_bpp = compute_baseline_pipe_bpp(to_intel_crtc(crtc), ++ fb, pipe_config); + if (plane_bpp < 0) + goto fail; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0250-drm-i915-fix-EDID-sink-based-bpp-clamping.patch b/patches.baytrail/0250-drm-i915-fix-EDID-sink-based-bpp-clamping.patch new file mode 100644 index 000000000000..484cbcf54a6f --- /dev/null +++ b/patches.baytrail/0250-drm-i915-fix-EDID-sink-based-bpp-clamping.patch @@ -0,0 +1,64 @@ +From b2d8446051b9cc80759004487b0d0d3130218c6f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 2 Jun 2013 13:26:24 +0200 +Subject: drm/i915: fix EDID/sink-based bpp clamping + +Since this is run in the compute config stage we need to check +the new_ pointers, i.e the stage output routing, not the current +modeset layout. Also there was a little logic bug in properly skipping +connectors: The old code did not skip any unused connectors and so +clamped to whatever was left in there (usually 0 if that connector +hasn't seen a EDID 1.4 screen ever since boot-up). + +This has been broken when moving the pipe bpp selection in + +commit 4e53c2e010e531b4a014692199e978482d471c7e +Author: Daniel Vetter +Date: Wed Mar 27 00:44:58 2013 +0100 + + drm/i915: precompute pipe bpp before touching the hw + +To avoid too much casting switch from drm_ to intel_ types. + +Also add a bit of debug output to help reconstructing what's going +on. + +v2: Try to clarify this a bit: +- s/pipe_config_set_bpp/compute_baseline_pipe_bpp/ to make it clearer + at which stage this function is run. Also add a comment about what + it does. +- Extract the sink clamping into it's own function. + +v3: Actually make it compile. + +v4: Split out all the prep refactoring to make the bugfix stick out +really badly. Also elaborate a bit in the commit message about the +nature of the bugfix. + +Cc: Chris Wilson +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 1b829e05469963301736df69f0a2a2c3d3fb2225) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index e51b59cdee23..989b9af8e2bc 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -7732,8 +7732,8 @@ compute_baseline_pipe_bpp(struct intel_crtc *crtc, + /* Clamp display bpp to EDID value */ + list_for_each_entry(connector, &dev->mode_config.connector_list, + base.head) { +- if (connector->base.encoder && +- connector->base.encoder->crtc != crtc) ++ if (!connector->new_encoder || ++ connector->new_encoder->new_crtc != crtc) + continue; + + connected_sink_compute_bpp(connector, pipe_config); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0251-drm-i915-split-out-intel_pnv_find_best_PLL.patch b/patches.baytrail/0251-drm-i915-split-out-intel_pnv_find_best_PLL.patch new file mode 100644 index 000000000000..d7cf53873d8d --- /dev/null +++ b/patches.baytrail/0251-drm-i915-split-out-intel_pnv_find_best_PLL.patch @@ -0,0 +1,200 @@ +From bd3df75a31a1e4a0d7e2c69e228cbf896b0360f3 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sat, 1 Jun 2013 17:16:17 +0200 +Subject: drm/i915: split out intel_pnv_find_best_PLL + +Pineview is just different. + +Also split out i9xx_clock from intel_clock and drop the now redundant +struct device * parameter. + +Note that in this patch I kill an XXX comment about 100MHz clocks. I +couldn't figure out what this is about, and we don't seem to have any +bug reports about this either. I suspect that it's a remnant from when +the i9xx and ilk+ modeset code was all in the same file since ilk+ +does indeed have a 100MHz clock. So I've just killed it to stop the +cargo-culting. + +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit ac58c3f046dde3c29b0e3fc7ea71a82b5f80c470) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 92 ++++++++++++++++++++++++++++++------ + 1 file changed, 77 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 989b9af8e2bc..c06140cbc6af 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -97,10 +97,13 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock); + static bool ++intel_pnv_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, ++ int target, int refclk, intel_clock_t *match_clock, ++ intel_clock_t *best_clock); ++static bool + intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock); +- + static bool + intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, + int target, int refclk, intel_clock_t *match_clock, +@@ -246,7 +249,7 @@ static const intel_limit_t intel_limits_pineview_sdvo = { + .p1 = { .min = 1, .max = 8 }, + .p2 = { .dot_limit = 200000, + .p2_slow = 10, .p2_fast = 5 }, +- .find_pll = intel_find_best_PLL, ++ .find_pll = intel_pnv_find_best_PLL, + }; + + static const intel_limit_t intel_limits_pineview_lvds = { +@@ -260,7 +263,7 @@ static const intel_limit_t intel_limits_pineview_lvds = { + .p1 = { .min = 1, .max = 8 }, + .p2 = { .dot_limit = 112000, + .p2_slow = 14, .p2_fast = 14 }, +- .find_pll = intel_find_best_PLL, ++ .find_pll = intel_pnv_find_best_PLL, + }; + + /* Ironlake / Sandybridge +@@ -475,12 +478,8 @@ static uint32_t i9xx_dpll_compute_m(struct dpll *dpll) + return 5 * (dpll->m1 + 2) + (dpll->m2 + 2); + } + +-static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock) ++static void i9xx_clock(int refclk, intel_clock_t *clock) + { +- if (IS_PINEVIEW(dev)) { +- pineview_clock(refclk, clock); +- return; +- } + clock->m = i9xx_dpll_compute_m(clock); + clock->p = clock->p1 * clock->p2; + clock->vco = refclk * clock->m / (clock->n + 2); +@@ -541,7 +540,68 @@ static bool + intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock) ++{ ++ struct drm_device *dev = crtc->dev; ++ intel_clock_t clock; ++ int err = target; ++ ++ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { ++ /* ++ * For LVDS just rely on its current settings for dual-channel. ++ * We haven't figured out how to reliably set up different ++ * single/dual channel state, if we even can. ++ */ ++ if (intel_is_dual_link_lvds(dev)) ++ clock.p2 = limit->p2.p2_fast; ++ else ++ clock.p2 = limit->p2.p2_slow; ++ } else { ++ if (target < limit->p2.dot_limit) ++ clock.p2 = limit->p2.p2_slow; ++ else ++ clock.p2 = limit->p2.p2_fast; ++ } ++ ++ memset(best_clock, 0, sizeof(*best_clock)); ++ ++ for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; ++ clock.m1++) { ++ for (clock.m2 = limit->m2.min; ++ clock.m2 <= limit->m2.max; clock.m2++) { ++ /* m1 is always 0 in Pineview */ ++ if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev)) ++ break; ++ for (clock.n = limit->n.min; ++ clock.n <= limit->n.max; clock.n++) { ++ for (clock.p1 = limit->p1.min; ++ clock.p1 <= limit->p1.max; clock.p1++) { ++ int this_err; + ++ i9xx_clock(refclk, &clock); ++ if (!intel_PLL_is_valid(dev, limit, ++ &clock)) ++ continue; ++ if (match_clock && ++ clock.p != match_clock->p) ++ continue; ++ ++ this_err = abs(clock.dot - target); ++ if (this_err < err) { ++ *best_clock = clock; ++ err = this_err; ++ } ++ } ++ } ++ } ++ } ++ ++ return (err != target); ++} ++ ++static bool ++intel_pnv_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, ++ int target, int refclk, intel_clock_t *match_clock, ++ intel_clock_t *best_clock) + { + struct drm_device *dev = crtc->dev; + intel_clock_t clock; +@@ -579,7 +639,7 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, + clock.p1 <= limit->p1.max; clock.p1++) { + int this_err; + +- intel_clock(dev, refclk, &clock); ++ pineview_clock(refclk, &clock); + if (!intel_PLL_is_valid(dev, limit, + &clock)) + continue; +@@ -638,7 +698,7 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, + clock.p1 >= limit->p1.min; clock.p1--) { + int this_err; + +- intel_clock(dev, refclk, &clock); ++ i9xx_clock(refclk, &clock); + if (!intel_PLL_is_valid(dev, limit, + &clock)) + continue; +@@ -6914,8 +6974,10 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) + return 0; + } + +- /* XXX: Handle the 100Mhz refclk */ +- intel_clock(dev, 96000, &clock); ++ if (IS_PINEVIEW(dev)) ++ pineview_clock(96000, &clock); ++ else ++ i9xx_clock(96000, &clock); + } else { + bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN); + +@@ -6927,9 +6989,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) + if ((dpll & PLL_REF_INPUT_MASK) == + PLLB_REF_INPUT_SPREADSPECTRUMIN) { + /* XXX: might not be 66MHz */ +- intel_clock(dev, 66000, &clock); ++ i9xx_clock(66000, &clock); + } else +- intel_clock(dev, 48000, &clock); ++ i9xx_clock(48000, &clock); + } else { + if (dpll & PLL_P1_DIVIDE_BY_TWO) + clock.p1 = 2; +@@ -6942,7 +7004,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) + else + clock.p2 = 2; + +- intel_clock(dev, 48000, &clock); ++ i9xx_clock(48000, &clock); + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0252-drm-i915-move-find_pll-callback-to-dev_priv-display.patch b/patches.baytrail/0252-drm-i915-move-find_pll-callback-to-dev_priv-display.patch new file mode 100644 index 000000000000..b3f934c3df8d --- /dev/null +++ b/patches.baytrail/0252-drm-i915-move-find_pll-callback-to-dev_priv-display.patch @@ -0,0 +1,415 @@ +From 043261d79ed4087c60cd8254afe05dda45e69021 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 3 Jun 2013 22:40:22 +0200 +Subject: drm/i915: move find_pll callback to dev_priv->display + +Now that the DP madness is cleared out, this is all only per-platform. +So move it out from the intel clock limits structure. + +While at it drop the intel prefix on the static functions, call the +vtable entry find_dpll (since it's for the display pll) and rip out +the now unnecessary forward declarations. + +Note that the parameters of ->find_dpll are still unchanged, but they +eventually need to be moved over to just take in a pipe configuration. +But currently a lot of things are still missing from the pipe +configuration (reflock, output-specific dpll limits and preferences, +downclocked dotclock). So this will happen in a later step. + +Note that intel_g4x_limit has a peculiar case where it selects +intel_limits_i9xx_sdvo as the limit. This is pretty bogus and also not +used since the only output types left are DP and native TV-out which +both use special pre-tuned dpll values. + +v2: Re-add comment for the find_pll callback (requested by Paulo) and +elaborate on why the transformation is correct for g4x platforms (to +clarify a review question from Paulo). Double up on that by adding a +WARN as suggested by Paulo Zanoni on irc. + +v3: Initialize limits to NULL since gcc is now unhappy. + +v4: v2/3 will blow up with a NULL dereference in ->find_dpll for dp and +TV-out ports, spotted by Paulo on irc. So just give up on this madness for +now, and leave this to be fixed in a later patch. + +v5: Since the ever-so-slight change for g4x might result in some dpll +parameter computation failing spuriously where before it didn't for +ports with preset dpll settings (DP & TV-out) override this. For +paranoia also do it in the ilk+ code. + +Cc: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit ee9300bb5fa423117585a57c6a158522d2298b4e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 20 +++++++ + drivers/gpu/drm/i915/intel_display.c | 110 +++++++++++------------------------ + 2 files changed, 53 insertions(+), 77 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 92a0f5e42aca..5297b1fe3a2c 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -306,6 +306,8 @@ struct drm_i915_error_state { + + struct intel_crtc_config; + struct intel_crtc; ++struct intel_limit; ++struct dpll; + + struct drm_i915_display_funcs { + bool (*fbc_enabled)(struct drm_device *dev); +@@ -313,6 +315,24 @@ struct drm_i915_display_funcs { + void (*disable_fbc)(struct drm_device *dev); + int (*get_display_clock_speed)(struct drm_device *dev); + int (*get_fifo_size)(struct drm_device *dev, int plane); ++ /** ++ * find_dpll() - Find the best values for the PLL ++ * @limit: limits for the PLL ++ * @crtc: current CRTC ++ * @target: target frequency in kHz ++ * @refclk: reference clock frequency in kHz ++ * @match_clock: if provided, @best_clock P divider must ++ * match the P divider from @match_clock ++ * used for LVDS downclocking ++ * @best_clock: best PLL values found ++ * ++ * Returns true on success, false on failure. ++ */ ++ bool (*find_dpll)(const struct intel_limit *limit, ++ struct drm_crtc *crtc, ++ int target, int refclk, ++ struct dpll *match_clock, ++ struct dpll *best_clock); + void (*update_wm)(struct drm_device *dev); + void (*update_sprite_wm)(struct drm_device *dev, int pipe, + uint32_t sprite_width, int pixel_size, +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index c06140cbc6af..e8985a1c1c2c 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -59,24 +59,6 @@ typedef struct intel_limit intel_limit_t; + struct intel_limit { + intel_range_t dot, vco, n, m, m1, m2, p, p1; + intel_p2_t p2; +- /** +- * find_pll() - Find the best values for the PLL +- * @limit: limits for the PLL +- * @crtc: current CRTC +- * @target: target frequency in kHz +- * @refclk: reference clock frequency in kHz +- * @match_clock: if provided, @best_clock P divider must +- * match the P divider from @match_clock +- * used for LVDS downclocking +- * @best_clock: best PLL values found +- * +- * Returns true on success, false on failure. +- */ +- bool (*find_pll)(const intel_limit_t *limit, +- struct drm_crtc *crtc, +- int target, int refclk, +- intel_clock_t *match_clock, +- intel_clock_t *best_clock); + }; + + /* FDI */ +@@ -92,23 +74,6 @@ intel_pch_rawclk(struct drm_device *dev) + return I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK; + } + +-static bool +-intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, +- int target, int refclk, intel_clock_t *match_clock, +- intel_clock_t *best_clock); +-static bool +-intel_pnv_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, +- int target, int refclk, intel_clock_t *match_clock, +- intel_clock_t *best_clock); +-static bool +-intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, +- int target, int refclk, intel_clock_t *match_clock, +- intel_clock_t *best_clock); +-static bool +-intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, +- int target, int refclk, intel_clock_t *match_clock, +- intel_clock_t *best_clock); +- + static inline u32 /* units of 100MHz */ + intel_fdi_link_freq(struct drm_device *dev) + { +@@ -130,7 +95,6 @@ static const intel_limit_t intel_limits_i8xx_dvo = { + .p1 = { .min = 2, .max = 33 }, + .p2 = { .dot_limit = 165000, + .p2_slow = 4, .p2_fast = 2 }, +- .find_pll = intel_find_best_PLL, + }; + + static const intel_limit_t intel_limits_i8xx_lvds = { +@@ -144,7 +108,6 @@ static const intel_limit_t intel_limits_i8xx_lvds = { + .p1 = { .min = 1, .max = 6 }, + .p2 = { .dot_limit = 165000, + .p2_slow = 14, .p2_fast = 7 }, +- .find_pll = intel_find_best_PLL, + }; + + static const intel_limit_t intel_limits_i9xx_sdvo = { +@@ -158,7 +121,6 @@ static const intel_limit_t intel_limits_i9xx_sdvo = { + .p1 = { .min = 1, .max = 8 }, + .p2 = { .dot_limit = 200000, + .p2_slow = 10, .p2_fast = 5 }, +- .find_pll = intel_find_best_PLL, + }; + + static const intel_limit_t intel_limits_i9xx_lvds = { +@@ -172,7 +134,6 @@ static const intel_limit_t intel_limits_i9xx_lvds = { + .p1 = { .min = 1, .max = 8 }, + .p2 = { .dot_limit = 112000, + .p2_slow = 14, .p2_fast = 7 }, +- .find_pll = intel_find_best_PLL, + }; + + +@@ -189,7 +150,6 @@ static const intel_limit_t intel_limits_g4x_sdvo = { + .p2_slow = 10, + .p2_fast = 10 + }, +- .find_pll = intel_g4x_find_best_PLL, + }; + + static const intel_limit_t intel_limits_g4x_hdmi = { +@@ -203,7 +163,6 @@ static const intel_limit_t intel_limits_g4x_hdmi = { + .p1 = { .min = 1, .max = 8}, + .p2 = { .dot_limit = 165000, + .p2_slow = 10, .p2_fast = 5 }, +- .find_pll = intel_g4x_find_best_PLL, + }; + + static const intel_limit_t intel_limits_g4x_single_channel_lvds = { +@@ -218,7 +177,6 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = { + .p2 = { .dot_limit = 0, + .p2_slow = 14, .p2_fast = 14 + }, +- .find_pll = intel_g4x_find_best_PLL, + }; + + static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { +@@ -233,7 +191,6 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { + .p2 = { .dot_limit = 0, + .p2_slow = 7, .p2_fast = 7 + }, +- .find_pll = intel_g4x_find_best_PLL, + }; + + static const intel_limit_t intel_limits_pineview_sdvo = { +@@ -249,7 +206,6 @@ static const intel_limit_t intel_limits_pineview_sdvo = { + .p1 = { .min = 1, .max = 8 }, + .p2 = { .dot_limit = 200000, + .p2_slow = 10, .p2_fast = 5 }, +- .find_pll = intel_pnv_find_best_PLL, + }; + + static const intel_limit_t intel_limits_pineview_lvds = { +@@ -263,7 +219,6 @@ static const intel_limit_t intel_limits_pineview_lvds = { + .p1 = { .min = 1, .max = 8 }, + .p2 = { .dot_limit = 112000, + .p2_slow = 14, .p2_fast = 14 }, +- .find_pll = intel_pnv_find_best_PLL, + }; + + /* Ironlake / Sandybridge +@@ -282,7 +237,6 @@ static const intel_limit_t intel_limits_ironlake_dac = { + .p1 = { .min = 1, .max = 8 }, + .p2 = { .dot_limit = 225000, + .p2_slow = 10, .p2_fast = 5 }, +- .find_pll = intel_g4x_find_best_PLL, + }; + + static const intel_limit_t intel_limits_ironlake_single_lvds = { +@@ -296,7 +250,6 @@ static const intel_limit_t intel_limits_ironlake_single_lvds = { + .p1 = { .min = 2, .max = 8 }, + .p2 = { .dot_limit = 225000, + .p2_slow = 14, .p2_fast = 14 }, +- .find_pll = intel_g4x_find_best_PLL, + }; + + static const intel_limit_t intel_limits_ironlake_dual_lvds = { +@@ -310,7 +263,6 @@ static const intel_limit_t intel_limits_ironlake_dual_lvds = { + .p1 = { .min = 2, .max = 8 }, + .p2 = { .dot_limit = 225000, + .p2_slow = 7, .p2_fast = 7 }, +- .find_pll = intel_g4x_find_best_PLL, + }; + + /* LVDS 100mhz refclk limits. */ +@@ -325,7 +277,6 @@ static const intel_limit_t intel_limits_ironlake_single_lvds_100m = { + .p1 = { .min = 2, .max = 8 }, + .p2 = { .dot_limit = 225000, + .p2_slow = 14, .p2_fast = 14 }, +- .find_pll = intel_g4x_find_best_PLL, + }; + + static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = { +@@ -339,7 +290,6 @@ static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = { + .p1 = { .min = 2, .max = 6 }, + .p2 = { .dot_limit = 225000, + .p2_slow = 7, .p2_fast = 7 }, +- .find_pll = intel_g4x_find_best_PLL, + }; + + static const intel_limit_t intel_limits_vlv_dac = { +@@ -353,7 +303,6 @@ static const intel_limit_t intel_limits_vlv_dac = { + .p1 = { .min = 1, .max = 3 }, + .p2 = { .dot_limit = 270000, + .p2_slow = 2, .p2_fast = 20 }, +- .find_pll = intel_vlv_find_best_pll, + }; + + static const intel_limit_t intel_limits_vlv_hdmi = { +@@ -367,7 +316,6 @@ static const intel_limit_t intel_limits_vlv_hdmi = { + .p1 = { .min = 2, .max = 3 }, + .p2 = { .dot_limit = 270000, + .p2_slow = 2, .p2_fast = 20 }, +- .find_pll = intel_vlv_find_best_pll, + }; + + static const intel_limit_t intel_limits_vlv_dp = { +@@ -381,7 +329,6 @@ static const intel_limit_t intel_limits_vlv_dp = { + .p1 = { .min = 1, .max = 3 }, + .p2 = { .dot_limit = 270000, + .p2_slow = 2, .p2_fast = 20 }, +- .find_pll = intel_vlv_find_best_pll, + }; + + static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, +@@ -537,7 +484,7 @@ static bool intel_PLL_is_valid(struct drm_device *dev, + } + + static bool +-intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, ++i9xx_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock) + { +@@ -599,9 +546,9 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, + } + + static bool +-intel_pnv_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, +- int target, int refclk, intel_clock_t *match_clock, +- intel_clock_t *best_clock) ++pnv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, ++ int target, int refclk, intel_clock_t *match_clock, ++ intel_clock_t *best_clock) + { + struct drm_device *dev = crtc->dev; + intel_clock_t clock; +@@ -661,9 +608,9 @@ intel_pnv_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, + } + + static bool +-intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, +- int target, int refclk, intel_clock_t *match_clock, +- intel_clock_t *best_clock) ++g4x_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, ++ int target, int refclk, intel_clock_t *match_clock, ++ intel_clock_t *best_clock) + { + struct drm_device *dev = crtc->dev; + intel_clock_t clock; +@@ -718,9 +665,9 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, + } + + static bool +-intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, +- int target, int refclk, intel_clock_t *match_clock, +- intel_clock_t *best_clock) ++vlv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, ++ int target, int refclk, intel_clock_t *match_clock, ++ intel_clock_t *best_clock) + { + u32 p1, p2, m1, m2, vco, bestn, bestm1, bestm2, bestp1, bestp2; + u32 m, n, fastclk; +@@ -4911,9 +4858,9 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. + */ + limit = intel_limit(crtc, refclk); +- ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL, +- &clock); +- if (!ok) { ++ ok = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock, ++ refclk, NULL, &clock); ++ if (!ok && !intel_crtc->config.clock_set) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); + return -EINVAL; + } +@@ -4928,10 +4875,10 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + * by using the FP0/FP1. In such case we will disable the LVDS + * downclock feature. + */ +- has_reduced_clock = limit->find_pll(limit, crtc, ++ has_reduced_clock = ++ dev_priv->display.find_dpll(limit, crtc, + dev_priv->lvds_downclock, +- refclk, +- &clock, ++ refclk, &clock, + &reduced_clock); + } + /* Compat-code for transition, will disappear. */ +@@ -5547,8 +5494,8 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. + */ + limit = intel_limit(crtc, refclk); +- ret = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL, +- clock); ++ ret = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock, ++ refclk, NULL, clock); + if (!ret) + return false; + +@@ -5559,11 +5506,11 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, + * by using the FP0/FP1. In such case we will disable the LVDS + * downclock feature. + */ +- *has_reduced_clock = limit->find_pll(limit, crtc, +- dev_priv->lvds_downclock, +- refclk, +- clock, +- reduced_clock); ++ *has_reduced_clock = ++ dev_priv->display.find_dpll(limit, crtc, ++ dev_priv->lvds_downclock, ++ refclk, clock, ++ reduced_clock); + } + + return true; +@@ -5749,7 +5696,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + + ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock, + &has_reduced_clock, &reduced_clock); +- if (!ok) { ++ if (!ok && !intel_crtc->config.clock_set) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); + return -EINVAL; + } +@@ -9104,6 +9051,15 @@ static void intel_init_display(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + ++ if (HAS_PCH_SPLIT(dev) || IS_G4X(dev)) ++ dev_priv->display.find_dpll = g4x_find_best_dpll; ++ else if (IS_VALLEYVIEW(dev)) ++ dev_priv->display.find_dpll = vlv_find_best_dpll; ++ else if (IS_PINEVIEW(dev)) ++ dev_priv->display.find_dpll = pnv_find_best_dpll; ++ else ++ dev_priv->display.find_dpll = i9xx_find_best_dpll; ++ + if (HAS_DDI(dev)) { + dev_priv->display.get_pipe_config = haswell_get_pipe_config; + dev_priv->display.crtc_mode_set = haswell_crtc_mode_set; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0253-drm-i915-fold-in-IS_PNV-checks-from-the-split-up-fin.patch b/patches.baytrail/0253-drm-i915-fold-in-IS_PNV-checks-from-the-split-up-fin.patch new file mode 100644 index 000000000000..33de78349e32 --- /dev/null +++ b/patches.baytrail/0253-drm-i915-fold-in-IS_PNV-checks-from-the-split-up-fin.patch @@ -0,0 +1,44 @@ +From 647c2f946258fb511afae73b127da61cac81e749 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 3 Jun 2013 20:56:24 +0200 +Subject: drm/i915: fold in IS_PNV checks from the split up find_dpll functions + +Since I stand by my rule that splitting functions should only do an +exact copy, this is a follow-up patch. + +Suggested-by: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit c0efc387a8893470c1744e775e214c069bd2465e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index e8985a1c1c2c..d23f4e1c977b 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -515,8 +515,7 @@ i9xx_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, + clock.m1++) { + for (clock.m2 = limit->m2.min; + clock.m2 <= limit->m2.max; clock.m2++) { +- /* m1 is always 0 in Pineview */ +- if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev)) ++ if (clock.m2 >= clock.m1) + break; + for (clock.n = limit->n.min; + clock.n <= limit->n.max; clock.n++) { +@@ -577,9 +576,6 @@ pnv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, + clock.m1++) { + for (clock.m2 = limit->m2.min; + clock.m2 <= limit->m2.max; clock.m2++) { +- /* m1 is always 0 in Pineview */ +- if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev)) +- break; + for (clock.n = limit->n.min; + clock.n <= limit->n.max; clock.n++) { + for (clock.p1 = limit->p1.min; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0254-drm-i915-clear-up-the-fdi-dotclock-semantics-for-M-N.patch b/patches.baytrail/0254-drm-i915-clear-up-the-fdi-dotclock-semantics-for-M-N.patch new file mode 100644 index 000000000000..595deae5f653 --- /dev/null +++ b/patches.baytrail/0254-drm-i915-clear-up-the-fdi-dotclock-semantics-for-M-N.patch @@ -0,0 +1,78 @@ +From 77043cf0368a0f6a671f48bfff89b71bfdbc6368 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sat, 1 Jun 2013 17:16:19 +0200 +Subject: drm/i915: clear up the fdi dotclock semantics for M/N computation + +We currently mutliply the link_bw of the fdi link with the pixel +multiplier, which is wrong: The FDI link doesn't suddenly grow more +bandwidth. In reality the pixel mutliplication only happens in the PCH, +before the pixels are fed into the port. + +But since we our code treats the uses the target clock after pixels +are doubled (tripled, ...) already, we need to correct this. + +Semantically it's clearer to divide the target clock to get the fdi +dotclock instead of multiplying the bw, so do that instead. + +Note that the target clock is already multiplied by the same factor, +so the division will never loose accuracy for the M/N computation. + +The lane computation otoh used the wrong value, we also need to feed +the fdi dotclock to that. + +Split out on a request from Paulo Zanoni. + +v2: Also fix the lane computation, it used the target clock to compute +the bw requirements, not the fdi dotclock (i.e. adjusted with the +pixel multiplier). Since sdvo only uses the pixel multiplier for +low-res modes (with a dotclock below 100MHz) we wouldn't ever have +rejected a bogus mode, but just used an inefficient fdi config. + +v3: Amend the commit message to explain better what the change for the +fdi lane config computation is all about. Requested by Paulo. + +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 2bd89a07db684573d2fce0d5148103c3dcfb0873) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index d23f4e1c977b..f80612174e6a 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3985,7 +3985,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc, + { + struct drm_device *dev = intel_crtc->base.dev; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; +- int target_clock, lane, link_bw; ++ int target_clock, lane, link_bw, fdi_dotclock; + bool setup_ok, needs_recompute = false; + + retry: +@@ -4003,14 +4003,16 @@ retry: + else + target_clock = adjusted_mode->clock; + +- lane = ironlake_get_lanes_required(target_clock, link_bw, ++ fdi_dotclock = target_clock; ++ if (pipe_config->pixel_multiplier > 1) ++ fdi_dotclock /= pipe_config->pixel_multiplier; ++ ++ lane = ironlake_get_lanes_required(fdi_dotclock, link_bw, + pipe_config->pipe_bpp); + + pipe_config->fdi_lanes = lane; + +- if (pipe_config->pixel_multiplier > 1) +- link_bw *= pipe_config->pixel_multiplier; +- intel_link_compute_m_n(pipe_config->pipe_bpp, lane, target_clock, ++ intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock, + link_bw, &pipe_config->fdi_m_n); + + setup_ok = ironlake_check_fdi_lanes(intel_crtc->base.dev, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0255-drm-i915-refactor-cpu-eDP-PLL-handling-a-bit.patch b/patches.baytrail/0255-drm-i915-refactor-cpu-eDP-PLL-handling-a-bit.patch new file mode 100644 index 000000000000..5bc65ece8225 --- /dev/null +++ b/patches.baytrail/0255-drm-i915-refactor-cpu-eDP-PLL-handling-a-bit.patch @@ -0,0 +1,121 @@ +From a402f14410640278ac0b33f7ccca207abee52e5c Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sat, 1 Jun 2013 17:16:20 +0200 +Subject: drm/i915: refactor cpu eDP PLL handling a bit + +This prepares a bit for the next big patch, where we switch the +semantics of the different clocks in the pipe config around. + +Since I've broken cpu eDP PLL handling in the first version I've +figured some refactoring is in order. + +Split out on request from Paulo Zanoni. + +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 7c62a164faea430c6e4c411eb0870640cf51a6e5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 38 ++++++++++++++------------------------ + 1 file changed, 14 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index be862039eeab..046d539d8746 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -800,24 +800,29 @@ void intel_dp_init_link_config(struct intel_dp *intel_dp) + } + } + +-static void ironlake_set_pll_edp(struct drm_crtc *crtc, int clock) ++static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp) + { +- struct drm_device *dev = crtc->dev; ++ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); ++ struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); ++ struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 dpa_ctl; + +- DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", clock); ++ DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", ++ crtc->config.adjusted_mode.clock); + dpa_ctl = I915_READ(DP_A); + dpa_ctl &= ~DP_PLL_FREQ_MASK; + +- if (clock < 200000) { ++ if (crtc->config.adjusted_mode.clock == 162000) { + /* For a long time we've carried around a ILK-DevA w/a for the + * 160MHz clock. If we're really unlucky, it's still required. + */ + DRM_DEBUG_KMS("160MHz cpu eDP clock, might need ilk devA w/a\n"); + dpa_ctl |= DP_PLL_FREQ_160MHZ; ++ intel_dp->DP |= DP_PLL_FREQ_160MHZ; + } else { + dpa_ctl |= DP_PLL_FREQ_270MHZ; ++ intel_dp->DP |= DP_PLL_FREQ_270MHZ; + } + + I915_WRITE(DP_A, dpa_ctl); +@@ -834,8 +839,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + enum port port = dp_to_dig_port(intel_dp)->port; +- struct drm_crtc *crtc = encoder->crtc; +- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); + + /* + * There are four kinds of DP registers: +@@ -865,7 +869,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + + if (intel_dp->has_audio) { + DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n", +- pipe_name(intel_crtc->pipe)); ++ pipe_name(crtc->pipe)); + intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; + intel_write_eld(encoder, adjusted_mode); + } +@@ -884,13 +888,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) + intel_dp->DP |= DP_ENHANCED_FRAMING; + +- intel_dp->DP |= intel_crtc->pipe << 29; +- +- /* don't miss out required setting for eDP */ +- if (adjusted_mode->clock < 200000) +- intel_dp->DP |= DP_PLL_FREQ_160MHZ; +- else +- intel_dp->DP |= DP_PLL_FREQ_270MHZ; ++ intel_dp->DP |= crtc->pipe << 29; + } else if (!HAS_PCH_CPT(dev) || port == PORT_A) { + if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev)) + intel_dp->DP |= intel_dp->color_range; +@@ -904,22 +902,14 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) + intel_dp->DP |= DP_ENHANCED_FRAMING; + +- if (intel_crtc->pipe == 1) ++ if (crtc->pipe == 1) + intel_dp->DP |= DP_PIPEB_SELECT; +- +- if (port == PORT_A && !IS_VALLEYVIEW(dev)) { +- /* don't miss out required setting for eDP */ +- if (adjusted_mode->clock < 200000) +- intel_dp->DP |= DP_PLL_FREQ_160MHZ; +- else +- intel_dp->DP |= DP_PLL_FREQ_270MHZ; +- } + } else { + intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; + } + + if (port == PORT_A && !IS_VALLEYVIEW(dev)) +- ironlake_set_pll_edp(crtc, adjusted_mode->clock); ++ ironlake_set_pll_cpu_edp(intel_dp); + } + + #define IDLE_ON_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0256-drm-i915-store-adjusted-dotclock-in-adjusted_mode-cl.patch b/patches.baytrail/0256-drm-i915-store-adjusted-dotclock-in-adjusted_mode-cl.patch new file mode 100644 index 000000000000..a2cac6c7730f --- /dev/null +++ b/patches.baytrail/0256-drm-i915-store-adjusted-dotclock-in-adjusted_mode-cl.patch @@ -0,0 +1,329 @@ +From 5ee0a522bd68f6962bfa73f61de6cc8db3140ebd Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sat, 1 Jun 2013 17:16:21 +0200 +Subject: drm/i915: store adjusted dotclock in adjusted_mode->clock + +... not the port clock. This allows us to kill the funny semantics +around pixel_target_clock. + +Since the dpll code still needs the real port clock, add a new +port_clock field to the pipe configuration. Handling the default case +for that one is a bit tricky, since encoders might not consistently +overwrite it when retrying the crtc/encoder bw arbitrage step in the +compute config stage. Hence we need to always clear port_clock and +update it again if the encoder hasn't put in something more specific. +This can't be done in one step since the encoder might want to adjust +the mode first. + +I was a bit on the fence whether I should subsume the pixel multiplier +handling into the port_clock, too. But then I decided against this +since it's on an abstract level still the dotclock of the adjusted +mode, and only our hw makes it a bit special due to the separate pixel +mulitplier setting (which requires that the dpll runs at the +non-multiplied dotclock). + +So after this patch the adjusted_mode accurately describes the mode we +feed into the port, after the panel fitter and pixel multiplier (or +line doubling, if we ever bother with that) have done their job. +Since the fdi link is between the pfit and the pixel multiplier steps +we need to be careful with calculating the fdi link config. + +v2: Fix up ilk cpu pll handling. + +v3: Introduce an fdi_dotclock variable in ironlake_fdi_compute_config +to make it clearer that we transmit the adjusted_mode without the +pixel multiplier taken into account. The old code multiplied the the +available link bw with the pixel multiplier, which results in the same +fdi configuration, but is much more confusing. + +v4: Rebase on top of Imre's is_cpu_edp removal. + +v5: Rebase on top of Paulo's haswell watermark fixes, which introduce +a new place which looked at the pixel_clock and so needed conversion. + +v6: Split out prep patches as requested by Paulo Zanoni. Also rebase +on top of the fdi dotclock handling fix in the fdi lanes/bw +computation code. + +Reviewed-by: Jesse Barnes (v3) +Reviewed-by: Paulo Zanoni (v6) +Signed-off-by: Daniel Vetter +(cherry picked from commit ff9a6750aca3553c78385a9aa89b678b2b9be7df) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 3 ++- + drivers/gpu/drm/i915/intel_display.c | 32 +++++++++++++++++--------------- + drivers/gpu/drm/i915/intel_dp.c | 18 +++++++----------- + drivers/gpu/drm/i915/intel_drv.h | 13 +++++++------ + drivers/gpu/drm/i915/intel_hdmi.c | 4 +--- + drivers/gpu/drm/i915/intel_pm.c | 5 +---- + 6 files changed, 35 insertions(+), 40 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 74b372dc14a4..fc31ffa497eb 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -624,7 +624,7 @@ intel_ddi_calculate_wrpll(int clock /* in Hz */, + clock, *p_out, *n2_out, *r2_out); + } + +-bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock) ++bool intel_ddi_pll_mode_set(struct drm_crtc *crtc) + { + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); +@@ -634,6 +634,7 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock) + int type = intel_encoder->type; + enum pipe pipe = intel_crtc->pipe; + uint32_t reg, val; ++ int clock = intel_crtc->config.port_clock; + + /* TODO: reuse PLLs when possible (compare values) */ + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index f80612174e6a..6d0f8f6ba4d2 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3985,7 +3985,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc, + { + struct drm_device *dev = intel_crtc->base.dev; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; +- int target_clock, lane, link_bw, fdi_dotclock; ++ int lane, link_bw, fdi_dotclock; + bool setup_ok, needs_recompute = false; + + retry: +@@ -3998,12 +3998,7 @@ retry: + */ + link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; + +- if (pipe_config->pixel_target_clock) +- target_clock = pipe_config->pixel_target_clock; +- else +- target_clock = adjusted_mode->clock; +- +- fdi_dotclock = target_clock; ++ fdi_dotclock = adjusted_mode->clock; + if (pipe_config->pixel_multiplier > 1) + fdi_dotclock /= pipe_config->pixel_multiplier; + +@@ -4353,8 +4348,6 @@ static void vlv_update_pll(struct intel_crtc *crtc) + { + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct drm_display_mode *adjusted_mode = +- &crtc->config.adjusted_mode; + struct intel_encoder *encoder; + int pipe = crtc->pipe; + u32 dpll, mdiv; +@@ -4407,7 +4400,7 @@ static void vlv_update_pll(struct intel_crtc *crtc) + vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); + + /* Set HBR and RBR LPF coefficients */ +- if (adjusted_mode->clock == 162000 || ++ if (crtc->config.port_clock == 162000 || + intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI)) + vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), + 0x005f0021); +@@ -4856,7 +4849,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. + */ + limit = intel_limit(crtc, refclk); +- ok = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock, ++ ok = dev_priv->display.find_dpll(limit, crtc, ++ intel_crtc->config.port_clock, + refclk, NULL, &clock); + if (!ok && !intel_crtc->config.clock_set) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); +@@ -5464,7 +5458,6 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc) + } + + static bool ironlake_compute_clocks(struct drm_crtc *crtc, +- struct drm_display_mode *adjusted_mode, + intel_clock_t *clock, + bool *has_reduced_clock, + intel_clock_t *reduced_clock) +@@ -5492,7 +5485,8 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. + */ + limit = intel_limit(crtc, refclk); +- ret = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock, ++ ret = dev_priv->display.find_dpll(limit, crtc, ++ to_intel_crtc(crtc)->config.port_clock, + refclk, NULL, clock); + if (!ret) + return false; +@@ -5692,7 +5686,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)), + "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev)); + +- ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock, ++ ok = ironlake_compute_clocks(crtc, &clock, + &has_reduced_clock, &reduced_clock); + if (!ok && !intel_crtc->config.clock_set) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); +@@ -5895,7 +5889,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + WARN(num_connectors != 1, "%d connectors attached to pipe %c\n", + num_connectors, pipe_name(pipe)); + +- if (!intel_ddi_pll_mode_set(crtc, adjusted_mode->clock)) ++ if (!intel_ddi_pll_mode_set(crtc)) + return -EINVAL; + + /* Ensure that the cursor is valid for the new mode before changing... */ +@@ -7809,6 +7803,9 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, + goto fail; + + encoder_retry: ++ /* Ensure the port clock default is reset when retrying. */ ++ pipe_config->port_clock = 0; ++ + /* Pass our mode to the connectors and the CRTC to give them a chance to + * adjust it according to limitations or connector properties, and also + * a chance to reject the mode entirely. +@@ -7837,6 +7834,11 @@ encoder_retry: + } + } + ++ /* Set default port clock if not overwritten by the encoder. Needs to be ++ * done afterwards in case the encoder adjusts the mode. */ ++ if (!pipe_config->port_clock) ++ pipe_config->port_clock = pipe_config->adjusted_mode.clock; ++ + ret = intel_crtc_compute_config(crtc, pipe_config); + if (ret < 0) { + DRM_DEBUG_KMS("CRTC fixup failed\n"); +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 046d539d8746..8d11dfa9a169 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -688,7 +688,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, + int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; + int bpp, mode_rate; + static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; +- int target_clock, link_avail, link_clock; ++ int link_avail, link_clock; + + if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A) + pipe_config->has_pch_encoder = true; +@@ -705,8 +705,6 @@ intel_dp_compute_config(struct intel_encoder *encoder, + intel_pch_panel_fitting(intel_crtc, pipe_config, + intel_connector->panel.fitting_mode); + } +- /* We need to take the panel's fixed mode into account. */ +- target_clock = adjusted_mode->clock; + + if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) + return false; +@@ -731,7 +729,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, + } + + for (; bpp >= 6*3; bpp -= 2*3) { +- mode_rate = intel_dp_link_required(target_clock, bpp); ++ mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp); + + for (clock = 0; clock <= max_clock; clock++) { + for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { +@@ -766,18 +764,17 @@ found: + + intel_dp->link_bw = bws[clock]; + intel_dp->lane_count = lane_count; +- adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw); + pipe_config->pipe_bpp = bpp; +- pipe_config->pixel_target_clock = target_clock; ++ pipe_config->port_clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw); + + DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n", + intel_dp->link_bw, intel_dp->lane_count, +- adjusted_mode->clock, bpp); ++ pipe_config->port_clock, bpp); + DRM_DEBUG_KMS("DP link bw required %i available %i\n", + mode_rate, link_avail); + + intel_link_compute_m_n(bpp, lane_count, +- target_clock, adjusted_mode->clock, ++ adjusted_mode->clock, pipe_config->port_clock, + &pipe_config->dp_m_n); + + intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw); +@@ -808,12 +805,11 @@ static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp) + struct drm_i915_private *dev_priv = dev->dev_private; + u32 dpa_ctl; + +- DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", +- crtc->config.adjusted_mode.clock); ++ DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", crtc->config.port_clock); + dpa_ctl = I915_READ(DP_A); + dpa_ctl &= ~DP_PLL_FREQ_MASK; + +- if (crtc->config.adjusted_mode.clock == 162000) { ++ if (crtc->config.port_clock == 162000) { + /* For a long time we've carried around a ILK-DevA w/a for the + * 160MHz clock. If we're really unlucky, it's still required. + */ +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index b81cc4512c0a..b0b5ea70af18 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -243,12 +243,13 @@ struct intel_crtc_config { + + int pipe_bpp; + struct intel_link_m_n dp_m_n; +- /** +- * This is currently used by DP and HDMI encoders since those can have a +- * target pixel clock != the port link clock (which is currently stored +- * in adjusted_mode->clock). ++ ++ /* ++ * Frequence the dpll for the port should run at. Differs from the ++ * adjusted dotclock e.g. for DP or 12bpc hdmi mode. + */ +- int pixel_target_clock; ++ int port_clock; ++ + /* Used by SDVO (and if we ever fix it, HDMI). */ + unsigned pixel_multiplier; + +@@ -786,7 +787,7 @@ extern void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, + extern void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc); + extern void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc); + extern void intel_ddi_setup_hw_pll_state(struct drm_device *dev); +-extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock); ++extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc); + extern void intel_ddi_put_crtc_pll(struct drm_crtc *crtc); + extern void intel_ddi_set_pipe_settings(struct drm_crtc *crtc); + extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder); +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 8062a92e6e80..bc12518a21b4 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -835,9 +835,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, + desired_bpp = 12*3; + + /* Need to adjust the port link by 1.5x for 12bpc. */ +- adjusted_mode->clock = clock_12bpc; +- pipe_config->pixel_target_clock = +- pipe_config->requested_mode.clock; ++ pipe_config->port_clock = clock_12bpc; + } else { + DRM_DEBUG_KMS("picking bpc to 8 for HDMI output\n"); + desired_bpp = 8*3; +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 8af5c12e944d..a6b1f22d9848 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2078,10 +2078,7 @@ static uint32_t hsw_wm_get_pixel_rate(struct drm_device *dev, + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + uint32_t pixel_rate, pfit_size; + +- if (intel_crtc->config.pixel_target_clock) +- pixel_rate = intel_crtc->config.pixel_target_clock; +- else +- pixel_rate = intel_crtc->config.adjusted_mode.clock; ++ pixel_rate = intel_crtc->config.adjusted_mode.clock; + + /* We only use IF-ID interlacing. If we ever use PF-ID we'll need to + * adjust the pixel_rate here. */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0257-drm-i915-Drop-some-no-longer-required-mode-adjusted_.patch b/patches.baytrail/0257-drm-i915-Drop-some-no-longer-required-mode-adjusted_.patch new file mode 100644 index 000000000000..4f945a954f3e --- /dev/null +++ b/patches.baytrail/0257-drm-i915-Drop-some-no-longer-required-mode-adjusted_.patch @@ -0,0 +1,120 @@ +From ddbf1b18e2955eaef330c527bc8bae4143186468 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sat, 1 Jun 2013 17:16:22 +0200 +Subject: drm/i915: Drop some no longer required mode/adjusted_mode parameters + +We can get at this easily through intel_crtc->config now. + +v2: Drop more stuff gcc spotted. + +v3: Drop even more stuff gcc spotted. + +v4: Yet more ... + +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 8a654f3b743d0f645848f5fde5059f31a78260bf) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 24 ++++++++---------------- + 1 file changed, 8 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 6d0f8f6ba4d2..ca0da5e3e5e5 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4573,7 +4573,6 @@ static void i9xx_update_pll(struct intel_crtc *crtc, + } + + static void i8xx_update_pll(struct intel_crtc *crtc, +- struct drm_display_mode *adjusted_mode, + intel_clock_t *reduced_clock, + int num_connectors) + { +@@ -4628,14 +4627,15 @@ static void i8xx_update_pll(struct intel_crtc *crtc, + I915_WRITE(DPLL(pipe), dpll); + } + +-static void intel_set_pipe_timings(struct intel_crtc *intel_crtc, +- struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) ++static void intel_set_pipe_timings(struct intel_crtc *intel_crtc) + { + struct drm_device *dev = intel_crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum pipe pipe = intel_crtc->pipe; + enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; ++ struct drm_display_mode *adjusted_mode = ++ &intel_crtc->config.adjusted_mode; ++ struct drm_display_mode *mode = &intel_crtc->config.requested_mode; + uint32_t vsyncshift, crtc_vtotal, crtc_vblank_end; + + /* We need to be careful not to changed the adjusted mode, for otherwise +@@ -4817,8 +4817,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- struct drm_display_mode *adjusted_mode = +- &intel_crtc->config.adjusted_mode; + struct drm_display_mode *mode = &intel_crtc->config.requested_mode; + int pipe = intel_crtc->pipe; + int plane = intel_crtc->plane; +@@ -4883,7 +4881,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + } + + if (IS_GEN2(dev)) +- i8xx_update_pll(intel_crtc, adjusted_mode, ++ i8xx_update_pll(intel_crtc, + has_reduced_clock ? &reduced_clock : NULL, + num_connectors); + else if (IS_VALLEYVIEW(dev)) +@@ -4903,7 +4901,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, + dspcntr |= DISPPLANE_SEL_PIPE_B; + } + +- intel_set_pipe_timings(intel_crtc, mode, adjusted_mode); ++ intel_set_pipe_timings(intel_crtc); + + /* pipesrc and dspsize control the size that is scaled from, + * which should always be the user's requested size. +@@ -5660,9 +5658,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- struct drm_display_mode *adjusted_mode = +- &intel_crtc->config.adjusted_mode; +- struct drm_display_mode *mode = &intel_crtc->config.requested_mode; + int pipe = intel_crtc->pipe; + int plane = intel_crtc->plane; + int num_connectors = 0; +@@ -5757,7 +5752,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + } + } + +- intel_set_pipe_timings(intel_crtc, mode, adjusted_mode); ++ intel_set_pipe_timings(intel_crtc); + + if (intel_crtc->config.has_pch_encoder) { + intel_cpu_transcoder_set_m_n(intel_crtc, +@@ -5865,9 +5860,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- struct drm_display_mode *adjusted_mode = +- &intel_crtc->config.adjusted_mode; +- struct drm_display_mode *mode = &intel_crtc->config.requested_mode; + int pipe = intel_crtc->pipe; + int plane = intel_crtc->plane; + int num_connectors = 0; +@@ -5900,7 +5892,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + + intel_crtc->lowfreq_avail = false; + +- intel_set_pipe_timings(intel_crtc, mode, adjusted_mode); ++ intel_set_pipe_timings(intel_crtc); + + if (intel_crtc->config.has_pch_encoder) { + intel_cpu_transcoder_set_m_n(intel_crtc, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0258-drm-i915-check-for-strange-pfit-pipe-assignemnt-on-i.patch b/patches.baytrail/0258-drm-i915-check-for-strange-pfit-pipe-assignemnt-on-i.patch new file mode 100644 index 000000000000..9095baf796a3 --- /dev/null +++ b/patches.baytrail/0258-drm-i915-check-for-strange-pfit-pipe-assignemnt-on-i.patch @@ -0,0 +1,50 @@ +From 4904237024bbd124a13e54ee5131f021f61cf58b Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sat, 1 Jun 2013 17:16:23 +0200 +Subject: drm/i915: check for strange pfit pipe assignemnt on ivb/hsw + +Panel fitters on ivb/hsw are not created equal since not all of them +support the new high-quality upscaling mode. To offset this the hw +allows us to freely assign the pfits to pipes. + +Since our code currently doesn't support this we might fall over when +taking over firmware state. So check for this case and WARN about it. +We can then improve the code once we've hit this in the wild. Or once +we decide to support the improved upscale modes, though that requires +global arbitrage of modeset resources across crtcs. + +v2: Check for IS_GEN7 instead of IS_IVB || IS_HSW as suggested by +Paulo in his review comment. + +Suggested-by: Mika Kuoppala +Cc: Mika Kuoppala +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit cb8b2a30b32cde5ac9053d399d084c487598976a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index ca0da5e3e5e5..83864bda87ac 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5803,6 +5803,14 @@ static void ironlake_get_pfit_config(struct intel_crtc *crtc, + if (tmp & PF_ENABLE) { + pipe_config->pch_pfit.pos = I915_READ(PF_WIN_POS(crtc->pipe)); + pipe_config->pch_pfit.size = I915_READ(PF_WIN_SZ(crtc->pipe)); ++ ++ /* We currently do not free assignements of panel fitters on ++ * ivb/hsw (since we don't use the higher upscaling modes which ++ * differentiates them) so just WARN about this case for now. */ ++ if (IS_GEN7(dev)) { ++ WARN_ON((tmp & PF_PIPE_SEL_MASK_IVB) != ++ PF_PIPE_SEL_IVB(crtc->pipe)); ++ } + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0259-drm-i915-VLV-doesn-t-have-the-ILK-style-LP-watermark.patch b/patches.baytrail/0259-drm-i915-VLV-doesn-t-have-the-ILK-style-LP-watermark.patch new file mode 100644 index 000000000000..c2251e6c5844 --- /dev/null +++ b/patches.baytrail/0259-drm-i915-VLV-doesn-t-have-the-ILK-style-LP-watermark.patch @@ -0,0 +1,37 @@ +From 280b2dcb714291346ae162e16cde0d3482d993ad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 21 May 2013 18:01:49 +0300 +Subject: drm/i915: VLV doesn't have the ILK+ style LP watermark registers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The LP watermark registers don't exist on VLV, so don't touch them. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 4548feb1fe1f17c0d7ad7acdd267a875b22e6910) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index a6b1f22d9848..e107d56efc38 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4797,10 +4797,6 @@ static void valleyview_init_clock_gating(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + int pipe; + +- I915_WRITE(WM3_LP_ILK, 0); +- I915_WRITE(WM2_LP_ILK, 0); +- I915_WRITE(WM1_LP_ILK, 0); +- + I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); + + /* WaDisableEarlyCull:vlv */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0260-drm-i915-Fix-DSPCLK_GATE_D-for-VLV.patch b/patches.baytrail/0260-drm-i915-Fix-DSPCLK_GATE_D-for-VLV.patch new file mode 100644 index 000000000000..2e433a9efca2 --- /dev/null +++ b/patches.baytrail/0260-drm-i915-Fix-DSPCLK_GATE_D-for-VLV.patch @@ -0,0 +1,50 @@ +From 6134b86ab84148c5da9ea9371e9c4c7c8370dac7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 21 May 2013 18:01:50 +0300 +Subject: drm/i915: Fix DSPCLK_GATE_D for VLV +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix the DSPCLK_GATE_D access for VLV. The code incorrectly tried to +poke at the ILK+ version of the register which is at the wrong offset. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit d7fe0cc0f2e0b302b247caa4306915a06218e0be) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 2 +- + drivers/gpu/drm/i915/intel_pm.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 13d4d5e21ce0..77ebaf06855a 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -1258,7 +1258,7 @@ + #define DSTATE_PLL_D3_OFF (1<<3) + #define DSTATE_GFX_CLOCK_GATING (1<<1) + #define DSTATE_DOT_CLOCK_GATING (1<<0) +-#define DSPCLK_GATE_D 0x6200 ++#define DSPCLK_GATE_D (dev_priv->info->display_mmio_offset + 0x6200) + # define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */ + # define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */ + # define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */ +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index e107d56efc38..6ce122be6b4b 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4797,7 +4797,7 @@ static void valleyview_init_clock_gating(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + int pipe; + +- I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); ++ I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); + + /* WaDisableEarlyCull:vlv */ + I915_WRITE(_3D_CHICKEN3, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0261-drm-i915-consolidate-and-tighten-encoder-cloning-che.patch b/patches.baytrail/0261-drm-i915-consolidate-and-tighten-encoder-cloning-che.patch new file mode 100644 index 000000000000..b2048280629a --- /dev/null +++ b/patches.baytrail/0261-drm-i915-consolidate-and-tighten-encoder-cloning-che.patch @@ -0,0 +1,196 @@ +From f3a04941c986b5e1e5a45b5d8e185b453b1d6a4b Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 30 May 2013 15:04:25 +0200 +Subject: drm/i915: consolidate and tighten encoder cloning checks + +Only lvds/tv did actually check for cloning or not, but many more +places should. + +Notices because my ivb tried to enable both cpu edp and vga on the +first crtc - the resulting confusion between has_pch_encoder, +has_dp_encoder but not actually being a pch dp encoder resulting in +hilarity (hitting a BUG). + +We _really_ need an igt to random-walk our modeset space more +exhaustively. + +The bug seems to have been exposed due to a race in the hw load +detection support for VGA: Right after a hotplug VGA was still +detected as connected, but obviously reading the EDID wasn't possible +any more. Hence why restarting X a bit later fixed things. Due to the +1024x756 fallback resolution suddenly more outputs had the same +resolution. + +On top of that SNA was confused with the possible_clones mask, trying +to clone outputs which cannot be cloned. That bug is now fixed with + +commit fc1e0702b25e647cb423851fb7228989fec28bd6 +Author: Daniel Vetter +Date: Wed May 29 11:25:28 2013 +0100 + + sna: fixup up possible_clones kms->X impedance mismatch + +v2: Kill intel_encoder_check_is_cloned, spotted by Paulo. + +v3: Drop the now unused pipe param. + +v4: Kill the stray printk Chris spotted. + +v5: Elaborate on how the bug in userspace happened and why it was racy +to reproduce. + +Cc: Chris Wilson +Cc: stable@vger.kernel.org +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit accfc0c50659c330cfde684017e5c1b58eee2857) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 64 ++++++++++++++---------------------- + drivers/gpu/drm/i915/intel_drv.h | 1 - + drivers/gpu/drm/i915/intel_lvds.c | 3 -- + drivers/gpu/drm/i915/intel_tv.c | 3 -- + 4 files changed, 24 insertions(+), 47 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 83864bda87ac..f8bfd510d2ff 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5868,27 +5868,9 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- int pipe = intel_crtc->pipe; + int plane = intel_crtc->plane; +- int num_connectors = 0; +- bool is_cpu_edp = false; +- struct intel_encoder *encoder; + int ret; + +- for_each_encoder_on_crtc(dev, crtc, encoder) { +- switch (encoder->type) { +- case INTEL_OUTPUT_EDP: +- if (enc_to_dig_port(&encoder->base)->port == PORT_A) +- is_cpu_edp = true; +- break; +- } +- +- num_connectors++; +- } +- +- WARN(num_connectors != 1, "%d connectors attached to pipe %c\n", +- num_connectors, pipe_name(pipe)); +- + if (!intel_ddi_pll_mode_set(crtc)) + return -EINVAL; + +@@ -7568,28 +7550,6 @@ static struct drm_crtc_helper_funcs intel_helper_funcs = { + .load_lut = intel_crtc_load_lut, + }; + +-bool intel_encoder_check_is_cloned(struct intel_encoder *encoder) +-{ +- struct intel_encoder *other_encoder; +- struct drm_crtc *crtc = &encoder->new_crtc->base; +- +- if (WARN_ON(!crtc)) +- return false; +- +- list_for_each_entry(other_encoder, +- &crtc->dev->mode_config.encoder_list, +- base.head) { +- +- if (&other_encoder->new_crtc->base != crtc || +- encoder == other_encoder) +- continue; +- else +- return true; +- } +- +- return false; +-} +- + static bool intel_encoder_crtc_ok(struct drm_encoder *encoder, + struct drm_crtc *crtc) + { +@@ -7773,6 +7733,25 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, + DRM_DEBUG_KMS("ips: %i\n", pipe_config->ips_enabled); + } + ++static bool check_encoder_cloning(struct drm_crtc *crtc) ++{ ++ int num_encoders = 0; ++ bool uncloneable_encoders = false; ++ struct intel_encoder *encoder; ++ ++ list_for_each_entry(encoder, &crtc->dev->mode_config.encoder_list, ++ base.head) { ++ if (&encoder->new_crtc->base != crtc) ++ continue; ++ ++ num_encoders++; ++ if (!encoder->cloneable) ++ uncloneable_encoders = true; ++ } ++ ++ return !(num_encoders > 1 && uncloneable_encoders); ++} ++ + static struct intel_crtc_config * + intel_modeset_pipe_config(struct drm_crtc *crtc, + struct drm_framebuffer *fb, +@@ -7785,6 +7764,11 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, + int plane_bpp, ret = -EINVAL; + bool retry = true; + ++ if (!check_encoder_cloning(crtc)) { ++ DRM_DEBUG_KMS("rejecting invalid cloning configuration\n"); ++ return ERR_PTR(-EINVAL); ++ } ++ + pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); + if (!pipe_config) + return ERR_PTR(-ENOMEM); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index b0b5ea70af18..baa217d89c59 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -629,7 +629,6 @@ extern void intel_crtc_load_lut(struct drm_crtc *crtc); + extern void intel_crtc_update_dpms(struct drm_crtc *crtc); + extern void intel_encoder_destroy(struct drm_encoder *encoder); + extern void intel_encoder_dpms(struct intel_encoder *encoder, int mode); +-extern bool intel_encoder_check_is_cloned(struct intel_encoder *encoder); + extern void intel_connector_dpms(struct drm_connector *, int mode); + extern bool intel_connector_get_hw_state(struct intel_connector *connector); + extern void intel_modeset_check_state(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 0b67e89cac9c..7feaba3de45f 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -264,9 +264,6 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + return false; + } + +- if (intel_encoder_check_is_cloned(&lvds_encoder->base)) +- return false; +- + if ((I915_READ(lvds_encoder->reg) & LVDS_A3_POWER_MASK) == + LVDS_A3_POWER_UP) + lvds_bpp = 8*3; +diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c +index a2fb39dede3c..d7fe4f89f7fc 100644 +--- a/drivers/gpu/drm/i915/intel_tv.c ++++ b/drivers/gpu/drm/i915/intel_tv.c +@@ -914,9 +914,6 @@ intel_tv_compute_config(struct intel_encoder *encoder, + if (!tv_mode) + return false; + +- if (intel_encoder_check_is_cloned(&intel_tv->base)) +- return false; +- + pipe_config->adjusted_mode.clock = tv_mode->clock; + DRM_DEBUG_KMS("forcing bpc to 8 for TV\n"); + pipe_config->pipe_bpp = 8*3; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0262-drm-i915-distinguish-between-error-messages-in-DIDL-.patch b/patches.baytrail/0262-drm-i915-distinguish-between-error-messages-in-DIDL-.patch new file mode 100644 index 000000000000..9e20b0dcd844 --- /dev/null +++ b/patches.baytrail/0262-drm-i915-distinguish-between-error-messages-in-DIDL-.patch @@ -0,0 +1,42 @@ +From 05f41a63270816574a246def7727d29f0723aada Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Wed, 5 Jun 2013 21:55:29 +0300 +Subject: drm/i915: distinguish between error messages in DIDL initialization + +Two exactly same error messages on different error paths makes debugging +difficult. Clarify the messages and distinguish them from each other. + +Signed-off-by: Jani Nikula +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit c2a2a1a722b7e4edce7dad285b461e0b2592eecc) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_opregion.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c +index 5c2d6939600e..79be7cfd3152 100644 +--- a/drivers/gpu/drm/i915/intel_opregion.c ++++ b/drivers/gpu/drm/i915/intel_opregion.c +@@ -312,7 +312,7 @@ static void intel_didl_outputs(struct drm_device *dev) + list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) { + if (i >= 8) { + dev_printk(KERN_ERR, &dev->pdev->dev, +- "More than 8 outputs detected\n"); ++ "More than 8 outputs detected via ACPI\n"); + return; + } + status = +@@ -339,7 +339,7 @@ blind_set: + int output_type = ACPI_OTHER_OUTPUT; + if (i >= 8) { + dev_printk(KERN_ERR, &dev->pdev->dev, +- "More than 8 outputs detected\n"); ++ "More than 8 outputs in connector list\n"); + return; + } + switch (connector->connector_type) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0263-drm-i915-set-default-value-for-config-pixel_multipli.patch b/patches.baytrail/0263-drm-i915-set-default-value-for-config-pixel_multipli.patch new file mode 100644 index 000000000000..89cd10679bb2 --- /dev/null +++ b/patches.baytrail/0263-drm-i915-set-default-value-for-config-pixel_multipli.patch @@ -0,0 +1,127 @@ +From 262b273f372d6546a823ee867dbb69a1b3451377 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sat, 1 Jun 2013 17:17:04 +0200 +Subject: drm/i915: set default value for config->pixel_multiplier + +This way we can simplify the code quite a bit. + +Also add a WARN in the sdvo code to complain about a bogus value +and kill the readout code in intel_ddi.c that Jesse sneaked in. +HW state readout for the pixel multiplier will work a bit differently +in the end. + +v2: Rebase on top of the fdi pixel mutliplier handling fix. + +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit ef1b460d1bab7e5b04c34f88c3dfa042528e7c27) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 1 - + drivers/gpu/drm/i915/intel_display.c | 29 ++++++++++------------------- + drivers/gpu/drm/i915/intel_sdvo.c | 1 + + 3 files changed, 11 insertions(+), 20 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index fc31ffa497eb..6df049fe7462 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -1280,7 +1280,6 @@ static void intel_ddi_get_config(struct intel_encoder *encoder, + flags |= DRM_MODE_FLAG_NVSYNC; + + pipe_config->adjusted_mode.flags |= flags; +- pipe_config->pixel_multiplier = 1; + } + + static void intel_ddi_destroy(struct drm_encoder *encoder) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index f8bfd510d2ff..7bd619db7cd6 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3999,8 +3999,7 @@ retry: + link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; + + fdi_dotclock = adjusted_mode->clock; +- if (pipe_config->pixel_multiplier > 1) +- fdi_dotclock /= pipe_config->pixel_multiplier; ++ fdi_dotclock /= pipe_config->pixel_multiplier; + + lane = ironlake_get_lanes_required(fdi_dotclock, link_bw, + pipe_config->pipe_bpp); +@@ -4454,11 +4453,8 @@ static void vlv_update_pll(struct intel_crtc *crtc) + if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) + DRM_ERROR("DPLL %d failed to lock\n", pipe); + +- dpll_md = 0; +- if (crtc->config.pixel_multiplier > 1) { +- dpll_md = (crtc->config.pixel_multiplier - 1) +- << DPLL_MD_UDI_MULTIPLIER_SHIFT; +- } ++ dpll_md = (crtc->config.pixel_multiplier - 1) ++ << DPLL_MD_UDI_MULTIPLIER_SHIFT; + I915_WRITE(DPLL_MD(pipe), dpll_md); + POSTING_READ(DPLL_MD(pipe)); + +@@ -4492,8 +4488,7 @@ static void i9xx_update_pll(struct intel_crtc *crtc, + else + dpll |= DPLLB_MODE_DAC_SERIAL; + +- if ((crtc->config.pixel_multiplier > 1) && +- (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))) { ++ if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { + dpll |= (crtc->config.pixel_multiplier - 1) + << SDVO_MULTIPLIER_SHIFT_HIRES; + } +@@ -4556,11 +4551,8 @@ static void i9xx_update_pll(struct intel_crtc *crtc, + udelay(150); + + if (INTEL_INFO(dev)->gen >= 4) { +- u32 dpll_md = 0; +- if (crtc->config.pixel_multiplier > 1) { +- dpll_md = (crtc->config.pixel_multiplier - 1) +- << DPLL_MD_UDI_MULTIPLIER_SHIFT; +- } ++ u32 dpll_md = (crtc->config.pixel_multiplier - 1) ++ << DPLL_MD_UDI_MULTIPLIER_SHIFT; + I915_WRITE(DPLL_MD(pipe), dpll_md); + } else { + /* The pixel multiplier can only be updated once the +@@ -5613,10 +5605,8 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, + else + dpll |= DPLLB_MODE_DAC_SERIAL; + +- if (intel_crtc->config.pixel_multiplier > 1) { +- dpll |= (intel_crtc->config.pixel_multiplier - 1) +- << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; +- } ++ dpll |= (intel_crtc->config.pixel_multiplier - 1) ++ << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; + + if (is_sdvo) + dpll |= DPLL_DVO_HIGH_SPEED; +@@ -7787,8 +7777,9 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, + goto fail; + + encoder_retry: +- /* Ensure the port clock default is reset when retrying. */ ++ /* Ensure the port clock defaults are reset when retrying. */ + pipe_config->port_clock = 0; ++ pipe_config->pixel_multiplier = 1; + + /* Pass our mode to the connectors and the CRTC to give them a chance to + * adjust it according to limitations or connector properties, and also +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index c55841937705..73179dfa5daa 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1219,6 +1219,7 @@ static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder) + + switch (intel_crtc->config.pixel_multiplier) { + default: ++ WARN(1, "unknown pixel mutlipler specified\n"); + case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; + case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; + case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0264-drm-i915-Track-clients-and-print-their-object-usage-.patch b/patches.baytrail/0264-drm-i915-Track-clients-and-print-their-object-usage-.patch new file mode 100644 index 000000000000..c826fa50958e --- /dev/null +++ b/patches.baytrail/0264-drm-i915-Track-clients-and-print-their-object-usage-.patch @@ -0,0 +1,107 @@ +From 7b69b79737f7325735e43b3b6e3189cd0af5e8da Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Tue, 4 Jun 2013 23:49:08 +0100 +Subject: drm/i915: Track clients and print their object usage in debugfs + +By stashing a pointer of who opened the device and keeping a list of +open fd, we can then walk each client and inspect how many objects they +have open. For example, + +i915_gem_objects: +1102 objects, 613646336 bytes +663 [662] objects, 468783104 [468750336] bytes in gtt + 37 [37] active objects, 46874624 [46874624] bytes + 626 [625] inactive objects, 421908480 [421875712] bytes +282 unbound objects, 6512640 bytes +85 purgeable objects, 6787072 bytes +28 pinned mappable objects, 3686400 bytes +40 fault mappable objects, 27783168 bytes +2145386496 [536870912] gtt total + +Xorg: 43 objects, 32243712 bytes (10223616 active, 16683008 inactive, 4096 unbound) +gnome-shell: 30 objects, 28381184 bytes (0 active, 28336128 inactive, 0 unbound) +xonotic-linux64: 1032 objects, 569933824 bytes (46874624 active, 383545344 inactive, 6508544 unbound) + +v2: Use existing drm->filelist as pointed out by Ben. +v3: Not even stashing the task_struct is required as Ben pointed out + drm_file->pid. + +Signed-off-by: Chris Wilson +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 2db8e9d6b255a4fd070df70fa58306bf64b41984) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 42 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 0e7e3c04d939..d4e78b64ca87 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -196,6 +196,32 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) + } \ + } while (0) + ++struct file_stats { ++ int count; ++ size_t total, active, inactive, unbound; ++}; ++ ++static int per_file_stats(int id, void *ptr, void *data) ++{ ++ struct drm_i915_gem_object *obj = ptr; ++ struct file_stats *stats = data; ++ ++ stats->count++; ++ stats->total += obj->base.size; ++ ++ if (obj->gtt_space) { ++ if (!list_empty(&obj->ring_list)) ++ stats->active += obj->base.size; ++ else ++ stats->inactive += obj->base.size; ++ } else { ++ if (!list_empty(&obj->global_list)) ++ stats->unbound += obj->base.size; ++ } ++ ++ return 0; ++} ++ + static int i915_gem_object_info(struct seq_file *m, void* data) + { + struct drm_info_node *node = (struct drm_info_node *) m->private; +@@ -204,6 +230,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data) + u32 count, mappable_count, purgeable_count; + size_t size, mappable_size, purgeable_size; + struct drm_i915_gem_object *obj; ++ struct drm_file *file; + int ret; + + ret = mutex_lock_interruptible(&dev->struct_mutex); +@@ -263,6 +290,21 @@ static int i915_gem_object_info(struct seq_file *m, void* data) + dev_priv->gtt.total, + dev_priv->gtt.mappable_end - dev_priv->gtt.start); + ++ seq_printf(m, "\n"); ++ list_for_each_entry_reverse(file, &dev->filelist, lhead) { ++ struct file_stats stats; ++ ++ memset(&stats, 0, sizeof(stats)); ++ idr_for_each(&file->object_idr, per_file_stats, &stats); ++ seq_printf(m, "%s: %u objects, %zu bytes (%zu active, %zu inactive, %zu unbound)\n", ++ get_pid_task(file->pid, PIDTYPE_PID)->comm, ++ stats.count, ++ stats.total, ++ stats.active, ++ stats.inactive, ++ stats.unbound); ++ } ++ + mutex_unlock(&dev->struct_mutex); + + return 0; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0265-drm-i915-add-ibx_irq_preinstall.patch b/patches.baytrail/0265-drm-i915-add-ibx_irq_preinstall.patch new file mode 100644 index 000000000000..c9a622d8a00f --- /dev/null +++ b/patches.baytrail/0265-drm-i915-add-ibx_irq_preinstall.patch @@ -0,0 +1,89 @@ +From 87306762f22e0facac9a08137cba763a768d869d Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Wed, 5 Jun 2013 14:21:51 -0300 +Subject: drm/i915: add ibx_irq_preinstall + +So we can remove some duplicate code. All the PCHs are very similar +and right now the code is the same. I plan to add more code, so we +would have more duplicated code. + +Signed-off-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 91738a95bf40a3405bb7b8a3e76d30e060a80705) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 44 ++++++++++++++++++++--------------------- + 1 file changed, 21 insertions(+), 23 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 2eaae3211553..8916651b3e1e 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2509,6 +2509,25 @@ void i915_hangcheck_elapsed(unsigned long data) + DRM_I915_HANGCHECK_JIFFIES)); + } + ++static void ibx_irq_preinstall(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (HAS_PCH_NOP(dev)) ++ return; ++ ++ /* south display irq */ ++ I915_WRITE(SDEIMR, 0xffffffff); ++ /* ++ * SDEIER is also touched by the interrupt handler to work around missed ++ * PCH interrupts. Hence we can't update it after the interrupt handler ++ * is enabled - instead we unconditionally enable all PCH interrupt ++ * sources here, but then only unmask them as needed with SDEIMR. ++ */ ++ I915_WRITE(SDEIER, 0xffffffff); ++ POSTING_READ(SDEIER); ++} ++ + /* drm_dma.h hooks + */ + static void ironlake_irq_preinstall(struct drm_device *dev) +@@ -2530,16 +2549,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev) + I915_WRITE(GTIER, 0x0); + POSTING_READ(GTIER); + +- /* south display irq */ +- I915_WRITE(SDEIMR, 0xffffffff); +- /* +- * SDEIER is also touched by the interrupt handler to work around missed +- * PCH interrupts. Hence we can't update it after the interrupt handler +- * is enabled - instead we unconditionally enable all PCH interrupt +- * sources here, but then only unmask them as needed with SDEIMR. +- */ +- I915_WRITE(SDEIER, 0xffffffff); +- POSTING_READ(SDEIER); ++ ibx_irq_preinstall(dev); + } + + static void ivybridge_irq_preinstall(struct drm_device *dev) +@@ -2566,19 +2576,7 @@ static void ivybridge_irq_preinstall(struct drm_device *dev) + I915_WRITE(GEN6_PMIER, 0x0); + POSTING_READ(GEN6_PMIER); + +- if (HAS_PCH_NOP(dev)) +- return; +- +- /* south display irq */ +- I915_WRITE(SDEIMR, 0xffffffff); +- /* +- * SDEIER is also touched by the interrupt handler to work around missed +- * PCH interrupts. Hence we can't update it after the interrupt handler +- * is enabled - instead we unconditionally enable all PCH interrupt +- * sources here, but then only unmask them as needed with SDEIMR. +- */ +- I915_WRITE(SDEIER, 0xffffffff); +- POSTING_READ(SDEIER); ++ ibx_irq_preinstall(dev); + } + + static void valleyview_irq_preinstall(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0266-Revert-drm-i915-Include-display_mmio_offset-in-seque.patch b/patches.baytrail/0266-Revert-drm-i915-Include-display_mmio_offset-in-seque.patch new file mode 100644 index 000000000000..d102b10f7ee8 --- /dev/null +++ b/patches.baytrail/0266-Revert-drm-i915-Include-display_mmio_offset-in-seque.patch @@ -0,0 +1,47 @@ +From 390acd2e535a8d1c78e9849d8e38a34edd3bcc6b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Thu, 6 Jun 2013 13:09:32 +0300 +Subject: Revert "drm/i915: Include display_mmio_offset in sequencer index/data + registers" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We use port I/O for VGA register access, so adding display_mmio_offset +is just wrong. + +This reverts commit 56a12a509296c87d6f149be86c6694d312b21d35. + +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 5434fd926d1e4de5d82fcbd4e7e4698cc6575bdb) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 77ebaf06855a..65547c1f1001 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -147,15 +147,9 @@ + #define VGA_MSR_MEM_EN (1<<1) + #define VGA_MSR_CGA_MODE (1<<0) + +-/* +- * SR01 is the only VGA register touched on non-UMS setups. +- * VLV doesn't do UMS, so the sequencer index/data registers +- * are the only VGA registers which need to include +- * display_mmio_offset. +- */ +-#define VGA_SR_INDEX (dev_priv->info->display_mmio_offset + 0x3c4) ++#define VGA_SR_INDEX 0x3c4 + #define SR01 1 +-#define VGA_SR_DATA (dev_priv->info->display_mmio_offset + 0x3c5) ++#define VGA_SR_DATA 0x3c5 + + #define VGA_AR_INDEX 0x3c0 + #define VGA_AR_VID_EN (1<<5) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0267-drm-i915-Always-load-the-display-palette-before-enab.patch b/patches.baytrail/0267-drm-i915-Always-load-the-display-palette-before-enab.patch new file mode 100644 index 000000000000..4559afe413ed --- /dev/null +++ b/patches.baytrail/0267-drm-i915-Always-load-the-display-palette-before-enab.patch @@ -0,0 +1,63 @@ +From c9a4f9452c674a864b7e27fccf1e977d1bb84bc4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 4 Jun 2013 13:48:59 +0300 +Subject: drm/i915: Always load the display palette before enabling the pipe +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Loading the palette after the planes are enabled can risk showing +incorrect colors. ILK+ already load the palette before even the pipe +is enabled. Just follow the same order for gen2-4 and VLV. + +According to BSpec the requirements for palette access are +display core clock and display PLL running. In certain platforms +just the core clock may be enough. But we definitely should have both +running when this gets called during the modeset. + +v2: Amend the commit message with some display PLL/core clock info + +Signed-off-by: Ville Syrjälä +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 63cbb0747622d923665294519e9a24bc9c654c19) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 7bd619db7cd6..885aa16b74f1 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3618,10 +3618,11 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) + /* Enable panel fitting for eDP */ + i9xx_pfit_enable(intel_crtc); + ++ intel_crtc_load_lut(crtc); ++ + intel_enable_pipe(dev_priv, pipe, false); + intel_enable_plane(dev_priv, plane, pipe); + +- intel_crtc_load_lut(crtc); + intel_update_fbc(dev); + + /* Give the overlay scaler a chance to enable if it's on this pipe */ +@@ -3657,12 +3658,13 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) + /* Enable panel fitting for LVDS */ + i9xx_pfit_enable(intel_crtc); + ++ intel_crtc_load_lut(crtc); ++ + intel_enable_pipe(dev_priv, pipe, false); + intel_enable_plane(dev_priv, plane, pipe); + if (IS_G4X(dev)) + g4x_fixup_plane(dev_priv, pipe); + +- intel_crtc_load_lut(crtc); + intel_update_fbc(dev); + + /* Give the overlay scaler a chance to enable if it's on this pipe */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0268-drm-i915-Always-enable-the-cursor-right-after-the-pr.patch b/patches.baytrail/0268-drm-i915-Always-enable-the-cursor-right-after-the-pr.patch new file mode 100644 index 000000000000..34a7a04fe854 --- /dev/null +++ b/patches.baytrail/0268-drm-i915-Always-enable-the-cursor-right-after-the-pr.patch @@ -0,0 +1,96 @@ +From 5f6b5c8bf7ce495c239364afee4774611421198a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 4 Jun 2013 13:49:00 +0300 +Subject: drm/i915: Always enable the cursor right after the primary plane +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Follow the same sequence when enabling the cursor plane during +modeset. No point in doing this stuff in different order on different +generations. + +This should also avoid a needless wait for vblank for the g4x cursor +workaround when the cursor gets enabled anyway. + +Acked-by: Egbert Eich +Signed-off-by: Ville Syrjälä +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 5c38d48cd8dfb3332c072a257bc2a6dab1e5dc3b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 885aa16b74f1..9e1ff008e733 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3219,6 +3219,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + intel_enable_pipe(dev_priv, pipe, + intel_crtc->config.has_pch_encoder); + intel_enable_plane(dev_priv, plane, pipe); ++ intel_crtc_update_cursor(crtc, true); + + if (intel_crtc->config.has_pch_encoder) + ironlake_pch_enable(crtc); +@@ -3227,8 +3228,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + intel_update_fbc(dev); + mutex_unlock(&dev->struct_mutex); + +- intel_crtc_update_cursor(crtc, true); +- + for_each_encoder_on_crtc(dev, crtc, encoder) + encoder->enable(encoder); + +@@ -3328,6 +3327,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) + intel_enable_pipe(dev_priv, pipe, + intel_crtc->config.has_pch_encoder); + intel_enable_plane(dev_priv, plane, pipe); ++ intel_crtc_update_cursor(crtc, true); + + hsw_enable_ips(intel_crtc); + +@@ -3338,8 +3338,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) + intel_update_fbc(dev); + mutex_unlock(&dev->struct_mutex); + +- intel_crtc_update_cursor(crtc, true); +- + for_each_encoder_on_crtc(dev, crtc, encoder) + encoder->enable(encoder); + +@@ -3622,12 +3620,12 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) + + intel_enable_pipe(dev_priv, pipe, false); + intel_enable_plane(dev_priv, plane, pipe); ++ intel_crtc_update_cursor(crtc, true); + + intel_update_fbc(dev); + + /* Give the overlay scaler a chance to enable if it's on this pipe */ + intel_crtc_dpms_overlay(intel_crtc, true); +- intel_crtc_update_cursor(crtc, true); + + mutex_unlock(&dev_priv->dpio_lock); + } +@@ -3662,6 +3660,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) + + intel_enable_pipe(dev_priv, pipe, false); + intel_enable_plane(dev_priv, plane, pipe); ++ intel_crtc_update_cursor(crtc, true); + if (IS_G4X(dev)) + g4x_fixup_plane(dev_priv, pipe); + +@@ -3669,7 +3668,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) + + /* Give the overlay scaler a chance to enable if it's on this pipe */ + intel_crtc_dpms_overlay(intel_crtc, true); +- intel_crtc_update_cursor(crtc, true); + + for_each_encoder_on_crtc(dev, crtc, encoder) + encoder->enable(encoder); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0269-drm-i915-Enable-the-overlay-right-after-primary-and-.patch b/patches.baytrail/0269-drm-i915-Enable-the-overlay-right-after-primary-and-.patch new file mode 100644 index 000000000000..08caabfc311b --- /dev/null +++ b/patches.baytrail/0269-drm-i915-Enable-the-overlay-right-after-primary-and-.patch @@ -0,0 +1,55 @@ +From ea429c26e8534e29b9e999d3e1b1df4f674a3ef0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 4 Jun 2013 13:49:01 +0300 +Subject: drm/i915: Enable the overlay right after primary and cursor planes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Again follow the same sequence for all generations, because doing +otherwise just doesn't make sense. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit f440eb1354bc92855bbbff08d3ac4a93029c3097) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 9e1ff008e733..00b197c625c2 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3622,11 +3622,11 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) + intel_enable_plane(dev_priv, plane, pipe); + intel_crtc_update_cursor(crtc, true); + +- intel_update_fbc(dev); +- + /* Give the overlay scaler a chance to enable if it's on this pipe */ + intel_crtc_dpms_overlay(intel_crtc, true); + ++ intel_update_fbc(dev); ++ + mutex_unlock(&dev_priv->dpio_lock); + } + +@@ -3664,11 +3664,11 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) + if (IS_G4X(dev)) + g4x_fixup_plane(dev_priv, pipe); + +- intel_update_fbc(dev); +- + /* Give the overlay scaler a chance to enable if it's on this pipe */ + intel_crtc_dpms_overlay(intel_crtc, true); + ++ intel_update_fbc(dev); ++ + for_each_encoder_on_crtc(dev, crtc, encoder) + encoder->enable(encoder); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0270-drm-i915-Follow-the-same-sequence-when-disabling-pla.patch b/patches.baytrail/0270-drm-i915-Follow-the-same-sequence-when-disabling-pla.patch new file mode 100644 index 000000000000..9745b2be80c9 --- /dev/null +++ b/patches.baytrail/0270-drm-i915-Follow-the-same-sequence-when-disabling-pla.patch @@ -0,0 +1,79 @@ +From c307ac446c7cb7ef6b452d3d80347d7ffd23c328 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 4 Jun 2013 13:49:02 +0300 +Subject: drm/i915: Follow the same sequence when disabling planes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +First disable FBC, then IPS, then disable all planes, and finally +disable the pipe. + +v2: Mention IPS in the commit message + +Signed-off-by: Ville Syrjälä +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 0d5b8c61d877072431d29f3338ec081a3f5d7981) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 00b197c625c2..b3dbdec72790 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3386,13 +3386,13 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) + + intel_crtc_wait_for_pending_flips(crtc); + drm_vblank_off(dev, pipe); +- intel_crtc_update_cursor(crtc, false); +- +- intel_disable_plane(dev_priv, plane, pipe); + + if (dev_priv->cfb_plane == plane) + intel_disable_fbc(dev); + ++ intel_crtc_update_cursor(crtc, false); ++ intel_disable_plane(dev_priv, plane, pipe); ++ + intel_set_pch_fifo_underrun_reporting(dev, pipe, false); + intel_disable_pipe(dev_priv, pipe); + +@@ -3465,7 +3465,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) + + intel_crtc_wait_for_pending_flips(crtc); + drm_vblank_off(dev, pipe); +- intel_crtc_update_cursor(crtc, false); + + /* FBC must be disabled before disabling the plane on HSW. */ + if (dev_priv->cfb_plane == plane) +@@ -3473,6 +3472,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) + + hsw_disable_ips(intel_crtc); + ++ intel_crtc_update_cursor(crtc, false); + intel_disable_plane(dev_priv, plane, pipe); + + if (intel_crtc->config.has_pch_encoder) +@@ -3706,13 +3706,14 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) + /* Give the overlay scaler a chance to disable if it's on this pipe */ + intel_crtc_wait_for_pending_flips(crtc); + drm_vblank_off(dev, pipe); +- intel_crtc_dpms_overlay(intel_crtc, false); +- intel_crtc_update_cursor(crtc, false); + + if (dev_priv->cfb_plane == plane) + intel_disable_fbc(dev); + ++ intel_crtc_dpms_overlay(intel_crtc, false); ++ intel_crtc_update_cursor(crtc, false); + intel_disable_plane(dev_priv, plane, pipe); ++ + intel_disable_pipe(dev_priv, pipe); + + i9xx_pfit_disable(intel_crtc); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0271-drm-i915-Drop-overlay-DPMS-call-from-valleyview_crtc.patch b/patches.baytrail/0271-drm-i915-Drop-overlay-DPMS-call-from-valleyview_crtc.patch new file mode 100644 index 000000000000..97391f2793bb --- /dev/null +++ b/patches.baytrail/0271-drm-i915-Drop-overlay-DPMS-call-from-valleyview_crtc.patch @@ -0,0 +1,36 @@ +From ab8f92be3931515e7bf35e5044e1845297d9e548 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 4 Jun 2013 13:49:03 +0300 +Subject: drm/i915: Drop overlay DPMS call from valleyview_crtc_enable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +VLV doesn't have the old video overlay. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit b85dfcf9240043e81ba13b1bc99afc8645bf4c6a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index b3dbdec72790..31076e0392e4 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3622,9 +3622,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) + intel_enable_plane(dev_priv, plane, pipe); + intel_crtc_update_cursor(crtc, true); + +- /* Give the overlay scaler a chance to enable if it's on this pipe */ +- intel_crtc_dpms_overlay(intel_crtc, true); +- + intel_update_fbc(dev); + + mutex_unlock(&dev_priv->dpio_lock); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0272-drm-i915-Disable-restore-all-sprite-planes-around-mo.patch b/patches.baytrail/0272-drm-i915-Disable-restore-all-sprite-planes-around-mo.patch new file mode 100644 index 000000000000..951f4389dea5 --- /dev/null +++ b/patches.baytrail/0272-drm-i915-Disable-restore-all-sprite-planes-around-mo.patch @@ -0,0 +1,153 @@ +From 8e588dc30b42c25ce0dac3fd6cf606aaba0dbd08 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 4 Jun 2013 13:49:04 +0300 +Subject: drm/i915: Disable/restore all sprite planes around modeset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Disable/restore sprite planes around mode-set just like we do for the +primary and cursor planes. Now that we have working sprite clipping, +this actually works quite decently. + +Previosuly we didn't even bother to disable sprites when changing mode, +which could lead to a corrupted sprite appearing on the screen after a +modeset (at least on my IVB). Not sure if all hardware generations would +be so forgiving when enabled sprites end up outside the pipe dimensons. + +v2: Disable rather than enable sprites in ironlake_crtc_disable() + +Signed-off-by: Ville Syrjälä +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit bb53d4aeac59079240605ef9269166f204612b78) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 29 +++++++++++++++++++++++++++++ + drivers/gpu/drm/i915/intel_drv.h | 1 + + drivers/gpu/drm/i915/intel_sprite.c | 8 ++++++++ + 3 files changed, 38 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 31076e0392e4..fc34abdae369 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3164,6 +3164,28 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc) + } + } + ++static void intel_enable_planes(struct drm_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->dev; ++ enum pipe pipe = to_intel_crtc(crtc)->pipe; ++ struct intel_plane *intel_plane; ++ ++ list_for_each_entry(intel_plane, &dev->mode_config.plane_list, base.head) ++ if (intel_plane->pipe == pipe) ++ intel_plane_restore(&intel_plane->base); ++} ++ ++static void intel_disable_planes(struct drm_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->dev; ++ enum pipe pipe = to_intel_crtc(crtc)->pipe; ++ struct intel_plane *intel_plane; ++ ++ list_for_each_entry(intel_plane, &dev->mode_config.plane_list, base.head) ++ if (intel_plane->pipe == pipe) ++ intel_plane_disable(&intel_plane->base); ++} ++ + static void ironlake_crtc_enable(struct drm_crtc *crtc) + { + struct drm_device *dev = crtc->dev; +@@ -3219,6 +3241,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + intel_enable_pipe(dev_priv, pipe, + intel_crtc->config.has_pch_encoder); + intel_enable_plane(dev_priv, plane, pipe); ++ intel_enable_planes(crtc); + intel_crtc_update_cursor(crtc, true); + + if (intel_crtc->config.has_pch_encoder) +@@ -3327,6 +3350,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) + intel_enable_pipe(dev_priv, pipe, + intel_crtc->config.has_pch_encoder); + intel_enable_plane(dev_priv, plane, pipe); ++ intel_enable_planes(crtc); + intel_crtc_update_cursor(crtc, true); + + hsw_enable_ips(intel_crtc); +@@ -3391,6 +3415,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) + intel_disable_fbc(dev); + + intel_crtc_update_cursor(crtc, false); ++ intel_disable_planes(crtc); + intel_disable_plane(dev_priv, plane, pipe); + + intel_set_pch_fifo_underrun_reporting(dev, pipe, false); +@@ -3473,6 +3498,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) + hsw_disable_ips(intel_crtc); + + intel_crtc_update_cursor(crtc, false); ++ intel_disable_planes(crtc); + intel_disable_plane(dev_priv, plane, pipe); + + if (intel_crtc->config.has_pch_encoder) +@@ -3620,6 +3646,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) + + intel_enable_pipe(dev_priv, pipe, false); + intel_enable_plane(dev_priv, plane, pipe); ++ intel_enable_planes(crtc); + intel_crtc_update_cursor(crtc, true); + + intel_update_fbc(dev); +@@ -3657,6 +3684,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) + + intel_enable_pipe(dev_priv, pipe, false); + intel_enable_plane(dev_priv, plane, pipe); ++ intel_enable_planes(crtc); + intel_crtc_update_cursor(crtc, true); + if (IS_G4X(dev)) + g4x_fixup_plane(dev_priv, pipe); +@@ -3709,6 +3737,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) + + intel_crtc_dpms_overlay(intel_crtc, false); + intel_crtc_update_cursor(crtc, false); ++ intel_disable_planes(crtc); + intel_disable_plane(dev_priv, plane, pipe); + + intel_disable_pipe(dev_priv, pipe); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index baa217d89c59..915d2693e1a0 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -633,6 +633,7 @@ extern void intel_connector_dpms(struct drm_connector *, int mode); + extern bool intel_connector_get_hw_state(struct intel_connector *connector); + extern void intel_modeset_check_state(struct drm_device *dev); + extern void intel_plane_restore(struct drm_plane *plane); ++extern void intel_plane_disable(struct drm_plane *plane); + + + static inline struct intel_encoder *intel_attached_encoder(struct drm_connector *connector) +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index 04d38d4d811a..1fa5612a4572 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -957,6 +957,14 @@ void intel_plane_restore(struct drm_plane *plane) + intel_plane->src_w, intel_plane->src_h); + } + ++void intel_plane_disable(struct drm_plane *plane) ++{ ++ if (!plane->crtc || !plane->fb) ++ return; ++ ++ intel_disable_plane(plane); ++} ++ + static const struct drm_plane_funcs intel_plane_funcs = { + .update_plane = intel_update_plane, + .disable_plane = intel_disable_plane, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0273-drm-i915-Improve-assert_planes_disabled.patch b/patches.baytrail/0273-drm-i915-Improve-assert_planes_disabled.patch new file mode 100644 index 000000000000..f6dca1f698e5 --- /dev/null +++ b/patches.baytrail/0273-drm-i915-Improve-assert_planes_disabled.patch @@ -0,0 +1,53 @@ +From 1a6d11332fd1b67099afac6e6d2ce6a8577beaaf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 4 Jun 2013 13:49:05 +0300 +Subject: drm/i915: Improve assert_planes_disabled() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Ever since gen4 primary planes were fixed to pipes. + +And for gen2-3, don't check plane B if it doesn't exist. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 653e10266df8319d6003fbf46ec34865a5a363f6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index fc34abdae369..8389d954c99c 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1105,12 +1105,13 @@ static void assert_plane(struct drm_i915_private *dev_priv, + static void assert_planes_disabled(struct drm_i915_private *dev_priv, + enum pipe pipe) + { ++ struct drm_device *dev = dev_priv->dev; + int reg, i; + u32 val; + int cur_pipe; + +- /* Planes are fixed to pipes on ILK+ */ +- if (HAS_PCH_SPLIT(dev_priv->dev) || IS_VALLEYVIEW(dev_priv->dev)) { ++ /* Primary planes are fixed to pipes on gen4+ */ ++ if (INTEL_INFO(dev)->gen >= 4) { + reg = DSPCNTR(pipe); + val = I915_READ(reg); + WARN((val & DISPLAY_PLANE_ENABLE), +@@ -1120,7 +1121,7 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv, + } + + /* Need to check both planes against the pipe */ +- for (i = 0; i < 2; i++) { ++ for (i = 0; i < INTEL_INFO(dev)->num_pipes; i++) { + reg = DSPCNTR(i); + val = I915_READ(reg); + cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >> +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0274-drm-i915-Spruce-up-assert_sprites_disabled.patch b/patches.baytrail/0274-drm-i915-Spruce-up-assert_sprites_disabled.patch new file mode 100644 index 000000000000..7ebcfdeb1962 --- /dev/null +++ b/patches.baytrail/0274-drm-i915-Spruce-up-assert_sprites_disabled.patch @@ -0,0 +1,66 @@ +From 49d01355d8d14a16287c33033085b8126d9e55ba Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 4 Jun 2013 13:49:06 +0300 +Subject: drm/i915: Spruce up assert_sprites_disabled() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Make assert_sprites_disabled() operational on all platforms where +we currently have sprite support enabled. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 20674eef808dada6c30988a8cfcb908406cdea02) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 27 +++++++++++++++++++-------- + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 8389d954c99c..54208ba52894 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1135,19 +1135,30 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv, + static void assert_sprites_disabled(struct drm_i915_private *dev_priv, + enum pipe pipe) + { ++ struct drm_device *dev = dev_priv->dev; + int reg, i; + u32 val; + +- if (!IS_VALLEYVIEW(dev_priv->dev)) +- return; +- +- /* Need to check both planes against the pipe */ +- for (i = 0; i < dev_priv->num_plane; i++) { +- reg = SPCNTR(pipe, i); ++ if (IS_VALLEYVIEW(dev)) { ++ for (i = 0; i < dev_priv->num_plane; i++) { ++ reg = SPCNTR(pipe, i); ++ val = I915_READ(reg); ++ WARN((val & SP_ENABLE), ++ "sprite %c assertion failure, should be off on pipe %c but is still active\n", ++ sprite_name(pipe, i), pipe_name(pipe)); ++ } ++ } else if (INTEL_INFO(dev)->gen >= 7) { ++ reg = SPRCTL(pipe); ++ val = I915_READ(reg); ++ WARN((val & SPRITE_ENABLE), ++ "sprite %c assertion failure, should be off on pipe %c but is still active\n", ++ plane_name(pipe), pipe_name(pipe)); ++ } else if (INTEL_INFO(dev)->gen >= 5) { ++ reg = DVSCNTR(pipe); + val = I915_READ(reg); +- WARN((val & SP_ENABLE), ++ WARN((val & DVS_ENABLE), + "sprite %c assertion failure, should be off on pipe %c but is still active\n", +- sprite_name(pipe, i), pipe_name(pipe)); ++ plane_name(pipe), pipe_name(pipe)); + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0275-drm-i915-Assert-dpll-running-in-intel_crtc_load_lut-.patch b/patches.baytrail/0275-drm-i915-Assert-dpll-running-in-intel_crtc_load_lut-.patch new file mode 100644 index 000000000000..5331c5eee509 --- /dev/null +++ b/patches.baytrail/0275-drm-i915-Assert-dpll-running-in-intel_crtc_load_lut-.patch @@ -0,0 +1,48 @@ +From 43b399b96c042230cccacac01e533d1e2464977f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 4 Jun 2013 13:49:07 +0300 +Subject: drm/i915: Assert dpll running in intel_crtc_load_lut() on pre-PCH + platforms +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Adding more context from Ville's reply to Rodrigo's question why we +need this: + +"The spec says that on some hardware you need to PLL running before you +can poke at the palette registers. I didn't actually try to anger the +hardware so I'm not really sure what would happen otherwise, but IIRC +Jesse said something about a hard system hang..." + +And generally documenting such ordering constraints with asserts is +Just Good. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Rodrigo Vivi +[danvet: Spruce up the commit message a lot.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 14420bd0065c1757a353e36ebc9cc4bdc6932dcd) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 54208ba52894..63ff08834209 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -6311,6 +6311,9 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) + if (!crtc->enabled || !intel_crtc->active) + return; + ++ if (!HAS_PCH_SPLIT(dev_priv->dev)) ++ assert_pll_enabled(dev_priv, pipe); ++ + /* use legacy palette for Ironlake */ + if (HAS_PCH_SPLIT(dev)) + palreg = LGC_PALETTE(pipe); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0276-drm-i915-hw-state-readout-support-for-pixel_multipli.patch b/patches.baytrail/0276-drm-i915-hw-state-readout-support-for-pixel_multipli.patch new file mode 100644 index 000000000000..3ee02943f9f0 --- /dev/null +++ b/patches.baytrail/0276-drm-i915-hw-state-readout-support-for-pixel_multipli.patch @@ -0,0 +1,173 @@ +From 2976464a757dd085d72ebe29aed51604012984d5 Mon Sep 17 00:00:00 2001 +From: James Ausmus +Date: Mon, 23 Sep 2013 16:52:48 -0700 +Subject: drm/i915: hw state readout support for pixel_multiplier + +Incomplete since ilk+ support needs proper pch dpll tracking first. +SDVO get_config parts based on a patch from Jesse Barnes, but fixed up +to actually work. + +v2: Make sure that we call encoder->get_config _after_ we +get_pipe_config to be consistent in both setup_hw_state and the +modeset state checker. Otherwise the clever trick with handling the +pixel mutliplier on i915G/GM where the encoder overrides the default +value of 1 from the crtc get_pipe_config function doesn't work. +Spotted by Imre Deak. + +v3: Actually cross-check the pixel mutliplier (but not on pch split +platforms for now). Now actually also tested on a i915G with a sdvo +encoder plugged in. + +Cc: Imre Deak +Cc: Jesse Barnes +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 6c49f24180c308a07be3f1d59ee7af33184ba17e) + +Conflicts: + drivers/gpu/drm/i915/intel_display.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 39 ++++++++++++++++++++++++++++++++++-- + drivers/gpu/drm/i915/intel_sdvo.c | 30 ++++++++++++++++++++++++++- + 2 files changed, 66 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 63ff08834209..69c70dd606e3 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5001,6 +5001,23 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, + + i9xx_get_pfit_config(crtc, pipe_config); + ++ if (INTEL_INFO(dev)->gen >= 4) { ++ tmp = I915_READ(DPLL_MD(crtc->pipe)); ++ pipe_config->pixel_multiplier = ++ ((tmp & DPLL_MD_UDI_MULTIPLIER_MASK) ++ >> DPLL_MD_UDI_MULTIPLIER_SHIFT) + 1; ++ } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { ++ tmp = I915_READ(DPLL(crtc->pipe)); ++ pipe_config->pixel_multiplier = ++ ((tmp & SDVO_MULTIPLIER_MASK) ++ >> SDVO_MULTIPLIER_SHIFT_HIRES) + 1; ++ } else { ++ /* Note that on i915G/GM the pixel multiplier is in the sdvo ++ * port and will be fixed up in the encoder->get_config ++ * function. */ ++ pipe_config->pixel_multiplier = 1; ++ } ++ + return true; + } + +@@ -5864,6 +5881,12 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + FDI_DP_PORT_WIDTH_SHIFT) + 1; + + ironlake_get_fdi_m_n_config(crtc, pipe_config); ++ ++ /* XXX: Can't properly read out the pch dpll pixel multiplier ++ * since we don't have state tracking for pch clocks yet. */ ++ pipe_config->pixel_multiplier = 1; ++ } else { ++ pipe_config->pixel_multiplier = 1; + } + + intel_get_pipe_timings(crtc, pipe_config); +@@ -5998,6 +6021,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) && + (I915_READ(IPS_CTL) & IPS_ENABLE); + ++ pipe_config->pixel_multiplier = 1; ++ + return true; + } + +@@ -8094,6 +8119,9 @@ intel_pipe_config_compare(struct drm_device *dev, + PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_start); + PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_end); + ++ if (!HAS_PCH_SPLIT(dev)) ++ PIPE_CONF_CHECK_I(pixel_multiplier); ++ + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, + DRM_MODE_FLAG_INTERLACE); + +@@ -8215,9 +8243,8 @@ intel_modeset_check_state(struct drm_device *dev) + enabled = true; + if (encoder->connectors_active) + active = true; +- if (encoder->get_config) +- encoder->get_config(encoder, &pipe_config); + } ++ + WARN(active != crtc->active, + "crtc's computed active state doesn't match tracked active state " + "(expected %i, found %i)\n", active, crtc->active); +@@ -8232,6 +8259,14 @@ intel_modeset_check_state(struct drm_device *dev) + if (crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) + active = crtc->active; + ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, ++ base.head) { ++ if (encoder->base.crtc != &crtc->base) ++ continue; ++ if (encoder->get_config) ++ encoder->get_config(encoder, &pipe_config); ++ } ++ + WARN(crtc->active != active, + "crtc active state doesn't match with hw state " + "(expected %i, found %i)\n", crtc->active, active); +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 73179dfa5daa..785968c6916f 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1313,9 +1313,13 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, + static void intel_sdvo_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) + { ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); + struct intel_sdvo_dtd dtd; +- u32 flags = 0; ++ int encoder_pixel_multiplier = 0; ++ u32 flags = 0, sdvox; ++ u8 val; + bool ret; + + ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); +@@ -1335,6 +1339,30 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, + flags |= DRM_MODE_FLAG_NVSYNC; + + pipe_config->adjusted_mode.flags |= flags; ++ ++ if (IS_I915G(dev) || IS_I915GM(dev)) { ++ sdvox = I915_READ(intel_sdvo->sdvo_reg); ++ pipe_config->pixel_multiplier = ++ ((sdvox & SDVO_PORT_MULTIPLY_MASK) ++ >> SDVO_PORT_MULTIPLY_SHIFT) + 1; ++ } ++ ++ /* Cross check the port pixel multiplier with the sdvo encoder state. */ ++ intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT, &val, 1); ++ switch (val) { ++ case SDVO_CLOCK_RATE_MULT_1X: ++ encoder_pixel_multiplier = 1; ++ break; ++ case SDVO_CLOCK_RATE_MULT_2X: ++ encoder_pixel_multiplier = 2; ++ break; ++ case SDVO_CLOCK_RATE_MULT_4X: ++ encoder_pixel_multiplier = 4; ++ break; ++ } ++ WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier, ++ "SDVO pixel multiplier mismatch, port: %i, encoder: %i\n", ++ pipe_config->pixel_multiplier, encoder_pixel_multiplier); + } + + static void intel_disable_sdvo(struct intel_encoder *encoder) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0277-drm-i915-update-FBC-maximum-fb-sizes.patch b/patches.baytrail/0277-drm-i915-update-FBC-maximum-fb-sizes.patch new file mode 100644 index 000000000000..8044c61d9e23 --- /dev/null +++ b/patches.baytrail/0277-drm-i915-update-FBC-maximum-fb-sizes.patch @@ -0,0 +1,62 @@ +From d2f63c4f790c1be74679692e81889b55c9ffcda2 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Tue, 4 Jun 2013 16:53:39 -0300 +Subject: drm/i915: update FBC maximum fb sizes + +CTG/ILK/SNB/IVB support 4kx2k surfaces. HSW supports 4kx4k, but +without proper front buffer invalidation on the last 2k lines, so +don't enable FBC on these cases for now. + +v2: Use gen >= 5, not gen > 4 (Daniel). + +Signed-off-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit f85da868e3b998394634209cc1e48e0f4126901b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 6ce122be6b4b..da49e46062e1 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -431,7 +431,7 @@ void intel_disable_fbc(struct drm_device *dev) + * - no pixel mulitply/line duplication + * - no alpha buffer discard + * - no dual wide +- * - framebuffer <= 2048 in width, 1536 in height ++ * - framebuffer <= max_hdisplay in width, max_vdisplay in height + * + * We can't assume that any compression will take place (worst case), + * so the compressed buffer has to be the same size as the uncompressed +@@ -449,6 +449,7 @@ void intel_update_fbc(struct drm_device *dev) + struct intel_framebuffer *intel_fb; + struct drm_i915_gem_object *obj; + int enable_fbc; ++ unsigned int max_hdisplay, max_vdisplay; + + if (!i915_powersave) + return; +@@ -507,8 +508,16 @@ void intel_update_fbc(struct drm_device *dev) + dev_priv->no_fbc_reason = FBC_UNSUPPORTED_MODE; + goto out_disable; + } +- if ((crtc->mode.hdisplay > 2048) || +- (crtc->mode.vdisplay > 1536)) { ++ ++ if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) { ++ max_hdisplay = 4096; ++ max_vdisplay = 2048; ++ } else { ++ max_hdisplay = 2048; ++ max_vdisplay = 1536; ++ } ++ if ((crtc->mode.hdisplay > max_hdisplay) || ++ (crtc->mode.vdisplay > max_vdisplay)) { + DRM_DEBUG_KMS("mode too large for compression, disabling\n"); + dev_priv->no_fbc_reason = FBC_MODE_TOO_LARGE; + goto out_disable; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0278-i915-drm-Add-private-api-for-power-well-usage.patch b/patches.baytrail/0278-i915-drm-Add-private-api-for-power-well-usage.patch new file mode 100644 index 000000000000..1f88ead4270f --- /dev/null +++ b/patches.baytrail/0278-i915-drm-Add-private-api-for-power-well-usage.patch @@ -0,0 +1,244 @@ +From 9466381b07a964c686d678d34ebc6079d3f5025c Mon Sep 17 00:00:00 2001 +From: Wang Xingchao +Date: Thu, 30 May 2013 22:07:11 +0800 +Subject: i915/drm: Add private api for power well usage + +Haswell Display audio depends on power well in graphic side, it should +request power well before use it and release power well after use. +I915 will not shutdown power well if it detects audio is using. +This patch protects display audio crash for Intel Haswell C3 stepping board. + +Signed-off-by: Wang Xingchao +Reviewed-by: Takashi Iwai +Reviewed-by: Damien Lespiau +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit a38911a3fede294e2adfd2deea8104dfbbd760c5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 6 +++ + drivers/gpu/drm/i915/i915_drv.h | 12 ++++++ + drivers/gpu/drm/i915/intel_drv.h | 4 ++ + drivers/gpu/drm/i915/intel_pm.c | 81 ++++++++++++++++++++++++++++++++++++---- + include/drm/i915_powerwell.h | 36 ++++++++++++++++++ + 5 files changed, 132 insertions(+), 7 deletions(-) + create mode 100644 include/drm/i915_powerwell.h + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index cd2a5f3f7db6..628f797358bb 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1634,6 +1634,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + /* Start out suspended */ + dev_priv->mm.suspended = 1; + ++ if (HAS_POWER_WELL(dev)) ++ i915_init_power_well(dev); ++ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = i915_load_modeset_init(dev); + if (ret < 0) { +@@ -1685,6 +1688,9 @@ int i915_driver_unload(struct drm_device *dev) + + intel_gpu_ips_teardown(); + ++ if (HAS_POWER_WELL(dev)) ++ i915_remove_power_well(dev); ++ + i915_teardown_sysfs(dev); + + if (dev_priv->mm.inactive_shrinker.shrink) +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 5297b1fe3a2c..fec0c8f56e05 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -741,6 +741,15 @@ struct intel_ilk_power_mgmt { + struct drm_i915_gem_object *renderctx; + }; + ++/* Power well structure for haswell */ ++struct i915_power_well { ++ struct drm_device *device; ++ spinlock_t lock; ++ /* power well enable/disable usage count */ ++ int count; ++ int i915_request; ++}; ++ + struct i915_dri1_state { + unsigned allow_batchbuffer : 1; + u32 __iomem *gfx_hws_cpu_addr; +@@ -1100,6 +1109,9 @@ typedef struct drm_i915_private { + * mchdev_lock in intel_pm.c */ + struct intel_ilk_power_mgmt ips; + ++ /* Haswell power well */ ++ struct i915_power_well power_well; ++ + enum no_fbc_reason no_fbc_reason; + + struct drm_mm_node *compressed_fb; +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 915d2693e1a0..0e5897cb8d48 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -768,6 +768,10 @@ extern void intel_update_fbc(struct drm_device *dev); + extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv); + extern void intel_gpu_ips_teardown(void); + ++/* Power well */ ++extern int i915_init_power_well(struct drm_device *dev); ++extern void i915_remove_power_well(struct drm_device *dev); ++ + extern bool intel_display_power_enabled(struct drm_device *dev, + enum intel_display_power_domain domain); + extern void intel_init_power_well(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index da49e46062e1..e3aa054417d6 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -5024,18 +5024,12 @@ bool intel_display_power_enabled(struct drm_device *dev, + } + } + +-void intel_set_power_well(struct drm_device *dev, bool enable) ++static void __intel_set_power_well(struct drm_device *dev, bool enable) + { + struct drm_i915_private *dev_priv = dev->dev_private; + bool is_enabled, enable_requested; + uint32_t tmp; + +- if (!HAS_POWER_WELL(dev)) +- return; +- +- if (!i915_disable_power_well && !enable) +- return; +- + tmp = I915_READ(HSW_PWR_WELL_DRIVER); + is_enabled = tmp & HSW_PWR_WELL_STATE; + enable_requested = tmp & HSW_PWR_WELL_ENABLE; +@@ -5058,6 +5052,79 @@ void intel_set_power_well(struct drm_device *dev, bool enable) + } + } + ++static struct i915_power_well *hsw_pwr; ++ ++/* Display audio driver power well request */ ++void i915_request_power_well(void) ++{ ++ if (WARN_ON(!hsw_pwr)) ++ return; ++ ++ spin_lock_irq(&hsw_pwr->lock); ++ if (!hsw_pwr->count++ && ++ !hsw_pwr->i915_request) ++ __intel_set_power_well(hsw_pwr->device, true); ++ spin_unlock_irq(&hsw_pwr->lock); ++} ++EXPORT_SYMBOL_GPL(i915_request_power_well); ++ ++/* Display audio driver power well release */ ++void i915_release_power_well(void) ++{ ++ if (WARN_ON(!hsw_pwr)) ++ return; ++ ++ spin_lock_irq(&hsw_pwr->lock); ++ WARN_ON(!hsw_pwr->count); ++ if (!--hsw_pwr->count && ++ !hsw_pwr->i915_request) ++ __intel_set_power_well(hsw_pwr->device, false); ++ spin_unlock_irq(&hsw_pwr->lock); ++} ++EXPORT_SYMBOL_GPL(i915_release_power_well); ++ ++int i915_init_power_well(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ hsw_pwr = &dev_priv->power_well; ++ ++ hsw_pwr->device = dev; ++ spin_lock_init(&hsw_pwr->lock); ++ hsw_pwr->count = 0; ++ ++ return 0; ++} ++ ++void i915_remove_power_well(struct drm_device *dev) ++{ ++ hsw_pwr = NULL; ++} ++ ++void intel_set_power_well(struct drm_device *dev, bool enable) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct i915_power_well *power_well = &dev_priv->power_well; ++ ++ if (!HAS_POWER_WELL(dev)) ++ return; ++ ++ if (!i915_disable_power_well && !enable) ++ return; ++ ++ spin_lock_irq(&power_well->lock); ++ power_well->i915_request = enable; ++ ++ /* only reject "disable" power well request */ ++ if (power_well->count && !enable) { ++ spin_unlock_irq(&power_well->lock); ++ return; ++ } ++ ++ __intel_set_power_well(dev, enable); ++ spin_unlock_irq(&power_well->lock); ++} ++ + /* + * Starting with Haswell, we have a "Power Down Well" that can be turned off + * when not needed anymore. We have 4 registers that can request the power well +diff --git a/include/drm/i915_powerwell.h b/include/drm/i915_powerwell.h +new file mode 100644 +index 000000000000..cfdc884405b7 +--- /dev/null ++++ b/include/drm/i915_powerwell.h +@@ -0,0 +1,36 @@ ++/************************************************************************** ++ * ++ * Copyright 2013 Intel Inc. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * ++ **************************************************************************/ ++ ++#ifndef _I915_POWERWELL_H_ ++#define _I915_POWERWELL_H_ ++ ++/* For use by hda_i915 driver */ ++extern void i915_request_power_well(void); ++extern void i915_release_power_well(void); ++ ++#endif /* _I915_POWERWELL_H_ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0279-drm-i915-pipe-config-quirk-infrastructure-plus-sdvo-.patch b/patches.baytrail/0279-drm-i915-pipe-config-quirk-infrastructure-plus-sdvo-.patch new file mode 100644 index 000000000000..c6fea94aa030 --- /dev/null +++ b/patches.baytrail/0279-drm-i915-pipe-config-quirk-infrastructure-plus-sdvo-.patch @@ -0,0 +1,153 @@ +From ef60f6c04841f649ef0e7c6c5c43a439fa0fe380 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 6 Jun 2013 14:55:52 +0200 +Subject: drm/i915: pipe config quirk infrastructure plus sdvo mode.flags fix + +For various reasons the hw state readout might not be able to +faithfully match the hw state: +- broken hw (like the case which motivated this patch here where the + sdvo encoder does not implemented mandatory functionality + correctly). +- platforms which are not supported fully with the pipe config + infrastructure +- if our code doesn't support a given hw configuration natively, e.g. + special restrictions on the per-pipe panel fitters when they're used + in high-quality scaling modes. + +In all these cases both fastboot and the hw state cross checker need +to be aware of these cases and act accordingly. To be able to do this +add a new quirk flag to the pipe config structure. + +The specific case at hand is an sdvo encoder which doesn't implement +the get_timings function, so adjusted_mode flags will be wrong. The +strange thing though is that the encoder _does_ work, even though it +doesn't implement any of the timings functions (so neither get nor +set, neither for input nor output timings). + +Not that non-compliant sdvo encoder are any surprise at all ... + +v2: +- Don't read random garbage from the dtd if the get_timings call + failed (suggested by Chris). +- Still check the interlaced flag, that's read out from someplace + else. We want maximal paranoia, after all. + +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit bb760063790fbbc3c956f23aff4dbdfdd3c03818) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 22 ++++++++++++++-------- + drivers/gpu/drm/i915/intel_drv.h | 11 +++++++++++ + drivers/gpu/drm/i915/intel_sdvo.c | 24 +++++++++++++----------- + 3 files changed, 38 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 69c70dd606e3..b8851f3f4911 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8095,6 +8095,9 @@ intel_pipe_config_compare(struct drm_device *dev, + return false; \ + } + ++#define PIPE_CONF_QUIRK(quirk) \ ++ ((current_config->quirks | pipe_config->quirks) & (quirk)) ++ + PIPE_CONF_CHECK_I(cpu_transcoder); + + PIPE_CONF_CHECK_I(has_pch_encoder); +@@ -8125,14 +8128,16 @@ intel_pipe_config_compare(struct drm_device *dev, + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, + DRM_MODE_FLAG_INTERLACE); + +- PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, +- DRM_MODE_FLAG_PHSYNC); +- PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, +- DRM_MODE_FLAG_NHSYNC); +- PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, +- DRM_MODE_FLAG_PVSYNC); +- PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, +- DRM_MODE_FLAG_NVSYNC); ++ if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) { ++ PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, ++ DRM_MODE_FLAG_PHSYNC); ++ PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, ++ DRM_MODE_FLAG_NHSYNC); ++ PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, ++ DRM_MODE_FLAG_PVSYNC); ++ PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, ++ DRM_MODE_FLAG_NVSYNC); ++ } + + PIPE_CONF_CHECK_I(requested_mode.hdisplay); + PIPE_CONF_CHECK_I(requested_mode.vdisplay); +@@ -8149,6 +8154,7 @@ intel_pipe_config_compare(struct drm_device *dev, + + #undef PIPE_CONF_CHECK_I + #undef PIPE_CONF_CHECK_FLAGS ++#undef PIPE_CONF_QUIRK + + return true; + } +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 0e5897cb8d48..a060d82f175b 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -193,6 +193,17 @@ typedef struct dpll { + } intel_clock_t; + + struct intel_crtc_config { ++ /** ++ * quirks - bitfield with hw state readout quirks ++ * ++ * For various reasons the hw state readout code might not be able to ++ * completely faithfully read out the current state. These cases are ++ * tracked with quirk flags so that fastboot and state checker can act ++ * accordingly. ++ */ ++#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */ ++ unsigned long quirks; ++ + struct drm_display_mode requested_mode; + struct drm_display_mode adjusted_mode; + /* This flag must be set by the encoder's compute_config callback if it +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 785968c6916f..1262fc4a1b34 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1324,19 +1324,21 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, + + ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); + if (!ret) { ++ /* Some sdvo encoders are not spec compliant and don't ++ * implement the mandatory get_timings function. */ + DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n"); +- return; +- } +- +- if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) +- flags |= DRM_MODE_FLAG_PHSYNC; +- else +- flags |= DRM_MODE_FLAG_NHSYNC; ++ pipe_config->quirks |= PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS; ++ } else { ++ if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) ++ flags |= DRM_MODE_FLAG_PHSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NHSYNC; + +- if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) +- flags |= DRM_MODE_FLAG_PVSYNC; +- else +- flags |= DRM_MODE_FLAG_NVSYNC; ++ if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) ++ flags |= DRM_MODE_FLAG_PVSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NVSYNC; ++ } + + pipe_config->adjusted_mode.flags |= flags; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0280-drm-i915-enable-30bpp-for-DP-outputs.patch b/patches.baytrail/0280-drm-i915-enable-30bpp-for-DP-outputs.patch new file mode 100644 index 000000000000..5967ca9b6e94 --- /dev/null +++ b/patches.baytrail/0280-drm-i915-enable-30bpp-for-DP-outputs.patch @@ -0,0 +1,48 @@ +From 87bfa88832b71d764b60f457e01560661f6934e1 Mon Sep 17 00:00:00 2001 +From: James Ausmus +Date: Mon, 23 Sep 2013 16:53:36 -0700 +Subject: drm/i915: enable 30bpp for DP outputs + +We always limited the link bw calculations to 24bpp. Tested with +my shiny new high-bpc screen, seems to work as advertised. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65280 +Tested-by: shui yangwei +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 3e7ca9858d51a8df2bb18b82a529df5e5f9abc51) + +Conflicts: + drivers/gpu/drm/i915/intel_dp.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 8d11dfa9a169..0066c2314e1f 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -716,17 +716,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, + /* Walk through all bpp values. Luckily they're all nicely spaced with 2 + * bpc in between. */ + bpp = pipe_config->pipe_bpp; +- +- /* +- * eDP panels are really fickle, try to enfore the bpp the firmware +- * recomments. This means we'll up-dither 16bpp framebuffers on +- * high-depth panels. +- */ +- if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp) { +- DRM_DEBUG_KMS("forcing bpp for eDP panel to BIOS-provided %i\n", +- dev_priv->vbt.edp_bpp); +- bpp = dev_priv->vbt.edp_bpp; +- } ++ if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp) ++ bpp = min_t(int, bpp, dev_priv->vbt.edp_bpp); + + for (; bpp >= 6*3; bpp -= 2*3) { + mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0281-drm-i915-Disable-primary-plane-trickle-feed-for-g4x.patch b/patches.baytrail/0281-drm-i915-Disable-primary-plane-trickle-feed-for-g4x.patch new file mode 100644 index 000000000000..1895d87e8790 --- /dev/null +++ b/patches.baytrail/0281-drm-i915-Disable-primary-plane-trickle-feed-for-g4x.patch @@ -0,0 +1,68 @@ +From 4b09d64485596ba706a226e2c3dc4d8bf7a787b0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 7 Jun 2013 10:47:01 +0300 +Subject: drm/i915: Disable primary plane trickle feed for g4x +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The docs say that the trickle feed disable bit is present (for primary +planes only, not video sprites) on CTG, and that it must be set +for ELK. Just set it for all g4x chipsets. + +v2: Do it in init_clock_gating too + +Reviewed-by: Chris Wilson +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit de1aa629aac8377bdfc55674bb8e30b5f15f418d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 3 +++ + drivers/gpu/drm/i915/intel_pm.c | 9 +++++++++ + 2 files changed, 12 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index b8851f3f4911..0e697bda5dab 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1958,6 +1958,9 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, + dspcntr &= ~DISPPLANE_TILED; + } + ++ if (IS_G4X(dev)) ++ dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; ++ + I915_WRITE(reg, dspcntr); + + linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index e3aa054417d6..af6c0d15d896 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4908,6 +4908,7 @@ static void g4x_init_clock_gating(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t dspclk_gate; ++ int pipe; + + I915_WRITE(RENCLK_GATE_D1, 0); + I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | +@@ -4924,6 +4925,14 @@ static void g4x_init_clock_gating(struct drm_device *dev) + /* WaDisableRenderCachePipelinedFlush */ + I915_WRITE(CACHE_MODE_0, + _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE)); ++ ++ for_each_pipe(pipe) { ++ I915_WRITE(DSPCNTR(pipe), ++ I915_READ(DSPCNTR(pipe)) | ++ DISPPLANE_TRICKLE_FEED_DISABLE); ++ intel_flush_display_plane(dev_priv, pipe); ++ } ++ + } + + static void crestline_init_clock_gating(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0282-drm-i915-Disable-trickle-feed-via-MI_ARB_STATE-for-t.patch b/patches.baytrail/0282-drm-i915-Disable-trickle-feed-via-MI_ARB_STATE-for-t.patch new file mode 100644 index 000000000000..05880d9a6a70 --- /dev/null +++ b/patches.baytrail/0282-drm-i915-Disable-trickle-feed-via-MI_ARB_STATE-for-t.patch @@ -0,0 +1,48 @@ +From d7aa5286201c7c2b61ae4da25355314084d4645c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 7 Jun 2013 10:47:02 +0300 +Subject: drm/i915: Disable trickle feed via MI_ARB_STATE for the gen4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +According to BSpec, trickle feed should be disabled for BW and +mobile CL. Those constraints seem to match all of our gen4 chipsets. + +Trickle feed is disabled via the MI_ARB_STATE register instead of +per plane controls on gen4. + +Reviewed-by: Chris Wilson +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 20f949670f51341f255b17ec4650fa69ba22cb87) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index af6c0d15d896..d1e2e68edeb7 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4944,6 +4944,8 @@ static void crestline_init_clock_gating(struct drm_device *dev) + I915_WRITE(DSPCLK_GATE_D, 0); + I915_WRITE(RAMCLK_GATE_D, 0); + I915_WRITE16(DEUC, 0); ++ I915_WRITE(MI_ARB_STATE, ++ _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); + } + + static void broadwater_init_clock_gating(struct drm_device *dev) +@@ -4956,6 +4958,8 @@ static void broadwater_init_clock_gating(struct drm_device *dev) + I965_ISC_CLOCK_GATE_DISABLE | + I965_FBC_CLOCK_GATE_DISABLE); + I915_WRITE(RENCLK_GATE_D2, 0); ++ I915_WRITE(MI_ARB_STATE, ++ _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); + } + + static void gen3_init_clock_gating(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0283-drm-i915-Disable-trickle-feed-in-ironlake_init_clock.patch b/patches.baytrail/0283-drm-i915-Disable-trickle-feed-in-ironlake_init_clock.patch new file mode 100644 index 000000000000..3f3198e5e5a6 --- /dev/null +++ b/patches.baytrail/0283-drm-i915-Disable-trickle-feed-in-ironlake_init_clock.patch @@ -0,0 +1,50 @@ +From 3993bfbeb68026e9a7bb7148bd6ad1386b243bc9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 7 Jun 2013 10:47:03 +0300 +Subject: drm/i915: Disable trickle feed in ironlake_init_clock_gating() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We disable trickle feed in all the (relevant) clock gating functions, +except ironlake_init_clock_gating(). Copy paste the same code there as +well. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit bdad2b2f31852af4eb450d6a96e38940a0a1fdef) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index d1e2e68edeb7..6b9718ef6266 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4391,6 +4391,7 @@ static void ironlake_init_clock_gating(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; ++ int pipe; + + /* Required for FBC */ + dspclk_gate |= ILK_DPFCRUNIT_CLOCK_GATE_DISABLE | +@@ -4450,6 +4451,13 @@ static void ironlake_init_clock_gating(struct drm_device *dev) + I915_WRITE(CACHE_MODE_0, + _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE)); + ++ for_each_pipe(pipe) { ++ I915_WRITE(DSPCNTR(pipe), ++ I915_READ(DSPCNTR(pipe)) | ++ DISPPLANE_TRICKLE_FEED_DISABLE); ++ intel_flush_display_plane(dev_priv, pipe); ++ } ++ + ibx_init_clock_gating(dev); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0284-drm-i915-Refactor-ctg-trickle-feed-disable.patch b/patches.baytrail/0284-drm-i915-Refactor-ctg-trickle-feed-disable.patch new file mode 100644 index 000000000000..377f81712255 --- /dev/null +++ b/patches.baytrail/0284-drm-i915-Refactor-ctg-trickle-feed-disable.patch @@ -0,0 +1,177 @@ +From 737c37212b1b3f98e929ef03a20b7d49ceef4e81 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 7 Jun 2013 10:47:04 +0300 +Subject: drm/i915: Refactor ctg+ trickle feed disable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Pull the code to disable trickle feed for all primary planes into a +separate function. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 0e088b8f33dab39bd8beb0c7a030d44beb936dd0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 62 +++++++++++++---------------------------- + 1 file changed, 19 insertions(+), 43 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 6b9718ef6266..b5959c49a6f4 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4387,11 +4387,23 @@ static void ibx_init_clock_gating(struct drm_device *dev) + I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); + } + ++static void g4x_disable_trickle_feed(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int pipe; ++ ++ for_each_pipe(pipe) { ++ I915_WRITE(DSPCNTR(pipe), ++ I915_READ(DSPCNTR(pipe)) | ++ DISPPLANE_TRICKLE_FEED_DISABLE); ++ intel_flush_display_plane(dev_priv, pipe); ++ } ++} ++ + static void ironlake_init_clock_gating(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; +- int pipe; + + /* Required for FBC */ + dspclk_gate |= ILK_DPFCRUNIT_CLOCK_GATE_DISABLE | +@@ -4451,12 +4463,7 @@ static void ironlake_init_clock_gating(struct drm_device *dev) + I915_WRITE(CACHE_MODE_0, + _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE)); + +- for_each_pipe(pipe) { +- I915_WRITE(DSPCNTR(pipe), +- I915_READ(DSPCNTR(pipe)) | +- DISPPLANE_TRICKLE_FEED_DISABLE); +- intel_flush_display_plane(dev_priv, pipe); +- } ++ g4x_disable_trickle_feed(dev); + + ibx_init_clock_gating(dev); + } +@@ -4512,7 +4519,6 @@ static void gen6_check_mch_setup(struct drm_device *dev) + static void gen6_init_clock_gating(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- int pipe; + uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; + + I915_WRITE(ILK_DSPCLK_GATE_D, dspclk_gate); +@@ -4588,12 +4594,7 @@ static void gen6_init_clock_gating(struct drm_device *dev) + I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | + GEN6_MBCTL_ENABLE_BOOT_FETCH); + +- for_each_pipe(pipe) { +- I915_WRITE(DSPCNTR(pipe), +- I915_READ(DSPCNTR(pipe)) | +- DISPPLANE_TRICKLE_FEED_DISABLE); +- intel_flush_display_plane(dev_priv, pipe); +- } ++ g4x_disable_trickle_feed(dev); + + /* The default value should be 0x200 according to docs, but the two + * platforms I checked have a 0 for this. (Maybe BIOS overrides?) */ +@@ -4654,7 +4655,6 @@ static void lpt_suspend_hw(struct drm_device *dev) + static void haswell_init_clock_gating(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- int pipe; + + I915_WRITE(WM3_LP_ILK, 0); + I915_WRITE(WM2_LP_ILK, 0); +@@ -4680,12 +4680,7 @@ static void haswell_init_clock_gating(struct drm_device *dev) + I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | + GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); + +- for_each_pipe(pipe) { +- I915_WRITE(DSPCNTR(pipe), +- I915_READ(DSPCNTR(pipe)) | +- DISPPLANE_TRICKLE_FEED_DISABLE); +- intel_flush_display_plane(dev_priv, pipe); +- } ++ g4x_disable_trickle_feed(dev); + + /* WaVSRefCountFullforceMissDisable:hsw */ + gen7_setup_fixed_func_scheduler(dev_priv); +@@ -4711,7 +4706,6 @@ static void haswell_init_clock_gating(struct drm_device *dev) + static void ivybridge_init_clock_gating(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- int pipe; + uint32_t snpcr; + + I915_WRITE(WM3_LP_ILK, 0); +@@ -4780,12 +4774,7 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) + I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | + GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); + +- for_each_pipe(pipe) { +- I915_WRITE(DSPCNTR(pipe), +- I915_READ(DSPCNTR(pipe)) | +- DISPPLANE_TRICKLE_FEED_DISABLE); +- intel_flush_display_plane(dev_priv, pipe); +- } ++ g4x_disable_trickle_feed(dev); + + /* WaMbcDriverBootEnable:ivb */ + I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | +@@ -4812,7 +4801,6 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) + static void valleyview_init_clock_gating(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- int pipe; + + I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); + +@@ -4885,12 +4873,7 @@ static void valleyview_init_clock_gating(struct drm_device *dev) + + I915_WRITE(GEN7_UCGCTL4, GEN7_L3BANK2X_CLOCK_GATE_DISABLE); + +- for_each_pipe(pipe) { +- I915_WRITE(DSPCNTR(pipe), +- I915_READ(DSPCNTR(pipe)) | +- DISPPLANE_TRICKLE_FEED_DISABLE); +- intel_flush_display_plane(dev_priv, pipe); +- } ++ g4x_disable_trickle_feed(dev); + + I915_WRITE(CACHE_MODE_1, + _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); +@@ -4916,7 +4899,6 @@ static void g4x_init_clock_gating(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t dspclk_gate; +- int pipe; + + I915_WRITE(RENCLK_GATE_D1, 0); + I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | +@@ -4934,13 +4916,7 @@ static void g4x_init_clock_gating(struct drm_device *dev) + I915_WRITE(CACHE_MODE_0, + _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE)); + +- for_each_pipe(pipe) { +- I915_WRITE(DSPCNTR(pipe), +- I915_READ(DSPCNTR(pipe)) | +- DISPPLANE_TRICKLE_FEED_DISABLE); +- intel_flush_display_plane(dev_priv, pipe); +- } +- ++ g4x_disable_trickle_feed(dev); + } + + static void crestline_init_clock_gating(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0285-drm-i915-Track-when-we-dirty-the-scanout-with-render.patch b/patches.baytrail/0285-drm-i915-Track-when-we-dirty-the-scanout-with-render.patch new file mode 100644 index 000000000000..8e3397ad0d8b --- /dev/null +++ b/patches.baytrail/0285-drm-i915-Track-when-we-dirty-the-scanout-with-render.patch @@ -0,0 +1,100 @@ +From 1bf78c2350823f98ee9e5ed70c517805b80fae03 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Thu, 6 Jun 2013 16:53:41 -0300 +Subject: drm/i915: Track when we dirty the scanout with render commands + +This is required for tracking render damage for use with FBC and will be +used in subsequent patches. + +Signed-off-by: Chris Wilson +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit c65355bbefaf02d8819a810aacfd566634e3b146) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- + drivers/gpu/drm/i915/intel_display.c | 13 +++++++++---- + drivers/gpu/drm/i915/intel_drv.h | 3 ++- + drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + + 4 files changed, 13 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index a8bb62ca8756..c98333d74111 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -786,7 +786,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects, + obj->dirty = 1; + obj->last_write_seqno = intel_ring_get_seqno(ring); + if (obj->pin_count) /* check for potential scanout */ +- intel_mark_fb_busy(obj); ++ intel_mark_fb_busy(obj, ring); + } + + trace_i915_gem_object_change_domain(obj, old_read, old_write); +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 0e697bda5dab..ddc8eea42b19 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -7116,7 +7116,8 @@ void intel_mark_idle(struct drm_device *dev) + } + } + +-void intel_mark_fb_busy(struct drm_i915_gem_object *obj) ++void intel_mark_fb_busy(struct drm_i915_gem_object *obj, ++ struct intel_ring_buffer *ring) + { + struct drm_device *dev = obj->base.dev; + struct drm_crtc *crtc; +@@ -7128,8 +7129,12 @@ void intel_mark_fb_busy(struct drm_i915_gem_object *obj) + if (!crtc->fb) + continue; + +- if (to_intel_framebuffer(crtc->fb)->obj == obj) +- intel_increase_pllclock(crtc); ++ if (to_intel_framebuffer(crtc->fb)->obj != obj) ++ continue; ++ ++ intel_increase_pllclock(crtc); ++ if (ring && intel_fbc_enabled(dev)) ++ ring->fbc_dirty = true; + } + } + +@@ -7579,7 +7584,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, + goto cleanup_pending; + + intel_disable_fbc(dev); +- intel_mark_fb_busy(obj); ++ intel_mark_fb_busy(obj, NULL); + mutex_unlock(&dev->struct_mutex); + + trace_i915_flip_request(intel_crtc->plane, obj); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index a060d82f175b..259a6873aacc 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -574,7 +574,8 @@ extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, + extern void intel_dvo_init(struct drm_device *dev); + extern void intel_tv_init(struct drm_device *dev); + extern void intel_mark_busy(struct drm_device *dev); +-extern void intel_mark_fb_busy(struct drm_i915_gem_object *obj); ++extern void intel_mark_fb_busy(struct drm_i915_gem_object *obj, ++ struct intel_ring_buffer *ring); + extern void intel_mark_idle(struct drm_device *dev); + extern bool intel_lvds_init(struct drm_device *dev); + extern bool intel_is_dual_link_lvds(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index 4c7e103e6fa4..efc403d1e3e0 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -140,6 +140,7 @@ struct intel_ring_buffer { + */ + u32 outstanding_lazy_request; + bool gpu_caches_dirty; ++ bool fbc_dirty; + + wait_queue_head_t irq_queue; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0286-drm-i915-WA-FBC-Render-Nuke.patch b/patches.baytrail/0286-drm-i915-WA-FBC-Render-Nuke.patch new file mode 100644 index 000000000000..cf36c5897702 --- /dev/null +++ b/patches.baytrail/0286-drm-i915-WA-FBC-Render-Nuke.patch @@ -0,0 +1,136 @@ +From 68449b3aaa8c55dd83dc7f21f0c2496238961987 Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Thu, 6 Jun 2013 16:58:16 -0300 +Subject: drm/i915: WA: FBC Render Nuke. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +WaFbcNukeOn3DBlt for IVB, HSW. + +According BSPec: "Workaround: Do not enable Render Command Streamer tracking for FBC. +Instead insert a LRI to address 0x50380 with data 0x00000004 after the PIPE_CONTROL that +follows each render submission." + +v2: Chris noticed that flush_domains check was missing here and also suggested to do + LRI only when fbc is enabled. To avoid do a I915_READ on every flush lets use the + module parameter check. + +v3: Adding Wa name as Damien suggested. + +v4: Ville noticed VLV doesn't support fbc at all and comment came wrong from spec. + +v5: Ville noticed than on blt a Cache Clean LRI should be used instead the Nuke one. + +v6: Check for flush domain on blt (by Ville). + Check for scanout dirty (by Chris). + +v7: Apply proper fbc_dirty implemented by Chris. + +v8: remove unused variables. + +Cc: Ville Syrjälä +Cc: Chris Wilson +Signed-off-by: Rodrigo Vivi +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit fd3da6c95b6d865446fa9b29df6edff4343e385a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 4 ++++ + drivers/gpu/drm/i915/intel_pm.c | 2 +- + drivers/gpu/drm/i915/intel_ringbuffer.c | 29 +++++++++++++++++++++++++++++ + 3 files changed, 34 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 65547c1f1001..225a28d67060 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -1022,6 +1022,10 @@ + #define IPS_CTL 0x43408 + #define IPS_ENABLE (1 << 31) + ++#define MSG_FBC_REND_STATE 0x50380 ++#define FBC_REND_NUKE (1<<2) ++#define FBC_REND_CACHE_CLEAN (1<<1) ++ + #define _HSW_PIPE_SLICE_CHICKEN_1_A 0x420B0 + #define _HSW_PIPE_SLICE_CHICKEN_1_B 0x420B4 + #define HSW_BYPASS_FBC_QUEUE (1<<22) +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index b5959c49a6f4..681699671893 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -274,7 +274,7 @@ static void gen7_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + struct drm_i915_gem_object *obj = intel_fb->obj; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + +- I915_WRITE(IVB_FBC_RT_BASE, obj->gtt_offset | ILK_FBC_RT_VALID); ++ I915_WRITE(IVB_FBC_RT_BASE, obj->gtt_offset); + + I915_WRITE(ILK_DPFC_CONTROL, DPFC_CTL_EN | DPFC_CTL_LIMIT_1X | + IVB_DPFC_CTL_FENCE_EN | +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index cd2daf2f5dd7..07a949c042f2 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -280,6 +280,27 @@ gen7_render_ring_cs_stall_wa(struct intel_ring_buffer *ring) + return 0; + } + ++static int gen7_ring_fbc_flush(struct intel_ring_buffer *ring, u32 value) ++{ ++ int ret; ++ ++ if (!ring->fbc_dirty) ++ return 0; ++ ++ ret = intel_ring_begin(ring, 4); ++ if (ret) ++ return ret; ++ intel_ring_emit(ring, MI_NOOP); ++ /* WaFbcNukeOn3DBlt:ivb/hsw */ ++ intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); ++ intel_ring_emit(ring, MSG_FBC_REND_STATE); ++ intel_ring_emit(ring, value); ++ intel_ring_advance(ring); ++ ++ ring->fbc_dirty = false; ++ return 0; ++} ++ + static int + gen7_render_ring_flush(struct intel_ring_buffer *ring, + u32 invalidate_domains, u32 flush_domains) +@@ -336,6 +357,9 @@ gen7_render_ring_flush(struct intel_ring_buffer *ring, + intel_ring_emit(ring, 0); + intel_ring_advance(ring); + ++ if (flush_domains) ++ return gen7_ring_fbc_flush(ring, FBC_REND_NUKE); ++ + return 0; + } + +@@ -1696,6 +1720,7 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, + static int gen6_ring_flush(struct intel_ring_buffer *ring, + u32 invalidate, u32 flush) + { ++ struct drm_device *dev = ring->dev; + uint32_t cmd; + int ret; + +@@ -1718,6 +1743,10 @@ static int gen6_ring_flush(struct intel_ring_buffer *ring, + intel_ring_emit(ring, 0); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); ++ ++ if (IS_GEN7(dev) && flush) ++ return gen7_ring_fbc_flush(ring, FBC_REND_CACHE_CLEAN); ++ + return 0; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0287-drm-i915-Make-g4x_fixup_plane-operational-again.patch b/patches.baytrail/0287-drm-i915-Make-g4x_fixup_plane-operational-again.patch new file mode 100644 index 000000000000..66d8d7197f85 --- /dev/null +++ b/patches.baytrail/0287-drm-i915-Make-g4x_fixup_plane-operational-again.patch @@ -0,0 +1,58 @@ +From 9b607b4b4d58ea16c1cc333882e8147d7bd6fe18 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 7 Jun 2013 18:52:24 +0300 +Subject: drm/i915: Make g4x_fixup_plane() operational again +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Don't enable the cursor until g4x_fixup_plane() had a chance to do +cast its magic spell. + +Egbert writes: +"Today I had the chance to test this. First I tried + if I can still reproduce the blank with this patch + added when I disable my voodoo g4x_fixup_plane(): + It turned out it still happens however very rarely + (like 1 out of 20 tries). When I reenabled my voodoo + the issue still occurred. + I had to switch two lines around, ie: + + intel_enable_plane(dev_priv, plane, pipe); + if (IS_G4X(dev)) + g4x_fixup_plane(dev_priv, pipe); + + intel_crtc_update_cursor(crtc, true); + + to avoid the blank screen issue - which is it didn't + happen in ~75 tries." + +v2: Add a comment to remind people of the ordering constraints + +Acked-by: Egbert Eich +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 22e407d749a418b4bb4cc93ef76e0429a9f83c82) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index ddc8eea42b19..8927b3fb1982 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3700,9 +3700,10 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) + intel_enable_pipe(dev_priv, pipe, false); + intel_enable_plane(dev_priv, plane, pipe); + intel_enable_planes(crtc); +- intel_crtc_update_cursor(crtc, true); ++ /* The fixup needs to happen before cursor is enabled */ + if (IS_G4X(dev)) + g4x_fixup_plane(dev_priv, pipe); ++ intel_crtc_update_cursor(crtc, true); + + /* Give the overlay scaler a chance to enable if it's on this pipe */ + intel_crtc_dpms_overlay(intel_crtc, true); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0288-drm-i915-Remove-dead-code-from-SDVO-initialisation.patch b/patches.baytrail/0288-drm-i915-Remove-dead-code-from-SDVO-initialisation.patch new file mode 100644 index 000000000000..2a9959288699 --- /dev/null +++ b/patches.baytrail/0288-drm-i915-Remove-dead-code-from-SDVO-initialisation.patch @@ -0,0 +1,53 @@ +From 8181e51dcbe56fc572c292e5e4aaed8a9aa4bdf3 Mon Sep 17 00:00:00 2001 +From: James Ausmus +Date: Mon, 23 Sep 2013 16:53:57 -0700 +Subject: drm/i915: Remove dead code from SDVO initialisation + +The hotplug_mask is no longer used as the hpd interrupt setup is now +handled in the core. + +Signed-off-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit e596a02ccfc6503ae5c37b14c74b6b743eefe102) + +Conflicts: + drivers/gpu/drm/i915/intel_sdvo.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sdvo.c | 13 ------------- + 1 file changed, 13 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 1262fc4a1b34..5c53fc79977a 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -2850,7 +2850,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_encoder *intel_encoder; + struct intel_sdvo *intel_sdvo; +- u32 hotplug_mask; + int i; + intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); + if (!intel_sdvo) +@@ -2879,18 +2878,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) + } + } + +- hotplug_mask = 0; +- if (IS_G4X(dev)) { +- hotplug_mask = intel_sdvo->is_sdvob ? +- SDVOB_HOTPLUG_INT_STATUS_G4X : SDVOC_HOTPLUG_INT_STATUS_G4X; +- } else if (IS_GEN4(dev)) { +- hotplug_mask = intel_sdvo->is_sdvob ? +- SDVOB_HOTPLUG_INT_STATUS_I965 : SDVOC_HOTPLUG_INT_STATUS_I965; +- } else { +- hotplug_mask = intel_sdvo->is_sdvob ? +- SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915; +- } +- + intel_encoder->compute_config = intel_sdvo_compute_config; + intel_encoder->disable = intel_disable_sdvo; + intel_encoder->mode_set = intel_sdvo_mode_set; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0289-drm-i915-Use-FBINFO_STATE-defines-instead-of-0-and-1.patch b/patches.baytrail/0289-drm-i915-Use-FBINFO_STATE-defines-instead-of-0-and-1.patch new file mode 100644 index 000000000000..d16b8accf51a --- /dev/null +++ b/patches.baytrail/0289-drm-i915-Use-FBINFO_STATE-defines-instead-of-0-and-1.patch @@ -0,0 +1,65 @@ +From 03a5ee0baf3d7ec0d492a368ee97098b729ccb4e Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 10 Jun 2013 15:48:09 +0100 +Subject: drm/i915: Use FBINFO_STATE defines instead of 0 and 1 + +This makes, arguably, the condition on state easier to read. + +Suggested-by: Chris Wilson +Signed-off-by: Damien Lespiau +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit b6f3eff7130bbdb3d3ca5b7bbff2384b362606b4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 6 +++--- + drivers/gpu/drm/i915/intel_fb.c | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 4ae308e845d4..0b1edad2b4df 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -570,7 +570,7 @@ static int i915_drm_freeze(struct drm_device *dev) + intel_opregion_fini(dev); + + console_lock(); +- intel_fbdev_set_suspend(dev, 1); ++ intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED); + console_unlock(); + + return 0; +@@ -614,7 +614,7 @@ void intel_console_resume(struct work_struct *work) + struct drm_device *dev = dev_priv->dev; + + console_lock(); +- intel_fbdev_set_suspend(dev, 0); ++ intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING); + console_unlock(); + } + +@@ -683,7 +683,7 @@ static int __i915_drm_thaw(struct drm_device *dev) + * path of resume if possible. + */ + if (console_trylock()) { +- intel_fbdev_set_suspend(dev, 0); ++ intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING); + console_unlock(); + } else { + schedule_work(&dev_priv->console_resume_work); +diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c +index 7f3ac54b56e9..dff669e2387f 100644 +--- a/drivers/gpu/drm/i915/intel_fb.c ++++ b/drivers/gpu/drm/i915/intel_fb.c +@@ -275,7 +275,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state) + * been restored from swap. If the object is stolen however, it will be + * full of whatever garbage was left in there. + */ +- if (!state && ifbdev->ifb.obj->stolen) ++ if (state == FBINFO_STATE_RUNNING && ifbdev->ifb.obj->stolen) + memset_io(info->screen_base, 0, info->screen_size); + + fb_set_suspend(info, state); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0290-drm-i915-fix-up-pch-pll-handling-in-mode_set.patch b/patches.baytrail/0290-drm-i915-fix-up-pch-pll-handling-in-mode_set.patch new file mode 100644 index 000000000000..b42705bfe447 --- /dev/null +++ b/patches.baytrail/0290-drm-i915-fix-up-pch-pll-handling-in-mode_set.patch @@ -0,0 +1,103 @@ +From 35cb46d950d8e9a098f6b2cb5eb24c5d7c1e3f46 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:03 +0200 +Subject: drm/i915: fix up pch pll handling in ->mode_set +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We ->mode_set is called we can't just blindly reuse an existing pll +since that might be shared with a different, still active pch output. + +v2: Only update the pll settings when the pch pll is know to be +unused, otherwise we can wreak havoc with a running pipe. Which in the +case of DP will likely result in a black screen due to loss of link +lock. + +v3: Tighten up the asserts a bit more, especially make sure that the +pch pll is still enabled when we try to disable it. This would have +caught the bug fixed in this patch. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit cdbd2316a03f68b25a135a34d1d24f01ddef0c53) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 35 +++++++++++++++++++---------------- + 1 file changed, 19 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 8927b3fb1982..89722233ad8b 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1427,7 +1427,8 @@ static void ironlake_enable_pch_pll(struct intel_crtc *intel_crtc) + /* PCH refclock must be enabled first */ + assert_pch_refclk_enabled(dev_priv); + +- if (pll->active++ && pll->on) { ++ if (pll->active++) { ++ WARN_ON(!pll->on); + assert_pch_pll_enabled(dev_priv, pll, NULL); + return; + } +@@ -1468,10 +1469,9 @@ static void intel_disable_pch_pll(struct intel_crtc *intel_crtc) + return; + } + +- if (--pll->active) { +- assert_pch_pll_enabled(dev_priv, pll, NULL); ++ assert_pch_pll_enabled(dev_priv, pll, NULL); ++ if (--pll->active) + return; +- } + + DRM_DEBUG_KMS("disabling PCH PLL %x\n", pll->pll_reg); + +@@ -3081,9 +3081,9 @@ static struct intel_pch_pll *intel_get_pch_pll(struct intel_crtc *intel_crtc, u3 + + pll = intel_crtc->pch_pll; + if (pll) { +- DRM_DEBUG_KMS("CRTC:%d reusing existing PCH PLL %x\n", ++ DRM_DEBUG_KMS("CRTC:%d dropping existing PCH PLL %x\n", + intel_crtc->base.base.id, pll->pll_reg); +- goto prepare; ++ intel_put_pch_pll(intel_crtc); + } + + if (HAS_PCH_IBX(dev_priv->dev)) { +@@ -3128,19 +3128,22 @@ static struct intel_pch_pll *intel_get_pch_pll(struct intel_crtc *intel_crtc, u3 + + found: + intel_crtc->pch_pll = pll; +- pll->refcount++; + DRM_DEBUG_DRIVER("using pll %d for pipe %c\n", i, pipe_name(intel_crtc->pipe)); +-prepare: /* separate function? */ +- DRM_DEBUG_DRIVER("switching PLL %x off\n", pll->pll_reg); ++ if (pll->active == 0) { ++ DRM_DEBUG_DRIVER("setting up pll %d\n", i); ++ WARN_ON(pll->on); ++ assert_pch_pll_disabled(dev_priv, pll, NULL); + +- /* Wait for the clocks to stabilize before rewriting the regs */ +- I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE); +- POSTING_READ(pll->pll_reg); +- udelay(150); ++ /* Wait for the clocks to stabilize before rewriting the regs */ ++ I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE); ++ POSTING_READ(pll->pll_reg); ++ udelay(150); ++ ++ I915_WRITE(pll->fp0_reg, fp); ++ I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE); ++ } ++ pll->refcount++; + +- I915_WRITE(pll->fp0_reg, fp); +- I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE); +- pll->on = false; + return pll; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0291-drm-i915-conditionally-disable-pch-resources-in-ilk_.patch b/patches.baytrail/0291-drm-i915-conditionally-disable-pch-resources-in-ilk_.patch new file mode 100644 index 000000000000..d130c2aa459c --- /dev/null +++ b/patches.baytrail/0291-drm-i915-conditionally-disable-pch-resources-in-ilk_.patch @@ -0,0 +1,114 @@ +From 3194c15479a09ab1d6690c3caf98a5325fed8f4c Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:04 +0200 +Subject: drm/i915: conditionally disable pch resources in ilk_crtc_disable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Simlar to how disable already works on haswell. This is possible +since we now carefully track the pch state in the pipe config. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit d925c59a8174c8c150da7e0a38e35d89a8e7149c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 69 +++++++++++++++++++----------------- + 1 file changed, 37 insertions(+), 32 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 89722233ad8b..74412d011df9 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3436,7 +3436,9 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) + intel_disable_planes(crtc); + intel_disable_plane(dev_priv, plane, pipe); + +- intel_set_pch_fifo_underrun_reporting(dev, pipe, false); ++ if (intel_crtc->config.has_pch_encoder) ++ intel_set_pch_fifo_underrun_reporting(dev, pipe, false); ++ + intel_disable_pipe(dev_priv, pipe); + + ironlake_pfit_disable(intel_crtc); +@@ -3445,42 +3447,45 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) + if (encoder->post_disable) + encoder->post_disable(encoder); + +- ironlake_fdi_disable(crtc); ++ if (intel_crtc->config.has_pch_encoder) { ++ ironlake_fdi_disable(crtc); + +- ironlake_disable_pch_transcoder(dev_priv, pipe); +- intel_set_pch_fifo_underrun_reporting(dev, pipe, true); ++ ironlake_disable_pch_transcoder(dev_priv, pipe); ++ intel_set_pch_fifo_underrun_reporting(dev, pipe, true); + +- if (HAS_PCH_CPT(dev)) { +- /* disable TRANS_DP_CTL */ +- reg = TRANS_DP_CTL(pipe); +- temp = I915_READ(reg); +- temp &= ~(TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK); +- temp |= TRANS_DP_PORT_SEL_NONE; +- I915_WRITE(reg, temp); +- +- /* disable DPLL_SEL */ +- temp = I915_READ(PCH_DPLL_SEL); +- switch (pipe) { +- case 0: +- temp &= ~(TRANSA_DPLL_ENABLE | TRANSA_DPLLB_SEL); +- break; +- case 1: +- temp &= ~(TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); +- break; +- case 2: +- /* C shares PLL A or B */ +- temp &= ~(TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL); +- break; +- default: +- BUG(); /* wtf */ ++ if (HAS_PCH_CPT(dev)) { ++ /* disable TRANS_DP_CTL */ ++ reg = TRANS_DP_CTL(pipe); ++ temp = I915_READ(reg); ++ temp &= ~(TRANS_DP_OUTPUT_ENABLE | ++ TRANS_DP_PORT_SEL_MASK); ++ temp |= TRANS_DP_PORT_SEL_NONE; ++ I915_WRITE(reg, temp); ++ ++ /* disable DPLL_SEL */ ++ temp = I915_READ(PCH_DPLL_SEL); ++ switch (pipe) { ++ case 0: ++ temp &= ~(TRANSA_DPLL_ENABLE | TRANSA_DPLLB_SEL); ++ break; ++ case 1: ++ temp &= ~(TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); ++ break; ++ case 2: ++ /* C shares PLL A or B */ ++ temp &= ~(TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL); ++ break; ++ default: ++ BUG(); /* wtf */ ++ } ++ I915_WRITE(PCH_DPLL_SEL, temp); + } +- I915_WRITE(PCH_DPLL_SEL, temp); +- } + +- /* disable PCH DPLL */ +- intel_disable_pch_pll(intel_crtc); ++ /* disable PCH DPLL */ ++ intel_disable_pch_pll(intel_crtc); + +- ironlake_fdi_pll_disable(intel_crtc); ++ ironlake_fdi_pll_disable(intel_crtc); ++ } + + intel_crtc->active = false; + intel_update_watermarks(dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0292-drm-i915-lock-down-pch-pll-accouting-some-more.patch b/patches.baytrail/0292-drm-i915-lock-down-pch-pll-accouting-some-more.patch new file mode 100644 index 000000000000..ed5998689be4 --- /dev/null +++ b/patches.baytrail/0292-drm-i915-lock-down-pch-pll-accouting-some-more.patch @@ -0,0 +1,63 @@ +From 094f7d93b6fbf0bf5798b062ecc53d5d8c716d3d Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 10 Jun 2013 17:28:22 +0200 +Subject: drm/i915: lock down pch pll accouting some more +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Before I start to make a complete mess out of this, crank up +the paranoia level a bit. + +v2: Kill the has_pch_encoder check in put_shared_dpll - it's invalid +as spotted by Ville since we currently only put the dpll when we +already have the new pipe config. So a direct pch port -> cpu edp +transition will hit this. + +v3: Now that I've lifted my blinders add the WARN_ON Ville requested. + +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit f4a091c71baa55dc8822614ab716525779623c1c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 74412d011df9..7f0a7f763c5f 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1432,6 +1432,7 @@ static void ironlake_enable_pch_pll(struct intel_crtc *intel_crtc) + assert_pch_pll_enabled(dev_priv, pll, NULL); + return; + } ++ WARN_ON(pll->on); + + DRM_DEBUG_KMS("enabling PCH PLL %x\n", pll->pll_reg); + +@@ -1470,6 +1471,7 @@ static void intel_disable_pch_pll(struct intel_crtc *intel_crtc) + } + + assert_pch_pll_enabled(dev_priv, pll, NULL); ++ WARN_ON(!pll->on); + if (--pll->active) + return; + +@@ -3069,7 +3071,11 @@ static void intel_put_pch_pll(struct intel_crtc *intel_crtc) + return; + } + +- --pll->refcount; ++ if (--pll->refcount == 0) { ++ WARN_ON(pll->on); ++ WARN_ON(pll->active); ++ } ++ + intel_crtc->pch_pll = NULL; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0293-drm-i915-s-pch_pll-shared_dpll.patch b/patches.baytrail/0293-drm-i915-s-pch_pll-shared_dpll.patch new file mode 100644 index 000000000000..1905fdac5600 --- /dev/null +++ b/patches.baytrail/0293-drm-i915-s-pch_pll-shared_dpll.patch @@ -0,0 +1,471 @@ +From 59292ff786779ebd8774b94ba55c14c909bbe7e1 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:06 +0200 +Subject: drm/i915: s/pch_pll/shared_dpll/ +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For fastboot we need some support to read out the sharing state of +plls, at least for platforms where they can be shared (or freely +assigned at least). Now for ivb we already have pretty extensive +infrastructure for tracking pch plls, and it took us an aweful lot of +tries to get that remotely right. Note that hsw could also share plls, +but even now they're already freely assignable. So we need this on +more than just ivb. + +So on top of the usual fastboot fun pll sharing seems to be an +additional step up in fragility. Hence a common infrastructure for all +shared/freely assignable display plls seems to be in order. + +The plan is to have a bit of dpll hw state readout code, which can be +used individually, but also to fill in the pipe config. The hw state +cross check code will then use that information to make sure that +after every modeset every pipe still is connected to a pll which still +has the correct configuration - a lot of the pch pll sharing bugs +where due to incorrect sharing. + +We start this endeavour with a simple s/pch_pll/shared_dpll/ rename +job. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit e72f9fbf99c4277b2ccfd4d55d66aa6caf922f42) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 14 ++--- + drivers/gpu/drm/i915/i915_drv.h | 6 +- + drivers/gpu/drm/i915/intel_display.c | 112 +++++++++++++++++------------------ + drivers/gpu/drm/i915/intel_drv.h | 2 +- + 4 files changed, 67 insertions(+), 67 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 0b1edad2b4df..235749dba729 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -457,7 +457,7 @@ void intel_detect_pch(struct drm_device *dev) + */ + if (INTEL_INFO(dev)->num_pipes == 0) { + dev_priv->pch_type = PCH_NOP; +- dev_priv->num_pch_pll = 0; ++ dev_priv->num_shared_dpll = 0; + return; + } + +@@ -476,34 +476,34 @@ void intel_detect_pch(struct drm_device *dev) + + if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_IBX; +- dev_priv->num_pch_pll = 2; ++ dev_priv->num_shared_dpll = 2; + DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); + WARN_ON(!IS_GEN5(dev)); + } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_CPT; +- dev_priv->num_pch_pll = 2; ++ dev_priv->num_shared_dpll = 2; + DRM_DEBUG_KMS("Found CougarPoint PCH\n"); + WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); + } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { + /* PantherPoint is CPT compatible */ + dev_priv->pch_type = PCH_CPT; +- dev_priv->num_pch_pll = 2; ++ dev_priv->num_shared_dpll = 2; + DRM_DEBUG_KMS("Found PatherPoint PCH\n"); + WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); + } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_LPT; +- dev_priv->num_pch_pll = 0; ++ dev_priv->num_shared_dpll = 0; + DRM_DEBUG_KMS("Found LynxPoint PCH\n"); + WARN_ON(!IS_HASWELL(dev)); + WARN_ON(IS_ULT(dev)); + } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_LPT; +- dev_priv->num_pch_pll = 0; ++ dev_priv->num_shared_dpll = 0; + DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); + WARN_ON(!IS_HASWELL(dev)); + WARN_ON(!IS_ULT(dev)); + } +- BUG_ON(dev_priv->num_pch_pll > I915_NUM_PLLS); ++ BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS); + } + pci_dev_put(pch); + } +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index fec0c8f56e05..d46339018156 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -132,7 +132,7 @@ enum hpd_pin { + list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ + if ((intel_encoder)->base.crtc == (__crtc)) + +-struct intel_pch_pll { ++struct intel_shared_dpll { + int refcount; /* count of number of CRTCs sharing this PLL */ + int active; /* count of number of active CRTCs (i.e. DPMS on) */ + bool on; /* is the PLL actually active? Disabled during modeset */ +@@ -1027,7 +1027,6 @@ typedef struct drm_i915_private { + u32 hpd_event_bits; + struct timer_list hotplug_reenable_timer; + +- int num_pch_pll; + int num_plane; + + unsigned long cfb_size; +@@ -1088,7 +1087,8 @@ typedef struct drm_i915_private { + struct drm_crtc *pipe_to_crtc_mapping[3]; + wait_queue_head_t pending_flip_queue; + +- struct intel_pch_pll pch_plls[I915_NUM_PLLS]; ++ int num_shared_dpll; ++ struct intel_shared_dpll shared_dplls[I915_NUM_PLLS]; + struct intel_ddi_plls ddi_plls; + + /* Reclocking support */ +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 7f0a7f763c5f..2f2f68a9a6d3 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -910,10 +910,10 @@ static void assert_pll(struct drm_i915_private *dev_priv, + #define assert_pll_disabled(d, p) assert_pll(d, p, false) + + /* For ILK+ */ +-static void assert_pch_pll(struct drm_i915_private *dev_priv, +- struct intel_pch_pll *pll, +- struct intel_crtc *crtc, +- bool state) ++static void assert_shared_dpll(struct drm_i915_private *dev_priv, ++ struct intel_shared_dpll *pll, ++ struct intel_crtc *crtc, ++ bool state) + { + u32 val; + bool cur_state; +@@ -952,8 +952,8 @@ static void assert_pch_pll(struct drm_i915_private *dev_priv, + } + } + } +-#define assert_pch_pll_enabled(d, p, c) assert_pch_pll(d, p, c, true) +-#define assert_pch_pll_disabled(d, p, c) assert_pch_pll(d, p, c, false) ++#define assert_shared_dpll_enabled(d, p, c) assert_shared_dpll(d, p, c, true) ++#define assert_shared_dpll_disabled(d, p, c) assert_shared_dpll(d, p, c, false) + + static void assert_fdi_tx(struct drm_i915_private *dev_priv, + enum pipe pipe, bool state) +@@ -1397,23 +1397,23 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port) + } + + /** +- * ironlake_enable_pch_pll - enable PCH PLL ++ * ironlake_enable_shared_dpll - enable PCH PLL + * @dev_priv: i915 private structure + * @pipe: pipe PLL to enable + * + * The PCH PLL needs to be enabled before the PCH transcoder, since it + * drives the transcoder clock. + */ +-static void ironlake_enable_pch_pll(struct intel_crtc *intel_crtc) ++static void ironlake_enable_shared_dpll(struct intel_crtc *intel_crtc) + { + struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; +- struct intel_pch_pll *pll; ++ struct intel_shared_dpll *pll; + int reg; + u32 val; + + /* PCH PLLs only available on ILK, SNB and IVB */ + BUG_ON(dev_priv->info->gen < 5); +- pll = intel_crtc->pch_pll; ++ pll = intel_crtc->shared_dpll; + if (pll == NULL) + return; + +@@ -1429,7 +1429,7 @@ static void ironlake_enable_pch_pll(struct intel_crtc *intel_crtc) + + if (pll->active++) { + WARN_ON(!pll->on); +- assert_pch_pll_enabled(dev_priv, pll, NULL); ++ assert_shared_dpll_enabled(dev_priv, pll, NULL); + return; + } + WARN_ON(pll->on); +@@ -1446,10 +1446,10 @@ static void ironlake_enable_pch_pll(struct intel_crtc *intel_crtc) + pll->on = true; + } + +-static void intel_disable_pch_pll(struct intel_crtc *intel_crtc) ++static void intel_disable_shared_dpll(struct intel_crtc *intel_crtc) + { + struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; +- struct intel_pch_pll *pll = intel_crtc->pch_pll; ++ struct intel_shared_dpll *pll = intel_crtc->shared_dpll; + int reg; + u32 val; + +@@ -1466,11 +1466,11 @@ static void intel_disable_pch_pll(struct intel_crtc *intel_crtc) + intel_crtc->base.base.id); + + if (WARN_ON(pll->active == 0)) { +- assert_pch_pll_disabled(dev_priv, pll, NULL); ++ assert_shared_dpll_disabled(dev_priv, pll, NULL); + return; + } + +- assert_pch_pll_enabled(dev_priv, pll, NULL); ++ assert_shared_dpll_enabled(dev_priv, pll, NULL); + WARN_ON(!pll->on); + if (--pll->active) + return; +@@ -1501,9 +1501,9 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, + BUG_ON(dev_priv->info->gen < 5); + + /* Make sure PCH DPLL is enabled */ +- assert_pch_pll_enabled(dev_priv, +- to_intel_crtc(crtc)->pch_pll, +- to_intel_crtc(crtc)); ++ assert_shared_dpll_enabled(dev_priv, ++ to_intel_crtc(crtc)->shared_dpll, ++ to_intel_crtc(crtc)); + + /* FDI must be feeding us bits for PCH ports */ + assert_fdi_tx_enabled(dev_priv, pipe); +@@ -2966,10 +2966,10 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) + * transcoder, and we actually should do this to not upset any PCH + * transcoder that already use the clock when we share it. + * +- * Note that enable_pch_pll tries to do the right thing, but get_pch_pll +- * unconditionally resets the pll - we need that to have the right LVDS +- * enable sequence. */ +- ironlake_enable_pch_pll(intel_crtc); ++ * Note that enable_shared_dpll tries to do the right thing, but ++ * get_shared_dpll unconditionally resets the pll - we need that to have ++ * the right LVDS enable sequence. */ ++ ironlake_enable_shared_dpll(intel_crtc); + + if (HAS_PCH_CPT(dev)) { + u32 sel; +@@ -2990,7 +2990,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) + sel = TRANSC_DPLLB_SEL; + break; + } +- if (intel_crtc->pch_pll->pll_reg == _PCH_DPLL_B) ++ if (intel_crtc->shared_dpll->pll_reg == _PCH_DPLL_B) + temp |= sel; + else + temp &= ~sel; +@@ -3059,9 +3059,9 @@ static void lpt_pch_enable(struct drm_crtc *crtc) + lpt_enable_pch_transcoder(dev_priv, cpu_transcoder); + } + +-static void intel_put_pch_pll(struct intel_crtc *intel_crtc) ++static void intel_put_shared_dpll(struct intel_crtc *intel_crtc) + { +- struct intel_pch_pll *pll = intel_crtc->pch_pll; ++ struct intel_shared_dpll *pll = intel_crtc->shared_dpll; + + if (pll == NULL) + return; +@@ -3076,26 +3076,26 @@ static void intel_put_pch_pll(struct intel_crtc *intel_crtc) + WARN_ON(pll->active); + } + +- intel_crtc->pch_pll = NULL; ++ intel_crtc->shared_dpll = NULL; + } + +-static struct intel_pch_pll *intel_get_pch_pll(struct intel_crtc *intel_crtc, u32 dpll, u32 fp) ++static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *intel_crtc, u32 dpll, u32 fp) + { + struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; +- struct intel_pch_pll *pll; ++ struct intel_shared_dpll *pll; + int i; + +- pll = intel_crtc->pch_pll; ++ pll = intel_crtc->shared_dpll; + if (pll) { + DRM_DEBUG_KMS("CRTC:%d dropping existing PCH PLL %x\n", + intel_crtc->base.base.id, pll->pll_reg); +- intel_put_pch_pll(intel_crtc); ++ intel_put_shared_dpll(intel_crtc); + } + + if (HAS_PCH_IBX(dev_priv->dev)) { + /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ + i = intel_crtc->pipe; +- pll = &dev_priv->pch_plls[i]; ++ pll = &dev_priv->shared_dplls[i]; + + DRM_DEBUG_KMS("CRTC:%d using pre-allocated PCH PLL %x\n", + intel_crtc->base.base.id, pll->pll_reg); +@@ -3103,8 +3103,8 @@ static struct intel_pch_pll *intel_get_pch_pll(struct intel_crtc *intel_crtc, u3 + goto found; + } + +- for (i = 0; i < dev_priv->num_pch_pll; i++) { +- pll = &dev_priv->pch_plls[i]; ++ for (i = 0; i < dev_priv->num_shared_dpll; i++) { ++ pll = &dev_priv->shared_dplls[i]; + + /* Only want to check enabled timings first */ + if (pll->refcount == 0) +@@ -3121,8 +3121,8 @@ static struct intel_pch_pll *intel_get_pch_pll(struct intel_crtc *intel_crtc, u3 + } + + /* Ok no matching timings, maybe there's a free one? */ +- for (i = 0; i < dev_priv->num_pch_pll; i++) { +- pll = &dev_priv->pch_plls[i]; ++ for (i = 0; i < dev_priv->num_shared_dpll; i++) { ++ pll = &dev_priv->shared_dplls[i]; + if (pll->refcount == 0) { + DRM_DEBUG_KMS("CRTC:%d allocated PCH PLL %x\n", + intel_crtc->base.base.id, pll->pll_reg); +@@ -3133,12 +3133,12 @@ static struct intel_pch_pll *intel_get_pch_pll(struct intel_crtc *intel_crtc, u3 + return NULL; + + found: +- intel_crtc->pch_pll = pll; ++ intel_crtc->shared_dpll = pll; + DRM_DEBUG_DRIVER("using pll %d for pipe %c\n", i, pipe_name(intel_crtc->pipe)); + if (pll->active == 0) { + DRM_DEBUG_DRIVER("setting up pll %d\n", i); + WARN_ON(pll->on); +- assert_pch_pll_disabled(dev_priv, pll, NULL); ++ assert_shared_dpll_disabled(dev_priv, pll, NULL); + + /* Wait for the clocks to stabilize before rewriting the regs */ + I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE); +@@ -3488,7 +3488,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) + } + + /* disable PCH DPLL */ +- intel_disable_pch_pll(intel_crtc); ++ intel_disable_shared_dpll(intel_crtc); + + ironlake_fdi_pll_disable(intel_crtc); + } +@@ -3561,7 +3561,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) + static void ironlake_crtc_off(struct drm_crtc *crtc) + { + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- intel_put_pch_pll(intel_crtc); ++ intel_put_shared_dpll(intel_crtc); + } + + static void haswell_crtc_off(struct drm_crtc *crtc) +@@ -5765,7 +5765,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + + /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ + if (intel_crtc->config.has_pch_encoder) { +- struct intel_pch_pll *pll; ++ struct intel_shared_dpll *pll; + + fp = i9xx_dpll_compute_fp(&intel_crtc->config.dpll); + if (has_reduced_clock) +@@ -5775,14 +5775,14 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + &fp, &reduced_clock, + has_reduced_clock ? &fp2 : NULL); + +- pll = intel_get_pch_pll(intel_crtc, dpll, fp); ++ pll = intel_get_shared_dpll(intel_crtc, dpll, fp); + if (pll == NULL) { + DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", + pipe_name(pipe)); + return -EINVAL; + } + } else +- intel_put_pch_pll(intel_crtc); ++ intel_put_shared_dpll(intel_crtc); + + if (intel_crtc->config.has_dp_encoder) + intel_dp_set_m_n(intel_crtc); +@@ -5791,11 +5791,11 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + if (encoder->pre_pll_enable) + encoder->pre_pll_enable(encoder); + +- if (intel_crtc->pch_pll) { +- I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll); ++ if (intel_crtc->shared_dpll) { ++ I915_WRITE(intel_crtc->shared_dpll->pll_reg, dpll); + + /* Wait for the clocks to stabilize. */ +- POSTING_READ(intel_crtc->pch_pll->pll_reg); ++ POSTING_READ(intel_crtc->shared_dpll->pll_reg); + udelay(150); + + /* The pixel multiplier can only be updated once the +@@ -5803,16 +5803,16 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + * + * So write it again. + */ +- I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll); ++ I915_WRITE(intel_crtc->shared_dpll->pll_reg, dpll); + } + + intel_crtc->lowfreq_avail = false; +- if (intel_crtc->pch_pll) { ++ if (intel_crtc->shared_dpll) { + if (is_lvds && has_reduced_clock && i915_powersave) { +- I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2); ++ I915_WRITE(intel_crtc->shared_dpll->fp1_reg, fp2); + intel_crtc->lowfreq_avail = true; + } else { +- I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp); ++ I915_WRITE(intel_crtc->shared_dpll->fp1_reg, fp); + } + } + +@@ -8750,20 +8750,20 @@ static void intel_cpu_pll_init(struct drm_device *dev) + intel_ddi_pll_init(dev); + } + +-static void intel_pch_pll_init(struct drm_device *dev) ++static void intel_shared_dpll_init(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; + int i; + +- if (dev_priv->num_pch_pll == 0) { ++ if (dev_priv->num_shared_dpll == 0) { + DRM_DEBUG_KMS("No PCH PLLs on this hardware, skipping initialisation\n"); + return; + } + +- for (i = 0; i < dev_priv->num_pch_pll; i++) { +- dev_priv->pch_plls[i].pll_reg = _PCH_DPLL(i); +- dev_priv->pch_plls[i].fp0_reg = _PCH_FP0(i); +- dev_priv->pch_plls[i].fp1_reg = _PCH_FP1(i); ++ for (i = 0; i < dev_priv->num_shared_dpll; i++) { ++ dev_priv->shared_dplls[i].pll_reg = _PCH_DPLL(i); ++ dev_priv->shared_dplls[i].fp0_reg = _PCH_FP0(i); ++ dev_priv->shared_dplls[i].fp1_reg = _PCH_FP1(i); + } + } + +@@ -9475,7 +9475,7 @@ void intel_modeset_init(struct drm_device *dev) + } + + intel_cpu_pll_init(dev); +- intel_pch_pll_init(dev); ++ intel_shared_dpll_init(dev); + + /* Just disable it once at startup */ + i915_disable_vga(dev); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 259a6873aacc..ccf92ff03755 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -317,7 +317,7 @@ struct intel_crtc { + struct intel_crtc_config config; + + /* We can share PLLs across outputs if the timings match */ +- struct intel_pch_pll *pch_pll; ++ struct intel_shared_dpll *shared_dpll; + uint32_t ddi_pll_sel; + + /* reset counter value when the last flip was submitted */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0294-drm-i915-switch-crtc-shared_dpll-from-a-pointer-to-a.patch b/patches.baytrail/0294-drm-i915-switch-crtc-shared_dpll-from-a-pointer-to-a.patch new file mode 100644 index 000000000000..7a3bd4e50d0c --- /dev/null +++ b/patches.baytrail/0294-drm-i915-switch-crtc-shared_dpll-from-a-pointer-to-a.patch @@ -0,0 +1,330 @@ +From 4999e50705bba978fee82b49a5e8fd11913fa118 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 7 Jun 2013 23:10:03 +0200 +Subject: drm/i915: switch crtc->shared_dpll from a pointer to an enum +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Dealing with discrete enum values is simpler for hw state readout and +pipe config computations than pointers - having neat names instead of +chasing pointers should look better in the code. + +This isn't a that good reason for pch plls, but on haswell we actually +have 3 different types of plls: WRPLL, SPLL and the DP clocks. Having +explicit names should help there. + +Since this also adds the intel_crtc_to_shared_dpll helper to further +abstract away the crtc -> dpll relationship this will also help to +make the next patch simpler, which moves the shared dpll into the pipe +configuration. + +Also note that for uniformity we have two special dpll ids: NONE for +pipes which need a shared pll but don't have one (yet) and private for +when there's a non-shared pll (e.g. per-pipe or per-port pll). + +I've thought whether we should also add a 2nd enum for the type of the +pll we want (for really generic pll selection code) but thrown that +idea out again - likely there's too much platform craziness going on +to be able to share the pll selection logic much. + +Since this touched all the shared_pll functions a bit I've also done +an s/intel_crtc/crtc/ replacement on a few of them. + +v2: Kill DPLL_ID_NONE. It's probably better to call it DPLL_ID_INVALID and use +it to check that the compute config stage assigns a dpll to every pipe. +But since that code isn't ready yet until we move the dpll selection out +of the ->mode_set callback, there's no use for it. + +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit e2b78267421c2b407409772119a4aa500da56cc8) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 7 +++ + drivers/gpu/drm/i915/intel_display.c | 90 ++++++++++++++++++++---------------- + drivers/gpu/drm/i915/intel_drv.h | 2 +- + 3 files changed, 58 insertions(+), 41 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index d46339018156..81a424d91c20 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -140,6 +140,13 @@ struct intel_shared_dpll { + int fp0_reg; + int fp1_reg; + }; ++ ++enum intel_dpll_id { ++ DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */ ++ /* real shared dpll ids must be >= 0 */ ++ DPLL_ID_PCH_PLL_A, ++ DPLL_ID_PCH_PLL_B, ++}; + #define I915_NUM_PLLS 2 + + /* Used by dp and fdi links */ +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 2f2f68a9a6d3..9af8a7449d3f 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -909,6 +909,17 @@ static void assert_pll(struct drm_i915_private *dev_priv, + #define assert_pll_enabled(d, p) assert_pll(d, p, true) + #define assert_pll_disabled(d, p) assert_pll(d, p, false) + ++static struct intel_shared_dpll * ++intel_crtc_to_shared_dpll(struct intel_crtc *crtc) ++{ ++ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; ++ ++ if (crtc->shared_dpll < 0) ++ return NULL; ++ ++ return &dev_priv->shared_dplls[crtc->shared_dpll]; ++} ++ + /* For ILK+ */ + static void assert_shared_dpll(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, +@@ -1404,16 +1415,15 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port) + * The PCH PLL needs to be enabled before the PCH transcoder, since it + * drives the transcoder clock. + */ +-static void ironlake_enable_shared_dpll(struct intel_crtc *intel_crtc) ++static void ironlake_enable_shared_dpll(struct intel_crtc *crtc) + { +- struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; +- struct intel_shared_dpll *pll; ++ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; ++ struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); + int reg; + u32 val; + + /* PCH PLLs only available on ILK, SNB and IVB */ + BUG_ON(dev_priv->info->gen < 5); +- pll = intel_crtc->shared_dpll; + if (pll == NULL) + return; + +@@ -1422,7 +1432,7 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *intel_crtc) + + DRM_DEBUG_KMS("enable PCH PLL %x (active %d, on? %d)for crtc %d\n", + pll->pll_reg, pll->active, pll->on, +- intel_crtc->base.base.id); ++ crtc->base.base.id); + + /* PCH refclock must be enabled first */ + assert_pch_refclk_enabled(dev_priv); +@@ -1446,10 +1456,10 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *intel_crtc) + pll->on = true; + } + +-static void intel_disable_shared_dpll(struct intel_crtc *intel_crtc) ++static void intel_disable_shared_dpll(struct intel_crtc *crtc) + { +- struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; +- struct intel_shared_dpll *pll = intel_crtc->shared_dpll; ++ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; ++ struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); + int reg; + u32 val; + +@@ -1463,7 +1473,7 @@ static void intel_disable_shared_dpll(struct intel_crtc *intel_crtc) + + DRM_DEBUG_KMS("disable PCH PLL %x (active %d, on? %d) for crtc %d\n", + pll->pll_reg, pll->active, pll->on, +- intel_crtc->base.base.id); ++ crtc->base.base.id); + + if (WARN_ON(pll->active == 0)) { + assert_shared_dpll_disabled(dev_priv, pll, NULL); +@@ -1478,7 +1488,7 @@ static void intel_disable_shared_dpll(struct intel_crtc *intel_crtc) + DRM_DEBUG_KMS("disabling PCH PLL %x\n", pll->pll_reg); + + /* Make sure transcoder isn't still depending on us */ +- assert_pch_transcoder_disabled(dev_priv, intel_crtc->pipe); ++ assert_pch_transcoder_disabled(dev_priv, crtc->pipe); + + reg = pll->pll_reg; + val = I915_READ(reg); +@@ -1495,6 +1505,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, + { + struct drm_device *dev = dev_priv->dev; + struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + uint32_t reg, val, pipeconf_val; + + /* PCH only available on ILK+ */ +@@ -1502,8 +1513,8 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, + + /* Make sure PCH DPLL is enabled */ + assert_shared_dpll_enabled(dev_priv, +- to_intel_crtc(crtc)->shared_dpll, +- to_intel_crtc(crtc)); ++ intel_crtc_to_shared_dpll(intel_crtc), ++ intel_crtc); + + /* FDI must be feeding us bits for PCH ports */ + assert_fdi_tx_enabled(dev_priv, pipe); +@@ -2990,7 +3001,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) + sel = TRANSC_DPLLB_SEL; + break; + } +- if (intel_crtc->shared_dpll->pll_reg == _PCH_DPLL_B) ++ if (intel_crtc->shared_dpll == DPLL_ID_PCH_PLL_B) + temp |= sel; + else + temp &= ~sel; +@@ -3059,9 +3070,9 @@ static void lpt_pch_enable(struct drm_crtc *crtc) + lpt_enable_pch_transcoder(dev_priv, cpu_transcoder); + } + +-static void intel_put_shared_dpll(struct intel_crtc *intel_crtc) ++static void intel_put_shared_dpll(struct intel_crtc *crtc) + { +- struct intel_shared_dpll *pll = intel_crtc->shared_dpll; ++ struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); + + if (pll == NULL) + return; +@@ -3076,29 +3087,28 @@ static void intel_put_shared_dpll(struct intel_crtc *intel_crtc) + WARN_ON(pll->active); + } + +- intel_crtc->shared_dpll = NULL; ++ crtc->shared_dpll = DPLL_ID_PRIVATE; + } + +-static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *intel_crtc, u32 dpll, u32 fp) ++static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, u32 dpll, u32 fp) + { +- struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; +- struct intel_shared_dpll *pll; +- int i; ++ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; ++ struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); ++ enum intel_dpll_id i; + +- pll = intel_crtc->shared_dpll; + if (pll) { + DRM_DEBUG_KMS("CRTC:%d dropping existing PCH PLL %x\n", +- intel_crtc->base.base.id, pll->pll_reg); +- intel_put_shared_dpll(intel_crtc); ++ crtc->base.base.id, pll->pll_reg); ++ intel_put_shared_dpll(crtc); + } + + if (HAS_PCH_IBX(dev_priv->dev)) { + /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ +- i = intel_crtc->pipe; ++ i = crtc->pipe; + pll = &dev_priv->shared_dplls[i]; + + DRM_DEBUG_KMS("CRTC:%d using pre-allocated PCH PLL %x\n", +- intel_crtc->base.base.id, pll->pll_reg); ++ crtc->base.base.id, pll->pll_reg); + + goto found; + } +@@ -3113,7 +3123,7 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *intel_ + if (dpll == (I915_READ(pll->pll_reg) & 0x7fffffff) && + fp == I915_READ(pll->fp0_reg)) { + DRM_DEBUG_KMS("CRTC:%d sharing existing PCH PLL %x (refcount %d, ative %d)\n", +- intel_crtc->base.base.id, ++ crtc->base.base.id, + pll->pll_reg, pll->refcount, pll->active); + + goto found; +@@ -3125,7 +3135,7 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *intel_ + pll = &dev_priv->shared_dplls[i]; + if (pll->refcount == 0) { + DRM_DEBUG_KMS("CRTC:%d allocated PCH PLL %x\n", +- intel_crtc->base.base.id, pll->pll_reg); ++ crtc->base.base.id, pll->pll_reg); + goto found; + } + } +@@ -3133,8 +3143,8 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *intel_ + return NULL; + + found: +- intel_crtc->shared_dpll = pll; +- DRM_DEBUG_DRIVER("using pll %d for pipe %c\n", i, pipe_name(intel_crtc->pipe)); ++ crtc->shared_dpll = i; ++ DRM_DEBUG_DRIVER("using pll %d for pipe %c\n", i, pipe_name(crtc->pipe)); + if (pll->active == 0) { + DRM_DEBUG_DRIVER("setting up pll %d\n", i); + WARN_ON(pll->on); +@@ -5730,6 +5740,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + bool ok, has_reduced_clock = false; + bool is_lvds = false; + struct intel_encoder *encoder; ++ struct intel_shared_dpll *pll; + int ret; + + for_each_encoder_on_crtc(dev, crtc, encoder) { +@@ -5765,8 +5776,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + + /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ + if (intel_crtc->config.has_pch_encoder) { +- struct intel_shared_dpll *pll; +- + fp = i9xx_dpll_compute_fp(&intel_crtc->config.dpll); + if (has_reduced_clock) + fp2 = i9xx_dpll_compute_fp(&reduced_clock); +@@ -5791,11 +5800,15 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + if (encoder->pre_pll_enable) + encoder->pre_pll_enable(encoder); + +- if (intel_crtc->shared_dpll) { +- I915_WRITE(intel_crtc->shared_dpll->pll_reg, dpll); ++ intel_crtc->lowfreq_avail = false; ++ ++ if (intel_crtc->config.has_pch_encoder) { ++ pll = intel_crtc_to_shared_dpll(intel_crtc); ++ ++ I915_WRITE(pll->pll_reg, dpll); + + /* Wait for the clocks to stabilize. */ +- POSTING_READ(intel_crtc->shared_dpll->pll_reg); ++ POSTING_READ(pll->pll_reg); + udelay(150); + + /* The pixel multiplier can only be updated once the +@@ -5803,16 +5816,13 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + * + * So write it again. + */ +- I915_WRITE(intel_crtc->shared_dpll->pll_reg, dpll); +- } ++ I915_WRITE(pll->pll_reg, dpll); + +- intel_crtc->lowfreq_avail = false; +- if (intel_crtc->shared_dpll) { + if (is_lvds && has_reduced_clock && i915_powersave) { +- I915_WRITE(intel_crtc->shared_dpll->fp1_reg, fp2); ++ I915_WRITE(pll->fp1_reg, fp2); + intel_crtc->lowfreq_avail = true; + } else { +- I915_WRITE(intel_crtc->shared_dpll->fp1_reg, fp); ++ I915_WRITE(pll->fp1_reg, fp); + } + } + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index ccf92ff03755..bcc313368410 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -317,7 +317,7 @@ struct intel_crtc { + struct intel_crtc_config config; + + /* We can share PLLs across outputs if the timings match */ +- struct intel_shared_dpll *shared_dpll; ++ enum intel_dpll_id shared_dpll; + uint32_t ddi_pll_sel; + + /* reset counter value when the last flip was submitted */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0295-drm-i915-move-shared_dpll-into-the-pipe-config.patch b/patches.baytrail/0295-drm-i915-move-shared_dpll-into-the-pipe-config.patch new file mode 100644 index 000000000000..24a66633b906 --- /dev/null +++ b/patches.baytrail/0295-drm-i915-move-shared_dpll-into-the-pipe-config.patch @@ -0,0 +1,145 @@ +From ef58b25b78ca4c35eb61872d3e580de3b50a2ee8 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 7 Jun 2013 23:10:32 +0200 +Subject: drm/i915: move shared_dpll into the pipe config +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With the big sed-job prep work done this is now really simple. With +the exception that we only assign the right shared dpll id in the +->mode_set callback but also depend upon the old one still being +around. + +Until that mess is fixed up we need to jump through a few hoops to +keep the old value save. + +v2: Kill the funny whitespace spotted by Chris. + +v3: Move the shared_dpll pipe config fixup into this patch as noticed +by Ville. Also unconditionally set the shared_dpll with the current +one, since otherwise we won't handle direct pch port -> cpu edp +transitions correctly. + +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit a43f6e0fd6219e806268d5fef67db722875393a0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 26 +++++++++++++++----------- + drivers/gpu/drm/i915/intel_drv.h | 5 +++-- + 2 files changed, 18 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 9af8a7449d3f..0fdb80517545 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -914,10 +914,10 @@ intel_crtc_to_shared_dpll(struct intel_crtc *crtc) + { + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + +- if (crtc->shared_dpll < 0) ++ if (crtc->config.shared_dpll < 0) + return NULL; + +- return &dev_priv->shared_dplls[crtc->shared_dpll]; ++ return &dev_priv->shared_dplls[crtc->config.shared_dpll]; + } + + /* For ILK+ */ +@@ -3001,7 +3001,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) + sel = TRANSC_DPLLB_SEL; + break; + } +- if (intel_crtc->shared_dpll == DPLL_ID_PCH_PLL_B) ++ if (intel_crtc->config.shared_dpll == DPLL_ID_PCH_PLL_B) + temp |= sel; + else + temp &= ~sel; +@@ -3087,7 +3087,7 @@ static void intel_put_shared_dpll(struct intel_crtc *crtc) + WARN_ON(pll->active); + } + +- crtc->shared_dpll = DPLL_ID_PRIVATE; ++ crtc->config.shared_dpll = DPLL_ID_PRIVATE; + } + + static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, u32 dpll, u32 fp) +@@ -3143,7 +3143,7 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, + return NULL; + + found: +- crtc->shared_dpll = i; ++ crtc->config.shared_dpll = i; + DRM_DEBUG_DRIVER("using pll %d for pipe %c\n", i, pipe_name(crtc->pipe)); + if (pll->active == 0) { + DRM_DEBUG_DRIVER("setting up pll %d\n", i); +@@ -4102,12 +4102,11 @@ static void hsw_compute_ips_config(struct intel_crtc *crtc, + pipe_config->pipe_bpp == 24; + } + +-static int intel_crtc_compute_config(struct drm_crtc *crtc, ++static int intel_crtc_compute_config(struct intel_crtc *crtc, + struct intel_crtc_config *pipe_config) + { +- struct drm_device *dev = crtc->dev; ++ struct drm_device *dev = crtc->base.dev; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; +- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + if (HAS_PCH_SPLIT(dev)) { + /* FDI link clock is fixed at 2.7G */ +@@ -4138,10 +4137,15 @@ static int intel_crtc_compute_config(struct drm_crtc *crtc, + } + + if (IS_HASWELL(dev)) +- hsw_compute_ips_config(intel_crtc, pipe_config); ++ hsw_compute_ips_config(crtc, pipe_config); ++ ++ /* XXX: PCH clock sharing is done in ->mode_set, so make sure the old ++ * clock survives for now. */ ++ if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) ++ pipe_config->shared_dpll = crtc->config.shared_dpll; + + if (pipe_config->has_pch_encoder) +- return ironlake_fdi_compute_config(intel_crtc, pipe_config); ++ return ironlake_fdi_compute_config(crtc, pipe_config); + + return 0; + } +@@ -7914,7 +7918,7 @@ encoder_retry: + if (!pipe_config->port_clock) + pipe_config->port_clock = pipe_config->adjusted_mode.clock; + +- ret = intel_crtc_compute_config(crtc, pipe_config); ++ ret = intel_crtc_compute_config(to_intel_crtc(crtc), pipe_config); + if (ret < 0) { + DRM_DEBUG_KMS("CRTC fixup failed\n"); + goto fail; +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index bcc313368410..3ecc3d0e6acc 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -252,6 +252,9 @@ struct intel_crtc_config { + * haswell. */ + struct dpll dpll; + ++ /* Selected dpll when shared or DPLL_ID_PRIVATE. */ ++ enum intel_dpll_id shared_dpll; ++ + int pipe_bpp; + struct intel_link_m_n dp_m_n; + +@@ -316,8 +319,6 @@ struct intel_crtc { + + struct intel_crtc_config config; + +- /* We can share PLLs across outputs if the timings match */ +- enum intel_dpll_id shared_dpll; + uint32_t ddi_pll_sel; + + /* reset counter value when the last flip was submitted */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0296-drm-i915-refactor-PCH_DPLL_SEL-defines.patch b/patches.baytrail/0296-drm-i915-refactor-PCH_DPLL_SEL-defines.patch new file mode 100644 index 000000000000..b6c986b7e1c4 --- /dev/null +++ b/patches.baytrail/0296-drm-i915-refactor-PCH_DPLL_SEL-defines.patch @@ -0,0 +1,97 @@ +From b53b1bd3890c5a98301e919c87139ae43bdc0fdb Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:09 +0200 +Subject: drm/i915: refactor PCH_DPLL_SEL #defines +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The bits are evenly space, so we can cut down on two big switch +blocks. This also greatly simplifies the hw state readout which +follows in the next patch. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 1188739757d0e78810de5fe83dbe0128f624b9e8) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 12 +++--------- + drivers/gpu/drm/i915/intel_display.c | 32 +++----------------------------- + 2 files changed, 6 insertions(+), 38 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 225a28d67060..776ef89cda14 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -3984,15 +3984,9 @@ + #define PCH_SSC4_AUX_PARMS 0xc6214 + + #define PCH_DPLL_SEL 0xc7000 +-#define TRANSA_DPLL_ENABLE (1<<3) +-#define TRANSA_DPLLB_SEL (1<<0) +-#define TRANSA_DPLLA_SEL 0 +-#define TRANSB_DPLL_ENABLE (1<<7) +-#define TRANSB_DPLLB_SEL (1<<4) +-#define TRANSB_DPLLA_SEL (0) +-#define TRANSC_DPLL_ENABLE (1<<11) +-#define TRANSC_DPLLB_SEL (1<<8) +-#define TRANSC_DPLLA_SEL (0) ++#define TRANS_DPLLB_SEL(pipe) (1 << (pipe * 4)) ++#define TRANS_DPLLA_SEL(pipe) 0 ++#define TRANS_DPLL_ENABLE(pipe) (1 << (pipe * 4 + 3)) + + /* transcoder */ + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 0fdb80517545..887b7e6f5025 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2986,21 +2986,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) + u32 sel; + + temp = I915_READ(PCH_DPLL_SEL); +- switch (pipe) { +- default: +- case 0: +- temp |= TRANSA_DPLL_ENABLE; +- sel = TRANSA_DPLLB_SEL; +- break; +- case 1: +- temp |= TRANSB_DPLL_ENABLE; +- sel = TRANSB_DPLLB_SEL; +- break; +- case 2: +- temp |= TRANSC_DPLL_ENABLE; +- sel = TRANSC_DPLLB_SEL; +- break; +- } ++ temp |= TRANS_DPLL_ENABLE(pipe); ++ sel = TRANS_DPLLB_SEL(pipe); + if (intel_crtc->config.shared_dpll == DPLL_ID_PCH_PLL_B) + temp |= sel; + else +@@ -3480,20 +3467,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) + + /* disable DPLL_SEL */ + temp = I915_READ(PCH_DPLL_SEL); +- switch (pipe) { +- case 0: +- temp &= ~(TRANSA_DPLL_ENABLE | TRANSA_DPLLB_SEL); +- break; +- case 1: +- temp &= ~(TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); +- break; +- case 2: +- /* C shares PLL A or B */ +- temp &= ~(TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL); +- break; +- default: +- BUG(); /* wtf */ +- } ++ temp &= ~(TRANS_DPLL_ENABLE(pipe) | TRANS_DPLLB_SEL(pipe)); + I915_WRITE(PCH_DPLL_SEL, temp); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0297-drm-i915-hw-state-readout-for-shared-pch-plls.patch b/patches.baytrail/0297-drm-i915-hw-state-readout-for-shared-pch-plls.patch new file mode 100644 index 000000000000..a3b8d78b3eaf --- /dev/null +++ b/patches.baytrail/0297-drm-i915-hw-state-readout-for-shared-pch-plls.patch @@ -0,0 +1,123 @@ +From ecf1997ca311a1f0a871631dab31ee149c16779b Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 7 Jun 2013 23:11:08 +0200 +Subject: drm/i915: hw state readout for shared pch plls +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Well, the first step of a long road at least, it only reads out +the pipe -> shared dpll association thus far. Other state which needs +to follow: + +- hw state of the dpll (on/off + dpll registers). Currently we just + read that out from the hw state, but that doesn't work too well when + the dpll is in use, but not yet fully enabled. We get away since + most likely it already has been enabled and so the correct state is + left behind in the registers. But that doesn't hold for atomic + modesets when we want to enable all pipes at once. + +- Refcount reconstruction for each dpll. + +- Cross-checking of all the above. For that we need to keep the dpll + register state both in the pipe and in the shared_dpll struct, so + that we can check that every pipe is still connected to a correctly + configured dpll. + +Note that since the refcount resconstruction isn't done yet this will +spill a few WARNs at boot-up while trying to disable pch plls which +have bogus refcounts. But since there's still a pile of refactoring to +do I'd like to lock down the state handling as soon as possible hence +decided against reordering the patches to quiet these WARNs - after +all the issues they're complaining about have existed since forever, +as Jesse can testify by having pch pll states blow up consistently in +his fastboot patches ... + +v2: We need to preserve the old shared_dpll since currently the +shared dpll refcount dropping/getting is done in ->mode_set. With +the usual pipe_config infrastructure the old dpll id is already lost +at that point, hence preserve it in the new config. + +v3: Rebase on top of the ips patch from Paulo. + +v4: We need to unconditionally take over the shared_dpll id from the +old pipe config when e.g. doing a direct pch port -> cpu edp +transition. + +v5: Move the saving of the old shared_dpll id to an ealier patch. + +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit c0d43d62233b3d4523a62fe88896bfc7a609e572) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 887b7e6f5025..c0a40063dded 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4998,6 +4998,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, + uint32_t tmp; + + pipe_config->cpu_transcoder = crtc->pipe; ++ pipe_config->shared_dpll = DPLL_ID_PRIVATE; + + tmp = I915_READ(PIPECONF(crtc->pipe)); + if (!(tmp & PIPECONF_ENABLE)) +@@ -5874,6 +5875,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + uint32_t tmp; + + pipe_config->cpu_transcoder = crtc->pipe; ++ pipe_config->shared_dpll = DPLL_ID_PRIVATE; + + tmp = I915_READ(PIPECONF(crtc->pipe)); + if (!(tmp & PIPECONF_ENABLE)) +@@ -5891,6 +5893,16 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + /* XXX: Can't properly read out the pch dpll pixel multiplier + * since we don't have state tracking for pch clocks yet. */ + pipe_config->pixel_multiplier = 1; ++ ++ if (HAS_PCH_IBX(dev_priv->dev)) { ++ pipe_config->shared_dpll = crtc->pipe; ++ } else { ++ tmp = I915_READ(PCH_DPLL_SEL); ++ if (tmp & TRANS_DPLLB_SEL(crtc->pipe)) ++ pipe_config->shared_dpll = DPLL_ID_PCH_PLL_B; ++ else ++ pipe_config->shared_dpll = DPLL_ID_PCH_PLL_A; ++ } + } else { + pipe_config->pixel_multiplier = 1; + } +@@ -5971,6 +5983,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + uint32_t tmp; + + pipe_config->cpu_transcoder = crtc->pipe; ++ pipe_config->shared_dpll = DPLL_ID_PRIVATE; ++ + tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); + if (tmp & TRANS_DDI_FUNC_ENABLE) { + enum pipe trans_edp_pipe; +@@ -7844,6 +7858,7 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, + drm_mode_copy(&pipe_config->adjusted_mode, mode); + drm_mode_copy(&pipe_config->requested_mode, mode); + pipe_config->cpu_transcoder = to_intel_crtc(crtc)->pipe; ++ pipe_config->shared_dpll = DPLL_ID_PRIVATE; + + /* Compute a starting value for pipe_config->pipe_bpp taking the source + * plane pixel format and any sink constraints into account. Returns the +@@ -8163,6 +8178,8 @@ intel_pipe_config_compare(struct drm_device *dev, + + PIPE_CONF_CHECK_I(ips_enabled); + ++ PIPE_CONF_CHECK_I(shared_dpll); ++ + #undef PIPE_CONF_CHECK_I + #undef PIPE_CONF_CHECK_FLAGS + #undef PIPE_CONF_QUIRK +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0298-drm-i915-consolidate-num_shared_dplls-assignement.patch b/patches.baytrail/0298-drm-i915-consolidate-num_shared_dplls-assignement.patch new file mode 100644 index 000000000000..3b5dada86749 --- /dev/null +++ b/patches.baytrail/0298-drm-i915-consolidate-num_shared_dplls-assignement.patch @@ -0,0 +1,116 @@ +From c9bf14961b028ab765cf8c3206a1626efda754a3 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:11 +0200 +Subject: drm/i915: consolidate ->num_shared_dplls assignement +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In the future this won't be just for pch plls, so move it into the +shared dpll init code. + +v2: Bikeshed the uncessary {} away while applying to appease +checkpatch. + +Reviewed-by: Ville Syrjälä (v1) +Signed-off-by: Daniel Vetter +(cherry picked from commit 7c74ade1de5b5311e7c886de27aa54e3285bd220) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 7 ------- + drivers/gpu/drm/i915/intel_display.c | 21 ++++++++++++++++----- + 2 files changed, 16 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 235749dba729..b255b0bb0953 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -457,7 +457,6 @@ void intel_detect_pch(struct drm_device *dev) + */ + if (INTEL_INFO(dev)->num_pipes == 0) { + dev_priv->pch_type = PCH_NOP; +- dev_priv->num_shared_dpll = 0; + return; + } + +@@ -476,34 +475,28 @@ void intel_detect_pch(struct drm_device *dev) + + if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_IBX; +- dev_priv->num_shared_dpll = 2; + DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); + WARN_ON(!IS_GEN5(dev)); + } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_CPT; +- dev_priv->num_shared_dpll = 2; + DRM_DEBUG_KMS("Found CougarPoint PCH\n"); + WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); + } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { + /* PantherPoint is CPT compatible */ + dev_priv->pch_type = PCH_CPT; +- dev_priv->num_shared_dpll = 2; + DRM_DEBUG_KMS("Found PatherPoint PCH\n"); + WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); + } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_LPT; +- dev_priv->num_shared_dpll = 0; + DRM_DEBUG_KMS("Found LynxPoint PCH\n"); + WARN_ON(!IS_HASWELL(dev)); + WARN_ON(IS_ULT(dev)); + } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_LPT; +- dev_priv->num_shared_dpll = 0; + DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); + WARN_ON(!IS_HASWELL(dev)); + WARN_ON(!IS_ULT(dev)); + } +- BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS); + } + pci_dev_put(pch); + } +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index c0a40063dded..da2c4070f154 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8755,15 +8755,12 @@ static void intel_cpu_pll_init(struct drm_device *dev) + intel_ddi_pll_init(dev); + } + +-static void intel_shared_dpll_init(struct drm_device *dev) ++static void ibx_pch_dpll_init(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; + int i; + +- if (dev_priv->num_shared_dpll == 0) { +- DRM_DEBUG_KMS("No PCH PLLs on this hardware, skipping initialisation\n"); +- return; +- } ++ dev_priv->num_shared_dpll = 2; + + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + dev_priv->shared_dplls[i].pll_reg = _PCH_DPLL(i); +@@ -8772,6 +8769,20 @@ static void intel_shared_dpll_init(struct drm_device *dev) + } + } + ++static void intel_shared_dpll_init(struct drm_device *dev) ++{ ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ ++ if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) ++ ibx_pch_dpll_init(dev); ++ else ++ dev_priv->num_shared_dpll = 0; ++ ++ BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS); ++ DRM_DEBUG_KMS("%i shared PLLs initialized\n", ++ dev_priv->num_shared_dpll); ++} ++ + static void intel_crtc_init(struct drm_device *dev, int pipe) + { + drm_i915_private_t *dev_priv = dev->dev_private; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0299-drm-i915-metadata-for-shared-dplls.patch b/patches.baytrail/0299-drm-i915-metadata-for-shared-dplls.patch new file mode 100644 index 000000000000..84755a15a02f --- /dev/null +++ b/patches.baytrail/0299-drm-i915-metadata-for-shared-dplls.patch @@ -0,0 +1,212 @@ +From 7c33e10b63e6017065b78cc23b631b8ac8504a52 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:12 +0200 +Subject: drm/i915: metadata for shared dplls +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +An id to match the idx (useful for register access macros) and a name +fore neater debug output. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 46edb027df0d4bd423f7430dd473609caad4674b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 19 ++++++++------ + drivers/gpu/drm/i915/intel_display.c | 48 +++++++++++++++++++++--------------- + 2 files changed, 39 insertions(+), 28 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 81a424d91c20..7e3d3b349bf6 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -132,23 +132,26 @@ enum hpd_pin { + list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ + if ((intel_encoder)->base.crtc == (__crtc)) + ++enum intel_dpll_id { ++ DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */ ++ /* real shared dpll ids must be >= 0 */ ++ DPLL_ID_PCH_PLL_A, ++ DPLL_ID_PCH_PLL_B, ++}; ++#define I915_NUM_PLLS 2 ++ + struct intel_shared_dpll { + int refcount; /* count of number of CRTCs sharing this PLL */ + int active; /* count of number of active CRTCs (i.e. DPMS on) */ + bool on; /* is the PLL actually active? Disabled during modeset */ ++ const char *name; ++ /* should match the index in the dev_priv->shared_dplls array */ ++ enum intel_dpll_id id; + int pll_reg; + int fp0_reg; + int fp1_reg; + }; + +-enum intel_dpll_id { +- DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */ +- /* real shared dpll ids must be >= 0 */ +- DPLL_ID_PCH_PLL_A, +- DPLL_ID_PCH_PLL_B, +-}; +-#define I915_NUM_PLLS 2 +- + /* Used by dp and fdi links */ + struct intel_link_m_n { + uint32_t tu; +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index da2c4070f154..3e5eeb0b5dec 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -935,14 +935,14 @@ static void assert_shared_dpll(struct drm_i915_private *dev_priv, + } + + if (WARN (!pll, +- "asserting PCH PLL %s with no PLL\n", state_string(state))) ++ "asserting DPLL %s with no DPLL\n", state_string(state))) + return; + + val = I915_READ(pll->pll_reg); + cur_state = !!(val & DPLL_VCO_ENABLE); + WARN(cur_state != state, +- "PCH PLL state for reg %x assertion failure (expected %s, current %s), val=%08x\n", +- pll->pll_reg, state_string(state), state_string(cur_state), val); ++ "%s assertion failure (expected %s, current %s), val=%08x\n", ++ pll->name, state_string(state), state_string(cur_state), val); + + /* Make sure the selected PLL is correctly attached to the transcoder */ + if (crtc && HAS_PCH_CPT(dev_priv->dev)) { +@@ -1430,8 +1430,8 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *crtc) + if (WARN_ON(pll->refcount == 0)) + return; + +- DRM_DEBUG_KMS("enable PCH PLL %x (active %d, on? %d)for crtc %d\n", +- pll->pll_reg, pll->active, pll->on, ++ DRM_DEBUG_KMS("enable %s (active %d, on? %d)for crtc %d\n", ++ pll->name, pll->active, pll->on, + crtc->base.base.id); + + /* PCH refclock must be enabled first */ +@@ -1444,7 +1444,7 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *crtc) + } + WARN_ON(pll->on); + +- DRM_DEBUG_KMS("enabling PCH PLL %x\n", pll->pll_reg); ++ DRM_DEBUG_KMS("enabling %s\n", pll->name); + + reg = pll->pll_reg; + val = I915_READ(reg); +@@ -1471,8 +1471,8 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc) + if (WARN_ON(pll->refcount == 0)) + return; + +- DRM_DEBUG_KMS("disable PCH PLL %x (active %d, on? %d) for crtc %d\n", +- pll->pll_reg, pll->active, pll->on, ++ DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n", ++ pll->name, pll->active, pll->on, + crtc->base.base.id); + + if (WARN_ON(pll->active == 0)) { +@@ -1485,7 +1485,7 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc) + if (--pll->active) + return; + +- DRM_DEBUG_KMS("disabling PCH PLL %x\n", pll->pll_reg); ++ DRM_DEBUG_KMS("disabling %s\n", pll->name); + + /* Make sure transcoder isn't still depending on us */ + assert_pch_transcoder_disabled(dev_priv, crtc->pipe); +@@ -3065,7 +3065,7 @@ static void intel_put_shared_dpll(struct intel_crtc *crtc) + return; + + if (pll->refcount == 0) { +- WARN(1, "bad PCH PLL refcount\n"); ++ WARN(1, "bad %s refcount\n", pll->name); + return; + } + +@@ -3084,8 +3084,8 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, + enum intel_dpll_id i; + + if (pll) { +- DRM_DEBUG_KMS("CRTC:%d dropping existing PCH PLL %x\n", +- crtc->base.base.id, pll->pll_reg); ++ DRM_DEBUG_KMS("CRTC:%d dropping existing %s\n", ++ crtc->base.base.id, pll->name); + intel_put_shared_dpll(crtc); + } + +@@ -3094,8 +3094,8 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, + i = crtc->pipe; + pll = &dev_priv->shared_dplls[i]; + +- DRM_DEBUG_KMS("CRTC:%d using pre-allocated PCH PLL %x\n", +- crtc->base.base.id, pll->pll_reg); ++ DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", ++ crtc->base.base.id, pll->name); + + goto found; + } +@@ -3109,9 +3109,9 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, + + if (dpll == (I915_READ(pll->pll_reg) & 0x7fffffff) && + fp == I915_READ(pll->fp0_reg)) { +- DRM_DEBUG_KMS("CRTC:%d sharing existing PCH PLL %x (refcount %d, ative %d)\n", ++ DRM_DEBUG_KMS("CRTC:%d sharing existing %s (refcount %d, ative %d)\n", + crtc->base.base.id, +- pll->pll_reg, pll->refcount, pll->active); ++ pll->name, pll->refcount, pll->active); + + goto found; + } +@@ -3121,8 +3121,8 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + pll = &dev_priv->shared_dplls[i]; + if (pll->refcount == 0) { +- DRM_DEBUG_KMS("CRTC:%d allocated PCH PLL %x\n", +- crtc->base.base.id, pll->pll_reg); ++ DRM_DEBUG_KMS("CRTC:%d allocated %s\n", ++ crtc->base.base.id, pll->name); + goto found; + } + } +@@ -3131,9 +3131,10 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, + + found: + crtc->config.shared_dpll = i; +- DRM_DEBUG_DRIVER("using pll %d for pipe %c\n", i, pipe_name(crtc->pipe)); ++ DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name, ++ pipe_name(crtc->pipe)); + if (pll->active == 0) { +- DRM_DEBUG_DRIVER("setting up pll %d\n", i); ++ DRM_DEBUG_DRIVER("setting up %s\n", pll->name); + WARN_ON(pll->on); + assert_shared_dpll_disabled(dev_priv, pll, NULL); + +@@ -8755,6 +8756,11 @@ static void intel_cpu_pll_init(struct drm_device *dev) + intel_ddi_pll_init(dev); + } + ++static char *ibx_pch_dpll_names[] = { ++ "PCH DPLL A", ++ "PCH DPLL B", ++}; ++ + static void ibx_pch_dpll_init(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; +@@ -8763,6 +8769,8 @@ static void ibx_pch_dpll_init(struct drm_device *dev) + dev_priv->num_shared_dpll = 2; + + for (i = 0; i < dev_priv->num_shared_dpll; i++) { ++ dev_priv->shared_dplls[i].id = i; ++ dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i]; + dev_priv->shared_dplls[i].pll_reg = _PCH_DPLL(i); + dev_priv->shared_dplls[i].fp0_reg = _PCH_FP0(i); + dev_priv->shared_dplls[i].fp1_reg = _PCH_FP1(i); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0300-drm-i915-scrap-register-address-storage.patch b/patches.baytrail/0300-drm-i915-scrap-register-address-storage.patch new file mode 100644 index 000000000000..7f1dbf6b965e --- /dev/null +++ b/patches.baytrail/0300-drm-i915-scrap-register-address-storage.patch @@ -0,0 +1,191 @@ +From e560ad6046950a9f20045d98563b0da19177128f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:13 +0200 +Subject: drm/i915: scrap register address storage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Using ids in register macros is much more common in our driver. Also +this way we can reduce the platform specific stuff a bit. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit e9a632a578e0205c1fb015bb01af49c2ae71d6f2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 3 --- + drivers/gpu/drm/i915/i915_reg.h | 6 +++--- + drivers/gpu/drm/i915/i915_ums.c | 2 +- + drivers/gpu/drm/i915/intel_display.c | 35 ++++++++++++++++------------------- + 4 files changed, 20 insertions(+), 26 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 7e3d3b349bf6..c0779fe39576 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -147,9 +147,6 @@ struct intel_shared_dpll { + const char *name; + /* should match the index in the dev_priv->shared_dplls array */ + enum intel_dpll_id id; +- int pll_reg; +- int fp0_reg; +- int fp1_reg; + }; + + /* Used by dp and fdi links */ +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 776ef89cda14..f21d0f5dc9f2 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -3936,15 +3936,15 @@ + + #define _PCH_DPLL_A 0xc6014 + #define _PCH_DPLL_B 0xc6018 +-#define _PCH_DPLL(pll) (pll == 0 ? _PCH_DPLL_A : _PCH_DPLL_B) ++#define PCH_DPLL(pll) (pll == 0 ? _PCH_DPLL_A : _PCH_DPLL_B) + + #define _PCH_FPA0 0xc6040 + #define FP_CB_TUNE (0x3<<22) + #define _PCH_FPA1 0xc6044 + #define _PCH_FPB0 0xc6048 + #define _PCH_FPB1 0xc604c +-#define _PCH_FP0(pll) (pll == 0 ? _PCH_FPA0 : _PCH_FPB0) +-#define _PCH_FP1(pll) (pll == 0 ? _PCH_FPA1 : _PCH_FPB1) ++#define PCH_FP0(pll) (pll == 0 ? _PCH_FPA0 : _PCH_FPB0) ++#define PCH_FP1(pll) (pll == 0 ? _PCH_FPA1 : _PCH_FPB1) + + #define PCH_DPLL_TEST 0xc606c + +diff --git a/drivers/gpu/drm/i915/i915_ums.c b/drivers/gpu/drm/i915/i915_ums.c +index 5ef30b2e6bc6..967da4772c44 100644 +--- a/drivers/gpu/drm/i915/i915_ums.c ++++ b/drivers/gpu/drm/i915/i915_ums.c +@@ -41,7 +41,7 @@ static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) + return false; + + if (HAS_PCH_SPLIT(dev)) +- dpll_reg = _PCH_DPLL(pipe); ++ dpll_reg = PCH_DPLL(pipe); + else + dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B; + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 3e5eeb0b5dec..cbe2a077a822 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -938,7 +938,7 @@ static void assert_shared_dpll(struct drm_i915_private *dev_priv, + "asserting DPLL %s with no DPLL\n", state_string(state))) + return; + +- val = I915_READ(pll->pll_reg); ++ val = I915_READ(PCH_DPLL(pll->id)); + cur_state = !!(val & DPLL_VCO_ENABLE); + WARN(cur_state != state, + "%s assertion failure (expected %s, current %s), val=%08x\n", +@@ -949,14 +949,14 @@ static void assert_shared_dpll(struct drm_i915_private *dev_priv, + u32 pch_dpll; + + pch_dpll = I915_READ(PCH_DPLL_SEL); +- cur_state = pll->pll_reg == _PCH_DPLL_B; ++ cur_state = pll->id == DPLL_ID_PCH_PLL_B; + if (!WARN(((pch_dpll >> (4 * crtc->pipe)) & 1) != cur_state, + "PLL[%d] not attached to this transcoder %c: %08x\n", + cur_state, pipe_name(crtc->pipe), pch_dpll)) { + cur_state = !!(val >> (4*crtc->pipe + 3)); + WARN(cur_state != state, + "PLL[%d] not %s on this transcoder %c: %08x\n", +- pll->pll_reg == _PCH_DPLL_B, ++ pll->id == DPLL_ID_PCH_PLL_B, + state_string(state), + pipe_name(crtc->pipe), + val); +@@ -1446,7 +1446,7 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *crtc) + + DRM_DEBUG_KMS("enabling %s\n", pll->name); + +- reg = pll->pll_reg; ++ reg = PCH_DPLL(pll->id); + val = I915_READ(reg); + val |= DPLL_VCO_ENABLE; + I915_WRITE(reg, val); +@@ -1490,7 +1490,7 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc) + /* Make sure transcoder isn't still depending on us */ + assert_pch_transcoder_disabled(dev_priv, crtc->pipe); + +- reg = pll->pll_reg; ++ reg = PCH_DPLL(pll->id); + val = I915_READ(reg); + val &= ~DPLL_VCO_ENABLE; + I915_WRITE(reg, val); +@@ -3107,8 +3107,8 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, + if (pll->refcount == 0) + continue; + +- if (dpll == (I915_READ(pll->pll_reg) & 0x7fffffff) && +- fp == I915_READ(pll->fp0_reg)) { ++ if (dpll == (I915_READ(PCH_DPLL(pll->id)) & 0x7fffffff) && ++ fp == I915_READ(PCH_FP0(pll->id))) { + DRM_DEBUG_KMS("CRTC:%d sharing existing %s (refcount %d, ative %d)\n", + crtc->base.base.id, + pll->name, pll->refcount, pll->active); +@@ -3139,12 +3139,12 @@ found: + assert_shared_dpll_disabled(dev_priv, pll, NULL); + + /* Wait for the clocks to stabilize before rewriting the regs */ +- I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE); +- POSTING_READ(pll->pll_reg); ++ I915_WRITE(PCH_DPLL(pll->id), dpll & ~DPLL_VCO_ENABLE); ++ POSTING_READ(PCH_DPLL(pll->id)); + udelay(150); + +- I915_WRITE(pll->fp0_reg, fp); +- I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE); ++ I915_WRITE(PCH_FP0(pll->id), fp); ++ I915_WRITE(PCH_DPLL(pll->id), dpll & ~DPLL_VCO_ENABLE); + } + pll->refcount++; + +@@ -5785,10 +5785,10 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + if (intel_crtc->config.has_pch_encoder) { + pll = intel_crtc_to_shared_dpll(intel_crtc); + +- I915_WRITE(pll->pll_reg, dpll); ++ I915_WRITE(PCH_DPLL(pll->id), dpll); + + /* Wait for the clocks to stabilize. */ +- POSTING_READ(pll->pll_reg); ++ POSTING_READ(PCH_DPLL(pll->id)); + udelay(150); + + /* The pixel multiplier can only be updated once the +@@ -5796,13 +5796,13 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + * + * So write it again. + */ +- I915_WRITE(pll->pll_reg, dpll); ++ I915_WRITE(PCH_DPLL(pll->id), dpll); + + if (is_lvds && has_reduced_clock && i915_powersave) { +- I915_WRITE(pll->fp1_reg, fp2); ++ I915_WRITE(PCH_FP1(pll->id), fp2); + intel_crtc->lowfreq_avail = true; + } else { +- I915_WRITE(pll->fp1_reg, fp); ++ I915_WRITE(PCH_FP1(pll->id), fp); + } + } + +@@ -8771,9 +8771,6 @@ static void ibx_pch_dpll_init(struct drm_device *dev) + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + dev_priv->shared_dplls[i].id = i; + dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i]; +- dev_priv->shared_dplls[i].pll_reg = _PCH_DPLL(i); +- dev_priv->shared_dplls[i].fp0_reg = _PCH_FP0(i); +- dev_priv->shared_dplls[i].fp1_reg = _PCH_FP1(i); + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0301-drm-i915-enable-disable-hooks-for-shared-dplls.patch b/patches.baytrail/0301-drm-i915-enable-disable-hooks-for-shared-dplls.patch new file mode 100644 index 000000000000..6b7aebcb1ce5 --- /dev/null +++ b/patches.baytrail/0301-drm-i915-enable-disable-hooks-for-shared-dplls.patch @@ -0,0 +1,194 @@ +From 9343f3db115d6952668ac1eafc70b1849345d5c8 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:14 +0200 +Subject: drm/i915: enable/disable hooks for shared dplls +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Looks at first like a bit of overkill, but +- Haswell actually wants different enable/disable functions for + different plls. +- And once we have full dpll hw state tracking we can move the full + register setup into the ->enable hook. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit e7b903d2525fe3be12b6535a27915186529a51b4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 7 +++- + drivers/gpu/drm/i915/intel_display.c | 71 ++++++++++++++++++++++-------------- + 2 files changed, 49 insertions(+), 29 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index c0779fe39576..aaff7ddc4162 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -132,6 +132,8 @@ enum hpd_pin { + list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ + if ((intel_encoder)->base.crtc == (__crtc)) + ++struct drm_i915_private; ++ + enum intel_dpll_id { + DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */ + /* real shared dpll ids must be >= 0 */ +@@ -147,6 +149,10 @@ struct intel_shared_dpll { + const char *name; + /* should match the index in the dev_priv->shared_dplls array */ + enum intel_dpll_id id; ++ void (*enable)(struct drm_i915_private *dev_priv, ++ struct intel_shared_dpll *pll); ++ void (*disable)(struct drm_i915_private *dev_priv, ++ struct intel_shared_dpll *pll); + }; + + /* Used by dp and fdi links */ +@@ -202,7 +208,6 @@ struct opregion_header; + struct opregion_acpi; + struct opregion_swsci; + struct opregion_asle; +-struct drm_i915_private; + + struct intel_opregion { + struct opregion_header __iomem *header; +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index cbe2a077a822..4dd9e134f687 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1419,8 +1419,6 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *crtc) + { + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); +- int reg; +- u32 val; + + /* PCH PLLs only available on ILK, SNB and IVB */ + BUG_ON(dev_priv->info->gen < 5); +@@ -1434,9 +1432,6 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *crtc) + pll->name, pll->active, pll->on, + crtc->base.base.id); + +- /* PCH refclock must be enabled first */ +- assert_pch_refclk_enabled(dev_priv); +- + if (pll->active++) { + WARN_ON(!pll->on); + assert_shared_dpll_enabled(dev_priv, pll, NULL); +@@ -1445,14 +1440,7 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *crtc) + WARN_ON(pll->on); + + DRM_DEBUG_KMS("enabling %s\n", pll->name); +- +- reg = PCH_DPLL(pll->id); +- val = I915_READ(reg); +- val |= DPLL_VCO_ENABLE; +- I915_WRITE(reg, val); +- POSTING_READ(reg); +- udelay(200); +- ++ pll->enable(dev_priv, pll); + pll->on = true; + } + +@@ -1460,8 +1448,6 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc) + { + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); +- int reg; +- u32 val; + + /* PCH only available on ILK+ */ + BUG_ON(dev_priv->info->gen < 5); +@@ -1486,17 +1472,7 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc) + return; + + DRM_DEBUG_KMS("disabling %s\n", pll->name); +- +- /* Make sure transcoder isn't still depending on us */ +- assert_pch_transcoder_disabled(dev_priv, crtc->pipe); +- +- reg = PCH_DPLL(pll->id); +- val = I915_READ(reg); +- val &= ~DPLL_VCO_ENABLE; +- I915_WRITE(reg, val); +- POSTING_READ(reg); +- udelay(200); +- ++ pll->disable(dev_priv, pll); + pll->on = false; + } + +@@ -8756,6 +8732,43 @@ static void intel_cpu_pll_init(struct drm_device *dev) + intel_ddi_pll_init(dev); + } + ++static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv, ++ struct intel_shared_dpll *pll) ++{ ++ uint32_t reg, val; ++ ++ /* PCH refclock must be enabled first */ ++ assert_pch_refclk_enabled(dev_priv); ++ ++ reg = PCH_DPLL(pll->id); ++ val = I915_READ(reg); ++ val |= DPLL_VCO_ENABLE; ++ I915_WRITE(reg, val); ++ POSTING_READ(reg); ++ udelay(200); ++} ++ ++static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv, ++ struct intel_shared_dpll *pll) ++{ ++ struct drm_device *dev = dev_priv->dev; ++ struct intel_crtc *crtc; ++ uint32_t reg, val; ++ ++ /* Make sure no transcoder isn't still depending on us. */ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { ++ if (intel_crtc_to_shared_dpll(crtc) == pll) ++ assert_pch_transcoder_disabled(dev_priv, crtc->pipe); ++ } ++ ++ reg = PCH_DPLL(pll->id); ++ val = I915_READ(reg); ++ val &= ~DPLL_VCO_ENABLE; ++ I915_WRITE(reg, val); ++ POSTING_READ(reg); ++ udelay(200); ++} ++ + static char *ibx_pch_dpll_names[] = { + "PCH DPLL A", + "PCH DPLL B", +@@ -8763,7 +8776,7 @@ static char *ibx_pch_dpll_names[] = { + + static void ibx_pch_dpll_init(struct drm_device *dev) + { +- drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = dev->dev_private; + int i; + + dev_priv->num_shared_dpll = 2; +@@ -8771,12 +8784,14 @@ static void ibx_pch_dpll_init(struct drm_device *dev) + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + dev_priv->shared_dplls[i].id = i; + dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i]; ++ dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable; ++ dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable; + } + } + + static void intel_shared_dpll_init(struct drm_device *dev) + { +- drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = dev->dev_private; + + if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) + ibx_pch_dpll_init(dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0302-drm-i915-drop-crtc-checking-from-assert_shared_dpll.patch b/patches.baytrail/0302-drm-i915-drop-crtc-checking-from-assert_shared_dpll.patch new file mode 100644 index 000000000000..2e97b3b05496 --- /dev/null +++ b/patches.baytrail/0302-drm-i915-drop-crtc-checking-from-assert_shared_dpll.patch @@ -0,0 +1,107 @@ +From 214ac6d59b698fa49712b1592dcac43de38d8bc7 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:15 +0200 +Subject: drm/i915: drop crtc checking from assert_shared_dpll +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The hw state readout code for the pipe config will now check +this for us, so rip out this hand-rolled complexity. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit e9d6944ed75dbf16ae34bb73bd1eeca7cb183b67) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 35 +++++++---------------------------- + 1 file changed, 7 insertions(+), 28 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 4dd9e134f687..f29c8a4477da 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -923,7 +923,6 @@ intel_crtc_to_shared_dpll(struct intel_crtc *crtc) + /* For ILK+ */ + static void assert_shared_dpll(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, +- struct intel_crtc *crtc, + bool state) + { + u32 val; +@@ -943,28 +942,9 @@ static void assert_shared_dpll(struct drm_i915_private *dev_priv, + WARN(cur_state != state, + "%s assertion failure (expected %s, current %s), val=%08x\n", + pll->name, state_string(state), state_string(cur_state), val); +- +- /* Make sure the selected PLL is correctly attached to the transcoder */ +- if (crtc && HAS_PCH_CPT(dev_priv->dev)) { +- u32 pch_dpll; +- +- pch_dpll = I915_READ(PCH_DPLL_SEL); +- cur_state = pll->id == DPLL_ID_PCH_PLL_B; +- if (!WARN(((pch_dpll >> (4 * crtc->pipe)) & 1) != cur_state, +- "PLL[%d] not attached to this transcoder %c: %08x\n", +- cur_state, pipe_name(crtc->pipe), pch_dpll)) { +- cur_state = !!(val >> (4*crtc->pipe + 3)); +- WARN(cur_state != state, +- "PLL[%d] not %s on this transcoder %c: %08x\n", +- pll->id == DPLL_ID_PCH_PLL_B, +- state_string(state), +- pipe_name(crtc->pipe), +- val); +- } +- } + } +-#define assert_shared_dpll_enabled(d, p, c) assert_shared_dpll(d, p, c, true) +-#define assert_shared_dpll_disabled(d, p, c) assert_shared_dpll(d, p, c, false) ++#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true) ++#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false) + + static void assert_fdi_tx(struct drm_i915_private *dev_priv, + enum pipe pipe, bool state) +@@ -1434,7 +1414,7 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *crtc) + + if (pll->active++) { + WARN_ON(!pll->on); +- assert_shared_dpll_enabled(dev_priv, pll, NULL); ++ assert_shared_dpll_enabled(dev_priv, pll); + return; + } + WARN_ON(pll->on); +@@ -1462,11 +1442,11 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc) + crtc->base.base.id); + + if (WARN_ON(pll->active == 0)) { +- assert_shared_dpll_disabled(dev_priv, pll, NULL); ++ assert_shared_dpll_disabled(dev_priv, pll); + return; + } + +- assert_shared_dpll_enabled(dev_priv, pll, NULL); ++ assert_shared_dpll_enabled(dev_priv, pll); + WARN_ON(!pll->on); + if (--pll->active) + return; +@@ -1489,8 +1469,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, + + /* Make sure PCH DPLL is enabled */ + assert_shared_dpll_enabled(dev_priv, +- intel_crtc_to_shared_dpll(intel_crtc), +- intel_crtc); ++ intel_crtc_to_shared_dpll(intel_crtc)); + + /* FDI must be feeding us bits for PCH ports */ + assert_fdi_tx_enabled(dev_priv, pipe); +@@ -3112,7 +3091,7 @@ found: + if (pll->active == 0) { + DRM_DEBUG_DRIVER("setting up %s\n", pll->name); + WARN_ON(pll->on); +- assert_shared_dpll_disabled(dev_priv, pll, NULL); ++ assert_shared_dpll_disabled(dev_priv, pll); + + /* Wait for the clocks to stabilize before rewriting the regs */ + I915_WRITE(PCH_DPLL(pll->id), dpll & ~DPLL_VCO_ENABLE); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0303-drm-i915-Fix-old-reference-to-i830_sdvo_get_capabili.patch b/patches.baytrail/0303-drm-i915-Fix-old-reference-to-i830_sdvo_get_capabili.patch new file mode 100644 index 000000000000..6060c15c0024 --- /dev/null +++ b/patches.baytrail/0303-drm-i915-Fix-old-reference-to-i830_sdvo_get_capabili.patch @@ -0,0 +1,31 @@ +From 49ee3b66adbd7fbf83d3e8f2298bc2af0fd99b26 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 10 Jun 2013 13:28:42 +0100 +Subject: drm/i915: Fix old reference to i830_sdvo_get_capabilities() + +It's now intel_sdvo_get_capabilities(). + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 19d415a25e9078dba26adb54396d4e5b30d3b572) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sdvo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 5c53fc79977a..019b0380a3d6 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -80,7 +80,7 @@ struct intel_sdvo { + + /* + * Capabilities of the SDVO device returned by +- * i830_sdvo_get_capabilities() ++ * intel_sdvo_get_capabilities() + */ + struct intel_sdvo_caps caps; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0304-drm-i915-Initialize-active_outputs-to-never-read-uni.patch b/patches.baytrail/0304-drm-i915-Initialize-active_outputs-to-never-read-uni.patch new file mode 100644 index 000000000000..e22020e9909d --- /dev/null +++ b/patches.baytrail/0304-drm-i915-Initialize-active_outputs-to-never-read-uni.patch @@ -0,0 +1,41 @@ +From 5c0a059d629b00e5497d444fa41dab8b523134fb Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 10 Jun 2013 13:49:25 +0100 +Subject: drm/i915: Initialize active_outputs to never read unitialized values + +In case of intel_sdvo_get_active_outputs() failing, we end up reading a +value from the stack. + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 2f28c50bb3881f11afee8f8c9041dad2c96653aa) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sdvo.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 019b0380a3d6..44609b623100 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1277,7 +1277,7 @@ static bool intel_sdvo_connector_get_hw_state(struct intel_connector *connector) + struct intel_sdvo_connector *intel_sdvo_connector = + to_intel_sdvo_connector(&connector->base); + struct intel_sdvo *intel_sdvo = intel_attached_sdvo(&connector->base); +- u16 active_outputs; ++ u16 active_outputs = 0; + + intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs); + +@@ -1293,7 +1293,7 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); +- u16 active_outputs; ++ u16 active_outputs = 0; + u32 tmp; + + tmp = I915_READ(intel_sdvo->sdvo_reg); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0305-drm-i915-Initialize-ring-hangcheck-upon-ring-init.patch b/patches.baytrail/0305-drm-i915-Initialize-ring-hangcheck-upon-ring-init.patch new file mode 100644 index 000000000000..52b01563a75d --- /dev/null +++ b/patches.baytrail/0305-drm-i915-Initialize-ring-hangcheck-upon-ring-init.patch @@ -0,0 +1,33 @@ +From c4b39cf5636e20fd0bc0ec734078dbb1f8d29a51 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 10 Jun 2013 11:20:19 +0100 +Subject: drm/i915: Initialize ring->hangcheck upon ring init + +When we reset and restart a ring, we also want to clear any existing +hangcheck. + +Signed-off-by: Chris Wilson +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 50f018dff180942dc40e601de6e97145a4aaeaa9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ringbuffer.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 07a949c042f2..1d4a7ee41881 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -453,6 +453,8 @@ static int init_ring_common(struct intel_ring_buffer *ring) + ring->last_retired_head = -1; + } + ++ memset(&ring->hangcheck, 0, sizeof(ring->hangcheck)); ++ + out: + if (HAS_FORCE_WAKE(dev)) + gen6_gt_force_wake_put(dev_priv); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0306-drm-i915-Only-slightly-increment-hangcheck-score-if-.patch b/patches.baytrail/0306-drm-i915-Only-slightly-increment-hangcheck-score-if-.patch new file mode 100644 index 000000000000..1bc76ac63aab --- /dev/null +++ b/patches.baytrail/0306-drm-i915-Only-slightly-increment-hangcheck-score-if-.patch @@ -0,0 +1,215 @@ +From ac8570c9d2d2d6f199dcc020d34a421ffe02f98e Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 10 Jun 2013 11:20:20 +0100 +Subject: drm/i915: Only slightly increment hangcheck score if we succesfully + kick a ring + +After kicking a ring, it should be free to make progress again and so +should not be accused of being stuck until hangcheck fires once more. In +order to catch a denial-of-service within a batch or across multiple +batches, we still do increment the hangcheck score - just not as +severely so that it takes multiple kicks to fail. + +This should address part of Ben's justified criticism of + +commit 05407ff889ceebe383aa5907219f86582ef96b72 +Author: Mika Kuoppala +Date: Thu May 30 09:04:29 2013 +0300 + + drm/i915: detect hang using per ring hangcheck_score + +"There's also another corner case on the kick. If the seqno = 2 +(though not stuck), and on the 3rd hangcheck, the ring is stuck, and +we try to kick it... we don't actually try to find out if the kick +helped." + +v2: Make sure we catch DoS attempts with batches full of invalid WAITs. +v3: Preserve the ability to detect loops by always charging the ring + if it is busy on the same request. +v4: Make sure we queue another check if on a new batch + +References: https://bugs.freedesktop.org/show_bug.cgi?id=65394 +Signed-off-by: Chris Wilson +Cc: Mika Kuoppala +Cc: Ben Widawsky +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 9107e9d227e3b0893829baee4ac59feb874d4c23) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 110 +++++++++++++++++++++------------------- + 1 file changed, 58 insertions(+), 52 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 8916651b3e1e..b1e504a8d531 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2351,21 +2351,11 @@ ring_last_seqno(struct intel_ring_buffer *ring) + struct drm_i915_gem_request, list)->seqno; + } + +-static bool i915_hangcheck_ring_idle(struct intel_ring_buffer *ring, +- u32 ring_seqno, bool *err) +-{ +- if (list_empty(&ring->request_list) || +- i915_seqno_passed(ring_seqno, ring_last_seqno(ring))) { +- /* Issue a wake-up to catch stuck h/w. */ +- if (waitqueue_active(&ring->irq_queue)) { +- DRM_ERROR("Hangcheck timer elapsed... %s idle\n", +- ring->name); +- wake_up_all(&ring->irq_queue); +- *err = true; +- } +- return true; +- } +- return false; ++static bool ++ring_idle(struct intel_ring_buffer *ring, u32 seqno) ++{ ++ return (list_empty(&ring->request_list) || ++ i915_seqno_passed(seqno, ring_last_seqno(ring))); + } + + static bool semaphore_passed(struct intel_ring_buffer *ring) +@@ -2399,16 +2389,26 @@ static bool semaphore_passed(struct intel_ring_buffer *ring) + ioread32(ring->virtual_start+acthd+4)+1); + } + +-static bool kick_ring(struct intel_ring_buffer *ring) ++static bool ring_hung(struct intel_ring_buffer *ring) + { + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- u32 tmp = I915_READ_CTL(ring); ++ u32 tmp; ++ ++ if (IS_GEN2(dev)) ++ return true; ++ ++ /* Is the chip hanging on a WAIT_FOR_EVENT? ++ * If so we can simply poke the RB_WAIT bit ++ * and break the hang. This should work on ++ * all but the second generation chipsets. ++ */ ++ tmp = I915_READ_CTL(ring); + if (tmp & RING_WAIT) { + DRM_ERROR("Kicking stuck wait on %s\n", + ring->name); + I915_WRITE_CTL(ring, tmp); +- return true; ++ return false; + } + + if (INTEL_INFO(dev)->gen >= 6 && +@@ -2417,22 +2417,10 @@ static bool kick_ring(struct intel_ring_buffer *ring) + DRM_ERROR("Kicking stuck semaphore on %s\n", + ring->name); + I915_WRITE_CTL(ring, tmp); +- return true; +- } +- return false; +-} +- +-static bool i915_hangcheck_ring_hung(struct intel_ring_buffer *ring) +-{ +- if (IS_GEN2(ring->dev)) + return false; ++ } + +- /* Is the chip hanging on a WAIT_FOR_EVENT? +- * If so we can simply poke the RB_WAIT bit +- * and break the hang. This should work on +- * all but the second generation chipsets. +- */ +- return !kick_ring(ring); ++ return true; + } + + /** +@@ -2450,45 +2438,63 @@ void i915_hangcheck_elapsed(unsigned long data) + struct intel_ring_buffer *ring; + int i; + int busy_count = 0, rings_hung = 0; +- bool stuck[I915_NUM_RINGS]; ++ bool stuck[I915_NUM_RINGS] = { 0 }; ++#define BUSY 1 ++#define KICK 5 ++#define HUNG 20 ++#define FIRE 30 + + if (!i915_enable_hangcheck) + return; + + for_each_ring(ring, dev_priv, i) { + u32 seqno, acthd; +- bool idle, err = false; ++ bool busy = true; + + seqno = ring->get_seqno(ring, false); + acthd = intel_ring_get_active_head(ring); +- idle = i915_hangcheck_ring_idle(ring, seqno, &err); +- stuck[i] = ring->hangcheck.acthd == acthd; +- +- if (idle) { +- if (err) +- ring->hangcheck.score += 2; +- else +- ring->hangcheck.score = 0; +- } else { +- busy_count++; + +- if (ring->hangcheck.seqno == seqno) { +- ring->hangcheck.score++; +- +- /* Kick ring if stuck*/ +- if (stuck[i]) +- i915_hangcheck_ring_hung(ring); ++ if (ring->hangcheck.seqno == seqno) { ++ if (ring_idle(ring, seqno)) { ++ if (waitqueue_active(&ring->irq_queue)) { ++ /* Issue a wake-up to catch stuck h/w. */ ++ DRM_ERROR("Hangcheck timer elapsed... %s idle\n", ++ ring->name); ++ wake_up_all(&ring->irq_queue); ++ ring->hangcheck.score += HUNG; ++ } else ++ busy = false; + } else { +- ring->hangcheck.score = 0; ++ int score; ++ ++ stuck[i] = ring->hangcheck.acthd == acthd; ++ if (stuck[i]) { ++ /* Every time we kick the ring, add a ++ * small increment to the hangcheck ++ * score so that we can catch a ++ * batch that is repeatedly kicked. ++ */ ++ score = ring_hung(ring) ? HUNG : KICK; ++ } else ++ score = BUSY; ++ ++ ring->hangcheck.score += score; + } ++ } else { ++ /* Gradually reduce the count so that we catch DoS ++ * attempts across multiple batches. ++ */ ++ if (ring->hangcheck.score > 0) ++ ring->hangcheck.score--; + } + + ring->hangcheck.seqno = seqno; + ring->hangcheck.acthd = acthd; ++ busy_count += busy; + } + + for_each_ring(ring, dev_priv, i) { +- if (ring->hangcheck.score > 2) { ++ if (ring->hangcheck.score > FIRE) { + rings_hung++; + DRM_ERROR("%s: %s on %s 0x%x\n", ring->name, + stuck[i] ? "stuck" : "no progress", +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0307-drm-i915-Don-t-count-semaphore-waits-towards-a-stuck.patch b/patches.baytrail/0307-drm-i915-Don-t-count-semaphore-waits-towards-a-stuck.patch new file mode 100644 index 000000000000..c81d35c4041f --- /dev/null +++ b/patches.baytrail/0307-drm-i915-Don-t-count-semaphore-waits-towards-a-stuck.patch @@ -0,0 +1,237 @@ +From 73e8d739d327e068bdf4bae329d273583f0ef8d2 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 10 Jun 2013 11:20:21 +0100 +Subject: drm/i915: Don't count semaphore waits towards a stuck ring + +If we detect a ring is in a valid wait for another, just let it be. +Eventually it will either begin to progress again, or the entire system +will come grinding to a halt and then hangcheck will fire as soon as the +deadlock is detected. + +This error was foretold by Ben in +commit 05407ff889ceebe383aa5907219f86582ef96b72 +Author: Mika Kuoppala +Date: Thu May 30 09:04:29 2013 +0300 + + drm/i915: detect hang using per ring hangcheck_score + +"If ring B is waiting on ring A via semaphore, and ring A is making +progress, albeit slowly - the hangcheck will fire. The check will +determine that A is moving, however ring B will appear hung because +the ACTHD doesn't move. I honestly can't say if that's actually a +realistic problem to hit it probably implies the timeout value is too +low." + +v2: Make sure we don't even incur the KICK cost whilst waiting. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65394 +Signed-off-by: Chris Wilson +Cc: Mika Kuoppala +Cc: Ben Widawsky +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 6274f2126a0454d3c3df1bc9cc6f5e18302696f7) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 121 +++++++++++++++++++++++--------- + drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + + 2 files changed, 90 insertions(+), 32 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index b1e504a8d531..486016b641e8 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2358,21 +2358,21 @@ ring_idle(struct intel_ring_buffer *ring, u32 seqno) + i915_seqno_passed(seqno, ring_last_seqno(ring))); + } + +-static bool semaphore_passed(struct intel_ring_buffer *ring) ++static struct intel_ring_buffer * ++semaphore_waits_for(struct intel_ring_buffer *ring, u32 *seqno) + { + struct drm_i915_private *dev_priv = ring->dev->dev_private; +- u32 acthd = intel_ring_get_active_head(ring) & HEAD_ADDR; +- struct intel_ring_buffer *signaller; +- u32 cmd, ipehr, acthd_min; ++ u32 cmd, ipehr, acthd, acthd_min; + + ipehr = I915_READ(RING_IPEHR(ring->mmio_base)); + if ((ipehr & ~(0x3 << 16)) != + (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | MI_SEMAPHORE_REGISTER)) +- return false; ++ return NULL; + + /* ACTHD is likely pointing to the dword after the actual command, + * so scan backwards until we find the MBOX. + */ ++ acthd = intel_ring_get_active_head(ring) & HEAD_ADDR; + acthd_min = max((int)acthd - 3 * 4, 0); + do { + cmd = ioread32(ring->virtual_start + acthd); +@@ -2381,22 +2381,53 @@ static bool semaphore_passed(struct intel_ring_buffer *ring) + + acthd -= 4; + if (acthd < acthd_min) +- return false; ++ return NULL; + } while (1); + +- signaller = &dev_priv->ring[(ring->id + (((ipehr >> 17) & 1) + 1)) % 3]; +- return i915_seqno_passed(signaller->get_seqno(signaller, false), +- ioread32(ring->virtual_start+acthd+4)+1); ++ *seqno = ioread32(ring->virtual_start+acthd+4)+1; ++ return &dev_priv->ring[(ring->id + (((ipehr >> 17) & 1) + 1)) % 3]; + } + +-static bool ring_hung(struct intel_ring_buffer *ring) ++static int semaphore_passed(struct intel_ring_buffer *ring) ++{ ++ struct drm_i915_private *dev_priv = ring->dev->dev_private; ++ struct intel_ring_buffer *signaller; ++ u32 seqno, ctl; ++ ++ ring->hangcheck.deadlock = true; ++ ++ signaller = semaphore_waits_for(ring, &seqno); ++ if (signaller == NULL || signaller->hangcheck.deadlock) ++ return -1; ++ ++ /* cursory check for an unkickable deadlock */ ++ ctl = I915_READ_CTL(signaller); ++ if (ctl & RING_WAIT_SEMAPHORE && semaphore_passed(signaller) < 0) ++ return -1; ++ ++ return i915_seqno_passed(signaller->get_seqno(signaller, false), seqno); ++} ++ ++static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) ++{ ++ struct intel_ring_buffer *ring; ++ int i; ++ ++ for_each_ring(ring, dev_priv, i) ++ ring->hangcheck.deadlock = false; ++} ++ ++static enum { wait, active, kick, hung } ring_stuck(struct intel_ring_buffer *ring, u32 acthd) + { + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 tmp; + ++ if (ring->hangcheck.acthd != acthd) ++ return active; ++ + if (IS_GEN2(dev)) +- return true; ++ return hung; + + /* Is the chip hanging on a WAIT_FOR_EVENT? + * If so we can simply poke the RB_WAIT bit +@@ -2408,19 +2439,24 @@ static bool ring_hung(struct intel_ring_buffer *ring) + DRM_ERROR("Kicking stuck wait on %s\n", + ring->name); + I915_WRITE_CTL(ring, tmp); +- return false; +- } +- +- if (INTEL_INFO(dev)->gen >= 6 && +- tmp & RING_WAIT_SEMAPHORE && +- semaphore_passed(ring)) { +- DRM_ERROR("Kicking stuck semaphore on %s\n", +- ring->name); +- I915_WRITE_CTL(ring, tmp); +- return false; ++ return kick; ++ } ++ ++ if (INTEL_INFO(dev)->gen >= 6 && tmp & RING_WAIT_SEMAPHORE) { ++ switch (semaphore_passed(ring)) { ++ default: ++ return hung; ++ case 1: ++ DRM_ERROR("Kicking stuck semaphore on %s\n", ++ ring->name); ++ I915_WRITE_CTL(ring, tmp); ++ return kick; ++ case 0: ++ return wait; ++ } + } + +- return true; ++ return hung; + } + + /** +@@ -2451,6 +2487,8 @@ void i915_hangcheck_elapsed(unsigned long data) + u32 seqno, acthd; + bool busy = true; + ++ semaphore_clear_deadlocks(dev_priv); ++ + seqno = ring->get_seqno(ring, false); + acthd = intel_ring_get_active_head(ring); + +@@ -2467,17 +2505,36 @@ void i915_hangcheck_elapsed(unsigned long data) + } else { + int score; + +- stuck[i] = ring->hangcheck.acthd == acthd; +- if (stuck[i]) { +- /* Every time we kick the ring, add a +- * small increment to the hangcheck +- * score so that we can catch a +- * batch that is repeatedly kicked. +- */ +- score = ring_hung(ring) ? HUNG : KICK; +- } else ++ /* We always increment the hangcheck score ++ * if the ring is busy and still processing ++ * the same request, so that no single request ++ * can run indefinitely (such as a chain of ++ * batches). The only time we do not increment ++ * the hangcheck score on this ring, if this ++ * ring is in a legitimate wait for another ++ * ring. In that case the waiting ring is a ++ * victim and we want to be sure we catch the ++ * right culprit. Then every time we do kick ++ * the ring, add a small increment to the ++ * score so that we can catch a batch that is ++ * being repeatedly kicked and so responsible ++ * for stalling the machine. ++ */ ++ switch (ring_stuck(ring, acthd)) { ++ case wait: ++ score = 0; ++ break; ++ case active: + score = BUSY; +- ++ break; ++ case kick: ++ score = KICK; ++ break; ++ case hung: ++ score = HUNG; ++ stuck[i] = true; ++ break; ++ } + ring->hangcheck.score += score; + } + } else { +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index efc403d1e3e0..a3e96103dbe5 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -38,6 +38,7 @@ struct intel_hw_status_page { + #define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base)) + + struct intel_ring_hangcheck { ++ bool deadlock; + u32 seqno; + u32 acthd; + int score; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0308-drm-i915-Eliminate-the-addr-seqno-from-the-hangcheck.patch b/patches.baytrail/0308-drm-i915-Eliminate-the-addr-seqno-from-the-hangcheck.patch new file mode 100644 index 000000000000..31fff6675763 --- /dev/null +++ b/patches.baytrail/0308-drm-i915-Eliminate-the-addr-seqno-from-the-hangcheck.patch @@ -0,0 +1,40 @@ +From ecb0044dc539859dbfea59587f9807258fabd665 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 10 Jun 2013 11:20:22 +0100 +Subject: drm/i915: Eliminate the addr/seqno from the hangcheck warning + +This is of no value to the developer reading the report, let alone the +bamboozled user. + +Signed-off-by: Chris Wilson +Acked-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit a43adf0747ecde0d211f29adcbebf067f92e9cbb) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 486016b641e8..b6e0b15552e9 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2552,12 +2552,10 @@ void i915_hangcheck_elapsed(unsigned long data) + + for_each_ring(ring, dev_priv, i) { + if (ring->hangcheck.score > FIRE) { +- rings_hung++; +- DRM_ERROR("%s: %s on %s 0x%x\n", ring->name, ++ DRM_ERROR("%s on %s ring\n", + stuck[i] ? "stuck" : "no progress", +- stuck[i] ? "addr" : "seqno", +- stuck[i] ? ring->hangcheck.acthd & HEAD_ADDR : +- ring->hangcheck.seqno); ++ ring->name); ++ rings_hung++; + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0309-drm-i915-WARN-if-the-fence-pin_count-is-invalid.patch b/patches.baytrail/0309-drm-i915-WARN-if-the-fence-pin_count-is-invalid.patch new file mode 100644 index 000000000000..ffbf0667da1a --- /dev/null +++ b/patches.baytrail/0309-drm-i915-WARN-if-the-fence-pin_count-is-invalid.patch @@ -0,0 +1,38 @@ +From 1299ac5d6df0da627ebb6a474e433f098fa668b2 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 12 Jun 2013 11:29:47 +0100 +Subject: drm/i915: WARN if the fence pin_count is invalid +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Stéphane Marchesin found a bug where the fences were not being restored, +and in particular the fence pin_count was incorrect. Had we had a +warning in place, this bug would have come to light much earlier. Better +late than never? + +Signed-off-by: Chris Wilson +Cc: Daniel Vetter +Cc: Stéphane Marchesin +Signed-off-by: Daniel Vetter +(cherry picked from commit b8c3af766b7f9350c581bb44e6ffaaabc8c1c198) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index aaff7ddc4162..24b5e25412be 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1705,6 +1705,7 @@ i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) + { + if (obj->fence_reg != I915_FENCE_REG_NONE) { + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; ++ WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count <= 0); + dev_priv->fence_regs[obj->fence_reg].pin_count--; + } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0310-drm-i915-disable-sdvo-pixel-multiplier-cross-check-f.patch b/patches.baytrail/0310-drm-i915-disable-sdvo-pixel-multiplier-cross-check-f.patch new file mode 100644 index 000000000000..4a984c2817ac --- /dev/null +++ b/patches.baytrail/0310-drm-i915-disable-sdvo-pixel-multiplier-cross-check-f.patch @@ -0,0 +1,76 @@ +From 2aabd37076e0d34510683811277181c166507b29 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 12 Jun 2013 11:47:24 +0200 +Subject: drm/i915: disable sdvo pixel multiplier cross-check for HAS_PCH_SPLIT +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We don't (yet) have proper pixel multiplier readout support on pch +split platforms, so the cross check will naturally fail. + +v2: Fix spelling in the comment, spotted by Ville. + +v3: Since the ordering constraint is pretty tricky between the crtc +get_pipe_config callback and the encoder->get_config callback add a +few comments about it. Prompted by a discussion with Chris Wilson on +irc about why this does work anywhere else than on i915g/gm. + +Reported-by: Chris Wilson +Acked-by: Chris Wilson +Cc: Chris Wilson +Cc: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit fdafa9e276235225ce087695984cf1e52dd0c159) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_drv.h | 3 ++- + drivers/gpu/drm/i915/intel_sdvo.c | 11 +++++++++++ + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 3ecc3d0e6acc..5817a1643dea 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -140,7 +140,8 @@ struct intel_encoder { + * it is connected to in the pipe parameter. */ + bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe); + /* Reconstructs the equivalent mode flags for the current hardware +- * state. */ ++ * state. This must be called _after_ display->get_pipe_config has ++ * pre-filled the pipe config. */ + void (*get_config)(struct intel_encoder *, + struct intel_crtc_config *pipe_config); + int crtc_mask; +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 44609b623100..2628d5622449 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1342,6 +1342,13 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, + + pipe_config->adjusted_mode.flags |= flags; + ++ /* ++ * pixel multiplier readout is tricky: Only on i915g/gm it is stored in ++ * the sdvo port register, on all other platforms it is part of the dpll ++ * state. Since the general pipe state readout happens before the ++ * encoder->get_config we so already have a valid pixel multplier on all ++ * other platfroms. ++ */ + if (IS_I915G(dev) || IS_I915GM(dev)) { + sdvox = I915_READ(intel_sdvo->sdvo_reg); + pipe_config->pixel_multiplier = +@@ -1362,6 +1369,10 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, + encoder_pixel_multiplier = 4; + break; + } ++ ++ if(HAS_PCH_SPLIT(dev)) ++ return; /* no pixel multiplier readout support yet */ ++ + WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier, + "SDVO pixel multiplier mismatch, port: %i, encoder: %i\n", + pipe_config->pixel_multiplier, encoder_pixel_multiplier); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0311-drm-i915-pnv-dpll-doesn-t-use-m1.patch b/patches.baytrail/0311-drm-i915-pnv-dpll-doesn-t-use-m1.patch new file mode 100644 index 000000000000..b4e02d98c1f5 --- /dev/null +++ b/patches.baytrail/0311-drm-i915-pnv-dpll-doesn-t-use-m1.patch @@ -0,0 +1,47 @@ +From 1da5d6aeb2f6038bd908c8e30de516b4d1989151 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 21 May 2013 21:54:55 +0200 +Subject: drm/i915: pnv dpll doesn't use m1! + +So don't try to store it in the DPLL_FP register. + +Otherwise it looks like the limits for pineview are correct: It has +it's own clock computation code, which doesn't use an offset for n +divisors, and the register value based m limits look sane enough. + +v2: Rebase on top of the pineview clock refactor and fixup up the +commit message: It's m1 pnv doens't care about, not m2! + +Quoting Damien's review: + + - "n can vary between 2 and 6, but we declare the 3-6 as limits. + - "p1 seems to be able to go up to 9 + - "the m upper limit seems a bit big, but the docs are a bit shy on + that values for pnv. + +"Otherwise, the change itself seems good:" + +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 7df00d7adb080122502a30ec48f237d2f90d36ad) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index f29c8a4477da..e21c1466a97d 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4236,7 +4236,7 @@ static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors) + + static uint32_t pnv_dpll_compute_fp(struct dpll *dpll) + { +- return (1 << dpll->n) << 16 | dpll->m1 << 8 | dpll->m2; ++ return (1 << dpll->n) << 16 | dpll->m2; + } + + static uint32_t i9xx_dpll_compute_fp(struct dpll *dpll) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0312-drm-i915-display-pll-hw-state-readout-and-checking.patch b/patches.baytrail/0312-drm-i915-display-pll-hw-state-readout-and-checking.patch new file mode 100644 index 000000000000..914423c82513 --- /dev/null +++ b/patches.baytrail/0312-drm-i915-display-pll-hw-state-readout-and-checking.patch @@ -0,0 +1,204 @@ +From 47fff9f06340231bec1845484552322a52b70561 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:16 +0200 +Subject: drm/i915: display pll hw state readout and checking + +Currently still with an empty register state, this will follow in a +next step. This one here just creates the new vfunc and uses it for +cross-checking, initial state takeover and the dpll assert function. + +And add a FIXME for the ddi pll readout code, which still needs to be +converted over. + +v2: +- Add some hw state readout debug output. +- Also cross check the enabled crtc counting. + +Note that I've botched up the patch ordering, and before this patch +we've read out the pll selection correctly, but did not reconstruct +the refcounts properly. See the bug link. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65673 +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 5358901f99153085db59c3644db00b8753b50ac1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 7 ++++ + drivers/gpu/drm/i915/intel_display.c | 77 +++++++++++++++++++++++++++++++++--- + 2 files changed, 79 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 24b5e25412be..41ec967a97bb 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -142,6 +142,9 @@ enum intel_dpll_id { + }; + #define I915_NUM_PLLS 2 + ++struct intel_dpll_hw_state { ++}; ++ + struct intel_shared_dpll { + int refcount; /* count of number of CRTCs sharing this PLL */ + int active; /* count of number of active CRTCs (i.e. DPMS on) */ +@@ -149,10 +152,14 @@ struct intel_shared_dpll { + const char *name; + /* should match the index in the dev_priv->shared_dplls array */ + enum intel_dpll_id id; ++ struct intel_dpll_hw_state hw_state; + void (*enable)(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll); + void (*disable)(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll); ++ bool (*get_hw_state)(struct drm_i915_private *dev_priv, ++ struct intel_shared_dpll *pll, ++ struct intel_dpll_hw_state *hw_state); + }; + + /* Used by dp and fdi links */ +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index e21c1466a97d..aba95868a7cb 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -925,8 +925,8 @@ static void assert_shared_dpll(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + bool state) + { +- u32 val; + bool cur_state; ++ struct intel_dpll_hw_state hw_state; + + if (HAS_PCH_LPT(dev_priv->dev)) { + DRM_DEBUG_DRIVER("LPT detected: skipping PCH PLL test\n"); +@@ -937,11 +937,10 @@ static void assert_shared_dpll(struct drm_i915_private *dev_priv, + "asserting DPLL %s with no DPLL\n", state_string(state))) + return; + +- val = I915_READ(PCH_DPLL(pll->id)); +- cur_state = !!(val & DPLL_VCO_ENABLE); ++ cur_state = pll->get_hw_state(dev_priv, pll, &hw_state); + WARN(cur_state != state, +- "%s assertion failure (expected %s, current %s), val=%08x\n", +- pll->name, state_string(state), state_string(cur_state), val); ++ "%s assertion failure (expected %s, current %s)\n", ++ pll->name, state_string(state), state_string(cur_state)); + } + #define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true) + #define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false) +@@ -8151,6 +8150,8 @@ intel_modeset_check_state(struct drm_device *dev) + struct intel_encoder *encoder; + struct intel_connector *connector; + struct intel_crtc_config pipe_config; ++ struct intel_dpll_hw_state dpll_hw_state; ++ int i; + + list_for_each_entry(connector, &dev->mode_config.connector_list, + base.head) { +@@ -8270,6 +8271,41 @@ intel_modeset_check_state(struct drm_device *dev) + "[sw state]"); + } + } ++ ++ for (i = 0; i < dev_priv->num_shared_dpll; i++) { ++ struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; ++ int enabled_crtcs = 0, active_crtcs = 0; ++ bool active; ++ ++ memset(&dpll_hw_state, 0, sizeof(dpll_hw_state)); ++ ++ DRM_DEBUG_KMS("%s\n", pll->name); ++ ++ active = pll->get_hw_state(dev_priv, pll, &dpll_hw_state); ++ ++ WARN(pll->active > pll->refcount, ++ "more active pll users than references: %i vs %i\n", ++ pll->active, pll->refcount); ++ WARN(pll->active && !pll->on, ++ "pll in active use but not on in sw tracking\n"); ++ WARN(pll->on != active, ++ "pll on state mismatch (expected %i, found %i)\n", ++ pll->on, active); ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, ++ base.head) { ++ if (crtc->base.enabled && intel_crtc_to_shared_dpll(crtc) == pll) ++ enabled_crtcs++; ++ if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) ++ active_crtcs++; ++ } ++ WARN(pll->active != active_crtcs, ++ "pll active crtcs mismatch (expected %i, found %i)\n", ++ pll->active, active_crtcs); ++ WARN(pll->refcount != enabled_crtcs, ++ "pll enabled crtcs mismatch (expected %i, found %i)\n", ++ pll->refcount, enabled_crtcs); ++ } + } + + static int __intel_set_mode(struct drm_crtc *crtc, +@@ -8711,6 +8747,17 @@ static void intel_cpu_pll_init(struct drm_device *dev) + intel_ddi_pll_init(dev); + } + ++static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv, ++ struct intel_shared_dpll *pll, ++ struct intel_dpll_hw_state *hw_state) ++{ ++ uint32_t val; ++ ++ val = I915_READ(PCH_DPLL(pll->id)); ++ ++ return val & DPLL_VCO_ENABLE; ++} ++ + static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) + { +@@ -8765,6 +8812,8 @@ static void ibx_pch_dpll_init(struct drm_device *dev) + dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i]; + dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable; + dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable; ++ dev_priv->shared_dplls[i].get_hw_state = ++ ibx_pch_dpll_get_hw_state; + } + } + +@@ -9702,6 +9751,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, + struct intel_crtc *crtc; + struct intel_encoder *encoder; + struct intel_connector *connector; ++ int i; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, + base.head) { +@@ -9717,9 +9767,26 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, + crtc->active ? "enabled" : "disabled"); + } + ++ /* FIXME: Smash this into the new shared dpll infrastructure. */ + if (HAS_DDI(dev)) + intel_ddi_setup_hw_pll_state(dev); + ++ for (i = 0; i < dev_priv->num_shared_dpll; i++) { ++ struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; ++ ++ pll->on = pll->get_hw_state(dev_priv, pll, &pll->hw_state); ++ pll->active = 0; ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, ++ base.head) { ++ if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) ++ pll->active++; ++ } ++ pll->refcount = pll->active; ++ ++ DRM_DEBUG_KMS("%s hw state readout: refcount %i\n", ++ pll->name, pll->refcount); ++ } ++ + list_for_each_entry(encoder, &dev->mode_config.encoder_list, + base.head) { + pipe = 0; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0313-drm-i915-extract-readout_hw_state-from-setup_hw_stat.patch b/patches.baytrail/0313-drm-i915-extract-readout_hw_state-from-setup_hw_stat.patch new file mode 100644 index 000000000000..0e21f90fa801 --- /dev/null +++ b/patches.baytrail/0313-drm-i915-extract-readout_hw_state-from-setup_hw_stat.patch @@ -0,0 +1,60 @@ +From b940485e1839d152aebff85c6db21ea4f36e26dc Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:17 +0200 +Subject: drm/i915: extract readout_hw_state from setup_hw_state + +Simply grew too big. This also makes the fixup and restore logic in +setup_hw_state stand out a bit more clearly. + +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 30e984df4c5633363b45108473b0561e7d89476d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index aba95868a7cb..aeff32e5c547 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -9740,14 +9740,10 @@ void i915_redisable_vga(struct drm_device *dev) + } + } + +-/* Scan out the current hw modeset state, sanitizes it and maps it into the drm +- * and i915 state tracking structures. */ +-void intel_modeset_setup_hw_state(struct drm_device *dev, +- bool force_restore) ++static void intel_modeset_readout_hw_state(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + enum pipe pipe; +- struct drm_plane *plane; + struct intel_crtc *crtc; + struct intel_encoder *encoder; + struct intel_connector *connector; +@@ -9823,6 +9819,20 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, + drm_get_connector_name(&connector->base), + connector->base.encoder ? "enabled" : "disabled"); + } ++} ++ ++/* Scan out the current hw modeset state, sanitizes it and maps it into the drm ++ * and i915 state tracking structures. */ ++void intel_modeset_setup_hw_state(struct drm_device *dev, ++ bool force_restore) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ enum pipe pipe; ++ struct drm_plane *plane; ++ struct intel_crtc *crtc; ++ struct intel_encoder *encoder; ++ ++ intel_modeset_readout_hw_state(dev); + + /* HW state is read out, now we need to sanitize this mess. */ + list_for_each_entry(encoder, &dev->mode_config.encoder_list, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0314-drm-i915-split-up-intel_modeset_check_state.patch b/patches.baytrail/0314-drm-i915-split-up-intel_modeset_check_state.patch new file mode 100644 index 000000000000..35675a409c85 --- /dev/null +++ b/patches.baytrail/0314-drm-i915-split-up-intel_modeset_check_state.patch @@ -0,0 +1,103 @@ +From 2ad3b115a44c7c774fc9dc9a00ee17ddb440de0f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:18 +0200 +Subject: drm/i915: split up intel_modeset_check_state + +Simply grew too large and needed to be split up into parts. + +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 91d1b4bd14fd0bfe87e91a0fd115fcc15c9c9cc5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 44 +++++++++++++++++++++++++++++------- + 1 file changed, 36 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index aeff32e5c547..eecfcea4bfc5 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8142,16 +8142,10 @@ intel_pipe_config_compare(struct drm_device *dev, + return true; + } + +-void +-intel_modeset_check_state(struct drm_device *dev) ++static void ++check_connector_state(struct drm_device *dev) + { +- drm_i915_private_t *dev_priv = dev->dev_private; +- struct intel_crtc *crtc; +- struct intel_encoder *encoder; + struct intel_connector *connector; +- struct intel_crtc_config pipe_config; +- struct intel_dpll_hw_state dpll_hw_state; +- int i; + + list_for_each_entry(connector, &dev->mode_config.connector_list, + base.head) { +@@ -8162,6 +8156,13 @@ intel_modeset_check_state(struct drm_device *dev) + WARN(&connector->new_encoder->base != connector->base.encoder, + "connector's staged encoder doesn't match current encoder\n"); + } ++} ++ ++static void ++check_encoder_state(struct drm_device *dev) ++{ ++ struct intel_encoder *encoder; ++ struct intel_connector *connector; + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, + base.head) { +@@ -8213,6 +8214,15 @@ intel_modeset_check_state(struct drm_device *dev) + tracked_pipe, pipe); + + } ++} ++ ++static void ++check_crtc_state(struct drm_device *dev) ++{ ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ struct intel_crtc *crtc; ++ struct intel_encoder *encoder; ++ struct intel_crtc_config pipe_config; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, + base.head) { +@@ -8271,6 +8281,15 @@ intel_modeset_check_state(struct drm_device *dev) + "[sw state]"); + } + } ++} ++ ++static void ++check_shared_dpll_state(struct drm_device *dev) ++{ ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ struct intel_crtc *crtc; ++ struct intel_dpll_hw_state dpll_hw_state; ++ int i; + + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; +@@ -8308,6 +8327,15 @@ intel_modeset_check_state(struct drm_device *dev) + } + } + ++void ++intel_modeset_check_state(struct drm_device *dev) ++{ ++ check_connector_state(dev); ++ check_encoder_state(dev); ++ check_crtc_state(dev); ++ check_shared_dpll_state(dev); ++} ++ + static int __intel_set_mode(struct drm_crtc *crtc, + struct drm_display_mode *mode, + int x, int y, struct drm_framebuffer *fb) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0315-drm-i915-WARN-on-lack-of-shared-dpll.patch b/patches.baytrail/0315-drm-i915-WARN-on-lack-of-shared-dpll.patch new file mode 100644 index 000000000000..096fea8af433 --- /dev/null +++ b/patches.baytrail/0315-drm-i915-WARN-on-lack-of-shared-dpll.patch @@ -0,0 +1,42 @@ +From 0a5bb54b923146f69b6acfadfaab483f217d4506 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:19 +0200 +Subject: drm/i915: WARN on lack of shared dpll + +Now that we have proper hw state reconstruction we should never have a +case where we don't have the software dpll state properly set up. So +add WARNs to the respective !pll cases in enable/disabel_shared_dpll. + +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 87a875bbffcfac7cb7c9a106fda40f04de1f60a2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index eecfcea4bfc5..9ed5e6ccdb43 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1401,7 +1401,7 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *crtc) + + /* PCH PLLs only available on ILK, SNB and IVB */ + BUG_ON(dev_priv->info->gen < 5); +- if (pll == NULL) ++ if (WARN_ON(pll == NULL)) + return; + + if (WARN_ON(pll->refcount == 0)) +@@ -1430,7 +1430,7 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc) + + /* PCH only available on ILK+ */ + BUG_ON(dev_priv->info->gen < 5); +- if (pll == NULL) ++ if (WARN_ON(pll == NULL)) + return; + + if (WARN_ON(pll->refcount == 0)) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0316-drm-i915-hw-state-readout-and-cross-checking-for-sha.patch b/patches.baytrail/0316-drm-i915-hw-state-readout-and-cross-checking-for-sha.patch new file mode 100644 index 000000000000..b242f59f6abe --- /dev/null +++ b/patches.baytrail/0316-drm-i915-hw-state-readout-and-cross-checking-for-sha.patch @@ -0,0 +1,164 @@ +From 97ca43ab87f5b74e806ca1fd49c2c2e230928b95 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:20 +0200 +Subject: drm/i915: hw state readout and cross-checking for shared dplls + +Just the plumbing, all the modeset and enable code has not yet been +switched over to use the new state. It seems to be decently broken +anyway, at least wrt to handling of the special pixel mutliplier +enabling sequence. Follow-up patches will clean up that mess. + +Another missing piece is more careful handling (and fixup) of the fp1 +alternate divisor state. The BIOS most likely doesn't bother to +program that one to what we expect. So we need to be more careful with +comparing that state, both for cross checking but also when checking +for dpll sharing when acquiring shared dpll. Otherwise fastboot will +deny a few shared dpll configurations which would otherwise work. + +v2: We need to memcpy the pipe config dpll hw state into the pll, for +otherwise the cross-check code will get angry. + +v3: Don't forget to read the pch pll state in the crtc get_pipe_config +function for ibx/ilk platforms. + +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 66e985c035f4554939b8b63a8e21418271160ab0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 3 +++ + drivers/gpu/drm/i915/intel_display.c | 38 ++++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/i915/intel_drv.h | 3 +++ + 3 files changed, 44 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 41ec967a97bb..0b7d8fd1685b 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -143,6 +143,9 @@ enum intel_dpll_id { + #define I915_NUM_PLLS 2 + + struct intel_dpll_hw_state { ++ uint32_t dpll; ++ uint32_t fp0; ++ uint32_t fp1; + }; + + struct intel_shared_dpll { +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 9ed5e6ccdb43..e29ce6b31f67 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3087,7 +3087,11 @@ found: + crtc->config.shared_dpll = i; + DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name, + pipe_name(crtc->pipe)); ++ + if (pll->active == 0) { ++ memcpy(&pll->hw_state, &crtc->config.dpll_hw_state, ++ sizeof(pll->hw_state)); ++ + DRM_DEBUG_DRIVER("setting up %s\n", pll->name); + WARN_ON(pll->on); + assert_shared_dpll_disabled(dev_priv, pll); +@@ -5718,6 +5722,13 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + &fp, &reduced_clock, + has_reduced_clock ? &fp2 : NULL); + ++ intel_crtc->config.dpll_hw_state.dpll = dpll | DPLL_VCO_ENABLE; ++ intel_crtc->config.dpll_hw_state.fp0 = fp; ++ if (has_reduced_clock) ++ intel_crtc->config.dpll_hw_state.fp1 = fp2; ++ else ++ intel_crtc->config.dpll_hw_state.fp1 = fp; ++ + pll = intel_get_shared_dpll(intel_crtc, dpll, fp); + if (pll == NULL) { + DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", +@@ -5837,6 +5848,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + return false; + + if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) { ++ struct intel_shared_dpll *pll; ++ + pipe_config->has_pch_encoder = true; + + tmp = I915_READ(FDI_RX_CTL(crtc->pipe)); +@@ -5858,6 +5871,11 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + else + pipe_config->shared_dpll = DPLL_ID_PCH_PLL_A; + } ++ ++ pll = &dev_priv->shared_dplls[pipe_config->shared_dpll]; ++ ++ WARN_ON(!pll->get_hw_state(dev_priv, pll, ++ &pipe_config->dpll_hw_state)); + } else { + pipe_config->pixel_multiplier = 1; + } +@@ -8058,6 +8076,15 @@ intel_pipe_config_compare(struct drm_device *dev, + struct intel_crtc_config *current_config, + struct intel_crtc_config *pipe_config) + { ++#define PIPE_CONF_CHECK_X(name) \ ++ if (current_config->name != pipe_config->name) { \ ++ DRM_ERROR("mismatch in " #name " " \ ++ "(expected 0x%08x, found 0x%08x)\n", \ ++ current_config->name, \ ++ pipe_config->name); \ ++ return false; \ ++ } ++ + #define PIPE_CONF_CHECK_I(name) \ + if (current_config->name != pipe_config->name) { \ + DRM_ERROR("mismatch in " #name " " \ +@@ -8134,7 +8161,11 @@ intel_pipe_config_compare(struct drm_device *dev, + PIPE_CONF_CHECK_I(ips_enabled); + + PIPE_CONF_CHECK_I(shared_dpll); ++ PIPE_CONF_CHECK_X(dpll_hw_state.dpll); ++ PIPE_CONF_CHECK_X(dpll_hw_state.fp0); ++ PIPE_CONF_CHECK_X(dpll_hw_state.fp1); + ++#undef PIPE_CONF_CHECK_X + #undef PIPE_CONF_CHECK_I + #undef PIPE_CONF_CHECK_FLAGS + #undef PIPE_CONF_QUIRK +@@ -8324,6 +8355,10 @@ check_shared_dpll_state(struct drm_device *dev) + WARN(pll->refcount != enabled_crtcs, + "pll enabled crtcs mismatch (expected %i, found %i)\n", + pll->refcount, enabled_crtcs); ++ ++ WARN(pll->on && memcmp(&pll->hw_state, &dpll_hw_state, ++ sizeof(dpll_hw_state)), ++ "pll hw state mismatch\n"); + } + } + +@@ -8782,6 +8817,9 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv, + uint32_t val; + + val = I915_READ(PCH_DPLL(pll->id)); ++ hw_state->dpll = val; ++ hw_state->fp0 = I915_READ(PCH_FP0(pll->id)); ++ hw_state->fp1 = I915_READ(PCH_FP1(pll->id)); + + return val & DPLL_VCO_ENABLE; + } +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 5817a1643dea..abe9c9e9d8a3 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -256,6 +256,9 @@ struct intel_crtc_config { + /* Selected dpll when shared or DPLL_ID_PRIVATE. */ + enum intel_dpll_id shared_dpll; + ++ /* Actual register state of the dpll, for shared dpll cross-checking. */ ++ struct intel_dpll_hw_state dpll_hw_state; ++ + int pipe_bpp; + struct intel_link_m_n dp_m_n; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0317-drm-i915-fix-up-pch-pll-enabling-for-pixel-multiplie.patch b/patches.baytrail/0317-drm-i915-fix-up-pch-pll-enabling-for-pixel-multiplie.patch new file mode 100644 index 000000000000..be4a32bb48f1 --- /dev/null +++ b/patches.baytrail/0317-drm-i915-fix-up-pch-pll-enabling-for-pixel-multiplie.patch @@ -0,0 +1,46 @@ +From 108b434e1db643a84d439f8820afb95ab8bcb83c Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:21 +0200 +Subject: drm/i915: fix up pch pll enabling for pixel multipliers + +We have a nice comment saying that the pixel multiplier only sticks +once the vco is on and stable. The only problem is that the enable bit +wasn't set at all. This patch fixes this and so brings the ilk+ pch +pll code in line with the i8xx/i9xx pll code. Or at least improves +matters a lot. + +This should fix sdvo on ilk-ivb for low-res modes. + +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 959e16d65d808602cd88b82530626f964f684c05) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index e29ce6b31f67..6b475793cb66 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5660,7 +5660,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, + else + dpll |= PLL_REF_INPUT_DREFCLK; + +- return dpll; ++ return dpll | DPLL_VCO_ENABLE; + } + + static int ironlake_crtc_mode_set(struct drm_crtc *crtc, +@@ -5722,7 +5722,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + &fp, &reduced_clock, + has_reduced_clock ? &fp2 : NULL); + +- intel_crtc->config.dpll_hw_state.dpll = dpll | DPLL_VCO_ENABLE; ++ intel_crtc->config.dpll_hw_state.dpll = dpll; + intel_crtc->config.dpll_hw_state.fp0 = fp; + if (has_reduced_clock) + intel_crtc->config.dpll_hw_state.fp1 = fp2; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0318-drm-i915-Try-harder-to-disable-trickle-feed-on-VLV.patch b/patches.baytrail/0318-drm-i915-Try-harder-to-disable-trickle-feed-on-VLV.patch new file mode 100644 index 000000000000..5f850cfaf217 --- /dev/null +++ b/patches.baytrail/0318-drm-i915-Try-harder-to-disable-trickle-feed-on-VLV.patch @@ -0,0 +1,69 @@ +From eedf76facbe0527aa8201e52d661005bbc36b3bd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 12 Jun 2013 22:11:18 +0300 +Subject: drm/i915: Try harder to disable trickle feed on VLV +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The specs are a bit unclear whether the per-plane trickle feed disable +control exists on VLV. There is another trickle feed disable control +in the MI_ARB register. + +After some experimentation it turns out both the DSPCNTR trickle feed +bits and the MI_ARB bit can be toggled. However the DSPCNTR bits don't +seem to have any effect. + +The MI_ARB bit, on the other hand, has a noticable effect. I performed +an experiment where I reduced the FIFO size via DSPARB and observed the +effect of the MI_ARB trickle feed bit on the display. + +Using a 1920x1080-60 mode, with MI_ARB=0x4 the display started to have +problems with DSPARB=0x42424242, whereas with MI_ARB=0x0 the problems +didn't start until DSPARB=0x09090909. This seems to confirm that the +MI_ARB trickle feed bit actually does work. + +So replace the use of the DSPCNTR trickle feed bits with MI_ARB +on VLV. + +v2: Amend commit message with results from experimentation + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit e0d8d59b0831523da61739c9d5e3bc3c77d7b5db) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 2 ++ + drivers/gpu/drm/i915/intel_pm.c | 2 +- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index f21d0f5dc9f2..da456bc4c35a 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -1369,6 +1369,8 @@ + #define FW_BLC_SELF_VLV (VLV_DISPLAY_BASE + 0x6500) + #define FW_CSPWRDWNEN (1<<15) + ++#define MI_ARB_VLV (VLV_DISPLAY_BASE + 0x6504) ++ + /* + * Palette regs + */ +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 681699671893..6ff11802e49a 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4873,7 +4873,7 @@ static void valleyview_init_clock_gating(struct drm_device *dev) + + I915_WRITE(GEN7_UCGCTL4, GEN7_L3BANK2X_CLOCK_GATE_DISABLE); + +- g4x_disable_trickle_feed(dev); ++ I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE); + + I915_WRITE(CACHE_MODE_1, + _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0319-drm-i915-add-struct-i915_ctx_hang_stats.patch b/patches.baytrail/0319-drm-i915-add-struct-i915_ctx_hang_stats.patch new file mode 100644 index 000000000000..4ac351ce39f8 --- /dev/null +++ b/patches.baytrail/0319-drm-i915-add-struct-i915_ctx_hang_stats.patch @@ -0,0 +1,73 @@ +From 0a73e165e739e38bd42b859834a62eacf28b15bf Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Wed, 12 Jun 2013 12:35:28 +0300 +Subject: drm/i915: add struct i915_ctx_hang_stats + +To count context losses, add struct i915_ctx_hang_stats for +both i915_hw_context and drm_i915_file_private. +drm_i915_file_private is used when there is no context. + +v2: renamed and cleaned up the struct (Chris Wilson, Ian Romanick) + +Signed-off-by: Mika Kuoppala +Reviewed-by: Chris Wilson +Acked-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit e59ec13de40ed1edd19940322ebd009423fd716d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 2 +- + drivers/gpu/drm/i915/i915_drv.h | 10 ++++++++++ + 2 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 628f797358bb..f4669802a0fb 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1782,7 +1782,7 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file) + struct drm_i915_file_private *file_priv; + + DRM_DEBUG_DRIVER("\n"); +- file_priv = kmalloc(sizeof(*file_priv), GFP_KERNEL); ++ file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL); + if (!file_priv) + return -ENOMEM; + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 0b7d8fd1685b..95b19a53aa26 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -508,6 +508,13 @@ struct i915_hw_ppgtt { + void (*cleanup)(struct i915_hw_ppgtt *ppgtt); + }; + ++struct i915_ctx_hang_stats { ++ /* This context had batch pending when hang was declared */ ++ unsigned batch_pending; ++ ++ /* This context had batch active when hang was declared */ ++ unsigned batch_active; ++}; + + /* This must match up with the value previously used for execbuf2.rsvd1. */ + #define DEFAULT_CONTEXT_ID 0 +@@ -518,6 +525,7 @@ struct i915_hw_context { + struct drm_i915_file_private *file_priv; + struct intel_ring_buffer *ring; + struct drm_i915_gem_object *obj; ++ struct i915_ctx_hang_stats hang_stats; + }; + + enum no_fbc_reason { +@@ -1378,6 +1386,8 @@ struct drm_i915_file_private { + struct list_head request_list; + } mm; + struct idr context_idr; ++ ++ struct i915_ctx_hang_stats hang_stats; + }; + + #define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0320-drm-i915-add-i915_gem_context_get_hang_stats.patch b/patches.baytrail/0320-drm-i915-add-i915_gem_context_get_hang_stats.patch new file mode 100644 index 000000000000..5da4ce34dc98 --- /dev/null +++ b/patches.baytrail/0320-drm-i915-add-i915_gem_context_get_hang_stats.patch @@ -0,0 +1,86 @@ +From e1c68a84e86ee299c1fd39fe8efb738a57efb3b7 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Wed, 12 Jun 2013 12:35:29 +0300 +Subject: drm/i915: add i915_gem_context_get_hang_stats() + +To get context hang statistics for specified context, +add i915_gem_context_get_hang_stats(). + +For arb-robustness, every context needs to have its own +hang statistics tracking. Added function will return +the user specified context statistics or in case of +default context, statistics from drm_i915_file_private. + +v2: handle default context inside get_reset_state + +v3: return struct pointer instead of passing it in as param + (Chris Wilson) + +Signed-off-by: Mika Kuoppala +Reviewed-by: Chris Wilson +Acked-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit c0bb617a70c94d660001f06f9810d53085e2c88d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 4 ++++ + drivers/gpu/drm/i915/i915_gem_context.c | 28 ++++++++++++++++++++++++++++ + 2 files changed, 32 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 95b19a53aa26..dcf5db4c0d8f 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1816,6 +1816,10 @@ static inline void i915_gem_context_unreference(struct i915_hw_context *ctx) + kref_put(&ctx->ref, i915_gem_context_free); + } + ++struct i915_ctx_hang_stats * __must_check ++i915_gem_context_get_hang_stats(struct intel_ring_buffer *ring, ++ struct drm_file *file, ++ u32 id); + int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); + int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index b3be2946e6db..e3e62aac413c 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -303,6 +303,34 @@ static int context_idr_cleanup(int id, void *p, void *data) + return 0; + } + ++struct i915_ctx_hang_stats * ++i915_gem_context_get_hang_stats(struct intel_ring_buffer *ring, ++ struct drm_file *file, ++ u32 id) ++{ ++ struct drm_i915_private *dev_priv = ring->dev->dev_private; ++ struct drm_i915_file_private *file_priv = file->driver_priv; ++ struct i915_hw_context *to; ++ ++ if (dev_priv->hw_contexts_disabled) ++ return ERR_PTR(-ENOENT); ++ ++ if (ring->id != RCS) ++ return ERR_PTR(-EINVAL); ++ ++ if (file == NULL) ++ return ERR_PTR(-EINVAL); ++ ++ if (id == DEFAULT_CONTEXT_ID) ++ return &file_priv->hang_stats; ++ ++ to = i915_gem_context_get(file->driver_priv, id); ++ if (to == NULL) ++ return ERR_PTR(-ENOENT); ++ ++ return &to->hang_stats; ++} ++ + void i915_gem_context_close(struct drm_device *dev, struct drm_file *file) + { + struct drm_i915_file_private *file_priv = file->driver_priv; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0321-drm-i915-change-i915_add_request-to-macro.patch b/patches.baytrail/0321-drm-i915-change-i915_add_request-to-macro.patch new file mode 100644 index 000000000000..fbdf526bcd2f --- /dev/null +++ b/patches.baytrail/0321-drm-i915-change-i915_add_request-to-macro.patch @@ -0,0 +1,149 @@ +From 9b7a49fa7922a18508a0fee8953ccd8ac5af96ab Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Wed, 12 Jun 2013 12:35:30 +0300 +Subject: drm/i915: change i915_add_request to macro + +Only execbuffer needed all the parameters on i915_add_request(). +By putting __i915_add_request behind macro, all current callsites +become cleaner. Following patch will introduce a new parameter +for __i915_add_request. With this patch, only the relevant callsite +will reflect the change making commit smaller and easier to understand. + +v2: _i915_add_request as function name (Chris Wilson) + +v3: change name __i915_add_request and fix ordering of params (Ben Widawsky) + +Signed-off-by: Mika Kuoppala +Reviewed-by: Chris Wilson +Acked-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 0025c0772de7451c2302fa628f038b213a0783bf) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 8 +++++--- + drivers/gpu/drm/i915/i915_gem.c | 11 +++++------ + drivers/gpu/drm/i915/i915_gem_context.c | 2 +- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- + drivers/gpu/drm/i915/intel_overlay.c | 4 ++-- + drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +- + 6 files changed, 15 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index dcf5db4c0d8f..3d8ae61ffe3b 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1758,9 +1758,11 @@ void i915_gem_init_swizzling(struct drm_device *dev); + void i915_gem_cleanup_ringbuffer(struct drm_device *dev); + int __must_check i915_gpu_idle(struct drm_device *dev); + int __must_check i915_gem_idle(struct drm_device *dev); +-int i915_add_request(struct intel_ring_buffer *ring, +- struct drm_file *file, +- u32 *seqno); ++int __i915_add_request(struct intel_ring_buffer *ring, ++ struct drm_file *file, ++ u32 *seqno); ++#define i915_add_request(ring, seqno) \ ++ __i915_add_request(ring, NULL, seqno); + int __must_check i915_wait_seqno(struct intel_ring_buffer *ring, + uint32_t seqno); + int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 694af6db61a2..6671b8e11e55 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -956,7 +956,7 @@ i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno) + + ret = 0; + if (seqno == ring->outstanding_lazy_request) +- ret = i915_add_request(ring, NULL, NULL); ++ ret = i915_add_request(ring, NULL); + + return ret; + } +@@ -2011,10 +2011,9 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno) + return 0; + } + +-int +-i915_add_request(struct intel_ring_buffer *ring, +- struct drm_file *file, +- u32 *out_seqno) ++int __i915_add_request(struct intel_ring_buffer *ring, ++ struct drm_file *file, ++ u32 *out_seqno) + { + drm_i915_private_t *dev_priv = ring->dev->dev_private; + struct drm_i915_gem_request *request; +@@ -2290,7 +2289,7 @@ i915_gem_retire_work_handler(struct work_struct *work) + idle = true; + for_each_ring(ring, dev_priv, i) { + if (ring->gpu_caches_dirty) +- i915_add_request(ring, NULL, NULL); ++ i915_add_request(ring, NULL); + + idle &= list_empty(&ring->request_list); + } +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index e3e62aac413c..51b7a2171cae 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -455,7 +455,7 @@ static int do_switch(struct i915_hw_context *to) + from->obj->dirty = 1; + BUG_ON(from->obj->ring != ring); + +- ret = i915_add_request(ring, NULL, NULL); ++ ret = i915_add_request(ring, NULL); + if (ret) { + /* Too late, we've already scheduled a context switch. + * Try to undo the change so that the hw state is +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index c98333d74111..d79ac7aa55d4 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -802,7 +802,7 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev, + ring->gpu_caches_dirty = true; + + /* Add a breadcrumb for the completion of the batch buffer */ +- (void)i915_add_request(ring, file, NULL); ++ (void)__i915_add_request(ring, file, NULL); + } + + static int +diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c +index 836794b68fc6..a3698812e9c7 100644 +--- a/drivers/gpu/drm/i915/intel_overlay.c ++++ b/drivers/gpu/drm/i915/intel_overlay.c +@@ -217,7 +217,7 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, + int ret; + + BUG_ON(overlay->last_flip_req); +- ret = i915_add_request(ring, NULL, &overlay->last_flip_req); ++ ret = i915_add_request(ring, &overlay->last_flip_req); + if (ret) + return ret; + +@@ -286,7 +286,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay, + intel_ring_emit(ring, flip_addr); + intel_ring_advance(ring); + +- return i915_add_request(ring, NULL, &overlay->last_flip_req); ++ return i915_add_request(ring, &overlay->last_flip_req); + } + + static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay) +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 1d4a7ee41881..a81647023139 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -1523,7 +1523,7 @@ int intel_ring_idle(struct intel_ring_buffer *ring) + + /* We need to add any requests required to flush the objects and ring */ + if (ring->outstanding_lazy_request) { +- ret = i915_add_request(ring, NULL, NULL); ++ ret = i915_add_request(ring, NULL); + if (ret) + return ret; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0322-drm-i915-add-batch-bo-to-i915_add_request.patch b/patches.baytrail/0322-drm-i915-add-batch-bo-to-i915_add_request.patch new file mode 100644 index 000000000000..356f6cf0493a --- /dev/null +++ b/patches.baytrail/0322-drm-i915-add-batch-bo-to-i915_add_request.patch @@ -0,0 +1,134 @@ +From 925be0fec93d527f53fdf0ced8f86a9b5f45002c Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Wed, 12 Jun 2013 15:01:39 +0300 +Subject: drm/i915: add batch bo to i915_add_request() + +In order to track down a batch buffer and context which +caused the ring to hang, store reference to bo into the request struct. +Request can also cause gpu to hang after the batch in the flush section +in the ring. To detect this add start of the flush portion offset into the +request. + +v2: Included comment about request vs batch_obj lifetimes (Chris Wilson) + +Signed-off-by: Mika Kuoppala +Reviewed-by: Chris Wilson +Acked-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 7d736f4f0b405b1421d280632ef077eb8135e5c6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 11 +++++++++-- + drivers/gpu/drm/i915/i915_gem.c | 13 ++++++++++++- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 7 ++++--- + 3 files changed, 25 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 3d8ae61ffe3b..e73bc66ef1dc 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1363,12 +1363,18 @@ struct drm_i915_gem_request { + /** GEM sequence number associated with this request. */ + uint32_t seqno; + +- /** Postion in the ringbuffer of the end of the request */ ++ /** Position in the ringbuffer of the start of the request */ ++ u32 head; ++ ++ /** Position in the ringbuffer of the end of the request */ + u32 tail; + + /** Context related to this request */ + struct i915_hw_context *ctx; + ++ /** Batch buffer related to this request if any */ ++ struct drm_i915_gem_object *batch_obj; ++ + /** Time at which this request was emitted, in jiffies. */ + unsigned long emitted_jiffies; + +@@ -1760,9 +1766,10 @@ int __must_check i915_gpu_idle(struct drm_device *dev); + int __must_check i915_gem_idle(struct drm_device *dev); + int __i915_add_request(struct intel_ring_buffer *ring, + struct drm_file *file, ++ struct drm_i915_gem_object *batch_obj, + u32 *seqno); + #define i915_add_request(ring, seqno) \ +- __i915_add_request(ring, NULL, seqno); ++ __i915_add_request(ring, NULL, NULL, seqno); + int __must_check i915_wait_seqno(struct intel_ring_buffer *ring, + uint32_t seqno); + int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 6671b8e11e55..855742a058b3 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2013,14 +2013,16 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno) + + int __i915_add_request(struct intel_ring_buffer *ring, + struct drm_file *file, ++ struct drm_i915_gem_object *obj, + u32 *out_seqno) + { + drm_i915_private_t *dev_priv = ring->dev->dev_private; + struct drm_i915_gem_request *request; +- u32 request_ring_position; ++ u32 request_ring_position, request_start; + int was_empty; + int ret; + ++ request_start = intel_ring_get_tail(ring); + /* + * Emit any outstanding flushes - execbuf can fail to emit the flush + * after having emitted the batchbuffer command. Hence we need to fix +@@ -2052,8 +2054,17 @@ int __i915_add_request(struct intel_ring_buffer *ring, + + request->seqno = intel_ring_get_seqno(ring); + request->ring = ring; ++ request->head = request_start; + request->tail = request_ring_position; + request->ctx = ring->last_context; ++ request->batch_obj = obj; ++ ++ /* Whilst this request exists, batch_obj will be on the ++ * active_list, and so will hold the active reference. Only when this ++ * request is retired will the the batch_obj be moved onto the ++ * inactive_list and lose its active reference. Hence we do not need ++ * to explicitly hold another reference here. ++ */ + + if (request->ctx) + i915_gem_context_reference(request->ctx); +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index d79ac7aa55d4..87a3227e5179 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -796,13 +796,14 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects, + static void + i915_gem_execbuffer_retire_commands(struct drm_device *dev, + struct drm_file *file, +- struct intel_ring_buffer *ring) ++ struct intel_ring_buffer *ring, ++ struct drm_i915_gem_object *obj) + { + /* Unconditionally force add_request to emit a full flush. */ + ring->gpu_caches_dirty = true; + + /* Add a breadcrumb for the completion of the batch buffer */ +- (void)__i915_add_request(ring, file, NULL); ++ (void)__i915_add_request(ring, file, obj, NULL); + } + + static int +@@ -1083,7 +1084,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags); + + i915_gem_execbuffer_move_to_active(&eb->objects, ring); +- i915_gem_execbuffer_retire_commands(dev, file, ring); ++ i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj); + + err: + eb_destroy(eb); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0323-drm-i915-store-ring-hangcheck-action.patch b/patches.baytrail/0323-drm-i915-store-ring-hangcheck-action.patch new file mode 100644 index 000000000000..f09077c3f732 --- /dev/null +++ b/patches.baytrail/0323-drm-i915-store-ring-hangcheck-action.patch @@ -0,0 +1,68 @@ +From 2117021b2325d4a5169175390c4d8560080359c4 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Wed, 12 Jun 2013 12:35:32 +0300 +Subject: drm/i915: store ring hangcheck action + +For guilty batchbuffer analysis later on when rings are reset, +store what state the ring was on when hang was declared. +This helps to weed out the waiting rings from the active ones. + +Signed-off-by: Mika Kuoppala +Reviewed-by: Chris Wilson +Acked-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit ad8beaeada276b4b2d31e1c3422346e8829a67d6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 8 ++++++-- + drivers/gpu/drm/i915/intel_ringbuffer.h | 3 +++ + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index b6e0b15552e9..5c344a5f307c 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2417,7 +2417,8 @@ static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) + ring->hangcheck.deadlock = false; + } + +-static enum { wait, active, kick, hung } ring_stuck(struct intel_ring_buffer *ring, u32 acthd) ++static enum intel_ring_hangcheck_action ++ring_stuck(struct intel_ring_buffer *ring, u32 acthd) + { + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -2520,7 +2521,10 @@ void i915_hangcheck_elapsed(unsigned long data) + * being repeatedly kicked and so responsible + * for stalling the machine. + */ +- switch (ring_stuck(ring, acthd)) { ++ ring->hangcheck.action = ring_stuck(ring, ++ acthd); ++ ++ switch (ring->hangcheck.action) { + case wait: + score = 0; + break; +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index a3e96103dbe5..799f04c9da45 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -37,11 +37,14 @@ struct intel_hw_status_page { + #define I915_READ_SYNC_0(ring) I915_READ(RING_SYNC_0((ring)->mmio_base)) + #define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base)) + ++enum intel_ring_hangcheck_action { wait, active, kick, hung }; ++ + struct intel_ring_hangcheck { + bool deadlock; + u32 seqno; + u32 acthd; + int score; ++ enum intel_ring_hangcheck_action action; + }; + + struct intel_ring_buffer { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0324-drm-i915-find-guilty-batch-buffer-on-ring-resets.patch b/patches.baytrail/0324-drm-i915-find-guilty-batch-buffer-on-ring-resets.patch new file mode 100644 index 000000000000..5635aa0e3c87 --- /dev/null +++ b/patches.baytrail/0324-drm-i915-find-guilty-batch-buffer-on-ring-resets.patch @@ -0,0 +1,166 @@ +From 8f2a1df53dda1674ffed043a982e7b5514e7dc50 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Wed, 12 Jun 2013 15:13:20 +0300 +Subject: drm/i915: find guilty batch buffer on ring resets +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +After hang check timer has declared gpu to be hung, +rings are reset. In ring reset, when clearing +request list, do post mortem analysis to find out +the guilty batch buffer. + +Select requests for further analysis by inspecting +the completed sequence number which has been updated +into the HWS page. If request was completed, it can't +be related to the hang. + +For noncompleted requests mark the batch as guilty +if the ring was not waiting and the ring head was +stuck inside the buffer object or in the flush region +right after the batch. For everything else, mark +them as innocents. + +v2: Fixed a typo in commit message (Ville Syrjälä) + +v3: - more descriptive function parameters (Chris Wilson) + - use masked head address when inspecting if request is in ring + - s/hangcheck.last_action/hangcheck.action + - added comment about unmasked head hitting batch_obj range + +Reviewed-by: Chris Wilson +Signed-off-by: Mika Kuoppala +Acked-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit aa60c664e6df502578454621c3a9b1f087ff8d25) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 97 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 97 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 855742a058b3..70af73dff001 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2121,6 +2121,94 @@ i915_gem_request_remove_from_client(struct drm_i915_gem_request *request) + spin_unlock(&file_priv->mm.lock); + } + ++static bool i915_head_inside_object(u32 acthd, struct drm_i915_gem_object *obj) ++{ ++ if (acthd >= obj->gtt_offset && ++ acthd < obj->gtt_offset + obj->base.size) ++ return true; ++ ++ return false; ++} ++ ++static bool i915_head_inside_request(const u32 acthd_unmasked, ++ const u32 request_start, ++ const u32 request_end) ++{ ++ const u32 acthd = acthd_unmasked & HEAD_ADDR; ++ ++ if (request_start < request_end) { ++ if (acthd >= request_start && acthd < request_end) ++ return true; ++ } else if (request_start > request_end) { ++ if (acthd >= request_start || acthd < request_end) ++ return true; ++ } ++ ++ return false; ++} ++ ++static bool i915_request_guilty(struct drm_i915_gem_request *request, ++ const u32 acthd, bool *inside) ++{ ++ /* There is a possibility that unmasked head address ++ * pointing inside the ring, matches the batch_obj address range. ++ * However this is extremely unlikely. ++ */ ++ ++ if (request->batch_obj) { ++ if (i915_head_inside_object(acthd, request->batch_obj)) { ++ *inside = true; ++ return true; ++ } ++ } ++ ++ if (i915_head_inside_request(acthd, request->head, request->tail)) { ++ *inside = false; ++ return true; ++ } ++ ++ return false; ++} ++ ++static void i915_set_reset_status(struct intel_ring_buffer *ring, ++ struct drm_i915_gem_request *request, ++ u32 acthd) ++{ ++ struct i915_ctx_hang_stats *hs = NULL; ++ bool inside, guilty; ++ ++ /* Innocent until proven guilty */ ++ guilty = false; ++ ++ if (ring->hangcheck.action != wait && ++ i915_request_guilty(request, acthd, &inside)) { ++ DRM_ERROR("%s hung %s bo (0x%x ctx %d) at 0x%x\n", ++ ring->name, ++ inside ? "inside" : "flushing", ++ request->batch_obj ? ++ request->batch_obj->gtt_offset : 0, ++ request->ctx ? request->ctx->id : 0, ++ acthd); ++ ++ guilty = true; ++ } ++ ++ /* If contexts are disabled or this is the default context, use ++ * file_priv->reset_state ++ */ ++ if (request->ctx && request->ctx->id != DEFAULT_CONTEXT_ID) ++ hs = &request->ctx->hang_stats; ++ else if (request->file_priv) ++ hs = &request->file_priv->hang_stats; ++ ++ if (hs) { ++ if (guilty) ++ hs->batch_active++; ++ else ++ hs->batch_pending++; ++ } ++} ++ + static void i915_gem_free_request(struct drm_i915_gem_request *request) + { + list_del(&request->list); +@@ -2135,6 +2223,12 @@ static void i915_gem_free_request(struct drm_i915_gem_request *request) + static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, + struct intel_ring_buffer *ring) + { ++ u32 completed_seqno; ++ u32 acthd; ++ ++ acthd = intel_ring_get_active_head(ring); ++ completed_seqno = ring->get_seqno(ring, false); ++ + while (!list_empty(&ring->request_list)) { + struct drm_i915_gem_request *request; + +@@ -2142,6 +2236,9 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, + struct drm_i915_gem_request, + list); + ++ if (request->seqno > completed_seqno) ++ i915_set_reset_status(ring, request, acthd); ++ + i915_gem_free_request(request); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0325-drm-i915-set-up-PIPECONF-explicitly-on-ilk-ivb.patch b/patches.baytrail/0325-drm-i915-set-up-PIPECONF-explicitly-on-ilk-ivb.patch new file mode 100644 index 000000000000..1464d8af2ed3 --- /dev/null +++ b/patches.baytrail/0325-drm-i915-set-up-PIPECONF-explicitly-on-ilk-ivb.patch @@ -0,0 +1,70 @@ +From 57d85c38b203da82dadf0a77e5087af2451adc4b Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 13 Jun 2013 00:54:57 +0200 +Subject: drm/i915: set up PIPECONF explicitly on ilk-ivb +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Dragging random garbage along from the BIOS isn't a good idea, since +we really only support exactly what we've set up. + +In the specific case for the bug reporter the BIOS used the 10bit +gamma table, but since we only support an 8bit table the dark colors +ended up all wrong and the light ones all unadjusted. + +Note that this has a nice implication for fastboot, it essentially +means that we have quite a bit more state to check and compare before +we can decide whether fastboot is possible. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65593 +Reported-and-Tested-by: Thomas Hebb +Cc: stable@vger.kernel.org +Reviewed-by: Chris Wilson +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 78114071ff9e3c2f6c1715bfb01ac8c0b3618e72) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 6b475793cb66..1bbab24b3293 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5342,9 +5342,8 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc) + int pipe = intel_crtc->pipe; + uint32_t val; + +- val = I915_READ(PIPECONF(pipe)); ++ val = 0; + +- val &= ~PIPECONF_BPC_MASK; + switch (intel_crtc->config.pipe_bpp) { + case 18: + val |= PIPECONF_6BPC; +@@ -5363,11 +5362,9 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc) + BUG(); + } + +- val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK); + if (intel_crtc->config.dither) + val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP); + +- val &= ~PIPECONF_INTERLACE_MASK; + if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) + val |= PIPECONF_INTERLACED_ILK; + else +@@ -5375,8 +5372,6 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc) + + if (intel_crtc->config.limited_color_range) + val |= PIPECONF_COLOR_RANGE_SELECT; +- else +- val &= ~PIPECONF_COLOR_RANGE_SELECT; + + I915_WRITE(PIPECONF(pipe), val); + POSTING_READ(PIPECONF(pipe)); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0326-drm-i915-set-up-PIPECONF-explicitly-for-i9xx-vlv-pla.patch b/patches.baytrail/0326-drm-i915-set-up-PIPECONF-explicitly-for-i9xx-vlv-pla.patch new file mode 100644 index 000000000000..f1d835fb315f --- /dev/null +++ b/patches.baytrail/0326-drm-i915-set-up-PIPECONF-explicitly-for-i9xx-vlv-pla.patch @@ -0,0 +1,81 @@ +From 17b72372335404ea3b033bd9391f32ab3d9f4dff Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 13 Jun 2013 00:54:58 +0200 +Subject: drm/i915: set up PIPECONF explicitly for i9xx/vlv platforms +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Same reasons as for the previous patch, just no bug report about +anything going wrong yet: We only support exactly the mode we program, +so don't leave any stale BIOS state behind. + +Again this will be fun to properly track for fastboot. + +Reviewed-by: Chris Wilson +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 9f11a9e4e50006b615ba94722dfc33ced89664cf) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 17 +++-------------- + 1 file changed, 3 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 1bbab24b3293..0d23d7bfc884 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4732,7 +4732,7 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t pipeconf; + +- pipeconf = I915_READ(PIPECONF(intel_crtc->pipe)); ++ pipeconf = 0; + + if (dev_priv->quirks & QUIRK_PIPEA_FORCE && + I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE) +@@ -4748,15 +4748,10 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) + if (intel_crtc->config.requested_mode.clock > + dev_priv->display.get_display_clock_speed(dev) * 9 / 10) + pipeconf |= PIPECONF_DOUBLE_WIDE; +- else +- pipeconf &= ~PIPECONF_DOUBLE_WIDE; + } + + /* only g4x and later have fancy bpc/dither controls */ + if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) { +- pipeconf &= ~(PIPECONF_BPC_MASK | +- PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK); +- + /* Bspec claims that we can't use dithering for 30bpp pipes. */ + if (intel_crtc->config.dither && intel_crtc->config.pipe_bpp != 30) + pipeconf |= PIPECONF_DITHER_EN | +@@ -4784,23 +4779,17 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) + pipeconf |= PIPECONF_CXSR_DOWNCLOCK; + } else { + DRM_DEBUG_KMS("disabling CxSR downclocking\n"); +- pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; + } + } + +- pipeconf &= ~PIPECONF_INTERLACE_MASK; + if (!IS_GEN2(dev) && + intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) + pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; + else + pipeconf |= PIPECONF_PROGRESSIVE; + +- if (IS_VALLEYVIEW(dev)) { +- if (intel_crtc->config.limited_color_range) +- pipeconf |= PIPECONF_COLOR_RANGE_SELECT; +- else +- pipeconf &= ~PIPECONF_COLOR_RANGE_SELECT; +- } ++ if (IS_VALLEYVIEW(dev) && intel_crtc->config.limited_color_range) ++ pipeconf |= PIPECONF_COLOR_RANGE_SELECT; + + I915_WRITE(PIPECONF(intel_crtc->pipe), pipeconf); + POSTING_READ(PIPECONF(intel_crtc->pipe)); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0327-drm-i915-explicitly-set-up-PIPECONF-and-gamma-table-.patch b/patches.baytrail/0327-drm-i915-explicitly-set-up-PIPECONF-and-gamma-table-.patch new file mode 100644 index 000000000000..caef9d4002af --- /dev/null +++ b/patches.baytrail/0327-drm-i915-explicitly-set-up-PIPECONF-and-gamma-table-.patch @@ -0,0 +1,77 @@ +From 1dc91cc92322c86a937405bc660332eb065d7d57 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 13 Jun 2013 00:54:59 +0200 +Subject: drm/i915: explicitly set up PIPECONF (and gamma table) on haswell +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Again we don't really support different settings, so don't let the +BIOS sneak stuff through. + +Since the motivation for this patch series is to ensure we have the +correct gamma table mode selected also add the required write to the +GAMMA_MODE register to select the 8bit legacy table. + +And since I find lowercase letters in #defines offensive, also +bikeshed those. + +Reviewed-by: Chris Wilson +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 3eff4faa9f59c581538663e3f42b9e16210cafd0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 6 +++--- + drivers/gpu/drm/i915/intel_display.c | 7 ++++--- + 2 files changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index da456bc4c35a..a2fe7efe0701 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -3678,9 +3678,9 @@ + #define _GAMMA_MODE_B 0x4ac80 + #define GAMMA_MODE(pipe) _PIPE(pipe, _GAMMA_MODE_A, _GAMMA_MODE_B) + #define GAMMA_MODE_MODE_MASK (3 << 0) +-#define GAMMA_MODE_MODE_8bit (0 << 0) +-#define GAMMA_MODE_MODE_10bit (1 << 0) +-#define GAMMA_MODE_MODE_12bit (2 << 0) ++#define GAMMA_MODE_MODE_8BIT (0 << 0) ++#define GAMMA_MODE_MODE_10BIT (1 << 0) ++#define GAMMA_MODE_MODE_12BIT (2 << 0) + #define GAMMA_MODE_MODE_SPLIT (3 << 0) + + /* interrupts */ +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 0d23d7bfc884..24c8384228b6 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5437,13 +5437,11 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc) + enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; + uint32_t val; + +- val = I915_READ(PIPECONF(cpu_transcoder)); ++ val = 0; + +- val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK); + if (intel_crtc->config.dither) + val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP); + +- val &= ~PIPECONF_INTERLACE_MASK_HSW; + if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) + val |= PIPECONF_INTERLACED_ILK; + else +@@ -5451,6 +5449,9 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc) + + I915_WRITE(PIPECONF(cpu_transcoder), val); + POSTING_READ(PIPECONF(cpu_transcoder)); ++ ++ I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT); ++ POSTING_READ(GAMMA_MODE(intel_crtc->pipe)); + } + + static bool ironlake_compute_clocks(struct drm_crtc *crtc, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0328-drm-i915-stop-killing-pfit-on-i9xx.patch b/patches.baytrail/0328-drm-i915-stop-killing-pfit-on-i9xx.patch new file mode 100644 index 000000000000..b9aabd4a625c --- /dev/null +++ b/patches.baytrail/0328-drm-i915-stop-killing-pfit-on-i9xx.patch @@ -0,0 +1,132 @@ +From ad5b8315250a36c3c08412dc67440174c7063a4f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 6 Jun 2013 22:22:47 +0200 +Subject: drm/i915: stop killing pfit on i9xx + +Nowadays (i.e. with Valleyview) we also have edp on non-PCH_SPLIT +platforms, so just checking for LVDS is not good enough. + +Secondly we have full pfit pipe config tracking, so we'll correctly +disable the pfit as part of the initial modeset. + +For fastboot we need a bit of work here to correctly kill unsupported +configs (if e.g. the pfit is used on anything else than the built-in +panel). But since that's not yet supported we don't need to worry. + +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit c9093354a1e839be057aee66bac37bd3b2f44d0e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 7 +------ + drivers/gpu/drm/i915/intel_drv.h | 2 +- + drivers/gpu/drm/i915/intel_lvds.c | 20 ++++++++++---------- + 3 files changed, 12 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 24c8384228b6..28f97e9aeedc 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8986,13 +8986,8 @@ static void intel_setup_outputs(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_encoder *encoder; + bool dpd_is_edp = false; +- bool has_lvds; + +- has_lvds = intel_lvds_init(dev); +- if (!has_lvds && !HAS_PCH_SPLIT(dev)) { +- /* disable the panel fitter on everything but LVDS */ +- I915_WRITE(PFIT_CONTROL, 0); +- } ++ intel_lvds_init(dev); + + if (!IS_ULT(dev)) + intel_crt_init(dev); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index abe9c9e9d8a3..20396d624819 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -582,7 +582,7 @@ extern void intel_mark_busy(struct drm_device *dev); + extern void intel_mark_fb_busy(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *ring); + extern void intel_mark_idle(struct drm_device *dev); +-extern bool intel_lvds_init(struct drm_device *dev); ++extern void intel_lvds_init(struct drm_device *dev); + extern bool intel_is_dual_link_lvds(struct drm_device *dev); + extern void intel_dp_init(struct drm_device *dev, int output_reg, + enum port port); +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 7feaba3de45f..3264bfa842fc 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -909,7 +909,7 @@ static bool intel_lvds_supported(struct drm_device *dev) + * Create the connector, register the LVDS DDC bus, and try to figure out what + * modes we can display on the LVDS panel (if present). + */ +-bool intel_lvds_init(struct drm_device *dev) ++void intel_lvds_init(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_lvds_encoder *lvds_encoder; +@@ -927,35 +927,35 @@ bool intel_lvds_init(struct drm_device *dev) + u8 pin; + + if (!intel_lvds_supported(dev)) +- return false; ++ return; + + /* Skip init on machines we know falsely report LVDS */ + if (dmi_check_system(intel_no_lvds)) +- return false; ++ return; + + pin = GMBUS_PORT_PANEL; + if (!lvds_is_present_in_vbt(dev, &pin)) { + DRM_DEBUG_KMS("LVDS is not present in VBT\n"); +- return false; ++ return; + } + + if (HAS_PCH_SPLIT(dev)) { + if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) +- return false; ++ return; + if (dev_priv->vbt.edp_support) { + DRM_DEBUG_KMS("disable LVDS for eDP support\n"); +- return false; ++ return; + } + } + + lvds_encoder = kzalloc(sizeof(struct intel_lvds_encoder), GFP_KERNEL); + if (!lvds_encoder) +- return false; ++ return; + + lvds_connector = kzalloc(sizeof(struct intel_lvds_connector), GFP_KERNEL); + if (!lvds_connector) { + kfree(lvds_encoder); +- return false; ++ return; + } + + lvds_encoder->attached_connector = lvds_connector; +@@ -1126,7 +1126,7 @@ out: + intel_panel_init(&intel_connector->panel, fixed_mode); + intel_panel_setup_backlight(connector); + +- return true; ++ return; + + failed: + DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); +@@ -1136,5 +1136,5 @@ failed: + drm_mode_destroy(dev, fixed_mode); + kfree(lvds_encoder); + kfree(lvds_connector); +- return false; ++ return; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0329-drm-i915-simplify-the-reduced-clock-handling-for-pch.patch b/patches.baytrail/0329-drm-i915-simplify-the-reduced-clock-handling-for-pch.patch new file mode 100644 index 000000000000..c6f4818969c0 --- /dev/null +++ b/patches.baytrail/0329-drm-i915-simplify-the-reduced-clock-handling-for-pch.patch @@ -0,0 +1,62 @@ +From 24a3492aef4e63327e474aef6e0192458b5c4562 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:22 +0200 +Subject: drm/i915: simplify the reduced clock handling for pch plls + +Just move the lowfreq_avail logic out of the register writing as a +prep step for the next patch, which will coalesce all the pch pll +enabling into one spot. + +Note that writing the reduced clock dividers to FP1 in a few more +cases (as this patch ends up doing) isn't really relevant since the +FP1 value only matters when we enable the low lock. Which despite +can only happen if we've actually enabled the reduced dotclock and +furthermore isn't even properly implemented on ilk+: Despite claims to +the contrary in the code switching between frequencies if fully +manual. + +v2: Explain matters around the FP1 change to answer a question Damien +raised in his review. + +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit bcd644e046d97b317255ee75f0ebd289b9bcd9ba) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 28f97e9aeedc..fd96db306c6a 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5730,7 +5730,10 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + if (encoder->pre_pll_enable) + encoder->pre_pll_enable(encoder); + +- intel_crtc->lowfreq_avail = false; ++ if (is_lvds && has_reduced_clock && i915_powersave) ++ intel_crtc->lowfreq_avail = true; ++ else ++ intel_crtc->lowfreq_avail = false; + + if (intel_crtc->config.has_pch_encoder) { + pll = intel_crtc_to_shared_dpll(intel_crtc); +@@ -5748,12 +5751,10 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + */ + I915_WRITE(PCH_DPLL(pll->id), dpll); + +- if (is_lvds && has_reduced_clock && i915_powersave) { ++ if (has_reduced_clock) + I915_WRITE(PCH_FP1(pll->id), fp2); +- intel_crtc->lowfreq_avail = true; +- } else { ++ else + I915_WRITE(PCH_FP1(pll->id), fp); +- } + } + + intel_set_pipe_timings(intel_crtc); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0330-drm-i915-Remove-extra-ring-from-error-message.patch b/patches.baytrail/0330-drm-i915-Remove-extra-ring-from-error-message.patch new file mode 100644 index 000000000000..5274534d02ea --- /dev/null +++ b/patches.baytrail/0330-drm-i915-Remove-extra-ring-from-error-message.patch @@ -0,0 +1,32 @@ +From 5a98d3a3e680490278bc2e9b3ad1075439604044 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 13 Jun 2013 21:33:33 -0700 +Subject: drm/i915: Remove extra "ring" from error message + +The ring names already have "ring" in it. + +CC: Chris Wilson +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit acd78c117f0ac6960dc9e51801adb59810e49e75) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 5c344a5f307c..a35fb3ce973b 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2556,7 +2556,7 @@ void i915_hangcheck_elapsed(unsigned long data) + + for_each_ring(ring, dev_priv, i) { + if (ring->hangcheck.score > FIRE) { +- DRM_ERROR("%s on %s ring\n", ++ DRM_ERROR("%s on %s\n", + stuck[i] ? "stuck" : "no progress", + ring->name); + rings_hung++; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0331-drm-i915-Kill-useless-Enable-panel-fitter-comments.patch b/patches.baytrail/0331-drm-i915-Kill-useless-Enable-panel-fitter-comments.patch new file mode 100644 index 000000000000..ee0de459f41f --- /dev/null +++ b/patches.baytrail/0331-drm-i915-Kill-useless-Enable-panel-fitter-comments.patch @@ -0,0 +1,59 @@ +From 7134654c3f1a430482fb6737812e4ff8b6d5c754 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 14 Jun 2013 00:51:23 +0200 +Subject: drm/i915: Kill useless "Enable panel fitter" comments + +Now that we have this all nicely abstract into separate functions with +self-documenting names this is pointless. And as Yuly Novikov spotted +in the case of ilk-ivb also wrong since we use the pfit both for lvds +and eDP + +Reported-By: Yuly Novikov +Cc: Jesse Barnes +Acked-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 05d62b831367cece58363dfe5768a00d2a1faaf5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index fd96db306c6a..9c5eae0f42f6 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3209,7 +3209,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + if (encoder->pre_enable) + encoder->pre_enable(encoder); + +- /* Enable panel fitting for LVDS */ + ironlake_pfit_enable(intel_crtc); + + /* +@@ -3315,7 +3314,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) + + intel_ddi_enable_pipe_clock(intel_crtc); + +- /* Enable panel fitting for eDP */ + ironlake_pfit_enable(intel_crtc); + + /* +@@ -3611,7 +3609,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) + for_each_encoder_on_crtc(dev, crtc, encoder) + encoder->enable(encoder); + +- /* Enable panel fitting for eDP */ + i9xx_pfit_enable(intel_crtc); + + intel_crtc_load_lut(crtc); +@@ -3649,7 +3646,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) + if (encoder->pre_enable) + encoder->pre_enable(encoder); + +- /* Enable panel fitting for LVDS */ + i9xx_pfit_enable(intel_crtc); + + intel_crtc_load_lut(crtc); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0332-drm-i915-remove-a-superflous-semi-colon.patch b/patches.baytrail/0332-drm-i915-remove-a-superflous-semi-colon.patch new file mode 100644 index 000000000000..a11f23d554ea --- /dev/null +++ b/patches.baytrail/0332-drm-i915-remove-a-superflous-semi-colon.patch @@ -0,0 +1,31 @@ +From 3cd18b148c2b9d417f926df6ff0f4e6579312767 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 18 Jun 2013 10:29:58 +0300 +Subject: drm/i915: remove a superflous semi-colon + +This macro doesn't need a semi-colon. + +Signed-off-by: Dan Carpenter +Signed-off-by: Daniel Vetter +(cherry picked from commit 854c94a7854a4fabdd7db451cf1774e6dcba6bab) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index e73bc66ef1dc..fb98a787864f 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1769,7 +1769,7 @@ int __i915_add_request(struct intel_ring_buffer *ring, + struct drm_i915_gem_object *batch_obj, + u32 *seqno); + #define i915_add_request(ring, seqno) \ +- __i915_add_request(ring, NULL, NULL, seqno); ++ __i915_add_request(ring, NULL, NULL, seqno) + int __must_check i915_wait_seqno(struct intel_ring_buffer *ring, + uint32_t seqno); + int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0333-drm-make-drm_mm_init-return-void.patch b/patches.baytrail/0333-drm-make-drm_mm_init-return-void.patch new file mode 100644 index 000000000000..b8d533a77179 --- /dev/null +++ b/patches.baytrail/0333-drm-make-drm_mm_init-return-void.patch @@ -0,0 +1,130 @@ +From 9aeefe0127725edb81bd4d38feccf41b3bde24f0 Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Mon, 1 Jul 2013 20:32:58 +0200 +Subject: drm: make drm_mm_init() return void + +There is no reason to return "int" as this function never fails. +Furthermore, several drivers (ast, sis) already depend on this. + +Signed-off-by: David Herrmann +Reviewed-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit 77ef8bbc87be7ad10b410247efc6d0f10676b401) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_gem.c | 8 ++------ + drivers/gpu/drm/drm_mm.c | 4 +--- + drivers/gpu/drm/ttm/ttm_bo.c | 6 +----- + drivers/gpu/drm/ttm/ttm_bo_manager.c | 8 +------- + include/drm/drm_mm.h | 6 +++--- + 5 files changed, 8 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index 239ef30f4a62..4e7407cb0ebc 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -108,12 +108,8 @@ drm_gem_init(struct drm_device *dev) + return -ENOMEM; + } + +- if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START, +- DRM_FILE_PAGE_OFFSET_SIZE)) { +- drm_ht_remove(&mm->offset_hash); +- kfree(mm); +- return -ENOMEM; +- } ++ drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START, ++ DRM_FILE_PAGE_OFFSET_SIZE); + + return 0; + } +diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c +index 07cf99cc8862..7917729ee61d 100644 +--- a/drivers/gpu/drm/drm_mm.c ++++ b/drivers/gpu/drm/drm_mm.c +@@ -669,7 +669,7 @@ int drm_mm_clean(struct drm_mm * mm) + } + EXPORT_SYMBOL(drm_mm_clean); + +-int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) ++void drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) + { + INIT_LIST_HEAD(&mm->hole_stack); + INIT_LIST_HEAD(&mm->unused_nodes); +@@ -690,8 +690,6 @@ int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) + list_add_tail(&mm->head_node.hole_stack, &mm->hole_stack); + + mm->color_adjust = NULL; +- +- return 0; + } + EXPORT_SYMBOL(drm_mm_init); + +diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c +index 8697abd7b173..57f9766e1135 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo.c ++++ b/drivers/gpu/drm/ttm/ttm_bo.c +@@ -1627,9 +1627,7 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev, + goto out_no_sys; + + bdev->addr_space_rb = RB_ROOT; +- ret = drm_mm_init(&bdev->addr_space_mm, file_page_offset, 0x10000000); +- if (unlikely(ret != 0)) +- goto out_no_addr_mm; ++ drm_mm_init(&bdev->addr_space_mm, file_page_offset, 0x10000000); + + INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue); + INIT_LIST_HEAD(&bdev->ddestroy); +@@ -1643,8 +1641,6 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev, + mutex_unlock(&glob->device_list_mutex); + + return 0; +-out_no_addr_mm: +- ttm_bo_clean_mm(bdev, 0); + out_no_sys: + return ret; + } +diff --git a/drivers/gpu/drm/ttm/ttm_bo_manager.c b/drivers/gpu/drm/ttm/ttm_bo_manager.c +index 9212494e9072..e4367f91472a 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo_manager.c ++++ b/drivers/gpu/drm/ttm/ttm_bo_manager.c +@@ -103,18 +103,12 @@ static int ttm_bo_man_init(struct ttm_mem_type_manager *man, + unsigned long p_size) + { + struct ttm_range_manager *rman; +- int ret; + + rman = kzalloc(sizeof(*rman), GFP_KERNEL); + if (!rman) + return -ENOMEM; + +- ret = drm_mm_init(&rman->mm, 0, p_size); +- if (ret) { +- kfree(rman); +- return ret; +- } +- ++ drm_mm_init(&rman->mm, 0, p_size); + spin_lock_init(&rman->lock); + man->priv = rman; + return 0; +diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h +index 88591ef8fa24..de9242542f05 100644 +--- a/include/drm/drm_mm.h ++++ b/include/drm/drm_mm.h +@@ -275,9 +275,9 @@ static inline struct drm_mm_node *drm_mm_search_free_in_range_color( + return drm_mm_search_free_in_range_generic(mm, size, alignment, color, + start, end, best_match); + } +-extern int drm_mm_init(struct drm_mm *mm, +- unsigned long start, +- unsigned long size); ++extern void drm_mm_init(struct drm_mm *mm, ++ unsigned long start, ++ unsigned long size); + extern void drm_mm_takedown(struct drm_mm *mm); + extern int drm_mm_clean(struct drm_mm *mm); + extern int drm_mm_pre_get(struct drm_mm *mm); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0334-drm-i915-don-t-check-encoder-at-DP-connector-destroy.patch b/patches.baytrail/0334-drm-i915-don-t-check-encoder-at-DP-connector-destroy.patch new file mode 100644 index 000000000000..6944195b85ed --- /dev/null +++ b/patches.baytrail/0334-drm-i915-don-t-check-encoder-at-DP-connector-destroy.patch @@ -0,0 +1,47 @@ +From 6b1cd26d404de74ce9fddad6675845307db67eb0 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Wed, 12 Jun 2013 17:27:23 -0300 +Subject: drm/i915: don't check encoder at DP connector destroy() + +By the time we call intel_dp_destroy (which destroys the connector) +the encoder may have been destroyed already, so if we use it we may be +reading some free memory. That happens in drm_mode_config_cleanup() +and also inside intel_dp_init_connector() when we detect a ghost eDP. + +I also hope this may solve some random memory bugs. + +Reported by kmemcheck. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Zoltan Nyul +Signed-off-by: Daniel Vetter +(cherry picked from commit acd8db100ed5220fe8043f91cdc20155325542a9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 0066c2314e1f..532197981bd7 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -2694,13 +2694,14 @@ done: + static void + intel_dp_destroy(struct drm_connector *connector) + { +- struct intel_dp *intel_dp = intel_attached_dp(connector); + struct intel_connector *intel_connector = to_intel_connector(connector); + + if (!IS_ERR_OR_NULL(intel_connector->edid)) + kfree(intel_connector->edid); + +- if (is_edp(intel_dp)) ++ /* Can't call is_edp() since the encoder may have been destroyed ++ * already. */ ++ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) + intel_panel_fini(&intel_connector->panel); + + drm_sysfs_connector_remove(connector); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0335-drm-i915-extract-intel_edp_init_connector.patch b/patches.baytrail/0335-drm-i915-extract-intel_edp_init_connector.patch new file mode 100644 index 000000000000..d5048a42b413 --- /dev/null +++ b/patches.baytrail/0335-drm-i915-extract-intel_edp_init_connector.patch @@ -0,0 +1,198 @@ +From 1125a7294a1187b78ef9c43e37ccd323867a63f4 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Wed, 12 Jun 2013 17:27:24 -0300 +Subject: drm/i915: extract intel_edp_init_connector + +Because intel_dp_init_connector is too big for my poor little brain. +No functional changes. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Zoltan Nyul +Signed-off-by: Daniel Vetter +(cherry picked from commit ed92f0b239ac971edc509169ae3d6955fbe0a188) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 151 ++++++++++++++++++++++------------------ + 1 file changed, 82 insertions(+), 69 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 532197981bd7..b307befdbdb0 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -2966,6 +2966,86 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, + I915_READ(pp_div_reg)); + } + ++static bool intel_edp_init_connector(struct intel_dp *intel_dp, ++ struct intel_connector *intel_connector) ++{ ++ struct drm_connector *connector = &intel_connector->base; ++ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); ++ struct drm_device *dev = intel_dig_port->base.base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_display_mode *fixed_mode = NULL; ++ struct edp_power_seq power_seq = { 0 }; ++ bool has_dpcd; ++ struct drm_display_mode *scan; ++ struct edid *edid; ++ ++ if (!is_edp(intel_dp)) ++ return true; ++ ++ intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); ++ ++ /* Cache DPCD and EDID for edp. */ ++ ironlake_edp_panel_vdd_on(intel_dp); ++ has_dpcd = intel_dp_get_dpcd(intel_dp); ++ ironlake_edp_panel_vdd_off(intel_dp, false); ++ ++ if (has_dpcd) { ++ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) ++ dev_priv->no_aux_handshake = ++ intel_dp->dpcd[DP_MAX_DOWNSPREAD] & ++ DP_NO_AUX_HANDSHAKE_LINK_TRAINING; ++ } else { ++ /* if this fails, presume the device is a ghost */ ++ DRM_INFO("failed to retrieve link info, disabling eDP\n"); ++ intel_dp_encoder_destroy(&intel_dig_port->base.base); ++ intel_dp_destroy(connector); ++ return false; ++ } ++ ++ /* We now know it's not a ghost, init power sequence regs. */ ++ intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, ++ &power_seq); ++ ++ ironlake_edp_panel_vdd_on(intel_dp); ++ edid = drm_get_edid(connector, &intel_dp->adapter); ++ if (edid) { ++ if (drm_add_edid_modes(connector, edid)) { ++ drm_mode_connector_update_edid_property(connector, ++ edid); ++ drm_edid_to_eld(connector, edid); ++ } else { ++ kfree(edid); ++ edid = ERR_PTR(-EINVAL); ++ } ++ } else { ++ edid = ERR_PTR(-ENOENT); ++ } ++ intel_connector->edid = edid; ++ ++ /* prefer fixed mode from EDID if available */ ++ list_for_each_entry(scan, &connector->probed_modes, head) { ++ if ((scan->type & DRM_MODE_TYPE_PREFERRED)) { ++ fixed_mode = drm_mode_duplicate(dev, scan); ++ break; ++ } ++ } ++ ++ /* fallback to VBT if available for eDP */ ++ if (!fixed_mode && dev_priv->vbt.lfp_lvds_vbt_mode) { ++ fixed_mode = drm_mode_duplicate(dev, ++ dev_priv->vbt.lfp_lvds_vbt_mode); ++ if (fixed_mode) ++ fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; ++ } ++ ++ ironlake_edp_panel_vdd_off(intel_dp, false); ++ ++ intel_panel_init(&intel_connector->panel, fixed_mode); ++ intel_panel_setup_backlight(connector); ++ ++ return true; ++} ++ + void + intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + struct intel_connector *intel_connector) +@@ -2975,8 +3055,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + struct intel_encoder *intel_encoder = &intel_dig_port->base; + struct drm_device *dev = intel_encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct drm_display_mode *fixed_mode = NULL; +- struct edp_power_seq power_seq = { 0 }; + enum port port = intel_dig_port->port; + const char *name = NULL; + int type; +@@ -3077,75 +3155,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + BUG(); + } + +- if (is_edp(intel_dp)) +- intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); +- + intel_dp_i2c_init(intel_dp, intel_connector, name); + +- /* Cache DPCD and EDID for edp. */ +- if (is_edp(intel_dp)) { +- bool ret; +- struct drm_display_mode *scan; +- struct edid *edid; +- +- ironlake_edp_panel_vdd_on(intel_dp); +- ret = intel_dp_get_dpcd(intel_dp); +- ironlake_edp_panel_vdd_off(intel_dp, false); +- +- if (ret) { +- if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) +- dev_priv->no_aux_handshake = +- intel_dp->dpcd[DP_MAX_DOWNSPREAD] & +- DP_NO_AUX_HANDSHAKE_LINK_TRAINING; +- } else { +- /* if this fails, presume the device is a ghost */ +- DRM_INFO("failed to retrieve link info, disabling eDP\n"); +- intel_dp_encoder_destroy(&intel_encoder->base); +- intel_dp_destroy(connector); +- return; +- } +- +- /* We now know it's not a ghost, init power sequence regs. */ +- intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, +- &power_seq); +- +- ironlake_edp_panel_vdd_on(intel_dp); +- edid = drm_get_edid(connector, &intel_dp->adapter); +- if (edid) { +- if (drm_add_edid_modes(connector, edid)) { +- drm_mode_connector_update_edid_property(connector, edid); +- drm_edid_to_eld(connector, edid); +- } else { +- kfree(edid); +- edid = ERR_PTR(-EINVAL); +- } +- } else { +- edid = ERR_PTR(-ENOENT); +- } +- intel_connector->edid = edid; +- +- /* prefer fixed mode from EDID if available */ +- list_for_each_entry(scan, &connector->probed_modes, head) { +- if ((scan->type & DRM_MODE_TYPE_PREFERRED)) { +- fixed_mode = drm_mode_duplicate(dev, scan); +- break; +- } +- } +- +- /* fallback to VBT if available for eDP */ +- if (!fixed_mode && dev_priv->vbt.lfp_lvds_vbt_mode) { +- fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode); +- if (fixed_mode) +- fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; +- } +- +- ironlake_edp_panel_vdd_off(intel_dp, false); +- } +- +- if (is_edp(intel_dp)) { +- intel_panel_init(&intel_connector->panel, fixed_mode); +- intel_panel_setup_backlight(connector); +- } ++ if (!intel_edp_init_connector(intel_dp, intel_connector)) ++ return; + + intel_dp_add_properties(intel_dp, connector); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0336-drm-i915-propagate-errors-from-intel_dp_init_connect.patch b/patches.baytrail/0336-drm-i915-propagate-errors-from-intel_dp_init_connect.patch new file mode 100644 index 000000000000..fa41dc08a3d0 --- /dev/null +++ b/patches.baytrail/0336-drm-i915-propagate-errors-from-intel_dp_init_connect.patch @@ -0,0 +1,91 @@ +From 897f7793ad6f32bc1fc191bfbfc6ca9bbd509d08 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Wed, 12 Jun 2013 17:27:25 -0300 +Subject: drm/i915: propagate errors from intel_dp_init_connector + +In case we detect a "ghost eDP", intel_edp_init_connector frees both +the connector and encoder and then returns. On Haswell, intel_ddi_init +then tries to use the freed encoder on the HDMI initialization path +since the following commit: + +commit 21a8e6a4853b2ed39fa4c5188a710f2cf1b92026 +Author: Daniel Vetter +Date: Wed Apr 10 23:28:35 2013 +0200 + drm/i915: don't setup hdmi for port D edp in ddi_init + +So now on intel_ddi_init we check for the "ghost eDP" case and return +without trying to initialize HDMI. This way we won't try to read the +freed "intel_encoder" struct in the next "if" statement. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Zoltan Nyul +Signed-off-by: Daniel Vetter +(cherry picked from commit 16c255335b0ec39b4e5e976f4b260978aeed5a68) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 3 ++- + drivers/gpu/drm/i915/intel_dp.c | 6 ++++-- + drivers/gpu/drm/i915/intel_drv.h | 2 +- + 3 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 6df049fe7462..73acdbae3301 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -1360,7 +1360,8 @@ void intel_ddi_init(struct drm_device *dev, enum port port) + intel_encoder->cloneable = false; + intel_encoder->hot_plug = intel_ddi_hot_plug; + +- intel_dp_init_connector(intel_dig_port, dp_connector); ++ if (!intel_dp_init_connector(intel_dig_port, dp_connector)) ++ return; + + if (intel_encoder->type != INTEL_OUTPUT_EDP) { + hdmi_connector = kzalloc(sizeof(struct intel_connector), +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index b307befdbdb0..cd7a28762333 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -3046,7 +3046,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, + return true; + } + +-void ++bool + intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + struct intel_connector *intel_connector) + { +@@ -3158,7 +3158,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + intel_dp_i2c_init(intel_dp, intel_connector, name); + + if (!intel_edp_init_connector(intel_dp, intel_connector)) +- return; ++ return false; + + intel_dp_add_properties(intel_dp, connector); + +@@ -3170,6 +3170,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + u32 temp = I915_READ(PEG_BAND_GAP_DATA); + I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); + } ++ ++ return true; + } + + void +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 20396d624819..c7b93c61e467 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -586,7 +586,7 @@ extern void intel_lvds_init(struct drm_device *dev); + extern bool intel_is_dual_link_lvds(struct drm_device *dev); + extern void intel_dp_init(struct drm_device *dev, int output_reg, + enum port port); +-extern void intel_dp_init_connector(struct intel_digital_port *intel_dig_port, ++extern bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + struct intel_connector *intel_connector); + extern void intel_dp_init_link_config(struct intel_dp *intel_dp); + extern void intel_dp_start_link_train(struct intel_dp *intel_dp); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0337-drm-i915-fix-the-ghost-eDP-connector-unwind-path.patch b/patches.baytrail/0337-drm-i915-fix-the-ghost-eDP-connector-unwind-path.patch new file mode 100644 index 000000000000..f93279b34628 --- /dev/null +++ b/patches.baytrail/0337-drm-i915-fix-the-ghost-eDP-connector-unwind-path.patch @@ -0,0 +1,85 @@ +From 4c61b19b8fd1ed30b80dbd6dba91146e71c532d0 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Wed, 12 Jun 2013 17:27:26 -0300 +Subject: drm/i915: fix the "ghost eDP" connector unwind path + +Because calling intel_dp_destroy inside intel_edp_init_connector is +just wrong. This is the initialization path, so we should properly +unwind all the initialization through the whole caller stack. + +On the intel_dp_destroy function we do the following: +1 - Free edid if it exists +2 - Call intel_panel_fini in case it's eDP +3 - Call drm_sysfs_connector_remove +4 - Call drm_connector_cleanup +5 - Free the connector + +And here is how we unwind each specific step: +1 - No need as we still didn't assign anything +2 - No need as we still didn't call intel_panel_init +3 - Call it in the same function that called drm_sysfs_connector_add +4 - Call it in the same function that called drm_connector_init +5 - Free it in the same function that allocated it + +Signed-off-by: Paulo Zanoni +Reviewed-by: Zoltan Nyul +Signed-off-by: Daniel Vetter +(cherry picked from commit b2f246a8998ccf9e00477c8829a62139804e9857) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 4 +++- + drivers/gpu/drm/i915/intel_dp.c | 9 ++++++--- + 2 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 73acdbae3301..c7cac2f9a053 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -1360,8 +1360,10 @@ void intel_ddi_init(struct drm_device *dev, enum port port) + intel_encoder->cloneable = false; + intel_encoder->hot_plug = intel_ddi_hot_plug; + +- if (!intel_dp_init_connector(intel_dig_port, dp_connector)) ++ if (!intel_dp_init_connector(intel_dig_port, dp_connector)) { ++ kfree(dp_connector); + return; ++ } + + if (intel_encoder->type != INTEL_OUTPUT_EDP) { + hdmi_connector = kzalloc(sizeof(struct intel_connector), +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index cd7a28762333..7da84180d7ce 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -2998,7 +2998,6 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, + /* if this fails, presume the device is a ghost */ + DRM_INFO("failed to retrieve link info, disabling eDP\n"); + intel_dp_encoder_destroy(&intel_dig_port->base.base); +- intel_dp_destroy(connector); + return false; + } + +@@ -3157,8 +3156,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + + intel_dp_i2c_init(intel_dp, intel_connector, name); + +- if (!intel_edp_init_connector(intel_dp, intel_connector)) ++ if (!intel_edp_init_connector(intel_dp, intel_connector)) { ++ drm_sysfs_connector_remove(connector); ++ drm_connector_cleanup(connector); + return false; ++ } + + intel_dp_add_properties(intel_dp, connector); + +@@ -3217,5 +3219,6 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) + intel_encoder->cloneable = false; + intel_encoder->hot_plug = intel_dp_hot_plug; + +- intel_dp_init_connector(intel_dig_port, intel_connector); ++ if (!intel_dp_init_connector(intel_dig_port, intel_connector)) ++ kfree(intel_connector); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0338-drm-i915-fix-the-ghost-eDP-encoder-unwind-path.patch b/patches.baytrail/0338-drm-i915-fix-the-ghost-eDP-encoder-unwind-path.patch new file mode 100644 index 000000000000..81be146290de --- /dev/null +++ b/patches.baytrail/0338-drm-i915-fix-the-ghost-eDP-encoder-unwind-path.patch @@ -0,0 +1,89 @@ +From b76b6f1d0b67532fdd33934addae3c3e30e8f8c1 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Wed, 12 Jun 2013 17:27:27 -0300 +Subject: drm/i915: fix the "ghost eDP" encoder unwind path + +Because calling intel_dp_encoder_destroy inside +intel_edp_init_connector is just wrong. This is the initialization +path, so we should properly unwind all the initialization through the +whole caller stack. + +On the intel_dp_encoder_destroy function we do the following: +1 - Call i2c_del_adapter +2 - Call drm_encoder_cleanup +3 - If edp: +3.1 - Cancel panel_vdd_work +3.2 - Call ironlake_panel_vdd_of_sync +4 - Free the encoder + +And here is how we unwind each specific step: +1 - We have intel_dp_init_connector -> intel_dp_i2c_init -> + i2c_dp_aux_add_bus -> i2c_add_adapter, so we call + i2c_del_dapter at intel_dp_init_connector +2 - Call it in the same function that called drm_encoder_init +3 - Call it in the same function that called INIT_DELAYED_WORK +4 - Free it in the same function that allocated it + +Signed-off-by: Paulo Zanoni +Reviewed-by: Zoltan Nyul +Signed-off-by: Daniel Vetter +(cherry picked from commit 15b1d171d87e86366266255462e6b11d21b61c1c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 2 ++ + drivers/gpu/drm/i915/intel_dp.c | 13 +++++++++++-- + 2 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index c7cac2f9a053..0bf5be1bf5c9 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -1361,6 +1361,8 @@ void intel_ddi_init(struct drm_device *dev, enum port port) + intel_encoder->hot_plug = intel_ddi_hot_plug; + + if (!intel_dp_init_connector(intel_dig_port, dp_connector)) { ++ drm_encoder_cleanup(encoder); ++ kfree(intel_dig_port); + kfree(dp_connector); + return; + } +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 7da84180d7ce..0cd390ef6f0e 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -2997,7 +2997,6 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, + } else { + /* if this fails, presume the device is a ghost */ + DRM_INFO("failed to retrieve link info, disabling eDP\n"); +- intel_dp_encoder_destroy(&intel_dig_port->base.base); + return false; + } + +@@ -3157,6 +3156,13 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + intel_dp_i2c_init(intel_dp, intel_connector, name); + + if (!intel_edp_init_connector(intel_dp, intel_connector)) { ++ i2c_del_adapter(&intel_dp->adapter); ++ if (is_edp(intel_dp)) { ++ cancel_delayed_work_sync(&intel_dp->panel_vdd_work); ++ mutex_lock(&dev->mode_config.mutex); ++ ironlake_panel_vdd_off_sync(intel_dp); ++ mutex_unlock(&dev->mode_config.mutex); ++ } + drm_sysfs_connector_remove(connector); + drm_connector_cleanup(connector); + return false; +@@ -3219,6 +3225,9 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) + intel_encoder->cloneable = false; + intel_encoder->hot_plug = intel_dp_hot_plug; + +- if (!intel_dp_init_connector(intel_dig_port, intel_connector)) ++ if (!intel_dp_init_connector(intel_dig_port, intel_connector)) { ++ drm_encoder_cleanup(encoder); ++ kfree(intel_dig_port); + kfree(intel_connector); ++ } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0339-drm-i915-check-the-return-value-of-intel_dp_i2c_init.patch b/patches.baytrail/0339-drm-i915-check-the-return-value-of-intel_dp_i2c_init.patch new file mode 100644 index 000000000000..c079d1b39213 --- /dev/null +++ b/patches.baytrail/0339-drm-i915-check-the-return-value-of-intel_dp_i2c_init.patch @@ -0,0 +1,44 @@ +From 1a2ece247f17addccbce131ba57391c11a042f0e Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Wed, 12 Jun 2013 17:27:28 -0300 +Subject: drm/i915: check the return value of intel_dp_i2c_init + +We've been ignoring this return value, so print a nice backtrace in +case it's not what we expected. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Zoltan Nyul +Signed-off-by: Daniel Vetter +(cherry picked from commit b2a1475561d59e8d182ba8cc4b7e78b662a3f533) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 0cd390ef6f0e..ddc06bef70e5 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -3055,7 +3055,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + struct drm_i915_private *dev_priv = dev->dev_private; + enum port port = intel_dig_port->port; + const char *name = NULL; +- int type; ++ int type, error; + + /* Preserve the current hw state. */ + intel_dp->DP = I915_READ(intel_dp->output_reg); +@@ -3153,7 +3153,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + BUG(); + } + +- intel_dp_i2c_init(intel_dp, intel_connector, name); ++ error = intel_dp_i2c_init(intel_dp, intel_connector, name); ++ WARN(error, "intel_dp_i2c_init failed with error %d for port %c\n", ++ error, port_name(port)); + + if (!intel_edp_init_connector(intel_dp, intel_connector)) { + i2c_del_adapter(&intel_dp->adapter); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0340-drm-i915-rename-intel_dp_destroy-to-intel_dp_connect.patch b/patches.baytrail/0340-drm-i915-rename-intel_dp_destroy-to-intel_dp_connect.patch new file mode 100644 index 000000000000..0c6157f7dd1b --- /dev/null +++ b/patches.baytrail/0340-drm-i915-rename-intel_dp_destroy-to-intel_dp_connect.patch @@ -0,0 +1,44 @@ +From 05fc6037d90b0a9f248f55a616f633f2fba543a2 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Wed, 12 Jun 2013 17:27:30 -0300 +Subject: drm/i915: rename intel_dp_destroy to intel_dp_connector_destroy + +Because it's the function that destroys the connector, not the +encoder. And we already have intel_dp_encoder_destroy. + +This has annoyed me for a long time. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Zoltan Nyul +Signed-off-by: Daniel Vetter +(cherry picked from commit 73845adf3357c3c71da25e18f44e5a9924d666d5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index ddc06bef70e5..0f7e9094098d 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -2692,7 +2692,7 @@ done: + } + + static void +-intel_dp_destroy(struct drm_connector *connector) ++intel_dp_connector_destroy(struct drm_connector *connector) + { + struct intel_connector *intel_connector = to_intel_connector(connector); + +@@ -2735,7 +2735,7 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = { + .detect = intel_dp_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .set_property = intel_dp_set_property, +- .destroy = intel_dp_destroy, ++ .destroy = intel_dp_connector_destroy, + }; + + static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0341-drm-i915-Fix-PCH-detect-with-multiple-ISA-bridges-in.patch b/patches.baytrail/0341-drm-i915-Fix-PCH-detect-with-multiple-ISA-bridges-in.patch new file mode 100644 index 000000000000..d2ef9a361d2e --- /dev/null +++ b/patches.baytrail/0341-drm-i915-Fix-PCH-detect-with-multiple-ISA-bridges-in.patch @@ -0,0 +1,64 @@ +From 927cf082463ae442014d8a34195010ce2ab7f708 Mon Sep 17 00:00:00 2001 +From: Rui Guo +Date: Wed, 19 Jun 2013 21:10:23 +0800 +Subject: drm/i915: Fix PCH detect with multiple ISA bridges in VM + +In some virtualized environments (e.g. XEN), there is irrelevant ISA bridge in +the system. To work reliably, we should scan trhough all the ISA bridge +devices and check for the first match, instead of only checking the first one. + +Signed-off-by: Rui Guo +[danvet: Fixup conflict with the num_pch_pll removal. And add +subsystem header to the commit message headline.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 6a9c4b35e6696a63805b6da5e4889c6986e9ee1b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index b255b0bb0953..27a8bedd9156 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -465,9 +465,15 @@ void intel_detect_pch(struct drm_device *dev) + * make graphics device passthrough work easy for VMM, that only + * need to expose ISA bridge to let driver know the real hardware + * underneath. This is a requirement from virtualization team. ++ * ++ * In some virtualized environments (e.g. XEN), there is irrelevant ++ * ISA bridge in the system. To work reliably, we should scan trhough ++ * all the ISA bridge devices and check for the first match, instead ++ * of only checking the first one. + */ + pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); +- if (pch) { ++ while (pch) { ++ struct pci_dev *curr = pch; + if (pch->vendor == PCI_VENDOR_ID_INTEL) { + unsigned short id; + id = pch->device & INTEL_PCH_DEVICE_ID_MASK; +@@ -496,10 +502,18 @@ void intel_detect_pch(struct drm_device *dev) + DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); + WARN_ON(!IS_HASWELL(dev)); + WARN_ON(!IS_ULT(dev)); ++ } else { ++ goto check_next; + } ++ pci_dev_put(pch); ++ break; + } +- pci_dev_put(pch); ++check_next: ++ pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, curr); ++ pci_dev_put(curr); + } ++ if (!pch) ++ DRM_DEBUG_KMS("No PCH found?\n"); + } + + bool i915_semaphore_is_enabled(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0342-drm-i915-tune-down-DIDL-warning-about-too-many-outpu.patch b/patches.baytrail/0342-drm-i915-tune-down-DIDL-warning-about-too-many-outpu.patch new file mode 100644 index 000000000000..1618bd77cc93 --- /dev/null +++ b/patches.baytrail/0342-drm-i915-tune-down-DIDL-warning-about-too-many-outpu.patch @@ -0,0 +1,51 @@ +From e622cbff5041689378f915f41715311b616be112 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 24 Jun 2013 18:32:36 +0200 +Subject: drm/i915: tune down DIDL warning about too many outputs + +Nothing the user (nor we) really can do about this, but upsets a nice +quiet boot. + +Note that this happens mostly on SDVs where OEMs obviously haven't had +a chance yet to appropriately trim the output list. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65988 +Reviewed-by: Damien Lespiau +[danvet: Amend commit message a bit to clarify a question from Paulo.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 0f4f7b57954dda93b10e3b46594b0bfe24bba22c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_opregion.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c +index 79be7cfd3152..cfb8fb68f09c 100644 +--- a/drivers/gpu/drm/i915/intel_opregion.c ++++ b/drivers/gpu/drm/i915/intel_opregion.c +@@ -311,8 +311,8 @@ static void intel_didl_outputs(struct drm_device *dev) + + list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) { + if (i >= 8) { +- dev_printk(KERN_ERR, &dev->pdev->dev, +- "More than 8 outputs detected via ACPI\n"); ++ dev_dbg(&dev->pdev->dev, ++ "More than 8 outputs detected via ACPI\n"); + return; + } + status = +@@ -338,8 +338,8 @@ blind_set: + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + int output_type = ACPI_OTHER_OUTPUT; + if (i >= 8) { +- dev_printk(KERN_ERR, &dev->pdev->dev, +- "More than 8 outputs in connector list\n"); ++ dev_dbg(&dev->pdev->dev, ++ "More than 8 outputs in connector list\n"); + return; + } + switch (connector->connector_type) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0343-drm-i915-fix-build-warning-on-format-specifier-misma.patch b/patches.baytrail/0343-drm-i915-fix-build-warning-on-format-specifier-misma.patch new file mode 100644 index 000000000000..dc3483f1002e --- /dev/null +++ b/patches.baytrail/0343-drm-i915-fix-build-warning-on-format-specifier-misma.patch @@ -0,0 +1,39 @@ +From bfc9affe523ef2d2b72844b56151e82bbb602081 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Fri, 7 Jun 2013 16:03:50 +0300 +Subject: drm/i915: fix build warning on format specifier mismatch +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +drivers/gpu/drm/i915/i915_gem.c: In function ‘i915_gem_object_bind_to_gtt’: +drivers/gpu/drm/i915/i915_gem.c:3002:3: warning: format ‘%ld’ expects +argument of type ‘long int’, but argument 5 has type ‘size_t’ [-Wformat] + +v2: Use %zu instead of %d. Two char patch, and 100% wrong. (Ville) + +Signed-off-by: Jani Nikula +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 3765f3048651586e2617793e9efe184ff8c79a97) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 70af73dff001..5fcee7608228 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3138,7 +3138,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + * before evicting everything in a vain attempt to find space. + */ + if (obj->base.size > gtt_max) { +- DRM_ERROR("Attempting to bind an object larger than the aperture: object=%zd > %s aperture=%ld\n", ++ DRM_ERROR("Attempting to bind an object larger than the aperture: object=%zd > %s aperture=%zu\n", + obj->base.size, + map_and_fenceable ? "mappable" : "total", + gtt_max); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0344-drm-i915-Introduce-an-HAS_IPS-macro.patch b/patches.baytrail/0344-drm-i915-Introduce-an-HAS_IPS-macro.patch new file mode 100644 index 000000000000..e97357a3a49d --- /dev/null +++ b/patches.baytrail/0344-drm-i915-Introduce-an-HAS_IPS-macro.patch @@ -0,0 +1,69 @@ +From f336d3c8e153abd11567568c6ebfcd9352ee16c5 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 24 Jun 2013 18:29:34 +0100 +Subject: drm/i915: Introduce an HAS_IPS() macro + +Follow the trend and don't code conditions with platforms but with +features. + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit f5adf94e5fed2468eef4f0c094b66bf834770d7b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 2 +- + drivers/gpu/drm/i915/i915_drv.h | 2 ++ + drivers/gpu/drm/i915/intel_display.c | 4 ++-- + 3 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index d4e78b64ca87..f72d5a3fdfba 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1483,7 +1483,7 @@ static int i915_ips_status(struct seq_file *m, void *unused) + struct drm_device *dev = node->minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + +- if (!IS_ULT(dev)) { ++ if (!HAS_IPS(dev)) { + seq_puts(m, "not supported\n"); + return 0; + } +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index fb98a787864f..1929bffc1c77 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1475,6 +1475,8 @@ struct drm_i915_file_private { + #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) + #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) + ++#define HAS_IPS(dev) (IS_ULT(dev)) ++ + #define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5) + + #define HAS_DDI(dev) (INTEL_INFO(dev)->has_ddi) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 9c5eae0f42f6..82cdb4c5dede 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3250,7 +3250,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + /* IPS only exists on ULT machines and is tied to pipe A. */ + static bool hsw_crtc_supports_ips(struct intel_crtc *crtc) + { +- return IS_ULT(crtc->base.dev) && crtc->pipe == PIPE_A; ++ return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A; + } + + static void hsw_enable_ips(struct intel_crtc *crtc) +@@ -4065,7 +4065,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, + pipe_config->pipe_bpp = 8*3; + } + +- if (IS_HASWELL(dev)) ++ if (HAS_IPS(dev)) + hsw_compute_ips_config(crtc, pipe_config); + + /* XXX: PCH clock sharing is done in ->mode_set, so make sure the old +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0345-drm-i915-don-t-scream-into-dmesg-when-a-modeset-fail.patch b/patches.baytrail/0345-drm-i915-don-t-scream-into-dmesg-when-a-modeset-fail.patch new file mode 100644 index 000000000000..769f5becae58 --- /dev/null +++ b/patches.baytrail/0345-drm-i915-don-t-scream-into-dmesg-when-a-modeset-fail.patch @@ -0,0 +1,38 @@ +From a6b237fd0a42eafdb93833157080c570818ccece Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 25 Jun 2013 11:06:52 +0200 +Subject: drm/i915: don't scream into dmesg when a modeset fails + +There are legit cases, e.g. when userspace asks for something +impossible. So tune it down to debug output like we do with all other +userspace-triggerable warnings. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66111#c5 +Reviewed-by: Chris Wilson +[danvet: Rebased.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit bf67dfeb6899e140710d2138535b519dd8e46417) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 82cdb4c5dede..0cc81f6c0af3 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8760,8 +8760,8 @@ static int intel_crtc_set_config(struct drm_mode_set *set) + } + + if (ret) { +- DRM_ERROR("failed to set mode on [CRTC:%d], err = %d\n", +- set->crtc->base.id, ret); ++ DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n", ++ set->crtc->base.id, ret); + fail: + intel_set_config_restore_state(dev, config); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0346-drm-i915-Remove-duplicated-WaForceL3Serialization-vl.patch b/patches.baytrail/0346-drm-i915-Remove-duplicated-WaForceL3Serialization-vl.patch new file mode 100644 index 000000000000..09527c5853d1 --- /dev/null +++ b/patches.baytrail/0346-drm-i915-Remove-duplicated-WaForceL3Serialization-vl.patch @@ -0,0 +1,37 @@ +From 3e0bc0db8e5208aa7c20a09814e8d94f578af954 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 25 Jun 2013 16:38:21 +0300 +Subject: drm/i915: Remove duplicated WaForceL3Serialization:vlv +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +No need to apply WaForceL3Serialization:vlv twice. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit e4e9222d4b5e041c3b5a54ee21d6c62e7cc56609) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 6ff11802e49a..ef160e9a3ba6 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4834,10 +4834,6 @@ static void valleyview_init_clock_gating(struct drm_device *dev) + I915_WRITE(GEN7_ROW_CHICKEN2, + _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + +- /* WaForceL3Serialization:vlv */ +- I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) & +- ~L3SQ_URB_READ_CAM_MATCH_DISABLE); +- + /* This is required by WaCatErrorRejectionIssue:vlv */ + I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0347-drm-i915-Detect-invalid-scanout-pitches.patch b/patches.baytrail/0347-drm-i915-Detect-invalid-scanout-pitches.patch new file mode 100644 index 000000000000..efdc7947ba41 --- /dev/null +++ b/patches.baytrail/0347-drm-i915-Detect-invalid-scanout-pitches.patch @@ -0,0 +1,73 @@ +From fb4fea58f0910b13047947a03b8cfa8c5f5890d0 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Tue, 25 Jun 2013 17:26:45 +0100 +Subject: drm/i915: Detect invalid scanout pitches +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Report back the user error of attempting to setup a CRTC with an invalid +framebuffer pitch. This is trickier than it should be as on gen4, there +is a restriction that tiled surfaces must have a stride less than 16k - +which is less than the largest supported CRTC size. + +v2: Fix the limits for gen3 +v3: Move check into intel_framebuffer_init() and fix VLV limits. (vsyrjala) +v4: Use idiomatic '>=' for generation checks + +References: https://bugs.freedesktop.org/show_bug.cgi?id=65099 +Signed-off-by: Chris Wilson +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit a35cdaa0e13e24f3fccc518bfef1516aa8a8a665) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 25 +++++++++++++++++++++---- + 1 file changed, 21 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 0cc81f6c0af3..e441a4b5904a 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -9128,6 +9128,7 @@ int intel_framebuffer_init(struct drm_device *dev, + struct drm_mode_fb_cmd2 *mode_cmd, + struct drm_i915_gem_object *obj) + { ++ int pitch_limit; + int ret; + + if (obj->tiling_mode == I915_TILING_Y) { +@@ -9141,10 +9142,26 @@ int intel_framebuffer_init(struct drm_device *dev, + return -EINVAL; + } + +- /* FIXME <= Gen4 stride limits are bit unclear */ +- if (mode_cmd->pitches[0] > 32768) { +- DRM_DEBUG("pitch (%d) must be at less than 32768\n", +- mode_cmd->pitches[0]); ++ if (INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev)) { ++ pitch_limit = 32*1024; ++ } else if (INTEL_INFO(dev)->gen >= 4) { ++ if (obj->tiling_mode) ++ pitch_limit = 16*1024; ++ else ++ pitch_limit = 32*1024; ++ } else if (INTEL_INFO(dev)->gen >= 3) { ++ if (obj->tiling_mode) ++ pitch_limit = 8*1024; ++ else ++ pitch_limit = 16*1024; ++ } else ++ /* XXX DSPC is limited to 4k tiled */ ++ pitch_limit = 8*1024; ++ ++ if (mode_cmd->pitches[0] > pitch_limit) { ++ DRM_DEBUG("%s pitch (%d) must be at less than %d\n", ++ obj->tiling_mode ? "tiled" : "linear", ++ mode_cmd->pitches[0], pitch_limit); + return -EINVAL; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0348-drm-i915-Clean-up-VLV-rps-code-a-bit.patch b/patches.baytrail/0348-drm-i915-Clean-up-VLV-rps-code-a-bit.patch new file mode 100644 index 000000000000..3e1f05e52854 --- /dev/null +++ b/patches.baytrail/0348-drm-i915-Clean-up-VLV-rps-code-a-bit.patch @@ -0,0 +1,121 @@ +From be2e64c2b4121991a3e3a062868b4ffc8fac9923 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 25 Jun 2013 19:21:01 +0300 +Subject: drm/i915: Clean up VLV rps code a bit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Always print both the MHz value and raw register value for rps stuff. + +Also kill a somewhat pointless local 'rpe' variable and just use +dev_priv->rps.rpe_delay. + +While at it clean up the caps in "GPU" and "Punit" debug messages. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 73008b989faf4200907a858f9b902ee29d6edbea) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 50 ++++++++++++++++++++++++----------------- + 1 file changed, 30 insertions(+), 20 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index ef160e9a3ba6..9f1134b95fa7 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3080,10 +3080,11 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) + WARN_ON(val > dev_priv->rps.max_delay); + WARN_ON(val < dev_priv->rps.min_delay); + +- DRM_DEBUG_DRIVER("gpu freq request from %d to %d\n", ++ DRM_DEBUG_DRIVER("GPU freq request from %d MHz (%u) to %d MHz (%u)\n", + vlv_gpu_freq(dev_priv->mem_freq, + dev_priv->rps.cur_delay), +- vlv_gpu_freq(dev_priv->mem_freq, val)); ++ dev_priv->rps.cur_delay, ++ vlv_gpu_freq(dev_priv->mem_freq, val), val); + + if (val == dev_priv->rps.cur_delay) + return; +@@ -3101,8 +3102,9 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) + + pval = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); + if ((pval >> 8) != val) +- DRM_DEBUG_DRIVER("punit overrode freq: %d requested, but got %d\n", +- val, pval >> 8); ++ DRM_DEBUG_DRIVER("Punit overrode GPU freq: %d MHz (%u) requested, but got %d Mhz (%u)\n", ++ vlv_gpu_freq(dev_priv->mem_freq, val), val, ++ vlv_gpu_freq(dev_priv->mem_freq, pval >> 8), pval >> 8); + + /* Make sure we continue to get interrupts + * until we hit the minimum or maximum frequencies. +@@ -3496,7 +3498,7 @@ static void valleyview_enable_rps(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring; +- u32 gtfifodbg, val, rpe; ++ u32 gtfifodbg, val; + int i; + + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); +@@ -3557,31 +3559,39 @@ static void valleyview_enable_rps(struct drm_device *dev) + DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & 0x10 ? "yes" : "no"); + DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val); + +- DRM_DEBUG_DRIVER("current GPU freq: %d\n", +- vlv_gpu_freq(dev_priv->mem_freq, (val >> 8) & 0xff)); + dev_priv->rps.cur_delay = (val >> 8) & 0xff; ++ DRM_DEBUG_DRIVER("current GPU freq: %d MHz (%u)\n", ++ vlv_gpu_freq(dev_priv->mem_freq, ++ dev_priv->rps.cur_delay), ++ dev_priv->rps.cur_delay); + + dev_priv->rps.max_delay = valleyview_rps_max_freq(dev_priv); + dev_priv->rps.hw_max = dev_priv->rps.max_delay; +- DRM_DEBUG_DRIVER("max GPU freq: %d\n", vlv_gpu_freq(dev_priv->mem_freq, +- dev_priv->rps.max_delay)); ++ DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", ++ vlv_gpu_freq(dev_priv->mem_freq, ++ dev_priv->rps.max_delay), ++ dev_priv->rps.max_delay); + +- rpe = valleyview_rps_rpe_freq(dev_priv); +- DRM_DEBUG_DRIVER("RPe GPU freq: %d\n", +- vlv_gpu_freq(dev_priv->mem_freq, rpe)); +- dev_priv->rps.rpe_delay = rpe; ++ dev_priv->rps.rpe_delay = valleyview_rps_rpe_freq(dev_priv); ++ DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n", ++ vlv_gpu_freq(dev_priv->mem_freq, ++ dev_priv->rps.rpe_delay), ++ dev_priv->rps.rpe_delay); + +- val = valleyview_rps_min_freq(dev_priv); +- DRM_DEBUG_DRIVER("min GPU freq: %d\n", vlv_gpu_freq(dev_priv->mem_freq, +- val)); +- dev_priv->rps.min_delay = val; ++ dev_priv->rps.min_delay = valleyview_rps_min_freq(dev_priv); ++ DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n", ++ vlv_gpu_freq(dev_priv->mem_freq, ++ dev_priv->rps.min_delay), ++ dev_priv->rps.min_delay); + +- DRM_DEBUG_DRIVER("setting GPU freq to %d\n", +- vlv_gpu_freq(dev_priv->mem_freq, rpe)); ++ DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n", ++ vlv_gpu_freq(dev_priv->mem_freq, ++ dev_priv->rps.rpe_delay), ++ dev_priv->rps.rpe_delay); + + INIT_DELAYED_WORK(&dev_priv->rps.vlv_work, vlv_rps_timer_work); + +- valleyview_set_rps(dev_priv->dev, rpe); ++ valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay); + + /* requires MSI enabled */ + I915_WRITE(GEN6_PMIER, GEN6_PM_RPS_EVENTS); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0349-drm-i915-Don-t-wait-for-Punit-after-each-freq-change.patch b/patches.baytrail/0349-drm-i915-Don-t-wait-for-Punit-after-each-freq-change.patch new file mode 100644 index 000000000000..75b16ad96521 --- /dev/null +++ b/patches.baytrail/0349-drm-i915-Don-t-wait-for-Punit-after-each-freq-change.patch @@ -0,0 +1,121 @@ +From 2da6a37ac0c5a3c36cc58ff11a6c529c8c4205fa Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 25 Jun 2013 19:21:02 +0300 +Subject: drm/i915: Don't wait for Punit after each freq change on VLV +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It seems that even though Punit reports the frequency change to have +been completed, it still reports the old frequency in the status +register for some time. + +So rather than polling for Punit to complete the frequency change after +each request, poll before. This gets rid of the spurious "Punit overrode +GPU freq" messages. + +This also lets us continue working while Punit is performing the actual +frequency change. As a result, openarena demo088-test1 timedemo average +fps is increased by ~5 fps, and the slowest frame duration is reduced +by ~25%. + +The sysfs cur_freq file always reads the current frequency from Punit +anyway, so having rps.cur_delay be slightly off at times doesn't matter. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 80814ae4dae5d2070b1ca848df728feb6a10e6f2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 53 +++++++++++++++++++++++++++-------------- + 1 file changed, 35 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 9f1134b95fa7..b3622a2f6c4f 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3069,17 +3069,49 @@ void gen6_set_rps(struct drm_device *dev, u8 val) + trace_intel_gpu_freq_change(val * 50); + } + ++/* ++ * Wait until the previous freq change has completed, ++ * or the timeout elapsed, and then update our notion ++ * of the current GPU frequency. ++ */ ++static void vlv_update_rps_cur_delay(struct drm_i915_private *dev_priv) ++{ ++ unsigned long timeout = jiffies + msecs_to_jiffies(10); ++ u32 pval; ++ ++ WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); ++ ++ do { ++ pval = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); ++ if (time_after(jiffies, timeout)) { ++ DRM_DEBUG_DRIVER("timed out waiting for Punit\n"); ++ break; ++ } ++ udelay(10); ++ } while (pval & 1); ++ ++ pval >>= 8; ++ ++ if (pval != dev_priv->rps.cur_delay) ++ DRM_DEBUG_DRIVER("Punit overrode GPU freq: %d MHz (%u) requested, but got %d Mhz (%u)\n", ++ vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.cur_delay), ++ dev_priv->rps.cur_delay, ++ vlv_gpu_freq(dev_priv->mem_freq, pval), pval); ++ ++ dev_priv->rps.cur_delay = pval; ++} ++ + void valleyview_set_rps(struct drm_device *dev, u8 val) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- unsigned long timeout = jiffies + msecs_to_jiffies(10); + u32 limits = gen6_rps_limits(dev_priv, &val); +- u32 pval; + + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(val > dev_priv->rps.max_delay); + WARN_ON(val < dev_priv->rps.min_delay); + ++ vlv_update_rps_cur_delay(dev_priv); ++ + DRM_DEBUG_DRIVER("GPU freq request from %d MHz (%u) to %d MHz (%u)\n", + vlv_gpu_freq(dev_priv->mem_freq, + dev_priv->rps.cur_delay), +@@ -3091,27 +3123,12 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) + + vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); + +- do { +- pval = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); +- if (time_after(jiffies, timeout)) { +- DRM_DEBUG_DRIVER("timed out waiting for Punit\n"); +- break; +- } +- udelay(10); +- } while (pval & 1); +- +- pval = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); +- if ((pval >> 8) != val) +- DRM_DEBUG_DRIVER("Punit overrode GPU freq: %d MHz (%u) requested, but got %d Mhz (%u)\n", +- vlv_gpu_freq(dev_priv->mem_freq, val), val, +- vlv_gpu_freq(dev_priv->mem_freq, pval >> 8), pval >> 8); +- + /* Make sure we continue to get interrupts + * until we hit the minimum or maximum frequencies. + */ + I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits); + +- dev_priv->rps.cur_delay = pval >> 8; ++ dev_priv->rps.cur_delay = val; + + trace_intel_gpu_freq_change(vlv_gpu_freq(dev_priv->mem_freq, val)); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0350-drm-i915-Make-the-rps-new_delay-comparison-more-read.patch b/patches.baytrail/0350-drm-i915-Make-the-rps-new_delay-comparison-more-read.patch new file mode 100644 index 000000000000..e43c57a05ad1 --- /dev/null +++ b/patches.baytrail/0350-drm-i915-Make-the-rps-new_delay-comparison-more-read.patch @@ -0,0 +1,37 @@ +From 459fd310a684c9d5dd012421286b1594b7001c15 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 25 Jun 2013 19:21:05 +0300 +Subject: drm/i915: Make the rps new_delay comparison more readable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Eliminate the weird inverted logic from the rps new_delay comparison. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit d8289c9e7bb34b136433a44937e3ebe3a7beea1c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index a35fb3ce973b..8bf780c41c50 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -707,8 +707,8 @@ static void gen6_pm_rps_work(struct work_struct *work) + /* sysfs frequency interfaces may have snuck in while servicing the + * interrupt + */ +- if (!(new_delay > dev_priv->rps.max_delay || +- new_delay < dev_priv->rps.min_delay)) { ++ if (new_delay >= dev_priv->rps.min_delay && ++ new_delay <= dev_priv->rps.max_delay) { + if (IS_VALLEYVIEW(dev_priv->dev)) + valleyview_set_rps(dev_priv->dev, new_delay); + else +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0351-drm-i915-GEN6_RP_INTERRUPT_LIMITS-doesn-t-seem-to-ex.patch b/patches.baytrail/0351-drm-i915-GEN6_RP_INTERRUPT_LIMITS-doesn-t-seem-to-ex.patch new file mode 100644 index 000000000000..3949195f6b41 --- /dev/null +++ b/patches.baytrail/0351-drm-i915-GEN6_RP_INTERRUPT_LIMITS-doesn-t-seem-to-ex.patch @@ -0,0 +1,50 @@ +From 2337a349c0c9e4d013563851c7e8220e13094334 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 25 Jun 2013 19:21:06 +0300 +Subject: drm/i915: GEN6_RP_INTERRUPT_LIMITS doesn't seem to exist on VLV +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +I can't find GEN6_RP_INTERRUPT_LIMITS (0xA014) anywhere in VLV docs. +Reading it always returns zero from what I can tell, and eliminating +it doesn't seem to make any difference to the behaviour of the system. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 7a67092a25d854a4f5c53a6495d33e250896f9db) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index b3622a2f6c4f..5da417f9c8c7 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3104,7 +3104,8 @@ static void vlv_update_rps_cur_delay(struct drm_i915_private *dev_priv) + void valleyview_set_rps(struct drm_device *dev, u8 val) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- u32 limits = gen6_rps_limits(dev_priv, &val); ++ ++ gen6_rps_limits(dev_priv, &val); + + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + WARN_ON(val > dev_priv->rps.max_delay); +@@ -3123,11 +3124,6 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) + + vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); + +- /* Make sure we continue to get interrupts +- * until we hit the minimum or maximum frequencies. +- */ +- I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits); +- + dev_priv->rps.cur_delay = val; + + trace_intel_gpu_freq_change(vlv_gpu_freq(dev_priv->mem_freq, val)); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0352-drm-i915-Don-t-increase-the-GPU-frequency-from-the-d.patch b/patches.baytrail/0352-drm-i915-Don-t-increase-the-GPU-frequency-from-the-d.patch new file mode 100644 index 000000000000..b844aa6f429e --- /dev/null +++ b/patches.baytrail/0352-drm-i915-Don-t-increase-the-GPU-frequency-from-the-d.patch @@ -0,0 +1,40 @@ +From e9ca918ae1d3fc2213b5d1de32aea0ae7a531e0a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 25 Jun 2013 21:38:10 +0300 +Subject: drm/i915: Don't increase the GPU frequency from the delayed VLV rps + timer +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There's little point in increasing the GPU frequency from the delayed +rps work on VLV. Now when the GPU is idle, the GPU frequency actually +keeps dropping gradually until it hits the minimum, whereas previously +it just ping-ponged constantly between RPe and RPe-1. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 6dc5848899a7ddbf1d02f104a97dde7ba0200693) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 5da417f9c8c7..f895d1508df8 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3461,7 +3461,8 @@ static void vlv_rps_timer_work(struct work_struct *work) + * min freq available. + */ + mutex_lock(&dev_priv->rps.hw_lock); +- valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay); ++ if (dev_priv->rps.cur_delay > dev_priv->rps.rpe_delay) ++ valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay); + mutex_unlock(&dev_priv->rps.hw_lock); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0353-drm-i915-Jump-to-at-least-RPe-on-VLV-when-increasing.patch b/patches.baytrail/0353-drm-i915-Jump-to-at-least-RPe-on-VLV-when-increasing.patch new file mode 100644 index 000000000000..dc413b462d3e --- /dev/null +++ b/patches.baytrail/0353-drm-i915-Jump-to-at-least-RPe-on-VLV-when-increasing.patch @@ -0,0 +1,53 @@ +From 49bdeee2b3077ddae5f394d23b1fcc30d3aeea26 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 25 Jun 2013 21:38:11 +0300 +Subject: drm/i915: Jump to at least RPe on VLV when increasing the GPU + frequency +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If the current GPU frquency is below RPe, and we're asked to increase +it, just go directly to RPe. This should provide better performance +faster than letting the frequency trickle up in response to the up +threshold interrupts. + +For now just do it for VLV, since that matches quite closely how VLV +used to operate when the rps delayed timer kept things at RPe always. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 7425034a3361145c109510892d1e5154af2cdfed) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 8bf780c41c50..5afa1d01c8a8 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -699,9 +699,17 @@ static void gen6_pm_rps_work(struct work_struct *work) + + mutex_lock(&dev_priv->rps.hw_lock); + +- if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) ++ if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) { + new_delay = dev_priv->rps.cur_delay + 1; +- else ++ ++ /* ++ * For better performance, jump directly ++ * to RPe if we're below it. ++ */ ++ if (IS_VALLEYVIEW(dev_priv->dev) && ++ dev_priv->rps.cur_delay < dev_priv->rps.rpe_delay) ++ new_delay = dev_priv->rps.rpe_delay; ++ } else + new_delay = dev_priv->rps.cur_delay - 1; + + /* sysfs frequency interfaces may have snuck in while servicing the +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0354-drm-i915-Fix-VLV-PLL-LPF-coefficients-for-DAC.patch b/patches.baytrail/0354-drm-i915-Fix-VLV-PLL-LPF-coefficients-for-DAC.patch new file mode 100644 index 000000000000..b8ee47a1f9cb --- /dev/null +++ b/patches.baytrail/0354-drm-i915-Fix-VLV-PLL-LPF-coefficients-for-DAC.patch @@ -0,0 +1,41 @@ +From 6156c74dbf521a7035984c63e178607597f64481 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 14 Jun 2013 14:02:52 +0300 +Subject: drm/i915: Fix VLV PLL LPF coefficients for DAC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The current PLL settings produce a rather unstable picture when +I hook up a VLV to my HP ZR24w display via a VGA cable. + +According to VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_9, we should +use the the same LPF coefficients for DAC as we do for HDMI and RBR DP. +And indeed that seems to cure the shivers. + +v2: Add the name of the relevant document to the commit message + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 99750bd46f6ad3816fe2045a34fac432114c8196) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index e441a4b5904a..6901b1b466e6 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4400,6 +4400,7 @@ static void vlv_update_pll(struct intel_crtc *crtc) + + /* Set HBR and RBR LPF coefficients */ + if (crtc->config.port_clock == 162000 || ++ intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_ANALOG) || + intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI)) + vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), + 0x005f0021); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0355-drm-i915-s-LFP-LPF-in-DPIO-PLL-register-names.patch b/patches.baytrail/0355-drm-i915-s-LFP-LPF-in-DPIO-PLL-register-names.patch new file mode 100644 index 000000000000..d4155d165995 --- /dev/null +++ b/patches.baytrail/0355-drm-i915-s-LFP-LPF-in-DPIO-PLL-register-names.patch @@ -0,0 +1,77 @@ +From d991307dd0f44aa4d585938f82e368da8bb30a9a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 14 Jun 2013 14:02:53 +0300 +Subject: drm/i915: s/LFP/LPF in DPIO PLL register names +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +LPF is short for "low pass filter". + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 4abb2c39811eb81a653461d5ed8c75c528cb2245) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 8 ++++---- + drivers/gpu/drm/i915/i915_reg.h | 6 +++--- + drivers/gpu/drm/i915/intel_display.c | 4 ++-- + 3 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index f72d5a3fdfba..04cf6c09710a 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1862,10 +1862,10 @@ static int i915_dpio_info(struct seq_file *m, void *data) + seq_printf(m, "DPIO_CORE_CLK_B: 0x%08x\n", + vlv_dpio_read(dev_priv, _DPIO_CORE_CLK_B)); + +- seq_printf(m, "DPIO_LFP_COEFF_A: 0x%08x\n", +- vlv_dpio_read(dev_priv, _DPIO_LFP_COEFF_A)); +- seq_printf(m, "DPIO_LFP_COEFF_B: 0x%08x\n", +- vlv_dpio_read(dev_priv, _DPIO_LFP_COEFF_B)); ++ seq_printf(m, "DPIO_LPF_COEFF_A: 0x%08x\n", ++ vlv_dpio_read(dev_priv, _DPIO_LPF_COEFF_A)); ++ seq_printf(m, "DPIO_LPF_COEFF_B: 0x%08x\n", ++ vlv_dpio_read(dev_priv, _DPIO_LPF_COEFF_B)); + + seq_printf(m, "DPIO_FASTCLK_DISABLE: 0x%08x\n", + vlv_dpio_read(dev_priv, DPIO_FASTCLK_DISABLE)); +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index a2fe7efe0701..13dd0731dbd7 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -448,9 +448,9 @@ + #define _DPIO_PLL_CML_B 0x806c + #define DPIO_PLL_CML(pipe) _PIPE(pipe, _DPIO_PLL_CML_A, _DPIO_PLL_CML_B) + +-#define _DPIO_LFP_COEFF_A 0x8048 +-#define _DPIO_LFP_COEFF_B 0x8068 +-#define DPIO_LFP_COEFF(pipe) _PIPE(pipe, _DPIO_LFP_COEFF_A, _DPIO_LFP_COEFF_B) ++#define _DPIO_LPF_COEFF_A 0x8048 ++#define _DPIO_LPF_COEFF_B 0x8068 ++#define DPIO_LPF_COEFF(pipe) _PIPE(pipe, _DPIO_LPF_COEFF_A, _DPIO_LPF_COEFF_B) + + #define DPIO_CALIBRATION 0x80ac + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 6901b1b466e6..7a4669183b6a 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4402,10 +4402,10 @@ static void vlv_update_pll(struct intel_crtc *crtc) + if (crtc->config.port_clock == 162000 || + intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_ANALOG) || + intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI)) +- vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), ++ vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe), + 0x005f0021); + else +- vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), ++ vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe), + 0x00d0000f); + + if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) || +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0356-Revert-drm-i915-Don-t-use-the-HDMI-port-color-range-.patch b/patches.baytrail/0356-Revert-drm-i915-Don-t-use-the-HDMI-port-color-range-.patch new file mode 100644 index 000000000000..f71a6b146056 --- /dev/null +++ b/patches.baytrail/0356-Revert-drm-i915-Don-t-use-the-HDMI-port-color-range-.patch @@ -0,0 +1,42 @@ +From 8969b2b8ca45f3a05ceb3dd76cf57afac4f4856d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 25 Jun 2013 14:16:34 +0300 +Subject: Revert "drm/i915: Don't use the HDMI port color range bit on + Valleyview" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The PIPECONF color range bit doesn't appear to be effective, on HDMI +outputs at least. The color range bit in the port register works though, +so let's use it. + +I have not yet verified whether the PIPECONF bit works on DP outputs. + +This reverts commit 83a2af88f80ebf8104c9e083b786668b00f5b9ce. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 2af2c4909b7c8bc76beef25941b2218b3bd8e4fc) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_hdmi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index bc12518a21b4..98df2a0c85bd 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -602,7 +602,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, + u32 hdmi_val; + + hdmi_val = SDVO_ENCODING_HDMI; +- if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev)) ++ if (!HAS_PCH_SPLIT(dev)) + hdmi_val |= intel_hdmi->color_range; + if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) + hdmi_val |= SDVO_VSYNC_ACTIVE_HIGH; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0357-drm-i915-Fix-VLV-sprite-register-offsets.patch b/patches.baytrail/0357-drm-i915-Fix-VLV-sprite-register-offsets.patch new file mode 100644 index 000000000000..7954c8ee110f --- /dev/null +++ b/patches.baytrail/0357-drm-i915-Fix-VLV-sprite-register-offsets.patch @@ -0,0 +1,91 @@ +From cdd9252b0beeb0ae371922a6e65ded17eac7fd94 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 25 Jun 2013 14:16:35 +0300 +Subject: drm/i915: Fix VLV sprite register offsets +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We forgot to add VLV_DISPLAY_BASE to the VLV sprite registers, which +caused the sprites to not work at all. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 921c3b677bf6340cd92800fb99350532674dea29) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 50 ++++++++++++++++++++--------------------- + 1 file changed, 25 insertions(+), 25 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 13dd0731dbd7..342f1f336168 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -3494,7 +3494,7 @@ + #define SPRGAMC(pipe) _PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC) + #define SPRSURFLIVE(pipe) _PIPE(pipe, _SPRA_SURFLIVE, _SPRB_SURFLIVE) + +-#define _SPACNTR 0x72180 ++#define _SPACNTR (VLV_DISPLAY_BASE + 0x72180) + #define SP_ENABLE (1<<31) + #define SP_GEAMMA_ENABLE (1<<30) + #define SP_PIXFORMAT_MASK (0xf<<26) +@@ -3513,30 +3513,30 @@ + #define SP_YUV_ORDER_YVYU (2<<16) + #define SP_YUV_ORDER_VYUY (3<<16) + #define SP_TILED (1<<10) +-#define _SPALINOFF 0x72184 +-#define _SPASTRIDE 0x72188 +-#define _SPAPOS 0x7218c +-#define _SPASIZE 0x72190 +-#define _SPAKEYMINVAL 0x72194 +-#define _SPAKEYMSK 0x72198 +-#define _SPASURF 0x7219c +-#define _SPAKEYMAXVAL 0x721a0 +-#define _SPATILEOFF 0x721a4 +-#define _SPACONSTALPHA 0x721a8 +-#define _SPAGAMC 0x721f4 +- +-#define _SPBCNTR 0x72280 +-#define _SPBLINOFF 0x72284 +-#define _SPBSTRIDE 0x72288 +-#define _SPBPOS 0x7228c +-#define _SPBSIZE 0x72290 +-#define _SPBKEYMINVAL 0x72294 +-#define _SPBKEYMSK 0x72298 +-#define _SPBSURF 0x7229c +-#define _SPBKEYMAXVAL 0x722a0 +-#define _SPBTILEOFF 0x722a4 +-#define _SPBCONSTALPHA 0x722a8 +-#define _SPBGAMC 0x722f4 ++#define _SPALINOFF (VLV_DISPLAY_BASE + 0x72184) ++#define _SPASTRIDE (VLV_DISPLAY_BASE + 0x72188) ++#define _SPAPOS (VLV_DISPLAY_BASE + 0x7218c) ++#define _SPASIZE (VLV_DISPLAY_BASE + 0x72190) ++#define _SPAKEYMINVAL (VLV_DISPLAY_BASE + 0x72194) ++#define _SPAKEYMSK (VLV_DISPLAY_BASE + 0x72198) ++#define _SPASURF (VLV_DISPLAY_BASE + 0x7219c) ++#define _SPAKEYMAXVAL (VLV_DISPLAY_BASE + 0x721a0) ++#define _SPATILEOFF (VLV_DISPLAY_BASE + 0x721a4) ++#define _SPACONSTALPHA (VLV_DISPLAY_BASE + 0x721a8) ++#define _SPAGAMC (VLV_DISPLAY_BASE + 0x721f4) ++ ++#define _SPBCNTR (VLV_DISPLAY_BASE + 0x72280) ++#define _SPBLINOFF (VLV_DISPLAY_BASE + 0x72284) ++#define _SPBSTRIDE (VLV_DISPLAY_BASE + 0x72288) ++#define _SPBPOS (VLV_DISPLAY_BASE + 0x7228c) ++#define _SPBSIZE (VLV_DISPLAY_BASE + 0x72290) ++#define _SPBKEYMINVAL (VLV_DISPLAY_BASE + 0x72294) ++#define _SPBKEYMSK (VLV_DISPLAY_BASE + 0x72298) ++#define _SPBSURF (VLV_DISPLAY_BASE + 0x7229c) ++#define _SPBKEYMAXVAL (VLV_DISPLAY_BASE + 0x722a0) ++#define _SPBTILEOFF (VLV_DISPLAY_BASE + 0x722a4) ++#define _SPBCONSTALPHA (VLV_DISPLAY_BASE + 0x722a8) ++#define _SPBGAMC (VLV_DISPLAY_BASE + 0x722f4) + + #define SPCNTR(pipe, plane) _PIPE(pipe * 2 + plane, _SPACNTR, _SPBCNTR) + #define SPLINOFF(pipe, plane) _PIPE(pipe * 2 + plane, _SPALINOFF, _SPBLINOFF) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0358-drm-i915-fix-locking-around-ironlake_enable-disable_.patch b/patches.baytrail/0358-drm-i915-fix-locking-around-ironlake_enable-disable_.patch new file mode 100644 index 000000000000..f11ce58a41fb --- /dev/null +++ b/patches.baytrail/0358-drm-i915-fix-locking-around-ironlake_enable-disable_.patch @@ -0,0 +1,119 @@ +From def345ed308deb5023a0801a6eec65a3e9782cb6 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 27 Jun 2013 13:44:58 +0200 +Subject: drm/i915: fix locking around ironlake_enable|disable_display_irq + +The haswell unclaimed register handling code forgot to take the +spinlock. Since this is in the context of the non-rentrant interupt +handler and we only have one interrupt handler it is sufficient to +just grab the spinlock - we do not need to exclude any other +interrupts from running on the same cpu. + +To prevent such gaffles in the future sprinkle assert_spin_locked over +these functions. Unfornately this requires us to hold the spinlock in +the ironlake postinstall hook where it is not strictly required: +Currently that is run in single-threaded context and with userspace +exlcuded from running concurrent ioctls. Add a comment explaining +this. + +v2: ivb_can_enable_err_int also needs to be protected by the spinlock. +To ensure this won't happen in the future again also sprinkle a +spinlock assert in there. + +v3: Kill the 2nd call to ivb_can_enable_err_int I've accidentally left +behind, spotted by Paulo. + +Cc: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 4bc9d4301573403c578e545b34dceac61891f39c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 27 ++++++++++++++++++++++++--- + 1 file changed, 24 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 5afa1d01c8a8..ecea1896b0cc 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -86,6 +86,8 @@ static void i915_hpd_irq_setup(struct drm_device *dev); + static void + ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) + { ++ assert_spin_locked(&dev_priv->irq_lock); ++ + if ((dev_priv->irq_mask & mask) != 0) { + dev_priv->irq_mask &= ~mask; + I915_WRITE(DEIMR, dev_priv->irq_mask); +@@ -96,6 +98,8 @@ ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) + static void + ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) + { ++ assert_spin_locked(&dev_priv->irq_lock); ++ + if ((dev_priv->irq_mask & mask) != mask) { + dev_priv->irq_mask |= mask; + I915_WRITE(DEIMR, dev_priv->irq_mask); +@@ -109,6 +113,8 @@ static bool ivb_can_enable_err_int(struct drm_device *dev) + struct intel_crtc *crtc; + enum pipe pipe; + ++ assert_spin_locked(&dev_priv->irq_lock); ++ + for_each_pipe(pipe) { + crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); + +@@ -1217,8 +1223,11 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + /* On Haswell, also mask ERR_INT because we don't want to risk + * generating "unclaimed register" interrupts from inside the interrupt + * handler. */ +- if (IS_HASWELL(dev)) ++ if (IS_HASWELL(dev)) { ++ spin_lock(&dev_priv->irq_lock); + ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); ++ spin_unlock(&dev_priv->irq_lock); ++ } + + gt_iir = I915_READ(GTIIR); + if (gt_iir) { +@@ -1271,8 +1280,12 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + ret = IRQ_HANDLED; + } + +- if (IS_HASWELL(dev) && ivb_can_enable_err_int(dev)) +- ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB); ++ if (IS_HASWELL(dev)) { ++ spin_lock(&dev_priv->irq_lock); ++ if (ivb_can_enable_err_int(dev)) ++ ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB); ++ spin_unlock(&dev_priv->irq_lock); ++ } + + I915_WRITE(DEIER, de_ier); + POSTING_READ(DEIER); +@@ -2743,6 +2756,8 @@ static void ibx_irq_postinstall(struct drm_device *dev) + + static int ironlake_irq_postinstall(struct drm_device *dev) + { ++ unsigned long irqflags; ++ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + /* enable kind of interrupts always enabled */ + u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | +@@ -2781,7 +2796,13 @@ static int ironlake_irq_postinstall(struct drm_device *dev) + /* Clear & enable PCU event interrupts */ + I915_WRITE(DEIIR, DE_PCU_EVENT); + I915_WRITE(DEIER, I915_READ(DEIER) | DE_PCU_EVENT); ++ ++ /* spinlocking not required here for correctness since interrupt ++ * setup is guaranteed to run in single-threaded context. But we ++ * need it to make the assert_spin_locked happy. */ ++ spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + ironlake_enable_display_irq(dev_priv, DE_PCU_EVENT); ++ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + } + + return 0; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0359-drm-i915-close-tiny-race-in-the-ilk-pcu-even-interru.patch b/patches.baytrail/0359-drm-i915-close-tiny-race-in-the-ilk-pcu-even-interru.patch new file mode 100644 index 000000000000..a84c5a24183e --- /dev/null +++ b/patches.baytrail/0359-drm-i915-close-tiny-race-in-the-ilk-pcu-even-interru.patch @@ -0,0 +1,62 @@ +From 0ca8a9ab5a237f848ff1b83e6acc51fa4a24baa6 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 27 Jun 2013 13:44:59 +0200 +Subject: drm/i915: close tiny race in the ilk pcu even interrupt setup + +By the time we write DEIER in the postinstall hook the interrupt +handler could run any time. And it does modify DEIER to handle +interrupts. + +Hence the DEIER read-modify-write cycle for enabling the PCU event +source is racy. Close this races the same way we handle vblank +interrupts: Unconditionally enable the interrupt in the IER register, +but conditionally mask it in IMR. The later poses no such race since +the interrupt handler does not touch DEIMR. + +Also update the comment, the clearing has already happened +unconditionally above. + +v2: Actually shove the updated comment into the right train^W commit, +as spotted by Paulo. + +Cc: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 6005ce42433df3f69de99d7e730383a6adb852ef) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index ecea1896b0cc..27374f421354 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2771,7 +2771,8 @@ static int ironlake_irq_postinstall(struct drm_device *dev) + /* should always can generate irq */ + I915_WRITE(DEIIR, I915_READ(DEIIR)); + I915_WRITE(DEIMR, dev_priv->irq_mask); +- I915_WRITE(DEIER, display_mask | DE_PIPEA_VBLANK | DE_PIPEB_VBLANK); ++ I915_WRITE(DEIER, display_mask | ++ DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT); + POSTING_READ(DEIER); + + dev_priv->gt_irq_mask = ~0; +@@ -2793,11 +2794,9 @@ static int ironlake_irq_postinstall(struct drm_device *dev) + ibx_irq_postinstall(dev); + + if (IS_IRONLAKE_M(dev)) { +- /* Clear & enable PCU event interrupts */ +- I915_WRITE(DEIIR, DE_PCU_EVENT); +- I915_WRITE(DEIER, I915_READ(DEIER) | DE_PCU_EVENT); +- +- /* spinlocking not required here for correctness since interrupt ++ /* Enable PCU event interrupts ++ * ++ * spinlocking not required here for correctness since interrupt + * setup is guaranteed to run in single-threaded context. But we + * need it to make the assert_spin_locked happy. */ + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0360-drm-i915-s-hotplug_irq_storm_detect-intel_hpd_irq_ha.patch b/patches.baytrail/0360-drm-i915-s-hotplug_irq_storm_detect-intel_hpd_irq_ha.patch new file mode 100644 index 000000000000..af389eac5601 --- /dev/null +++ b/patches.baytrail/0360-drm-i915-s-hotplug_irq_storm_detect-intel_hpd_irq_ha.patch @@ -0,0 +1,91 @@ +From 3a0b66ed6ee8c4cf0f2b66ea9db7e1f6ce6cd3b0 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 27 Jun 2013 17:52:11 +0200 +Subject: drm/i915: s/hotplug_irq_storm_detect/intel_hpd_irq_handler/ + +The combination of Paulo's fifo underrun detection code and Egbert's +hpd storm handling code unfortunately made the hpd storm handling code +racy. + +To avoid duplicating tricky interrupt locking code over all platforms +start with a bit of refactoring. This patch is the very first step +since in the end the irq storm handling code will handle all hotplug +logic (and so also encapsulate the locking nicely). + +v2: Rebase on top of the i965g/gm sdvo hpd fix. + +Cc: Egbert Eich +Reviewed-by: Egbert Eich +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 22062dbacf7ccc325c8b0ccc3fb90bf487be5c5c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 27374f421354..99bc9dc351e1 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -875,9 +875,9 @@ static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, + #define HPD_STORM_DETECT_PERIOD 1000 + #define HPD_STORM_THRESHOLD 5 + +-static inline bool hotplug_irq_storm_detect(struct drm_device *dev, +- u32 hotplug_trigger, +- const u32 *hpd) ++static inline bool intel_hpd_irq_handler(struct drm_device *dev, ++ u32 hotplug_trigger, ++ const u32 *hpd) + { + drm_i915_private_t *dev_priv = dev->dev_private; + unsigned long irqflags; +@@ -1018,7 +1018,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) + DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", + hotplug_status); + if (hotplug_trigger) { +- if (hotplug_irq_storm_detect(dev, hotplug_trigger, hpd_status_i915)) ++ if (intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915)) + i915_hpd_irq_setup(dev); + queue_work(dev_priv->wq, + &dev_priv->hotplug_work); +@@ -1049,7 +1049,7 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) + u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK; + + if (hotplug_trigger) { +- if (hotplug_irq_storm_detect(dev, hotplug_trigger, hpd_ibx)) ++ if (intel_hpd_irq_handler(dev, hotplug_trigger, hpd_ibx)) + ibx_hpd_irq_setup(dev); + queue_work(dev_priv->wq, &dev_priv->hotplug_work); + } +@@ -1154,7 +1154,7 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) + u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT; + + if (hotplug_trigger) { +- if (hotplug_irq_storm_detect(dev, hotplug_trigger, hpd_cpt)) ++ if (intel_hpd_irq_handler(dev, hotplug_trigger, hpd_cpt)) + ibx_hpd_irq_setup(dev); + queue_work(dev_priv->wq, &dev_priv->hotplug_work); + } +@@ -3278,7 +3278,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) + DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", + hotplug_status); + if (hotplug_trigger) { +- if (hotplug_irq_storm_detect(dev, hotplug_trigger, hpd_status_i915)) ++ if (intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915)) + i915_hpd_irq_setup(dev); + queue_work(dev_priv->wq, + &dev_priv->hotplug_work); +@@ -3519,7 +3519,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) + DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", + hotplug_status); + if (hotplug_trigger) { +- if (hotplug_irq_storm_detect(dev, hotplug_trigger, ++ if (intel_hpd_irq_handler(dev, hotplug_trigger, + IS_G4X(dev) ? hpd_status_gen4 : hpd_status_i915)) + i915_hpd_irq_setup(dev); + queue_work(dev_priv->wq, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0361-drm-i915-fold-the-hpd_irq_setup-call-into-intel_hpd_.patch b/patches.baytrail/0361-drm-i915-fold-the-hpd_irq_setup-call-into-intel_hpd_.patch new file mode 100644 index 000000000000..6b40da55a932 --- /dev/null +++ b/patches.baytrail/0361-drm-i915-fold-the-hpd_irq_setup-call-into-intel_hpd_.patch @@ -0,0 +1,125 @@ +From 8c60a6cc8169c56149a4e80ac36a4f13692c108c Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 27 Jun 2013 17:52:12 +0200 +Subject: drm/i915: fold the hpd_irq_setup call into intel_hpd_irq_handler + +We already have a vfunc for this (and other parts of the hpd storm +handling code already use it). + +v2: Rebase on top of the i965g/gm sdvo hpd fix. + +Cc: Egbert Eich +Reviewed-by: Egbert Eich +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 10a504de56f0451c828a9207e36c5610d5b0209a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 29 +++++++++++------------------ + 1 file changed, 11 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 99bc9dc351e1..779b40102b83 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -79,9 +79,6 @@ static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */ + [HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS + }; + +-static void ibx_hpd_irq_setup(struct drm_device *dev); +-static void i915_hpd_irq_setup(struct drm_device *dev); +- + /* For display hotplug interrupt */ + static void + ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) +@@ -875,14 +872,14 @@ static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, + #define HPD_STORM_DETECT_PERIOD 1000 + #define HPD_STORM_THRESHOLD 5 + +-static inline bool intel_hpd_irq_handler(struct drm_device *dev, ++static inline void intel_hpd_irq_handler(struct drm_device *dev, + u32 hotplug_trigger, + const u32 *hpd) + { + drm_i915_private_t *dev_priv = dev->dev_private; + unsigned long irqflags; + int i; +- bool ret = false; ++ bool storm_detected = false; + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + +@@ -902,7 +899,7 @@ static inline bool intel_hpd_irq_handler(struct drm_device *dev, + dev_priv->hpd_stats[i].hpd_mark = HPD_MARK_DISABLED; + dev_priv->hpd_event_bits &= ~(1 << i); + DRM_DEBUG_KMS("HPD interrupt storm detected on PIN %d\n", i); +- ret = true; ++ storm_detected = true; + } else { + dev_priv->hpd_stats[i].hpd_cnt++; + } +@@ -910,7 +907,8 @@ static inline bool intel_hpd_irq_handler(struct drm_device *dev, + + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + +- return ret; ++ if (storm_detected) ++ dev_priv->display.hpd_irq_setup(dev); + } + + static void gmbus_irq_handler(struct drm_device *dev) +@@ -1018,8 +1016,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) + DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", + hotplug_status); + if (hotplug_trigger) { +- if (intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915)) +- i915_hpd_irq_setup(dev); ++ intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915); + queue_work(dev_priv->wq, + &dev_priv->hotplug_work); + } +@@ -1049,8 +1046,7 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) + u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK; + + if (hotplug_trigger) { +- if (intel_hpd_irq_handler(dev, hotplug_trigger, hpd_ibx)) +- ibx_hpd_irq_setup(dev); ++ intel_hpd_irq_handler(dev, hotplug_trigger, hpd_ibx); + queue_work(dev_priv->wq, &dev_priv->hotplug_work); + } + if (pch_iir & SDE_AUDIO_POWER_MASK) { +@@ -1154,8 +1150,7 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) + u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT; + + if (hotplug_trigger) { +- if (intel_hpd_irq_handler(dev, hotplug_trigger, hpd_cpt)) +- ibx_hpd_irq_setup(dev); ++ intel_hpd_irq_handler(dev, hotplug_trigger, hpd_cpt); + queue_work(dev_priv->wq, &dev_priv->hotplug_work); + } + if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) { +@@ -3278,8 +3273,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) + DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", + hotplug_status); + if (hotplug_trigger) { +- if (intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915)) +- i915_hpd_irq_setup(dev); ++ intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915); + queue_work(dev_priv->wq, + &dev_priv->hotplug_work); + } +@@ -3519,9 +3513,8 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) + DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", + hotplug_status); + if (hotplug_trigger) { +- if (intel_hpd_irq_handler(dev, hotplug_trigger, +- IS_G4X(dev) ? hpd_status_gen4 : hpd_status_i915)) +- i915_hpd_irq_setup(dev); ++ intel_hpd_irq_handler(dev, hotplug_trigger, ++ IS_G4X(dev) ? hpd_status_gen4 : hpd_status_i915); + queue_work(dev_priv->wq, + &dev_priv->hotplug_work); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0362-drm-i915-fold-the-queue_work-into-intel_hpd_irq_hand.patch b/patches.baytrail/0362-drm-i915-fold-the-queue_work-into-intel_hpd_irq_hand.patch new file mode 100644 index 000000000000..d104fdee6d93 --- /dev/null +++ b/patches.baytrail/0362-drm-i915-fold-the-queue_work-into-intel_hpd_irq_hand.patch @@ -0,0 +1,83 @@ +From 027ca0f4232095bc6c5399d210b3addf36e03d9c Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 27 Jun 2013 17:52:13 +0200 +Subject: drm/i915: fold the queue_work into intel_hpd_irq_handler + +Everywhere the same. + +Note that this patch leaves unnecessary braces behind, but the next +patch will kill those all anyway (including the if itself) so I've +figured I can keep the diff a bit smaller. + +v2: Rebase on top of the i965g/gm sdvo hpd fix. + +Cc: Egbert Eich +Reviewed-by: Egbert Eich +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 5876fa0d9e9097d980a72152f4967a52b1adaaac) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 779b40102b83..cddfe417d878 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -909,6 +909,9 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, + + if (storm_detected) + dev_priv->display.hpd_irq_setup(dev); ++ ++ queue_work(dev_priv->wq, ++ &dev_priv->hotplug_work); + } + + static void gmbus_irq_handler(struct drm_device *dev) +@@ -1017,8 +1020,6 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) + hotplug_status); + if (hotplug_trigger) { + intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915); +- queue_work(dev_priv->wq, +- &dev_priv->hotplug_work); + } + I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); + I915_READ(PORT_HOTPLUG_STAT); +@@ -1047,7 +1048,6 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) + + if (hotplug_trigger) { + intel_hpd_irq_handler(dev, hotplug_trigger, hpd_ibx); +- queue_work(dev_priv->wq, &dev_priv->hotplug_work); + } + if (pch_iir & SDE_AUDIO_POWER_MASK) { + int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK) >> +@@ -1151,7 +1151,6 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) + + if (hotplug_trigger) { + intel_hpd_irq_handler(dev, hotplug_trigger, hpd_cpt); +- queue_work(dev_priv->wq, &dev_priv->hotplug_work); + } + if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) { + int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >> +@@ -3274,8 +3273,6 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) + hotplug_status); + if (hotplug_trigger) { + intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915); +- queue_work(dev_priv->wq, +- &dev_priv->hotplug_work); + } + I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); + POSTING_READ(PORT_HOTPLUG_STAT); +@@ -3515,8 +3512,6 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) + if (hotplug_trigger) { + intel_hpd_irq_handler(dev, hotplug_trigger, + IS_G4X(dev) ? hpd_status_gen4 : hpd_status_i915); +- queue_work(dev_priv->wq, +- &dev_priv->hotplug_work); + } + I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); + I915_READ(PORT_HOTPLUG_STAT); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0363-drm-i915-fold-the-no-irq-check-into-intel_hpd_irq_ha.patch b/patches.baytrail/0363-drm-i915-fold-the-no-irq-check-into-intel_hpd_irq_ha.patch new file mode 100644 index 000000000000..e80dcfc43c9d --- /dev/null +++ b/patches.baytrail/0363-drm-i915-fold-the-no-irq-check-into-intel_hpd_irq_ha.patch @@ -0,0 +1,103 @@ +From 2708d4972a34602bfbf3b3ebf480a3880b693f41 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 27 Jun 2013 17:52:14 +0200 +Subject: drm/i915: fold the no-irq check into intel_hpd_irq_handler + +The usual pattern for our sub-function irq_handlers is that they check +for the no-irq case themselves. This results in more streamlined code +in the upper irq handlers. + +v2: Rebase on top of the i965g/gm sdvo hpd fix. + +Cc: Egbert Eich +Reviewed-by: Egbert Eich +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 91d131d21e4916f84e5957cc25bea6dd355dfe77) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 33 +++++++++++++++++---------------- + 1 file changed, 17 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index cddfe417d878..2221158bebc5 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -881,6 +881,9 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, + int i; + bool storm_detected = false; + ++ if (!hotplug_trigger) ++ return; ++ + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + + for (i = 1; i < HPD_NUM_PINS; i++) { +@@ -1018,9 +1021,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) + + DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", + hotplug_status); +- if (hotplug_trigger) { +- intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915); +- } ++ ++ intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915); ++ + I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); + I915_READ(PORT_HOTPLUG_STAT); + } +@@ -1046,9 +1049,8 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) + int pipe; + u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK; + +- if (hotplug_trigger) { +- intel_hpd_irq_handler(dev, hotplug_trigger, hpd_ibx); +- } ++ intel_hpd_irq_handler(dev, hotplug_trigger, hpd_ibx); ++ + if (pch_iir & SDE_AUDIO_POWER_MASK) { + int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK) >> + SDE_AUDIO_POWER_SHIFT); +@@ -1149,9 +1151,8 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) + int pipe; + u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT; + +- if (hotplug_trigger) { +- intel_hpd_irq_handler(dev, hotplug_trigger, hpd_cpt); +- } ++ intel_hpd_irq_handler(dev, hotplug_trigger, hpd_cpt); ++ + if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) { + int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >> + SDE_AUDIO_POWER_SHIFT_CPT); +@@ -3271,9 +3272,9 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) + + DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", + hotplug_status); +- if (hotplug_trigger) { +- intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915); +- } ++ ++ intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915); ++ + I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); + POSTING_READ(PORT_HOTPLUG_STAT); + } +@@ -3509,10 +3510,10 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) + + DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", + hotplug_status); +- if (hotplug_trigger) { +- intel_hpd_irq_handler(dev, hotplug_trigger, +- IS_G4X(dev) ? hpd_status_gen4 : hpd_status_i915); +- } ++ ++ intel_hpd_irq_handler(dev, hotplug_trigger, ++ IS_G4X(dev) ? hpd_status_gen4 : hpd_status_i915); ++ + I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); + I915_READ(PORT_HOTPLUG_STAT); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0364-drm-i915-fix-hpd-interrupt-register-locking.patch b/patches.baytrail/0364-drm-i915-fix-hpd-interrupt-register-locking.patch new file mode 100644 index 000000000000..fdb5317736f3 --- /dev/null +++ b/patches.baytrail/0364-drm-i915-fix-hpd-interrupt-register-locking.patch @@ -0,0 +1,100 @@ +From df88d00a0e7a7654a8c808ca82f85fb80a5dbb4c Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 27 Jun 2013 17:52:15 +0200 +Subject: drm/i915: fix hpd interrupt register locking + +Our interrupt handler (in hardirq context) could race with the timer +(in softirq context), hence we need to hold the spinlock around the +call to ->hdp_irq_setup in intel_hpd_irq_handler, too. + +But as an optimization (and more so to clarify things) we don't need +to do the irqsave/restore dance in the hardirq context. + +Note also that on ilk+ the race isn't just against the hotplug +reenable timer, but also against the fifo underrun reporting. That one +also modifies the SDEIMR register (again protected by the same +dev_priv->irq_lock). + +To lock things down again sprinkle a assert_spin_locked. But exclude +the functions touching SDEIMR for now, I want to extract them all into +a new helper function (like we do already for pipestate, display +interrupts and all the various gt interrupts). + +v2: Add the missing 't' Egbert spotted in a comment. + +v3: Actually fix the right misspelled comment (Paulo). + +Cc: Egbert Eich +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit b5ea2d5681522f1b8ef886b5ac039903bf1d39fe) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 2221158bebc5..7748dce240d8 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -877,15 +877,13 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, + const u32 *hpd) + { + drm_i915_private_t *dev_priv = dev->dev_private; +- unsigned long irqflags; + int i; + bool storm_detected = false; + + if (!hotplug_trigger) + return; + +- spin_lock_irqsave(&dev_priv->irq_lock, irqflags); +- ++ spin_lock(&dev_priv->irq_lock); + for (i = 1; i < HPD_NUM_PINS; i++) { + + if (!(hpd[i] & hotplug_trigger) || +@@ -908,10 +906,9 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, + } + } + +- spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); +- + if (storm_detected) + dev_priv->display.hpd_irq_setup(dev); ++ spin_unlock(&dev_priv->irq_lock); + + queue_work(dev_priv->wq, + &dev_priv->hotplug_work); +@@ -3426,6 +3423,8 @@ static void i915_hpd_irq_setup(struct drm_device *dev) + struct intel_encoder *intel_encoder; + u32 hotplug_en; + ++ assert_spin_locked(&dev_priv->irq_lock); ++ + if (I915_HAS_HOTPLUG(dev)) { + hotplug_en = I915_READ(PORT_HOTPLUG_EN); + hotplug_en &= ~HOTPLUG_INT_EN_MASK; +@@ -3709,6 +3708,7 @@ void intel_hpd_init(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_mode_config *mode_config = &dev->mode_config; + struct drm_connector *connector; ++ unsigned long irqflags; + int i; + + for (i = 1; i < HPD_NUM_PINS; i++) { +@@ -3721,6 +3721,11 @@ void intel_hpd_init(struct drm_device *dev) + if (!connector->polled && I915_HAS_HOTPLUG(dev) && intel_connector->encoder->hpd_pin > HPD_NONE) + connector->polled = DRM_CONNECTOR_POLL_HPD; + } ++ ++ /* Interrupt setup is already guaranteed to be single-threaded, this is ++ * just to make the assert_spin_locked checks happy. */ ++ spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + if (dev_priv->display.hpd_irq_setup) + dev_priv->display.hpd_irq_setup(dev); ++ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0365-drm-i915-correct-intel_dp_get_config-function-for-De.patch b/patches.baytrail/0365-drm-i915-correct-intel_dp_get_config-function-for-De.patch new file mode 100644 index 000000000000..bf775cd00ac9 --- /dev/null +++ b/patches.baytrail/0365-drm-i915-correct-intel_dp_get_config-function-for-De.patch @@ -0,0 +1,93 @@ +From 070034ad42450056294bc77cb7aa210ef8ef497d Mon Sep 17 00:00:00 2001 +From: Xiong Zhang +Date: Fri, 28 Jun 2013 12:59:06 +0800 +Subject: drm/i915: correct intel_dp_get_config() function for DevCPT + +On DevCPT, the control register for Transcoder DP Sync Polarity is +TRANS_DP_CTL, not DP_CTL. +Without this patch, Many call trace occur on CPT machine with DP monitor. +The call trace is like: *ERROR* mismatch in adjusted_mode.flags(expected X,found X) + +v2: use intel-crtc to simple patch, suggested by Daniel. + +Signed-off-by: Xiong Zhang +[danvet: Extend the encoder->get_config comment to specify that we now +also depend upon intel_encoder->base.crtc being correct. Also bikeshed +s/intel_crtc/crtc/.] +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65287 +Signed-off-by: Daniel Vetter + +(cherry picked from commit 63000ef656190b65a8ae4d00acd7f22b6d92415d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 35 +++++++++++++++++++++++++---------- + drivers/gpu/drm/i915/intel_drv.h | 3 ++- + 2 files changed, 27 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 0f7e9094098d..47713d6aa4a5 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1335,20 +1335,35 @@ static void intel_dp_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) + { + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); +- struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + u32 tmp, flags = 0; ++ struct drm_device *dev = encoder->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ enum port port = dp_to_dig_port(intel_dp)->port; ++ struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); + +- tmp = I915_READ(intel_dp->output_reg); ++ if ((port == PORT_A) || !HAS_PCH_CPT(dev)) { ++ tmp = I915_READ(intel_dp->output_reg); ++ if (tmp & DP_SYNC_HS_HIGH) ++ flags |= DRM_MODE_FLAG_PHSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NHSYNC; + +- if (tmp & DP_SYNC_HS_HIGH) +- flags |= DRM_MODE_FLAG_PHSYNC; +- else +- flags |= DRM_MODE_FLAG_NHSYNC; ++ if (tmp & DP_SYNC_VS_HIGH) ++ flags |= DRM_MODE_FLAG_PVSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NVSYNC; ++ } else { ++ tmp = I915_READ(TRANS_DP_CTL(crtc->pipe)); ++ if (tmp & TRANS_DP_HSYNC_ACTIVE_HIGH) ++ flags |= DRM_MODE_FLAG_PHSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NHSYNC; + +- if (tmp & DP_SYNC_VS_HIGH) +- flags |= DRM_MODE_FLAG_PVSYNC; +- else +- flags |= DRM_MODE_FLAG_NVSYNC; ++ if (tmp & TRANS_DP_VSYNC_ACTIVE_HIGH) ++ flags |= DRM_MODE_FLAG_PVSYNC; ++ else ++ flags |= DRM_MODE_FLAG_NVSYNC; ++ } + + pipe_config->adjusted_mode.flags |= flags; + } +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index c7b93c61e467..b7d6e09456ce 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -141,7 +141,8 @@ struct intel_encoder { + bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe); + /* Reconstructs the equivalent mode flags for the current hardware + * state. This must be called _after_ display->get_pipe_config has +- * pre-filled the pipe config. */ ++ * pre-filled the pipe config. Note that intel_encoder->base.crtc must ++ * be set correctly before calling this function. */ + void (*get_config)(struct intel_encoder *, + struct intel_crtc_config *pipe_config); + int crtc_mask; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0366-drm-i915-Refactor-the-wait_rendering-completion-into.patch b/patches.baytrail/0366-drm-i915-Refactor-the-wait_rendering-completion-into.patch new file mode 100644 index 000000000000..2659b7c4f300 --- /dev/null +++ b/patches.baytrail/0366-drm-i915-Refactor-the-wait_rendering-completion-into.patch @@ -0,0 +1,102 @@ +From 8ede90d39f6fd423b9e3153e05a59e05fb1eb5e5 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Sat, 29 Jun 2013 22:05:26 +0100 +Subject: drm/i915: Refactor the wait_rendering completion into a common + routine + +Harmonise the completion logic between the non-blocking and normal +wait_rendering paths, and move that logic into a common function. + +In the process, we note that the last_write_seqno is by definition the +earlier of the two read/write seqnos and so all successful waits will +have passed the last_write_seqno. Therefore we can unconditionally clear +the write seqno and its domains in the completion logic. + +v2: Add the missing ring parameter, because sometimes it is good to have +things compile. + +Signed-off-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit d26e3af842023603747f1566caff5f471508bbd4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 48 ++++++++++++++++++++--------------------- + 1 file changed, 23 insertions(+), 25 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 5fcee7608228..2f58889ec120 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -1087,6 +1087,25 @@ i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno) + interruptible, NULL); + } + ++static int ++i915_gem_object_wait_rendering__tail(struct drm_i915_gem_object *obj, ++ struct intel_ring_buffer *ring) ++{ ++ i915_gem_retire_requests_ring(ring); ++ ++ /* Manually manage the write flush as we may have not yet ++ * retired the buffer. ++ * ++ * Note that the last_write_seqno is always the earlier of ++ * the two (read/write) seqno, so if we haved successfully waited, ++ * we know we have passed the last write. ++ */ ++ obj->last_write_seqno = 0; ++ obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS; ++ ++ return 0; ++} ++ + /** + * Ensures that all rendering to the object has completed and the object is + * safe to unbind from the GTT or access from the CPU. +@@ -1107,18 +1126,7 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, + if (ret) + return ret; + +- i915_gem_retire_requests_ring(ring); +- +- /* Manually manage the write flush as we may have not yet +- * retired the buffer. +- */ +- if (obj->last_write_seqno && +- i915_seqno_passed(seqno, obj->last_write_seqno)) { +- obj->last_write_seqno = 0; +- obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS; +- } +- +- return 0; ++ return i915_gem_object_wait_rendering__tail(obj, ring); + } + + /* A nonblocking variant of the above wait. This is a highly dangerous routine +@@ -1154,20 +1162,10 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj, + mutex_unlock(&dev->struct_mutex); + ret = __wait_seqno(ring, seqno, reset_counter, true, NULL); + mutex_lock(&dev->struct_mutex); ++ if (ret) ++ return ret; + +- i915_gem_retire_requests_ring(ring); +- +- /* Manually manage the write flush as we may have not yet +- * retired the buffer. +- */ +- if (ret == 0 && +- obj->last_write_seqno && +- i915_seqno_passed(seqno, obj->last_write_seqno)) { +- obj->last_write_seqno = 0; +- obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS; +- } +- +- return ret; ++ return i915_gem_object_wait_rendering__tail(obj, ring); + } + + /** +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0367-drm-i915-Break-up-the-large-vsnprintf-in-print_error.patch b/patches.baytrail/0367-drm-i915-Break-up-the-large-vsnprintf-in-print_error.patch new file mode 100644 index 000000000000..6d4aec397ad2 --- /dev/null +++ b/patches.baytrail/0367-drm-i915-Break-up-the-large-vsnprintf-in-print_error.patch @@ -0,0 +1,196 @@ +From a41d52f08034e78e3ba036142d6ded37577f6158 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Sat, 29 Jun 2013 23:26:50 +0100 +Subject: drm/i915: Break up the large vsnprintf() in print_error_buffers() + +So it appears that I have encountered some bogosity when trying to call +i915_error_printf() with many arguments from print_error_buffers(). The +symptom is that the vsnprintf parser tries to interpret an integer arg +as a character string, the resulting OOPS indicating stack corruption. +Replacing the single call with its 13 format specifiers and arguments +with multiple calls to i915_error_printf() worked fine. This patch goes +one step further and introduced i915_error_puts() to pass the strings +simply. + +It may not fix the root cause, but it does prevent my box from dying and +I think helps make print_error_buffers() more friendly. + +Signed-off-by: Chris Wilson +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66077 +Cc: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit baf27f9b17bf2f369f3865e38c41d2163e8d815d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 109 ++++++++++++++++++++++++++---------- + 1 file changed, 79 insertions(+), 30 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 04cf6c09710a..47d6c748057e 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -647,41 +647,44 @@ static const char *purgeable_flag(int purgeable) + return purgeable ? " purgeable" : ""; + } + +-static void i915_error_vprintf(struct drm_i915_error_state_buf *e, +- const char *f, va_list args) ++static bool __i915_error_ok(struct drm_i915_error_state_buf *e) + { +- unsigned len; + + if (!e->err && WARN(e->bytes > (e->size - 1), "overflow")) { + e->err = -ENOSPC; +- return; ++ return false; + } + + if (e->bytes == e->size - 1 || e->err) +- return; ++ return false; + +- /* Seek the first printf which is hits start position */ +- if (e->pos < e->start) { +- len = vsnprintf(NULL, 0, f, args); +- if (e->pos + len <= e->start) { +- e->pos += len; +- return; +- } ++ return true; ++} + +- /* First vsnprintf needs to fit in full for memmove*/ +- if (len >= e->size) { +- e->err = -EIO; +- return; +- } ++static bool __i915_error_seek(struct drm_i915_error_state_buf *e, ++ unsigned len) ++{ ++ if (e->pos + len <= e->start) { ++ e->pos += len; ++ return false; + } + +- len = vsnprintf(e->buf + e->bytes, e->size - e->bytes, f, args); +- if (len >= e->size - e->bytes) +- len = e->size - e->bytes - 1; ++ /* First vsnprintf needs to fit in its entirety for memmove */ ++ if (len >= e->size) { ++ e->err = -EIO; ++ return false; ++ } + ++ return true; ++} ++ ++static void __i915_error_advance(struct drm_i915_error_state_buf *e, ++ unsigned len) ++{ + /* If this is first printf in this window, adjust it so that + * start position matches start of the buffer + */ ++ + if (e->pos < e->start) { + const size_t off = e->start - e->pos; + +@@ -701,6 +704,51 @@ static void i915_error_vprintf(struct drm_i915_error_state_buf *e, + e->pos += len; + } + ++static void i915_error_vprintf(struct drm_i915_error_state_buf *e, ++ const char *f, va_list args) ++{ ++ unsigned len; ++ ++ if (!__i915_error_ok(e)) ++ return; ++ ++ /* Seek the first printf which is hits start position */ ++ if (e->pos < e->start) { ++ len = vsnprintf(NULL, 0, f, args); ++ if (!__i915_error_seek(e, len)) ++ return; ++ } ++ ++ len = vsnprintf(e->buf + e->bytes, e->size - e->bytes, f, args); ++ if (len >= e->size - e->bytes) ++ len = e->size - e->bytes - 1; ++ ++ __i915_error_advance(e, len); ++} ++ ++static void i915_error_puts(struct drm_i915_error_state_buf *e, ++ const char *str) ++{ ++ unsigned len; ++ ++ if (!__i915_error_ok(e)) ++ return; ++ ++ len = strlen(str); ++ ++ /* Seek the first printf which is hits start position */ ++ if (e->pos < e->start) { ++ if (!__i915_error_seek(e, len)) ++ return; ++ } ++ ++ if (len >= e->size - e->bytes) ++ len = e->size - e->bytes - 1; ++ memcpy(e->buf + e->bytes, str, len); ++ ++ __i915_error_advance(e, len); ++} ++ + void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...) + { + va_list args; +@@ -711,6 +759,7 @@ void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...) + } + + #define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__) ++#define err_puts(e, s) i915_error_puts(e, s) + + static void print_error_buffers(struct drm_i915_error_state_buf *m, + const char *name, +@@ -720,26 +769,26 @@ static void print_error_buffers(struct drm_i915_error_state_buf *m, + err_printf(m, "%s [%d]:\n", name, count); + + while (count--) { +- err_printf(m, " %08x %8u %02x %02x %x %x%s%s%s%s%s%s%s", ++ err_printf(m, " %08x %8u %02x %02x %x %x", + err->gtt_offset, + err->size, + err->read_domains, + err->write_domain, +- err->rseqno, err->wseqno, +- pin_flag(err->pinned), +- tiling_flag(err->tiling), +- dirty_flag(err->dirty), +- purgeable_flag(err->purgeable), +- err->ring != -1 ? " " : "", +- ring_str(err->ring), +- cache_level_str(err->cache_level)); ++ err->rseqno, err->wseqno); ++ err_puts(m, pin_flag(err->pinned)); ++ err_puts(m, tiling_flag(err->tiling)); ++ err_puts(m, dirty_flag(err->dirty)); ++ err_puts(m, purgeable_flag(err->purgeable)); ++ err_puts(m, err->ring != -1 ? " " : ""); ++ err_puts(m, ring_str(err->ring)); ++ err_puts(m, cache_level_str(err->cache_level)); + + if (err->name) + err_printf(m, " (name: %d)", err->name); + if (err->fence_reg != I915_FENCE_REG_NONE) + err_printf(m, " (fence: %d)", err->fence_reg); + +- err_printf(m, "\n"); ++ err_puts(m, "\n"); + err++; + } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0368-drm-i915-Don-t-try-to-tear-down-the-stolen-drm_mm-if.patch b/patches.baytrail/0368-drm-i915-Don-t-try-to-tear-down-the-stolen-drm_mm-if.patch new file mode 100644 index 000000000000..d413d84a7e81 --- /dev/null +++ b/patches.baytrail/0368-drm-i915-Don-t-try-to-tear-down-the-stolen-drm_mm-if.patch @@ -0,0 +1,80 @@ +From b98193c5349454f5a543d3701546f07e3af88e0f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 2 Jul 2013 10:48:31 +0200 +Subject: drm/i915: Don't try to tear down the stolen drm_mm if it's not there + +Every other place properly checks whether we've managed to set +up the stolen allocator at boot-up properly, with the exception +of the cleanup code. Which results in an ugly + +*ERROR* Memory manager not clean. Delaying takedown + +at module unload time since the drm_mm isn't initialized at all. + +v2: While at it check whether the stolen drm_mm is initialized instead +of the more obscure stolen_base == 0 check. + +v3: Fix up the logic. Also we need to keep the stolen_base check in +i915_gem_object_create_stolen_for_preallocated since that can be +called before stolen memory is fully set up. Spotted by Chris Wilson. + +v4: Readd the conversion in i915_gem_object_create_stolen_for_preallocated, +the check is for the dev_priv->mm.gtt_space drm_mm, the stolen +allocatot must already be initialized when calling that function (if +we indeed have stolen memory). + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65953 +Cc: Chris Wilson +Tested-by: lu hua (v3) +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 446f8d81ca2d9cefb614e87f2fabcc996a9e4e7e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_stolen.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index f713294618fe..982d4732cecf 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -147,7 +147,7 @@ int i915_gem_stolen_setup_compression(struct drm_device *dev, int size) + { + struct drm_i915_private *dev_priv = dev->dev_private; + +- if (dev_priv->mm.stolen_base == 0) ++ if (!drm_mm_initialized(&dev_priv->mm.stolen)) + return -ENODEV; + + if (size < dev_priv->cfb_size) +@@ -179,6 +179,9 @@ void i915_gem_cleanup_stolen(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + ++ if (!drm_mm_initialized(&dev_priv->mm.stolen)) ++ return; ++ + i915_gem_stolen_cleanup_compression(dev); + drm_mm_takedown(&dev_priv->mm.stolen); + } +@@ -300,7 +303,7 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size) + struct drm_i915_gem_object *obj; + struct drm_mm_node *stolen; + +- if (dev_priv->mm.stolen_base == 0) ++ if (!drm_mm_initialized(&dev_priv->mm.stolen)) + return NULL; + + DRM_DEBUG_KMS("creating stolen object: size=%x\n", size); +@@ -331,7 +334,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + struct drm_i915_gem_object *obj; + struct drm_mm_node *stolen; + +- if (dev_priv->mm.stolen_base == 0) ++ if (!drm_mm_initialized(&dev_priv->mm.stolen)) + return NULL; + + DRM_DEBUG_KMS("creating preallocated stolen object: stolen_offset=%x, gtt_offset=%x, size=%x\n", +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0369-drm-i915-reinit-status-page-registers-after-gpu-rese.patch b/patches.baytrail/0369-drm-i915-reinit-status-page-registers-after-gpu-rese.patch new file mode 100644 index 000000000000..4f3a57528ce7 --- /dev/null +++ b/patches.baytrail/0369-drm-i915-reinit-status-page-registers-after-gpu-rese.patch @@ -0,0 +1,121 @@ +From 02b4f8bd472ddf7a976ebe56ce11324b6e940304 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 3 Jul 2013 12:56:54 +0200 +Subject: drm/i915: reinit status page registers after gpu reset + +This fixes gpu reset on my gm45 - without this patch the bsd thing is +forever stuck since the seqno updates never reach the status page. + +Tbh I have no idea how this ever worked without rewriting the hws +registers after a gpu reset. + +To satisfy my OCD also give the functions a bit more consistent names: +- Use status_page everywhere, also for the physical addressed one. +- Use init for the allocation part and setup for the register setup + part consistently. + +Long term I'd really like to share the hw init parts completely +between gpu reset, resume and driver load, i.e. to call +i915_gem_init_hw instead of the individual pieces we might need. + +v2: Add the missing paragraph to the commit message about what bug +exactly this patch here fixes. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65495 +Cc: Chris Wilson +Reviewed-by: Chris Wilson +Tested-by: lu hua +Signed-off-by: Daniel Vetter +(cherry picked from commit 035dc1e0f9008b48630e02bf0eaa7cc547416d1d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ringbuffer.c | 29 +++++++++++++++++++---------- + 1 file changed, 19 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index a81647023139..079ef0129e74 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -379,6 +379,17 @@ u32 intel_ring_get_active_head(struct intel_ring_buffer *ring) + return I915_READ(acthd_reg); + } + ++static void ring_setup_phys_status_page(struct intel_ring_buffer *ring) ++{ ++ struct drm_i915_private *dev_priv = ring->dev->dev_private; ++ u32 addr; ++ ++ addr = dev_priv->status_page_dmah->busaddr; ++ if (INTEL_INFO(ring->dev)->gen >= 4) ++ addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0; ++ I915_WRITE(HWS_PGA, addr); ++} ++ + static int init_ring_common(struct intel_ring_buffer *ring) + { + struct drm_device *dev = ring->dev; +@@ -390,6 +401,11 @@ static int init_ring_common(struct intel_ring_buffer *ring) + if (HAS_FORCE_WAKE(dev)) + gen6_gt_force_wake_get(dev_priv); + ++ if (I915_NEED_GFX_HWS(dev)) ++ intel_ring_setup_status_page(ring); ++ else ++ ring_setup_phys_status_page(ring); ++ + /* Stop the ring if it's running. */ + I915_WRITE_CTL(ring, 0); + I915_WRITE_HEAD(ring, 0); +@@ -1234,7 +1250,6 @@ static int init_status_page(struct intel_ring_buffer *ring) + ring->status_page.obj = obj; + memset(ring->status_page.page_addr, 0, PAGE_SIZE); + +- intel_ring_setup_status_page(ring); + DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", + ring->name, ring->status_page.gfx_addr); + +@@ -1248,10 +1263,9 @@ err: + return ret; + } + +-static int init_phys_hws_pga(struct intel_ring_buffer *ring) ++static int init_phys_status_page(struct intel_ring_buffer *ring) + { + struct drm_i915_private *dev_priv = ring->dev->dev_private; +- u32 addr; + + if (!dev_priv->status_page_dmah) { + dev_priv->status_page_dmah = +@@ -1260,11 +1274,6 @@ static int init_phys_hws_pga(struct intel_ring_buffer *ring) + return -ENOMEM; + } + +- addr = dev_priv->status_page_dmah->busaddr; +- if (INTEL_INFO(ring->dev)->gen >= 4) +- addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0; +- I915_WRITE(HWS_PGA, addr); +- + ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; + memset(ring->status_page.page_addr, 0, PAGE_SIZE); + +@@ -1292,7 +1301,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, + return ret; + } else { + BUG_ON(ring->id != RCS); +- ret = init_phys_hws_pga(ring); ++ ret = init_phys_status_page(ring); + if (ret) + return ret; + } +@@ -1904,7 +1913,7 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) + } + + if (!I915_NEED_GFX_HWS(dev)) { +- ret = init_phys_hws_pga(ring); ++ ret = init_phys_status_page(ring); + if (ret) + return ret; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0370-drm-i915-switch-disable_power_well-default-value-to-.patch b/patches.baytrail/0370-drm-i915-switch-disable_power_well-default-value-to-.patch new file mode 100644 index 000000000000..28814deb3311 --- /dev/null +++ b/patches.baytrail/0370-drm-i915-switch-disable_power_well-default-value-to-.patch @@ -0,0 +1,36 @@ +From 884556d35128efd2069e4805a021a0f5048f4dda Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Wed, 3 Jul 2013 17:12:13 -0300 +Subject: drm/i915: switch disable_power_well default value to 1 + +Now that the audio driver is using our power well API, everything +should be working correctly, so let's give it a try. + +Signed-off-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit bf51d5e2cda5d36d98e4b46ac7fca9461e512c41) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 27a8bedd9156..45b3c030f483 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -123,10 +123,10 @@ module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 060 + MODULE_PARM_DESC(preliminary_hw_support, + "Enable preliminary hardware support. (default: false)"); + +-int i915_disable_power_well __read_mostly = 0; ++int i915_disable_power_well __read_mostly = 1; + module_param_named(disable_power_well, i915_disable_power_well, int, 0600); + MODULE_PARM_DESC(disable_power_well, +- "Disable the power well when possible (default: false)"); ++ "Disable the power well when possible (default: true)"); + + int i915_enable_ips __read_mostly = 1; + module_param_named(enable_ips, i915_enable_ips, int, 0600); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0371-drm-i915-fix-lane-bandwidth-capping-for-DP-1.2-sinks.patch b/patches.baytrail/0371-drm-i915-fix-lane-bandwidth-capping-for-DP-1.2-sinks.patch new file mode 100644 index 000000000000..93ce9d8c69af --- /dev/null +++ b/patches.baytrail/0371-drm-i915-fix-lane-bandwidth-capping-for-DP-1.2-sinks.patch @@ -0,0 +1,43 @@ +From b53c54ca82a560b896552b3ef034ce3368d9c189 Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Tue, 9 Jul 2013 17:05:26 +0300 +Subject: drm/i915: fix lane bandwidth capping for DP 1.2 sinks + +DP 1.2 compatible displays may report a 5.4Gbps maximum bandwidth which +the driver will treat as an invalid value and use 1.62Gbps instead. Fix +this by capping to 2.7Gbps for sinks reporting a 5.4Gbps max bw. + +Also add a warning for reserved values. + +v2: +- allow only bw values explicitly listed in the DP standard (Daniel, + Chris) + +Signed-off-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit d4eead50eb206b875f54f66cc0f6ec7d54122c28) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 47713d6aa4a5..3aed1fe0aa51 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -75,7 +75,12 @@ intel_dp_max_link_bw(struct intel_dp *intel_dp) + case DP_LINK_BW_1_62: + case DP_LINK_BW_2_7: + break; ++ case DP_LINK_BW_5_4: /* 1.2 capable displays may advertise higher bw */ ++ max_link_bw = DP_LINK_BW_2_7; ++ break; + default: ++ WARN(1, "invalid max DP link bw val %x, using 1.62Gbps\n", ++ max_link_bw); + max_link_bw = DP_LINK_BW_1_62; + break; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0372-Revert-drm-i915-Workaround-incoherence-between-fence.patch b/patches.baytrail/0372-Revert-drm-i915-Workaround-incoherence-between-fence.patch new file mode 100644 index 000000000000..1aa92cd022c0 --- /dev/null +++ b/patches.baytrail/0372-Revert-drm-i915-Workaround-incoherence-between-fence.patch @@ -0,0 +1,111 @@ +From cf09896eb9285f2446189d98d558998dcf8cd3b1 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 10 Jul 2013 13:36:24 +0100 +Subject: Revert "drm/i915: Workaround incoherence between fences and LLC + across multiple CPUs" + +This reverts commit 25ff119 and the follow on for Valleyview commit 2dc8aae. + +commit 25ff1195f8a0b3724541ae7bbe331b4296de9c06 +Author: Chris Wilson +Date: Thu Apr 4 21:31:03 2013 +0100 + + drm/i915: Workaround incoherence between fences and LLC across multiple CPUs + +commit 2dc8aae06d53458dd3624dc0accd4f81100ee631 +Author: Chris Wilson +Date: Wed May 22 17:08:06 2013 +0100 + + drm/i915: Workaround incoherence with fence updates on Valleyview + +Jon Bloomfield came up with a plausible explanation and cheap fix +(drm/i915: Fix incoherence with fence updates on Sandybridge+) for the +race condition, so lets run with it. + +This is a candidate for stable as the old workaround incurs a +significant cost (calling wbinvd on all CPUs before performing the +register write) for some workloads as noted by Carsten Emde. + +Link: http://lists.freedesktop.org/archives/intel-gfx/2013-June/028819.html +References: https://www.osadl.org/?id=1543#c7602 +References: https://bugs.freedesktop.org/show_bug.cgi?id=63825 +Signed-off-by: Chris Wilson +Cc: Daniel Vetter +Cc: Jon Bloomfield +Cc: Carsten Emde +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Vetter +(cherry picked from commit 46a0b638f35b45fc13d3dc0deb6a7e17988170b2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 47 ++++------------------------------------- + 1 file changed, 4 insertions(+), 43 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 2f58889ec120..d9e2208cfe98 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2832,56 +2832,17 @@ static inline int fence_number(struct drm_i915_private *dev_priv, + return fence - dev_priv->fence_regs; + } + +-struct write_fence { +- struct drm_device *dev; +- struct drm_i915_gem_object *obj; +- int fence; +-}; +- +-static void i915_gem_write_fence__ipi(void *data) +-{ +- struct write_fence *args = data; +- +- /* Required for SNB+ with LLC */ +- wbinvd(); +- +- /* Required for VLV */ +- i915_gem_write_fence(args->dev, args->fence, args->obj); +-} +- + static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, + struct drm_i915_fence_reg *fence, + bool enable) + { + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; +- struct write_fence args = { +- .dev = obj->base.dev, +- .fence = fence_number(dev_priv, fence), +- .obj = enable ? obj : NULL, +- }; +- +- /* In order to fully serialize access to the fenced region and +- * the update to the fence register we need to take extreme +- * measures on SNB+. In theory, the write to the fence register +- * flushes all memory transactions before, and coupled with the +- * mb() placed around the register write we serialise all memory +- * operations with respect to the changes in the tiler. Yet, on +- * SNB+ we need to take a step further and emit an explicit wbinvd() +- * on each processor in order to manually flush all memory +- * transactions before updating the fence register. +- * +- * However, Valleyview complicates matter. There the wbinvd is +- * insufficient and unlike SNB/IVB requires the serialising +- * register write. (Note that that register write by itself is +- * conversely not sufficient for SNB+.) To compromise, we do both. +- */ +- if (INTEL_INFO(args.dev)->gen >= 6) +- on_each_cpu(i915_gem_write_fence__ipi, &args, 1); +- else +- i915_gem_write_fence(args.dev, args.fence, args.obj); ++ int reg = fence_number(dev_priv, fence); ++ ++ i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL); + + if (enable) { +- obj->fence_reg = args.fence; ++ obj->fence_reg = reg; + fence->obj = obj; + list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); + } else { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0373-drm-i915-fix-up-readout-of-the-lvds-dither-bit-on-ge.patch b/patches.baytrail/0373-drm-i915-fix-up-readout-of-the-lvds-dither-bit-on-ge.patch new file mode 100644 index 000000000000..749976e53696 --- /dev/null +++ b/patches.baytrail/0373-drm-i915-fix-up-readout-of-the-lvds-dither-bit-on-ge.patch @@ -0,0 +1,99 @@ +From 3bd01ef97d4c2dd8f35f47f1fb11047931cf2158 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 11 Jul 2013 13:35:40 +0200 +Subject: drm/i915: fix up readout of the lvds dither bit on gen2/3 + +It's in the PFIT_CONTROL register, but very much associated with the +lvds encoder. So move the readout for it (in the case of an otherwise +disabled pfit) from the pipe to the lvds encoder's get_config +function. + +Otherwise we get a pipe state mismatch if we use pipe B for a non-lvds +output and we've left the dither bit enabled behind us. This can +happen if the BIOS has set the bit (some seem to unconditionally do +that, even in the complete absence of an lvds port), but not enabled +pipe B at boot-up. Then we won't clear the pfit control register since +we can only touch that if the pfit is associated with our pipe in the +crtc configuration - we could trample over the pfit state of the other +pipe otherwise since it's shared. Once pipe B is enabled we notice +that the 6to8 dither bit is set and complain about the mismatch. + +Note that testing indicates that we don't actually need to set this +bit when the pfit is disabled, dithering on 18bpp panels seems to work +regardless. But ripping that code out is not something for a bugfix +meant for -rc kernels. + +v2: While at it clarify the logic in i9xx_get_pfit_config, spurred by +comments from Chris on irc. + +v3: Use Chris suggestion to make the control flow in +i9xx_get_pfit_config easier to understand. + +v4: Kill the extra line, spotted by Chris. + +Reported-by: Knut Petersen +Cc: Knut Petersen +Cc: Chris Wilson +References: http://lists.freedesktop.org/archives/intel-gfx/2013-July/030092.html +Tested-by: Knut Petersen +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 0692282181e248328c226c2520994fc06dfd65bf) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 11 ++++------- + drivers/gpu/drm/i915/intel_lvds.c | 7 +++++++ + 2 files changed, 11 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 7a4669183b6a..2962d0fa11e1 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4913,22 +4913,19 @@ static void i9xx_get_pfit_config(struct intel_crtc *crtc, + uint32_t tmp; + + tmp = I915_READ(PFIT_CONTROL); ++ if (!(tmp & PFIT_ENABLE)) ++ return; + ++ /* Check whether the pfit is attached to our pipe. */ + if (INTEL_INFO(dev)->gen < 4) { + if (crtc->pipe != PIPE_B) + return; +- +- /* gen2/3 store dither state in pfit control, needs to match */ +- pipe_config->gmch_pfit.control = tmp & PANEL_8TO6_DITHER_ENABLE; + } else { + if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT)) + return; + } + +- if (!(tmp & PFIT_ENABLE)) +- return; +- +- pipe_config->gmch_pfit.control = I915_READ(PFIT_CONTROL); ++ pipe_config->gmch_pfit.control = tmp; + pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS); + if (INTEL_INFO(dev)->gen < 5) + pipe_config->gmch_pfit.lvds_border_bits = +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 3264bfa842fc..9eeae0e3a062 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -109,6 +109,13 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, + flags |= DRM_MODE_FLAG_PVSYNC; + + pipe_config->adjusted_mode.flags |= flags; ++ ++ /* gen2/3 store dither state in pfit control, needs to match */ ++ if (INTEL_INFO(dev)->gen < 4) { ++ tmp = I915_READ(PFIT_CONTROL); ++ ++ pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE; ++ } + } + + /* The LVDS pin pair needs to be on before the DPLLs are enabled. +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0374-drm-i915-fix-pfit-regression-for-non-autoscaled-reso.patch b/patches.baytrail/0374-drm-i915-fix-pfit-regression-for-non-autoscaled-reso.patch new file mode 100644 index 000000000000..a56ff092e197 --- /dev/null +++ b/patches.baytrail/0374-drm-i915-fix-pfit-regression-for-non-autoscaled-reso.patch @@ -0,0 +1,72 @@ +From 88ef018ef1229e52282ee5a080ef4efe796bcc08 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 12 Jul 2013 08:07:30 +0200 +Subject: drm/i915: fix pfit regression for non-autoscaled resolutions + +I.e. for letter/pillarboxing. For those cases we need to adjust the +mode a bit, but Jesse gmch pfit refactoring in + +commit 2dd24552cab40ea829ba3fda890eeafd2c4816d8 +Author: Jesse Barnes +Date: Thu Apr 25 12:55:01 2013 -0700 + + drm/i915: factor out GMCH panel fitting code and use for eDP v3 + +broke that by reordering the computation of the gmch pfit state with +the block of code that prepared the adjusted mode for it and told the +modeset core not to overwrite the adjusted mode with default settings. + +We might want to switch around the core code to just fill in defaults, +but this code predates the pipe_config modeset rework. And in the old +crtc helpers we did not have a suitable spot to do this. + +Cc: Mika Kuoppala +Cc: Jesse Barnes +Cc: Hans de Bruin +Reported-and-tested-by: Hans de Bruin +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 21d8a4756af5fdf4a42e79a77cf3b6f52678d443) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_lvds.c | 5 +---- + drivers/gpu/drm/i915/intel_panel.c | 3 +++ + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 9eeae0e3a062..44533dde25c1 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -297,14 +297,11 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + + intel_pch_panel_fitting(intel_crtc, pipe_config, + intel_connector->panel.fitting_mode); +- return true; + } else { + intel_gmch_panel_fitting(intel_crtc, pipe_config, + intel_connector->panel.fitting_mode); +- } + +- drm_mode_set_crtcinfo(adjusted_mode, 0); +- pipe_config->timings_set = true; ++ } + + /* + * XXX: It would be nice to support lower refresh rates on the +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index 01b5a519c43c..67e2c1f1c9a8 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -194,6 +194,9 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, + adjusted_mode->vdisplay == mode->vdisplay) + goto out; + ++ drm_mode_set_crtcinfo(adjusted_mode, 0); ++ pipe_config->timings_set = true; ++ + switch (fitting_mode) { + case DRM_MODE_SCALE_CENTER: + /* +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0375-drm-i915-Preserve-the-DDI_A_4_LANES-bit-from-the-bio.patch b/patches.baytrail/0375-drm-i915-Preserve-the-DDI_A_4_LANES-bit-from-the-bio.patch new file mode 100644 index 000000000000..be49c46e6b76 --- /dev/null +++ b/patches.baytrail/0375-drm-i915-Preserve-the-DDI_A_4_LANES-bit-from-the-bio.patch @@ -0,0 +1,45 @@ +From 9237256b4dc9207b37b52a0ee0b9b5770a5e5c92 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?St=C3=A9phane=20Marchesin?= +Date: Fri, 12 Jul 2013 13:54:41 -0700 +Subject: drm/i915: Preserve the DDI_A_4_LANES bit from the bios +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Otherwise the DDI_A_4_LANES bit gets lost and we can't use > 2 lanes +on eDP. This fixes eDP on hsw with > 2 lanes. + +Also s/port_reversal/saved_port_bits/ since the current name is +confusing. + +Signed-off-by: Stéphane Marchesin +Reviewed-by: Paulo Zanoni +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Vetter +(cherry picked from commit bcf53de4e60d9000b82f541d654529e2902a4c2c) +[dbasehore: removed if statement on a NULL pointer value in conflict] +Signed-off-by: Derek Basehore + +Conflicts: + drivers/gpu/drm/i915/intel_ddi.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 0bf5be1bf5c9..b042ee5c4070 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -1351,8 +1351,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port) + intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & + (DDI_BUF_PORT_REVERSAL | + DDI_A_4_LANES); +- if (hdmi_connector) +- intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port); + intel_dig_port->dp.output_reg = DDI_BUF_CTL(port); + + intel_encoder->type = INTEL_OUTPUT_UNKNOWN; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0376-drm-i915-fix-long-standing-SNB-regression-in-power-c.patch b/patches.baytrail/0376-drm-i915-fix-long-standing-SNB-regression-in-power-c.patch new file mode 100644 index 000000000000..b5dd0d8a4561 --- /dev/null +++ b/patches.baytrail/0376-drm-i915-fix-long-standing-SNB-regression-in-power-c.patch @@ -0,0 +1,79 @@ +From 9cdccab3f0ea875b9bc0f7a77eef020f5acd1daf Mon Sep 17 00:00:00 2001 +From: Konstantin Khlebnikov +Date: Wed, 17 Jul 2013 10:22:58 +0400 +Subject: drm/i915: fix long-standing SNB regression in power consumption after + resume v2 + +This patch fixes regression in power consumtion of sandy bridge gpu, which +exists since v3.6 Sometimes after resuming from s2ram gpu starts thinking that +it's extremely busy. After that it never reaches rc6 state. + +Bug exists since kernel v3.6: + +commit b4ae3f22d238617ca11610b29fde16cf8c0bc6e0 +Author: Jesse Barnes +Date: Thu Jun 14 11:04:48 2012 -0700 + + drm/i915: load boot context at driver init time + +For some reason RC6 is already enabled at the beginning of resuming process. +Following initliaztion breaks some internal state and confuses RPS engine. +This patch disables RC6 at the beginnig of resume and initialization. + +I've rearranged initialization sequence, because intel_disable_gt_powersave() +needs initialized force_wake_get/put and some locks from the dev_priv. + +Note: The culprit in the initialization sequence seems to be the write +to MBCTL added in the above mentioned commit. The first version of +this patch just held a forcewake reference across the clock gating +init functions, which seems to have been enought to gather quite a few +positive test reports. But since that smelled a bit like ad-hoc +duct-tape v2 now just disables rps/rc6 across the entire hw setup. + +References: https://bugs.freedesktop.org/show_bug.cgi?id=54089 +References: https://bugzilla.kernel.org/show_bug.cgi?id=58971 +References: https://patchwork.kernel.org/patch/2827634/ (patch v1) +Signed-off-by: Konstantin Khlebnikov +Cc: Daniel Vetter +Cc: Chris Wilson +Cc: Jesse Barnes +[danvet: Add note about v1 vs. v2 of this patch and use standard +layout for the commit citation. Also add the tested-bys from v1 and a +cc: stable.] +Cc: stable@vger.kernel.org (Note: tiny conflict due to the addition of +the backlight lock in 3.11) +Tested-by: Alexander Kaltsas (v1) +Tested-by: rocko (v1) +Tested-by: JohnMB (v1) +Signed-off-by: Daniel Vetter + +(cherry picked from commit 7dcd2677ea912573d9ed4bcd629b0023b2d11505) +[dbasehore: removed call to function that no longer exists, removed redundant +branch, and moved back spinlock initialization for conflict] +Signed-off-by: Derek Basehore + +Conflicts: + drivers/gpu/drm/i915/i915_dma.c + drivers/gpu/drm/i915/intel_pm.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index f895d1508df8..aa962ef827c4 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -5489,8 +5489,7 @@ void intel_gt_sanitize(struct drm_device *dev) + } + + /* BIOS often leaves RC6 enabled, but disable it for hw init */ +- if (INTEL_INFO(dev)->gen >= 6) +- intel_disable_gt_powersave(dev); ++ intel_disable_gt_powersave(dev); + } + + void intel_gt_init(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0377-drm-i915-Sanitize-shared-dpll-state.patch b/patches.baytrail/0377-drm-i915-Sanitize-shared-dpll-state.patch new file mode 100644 index 000000000000..e528c01f3450 --- /dev/null +++ b/patches.baytrail/0377-drm-i915-Sanitize-shared-dpll-state.patch @@ -0,0 +1,81 @@ +From 41d5751570c52b0dd020858fb4c0059dc46d4f8e Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 17 Jul 2013 06:55:04 +0200 +Subject: drm/i915: Sanitize shared dpll state + +There seems to be no limit to the amount of gunk the firmware can +leave behind. Some platforms leave pch dplls on which are not in +active use at all. The example in the bug report is a Apple Macbook +Pro. + +Note that this escape scrunity of the hw state checker until we've +tried to use this enabled, but unused pll since we did only check for +the inverse case of a in-used, but disabled pll. + +v2: Add a WARN in the pll state checker which would have caught this +case. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66952 +Reported-and-tested-by: shui yangwei +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 35c95375f69ceec721fea67a0532bc17ceb5cf64) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 2962d0fa11e1..cd93b1b1840d 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8318,6 +8318,8 @@ check_shared_dpll_state(struct drm_device *dev) + pll->active, pll->refcount); + WARN(pll->active && !pll->on, + "pll in active use but not on in sw tracking\n"); ++ WARN(pll->on && !pll->active, ++ "pll in on but not on in use in sw tracking\n"); + WARN(pll->on != active, + "pll on state mismatch (expected %i, found %i)\n", + pll->on, active); +@@ -9837,8 +9839,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) + } + pll->refcount = pll->active; + +- DRM_DEBUG_KMS("%s hw state readout: refcount %i\n", +- pll->name, pll->refcount); ++ DRM_DEBUG_KMS("%s hw state readout: refcount %i, on %i\n", ++ pll->name, pll->refcount, pll->on); + } + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, +@@ -9889,6 +9891,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, + struct drm_plane *plane; + struct intel_crtc *crtc; + struct intel_encoder *encoder; ++ int i; + + intel_modeset_readout_hw_state(dev); + +@@ -9904,6 +9907,18 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, + intel_dump_pipe_config(crtc, &crtc->config, "[setup_hw_state]"); + } + ++ for (i = 0; i < dev_priv->num_shared_dpll; i++) { ++ struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; ++ ++ if (!pll->on || pll->active) ++ continue; ++ ++ DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name); ++ ++ pll->disable(dev_priv, pll); ++ pll->on = false; ++ } ++ + if (force_restore) { + /* + * We need to use raw interfaces for restoring state to avoid +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0378-drm-i915-fix-up-gt-init-sequence-fallout.patch b/patches.baytrail/0378-drm-i915-fix-up-gt-init-sequence-fallout.patch new file mode 100644 index 000000000000..61d0d44aab7d --- /dev/null +++ b/patches.baytrail/0378-drm-i915-fix-up-gt-init-sequence-fallout.patch @@ -0,0 +1,65 @@ +From abb221042ebe297834475c54eeb9061480e0f280 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 13:16:24 +0200 +Subject: drm/i915: fix up gt init sequence fallout + +The regression fix for gen6+ rps fallout + +commit 7dcd2677ea912573d9ed4bcd629b0023b2d11505 +Author: Konstantin Khlebnikov +Date: Wed Jul 17 10:22:58 2013 +0400 + + drm/i915: fix long-standing SNB regression in power consumption after resume + +unintentionally also changed the init sequence ordering between +gt_init and gt_reset - we need to reset BIOS damage like leftover +forcewake references before we run our own code. Otherwise we can get +nasty dmesg noise like + +[drm:__gen6_gt_force_wake_mt_get] *ERROR* Timed out waiting for forcewake old ack to clear. + +again. Since _reset suggests that we first need to have stuff +initialized (which isn't the case here) call it sanitze instead. + +While at it also block out the rps disable introduced by the above +commit on ilk: We don't have any knowledge of ilk rps being broken in +similar ways. And the disable functions uses the default hw state +which is only read out when we're enabling rps. So essentially we've +been writing random grabage into that register. + +Reported-by: Chris Wilson +Cc: Chris Wilson +Cc: Konstantin Khlebnikov +Cc: Jesse Barnes +Cc: stable@vger.kernel.org +Tested-by: Chris Wilson +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 181d1b9e31c668259d3798c521672afb8edd355c) +[dbasehore: fixed conflict from missing line in commit due to 3.10 backport] +Signed-off-by: Derek Basehore + +Conflicts: + drivers/gpu/drm/i915/i915_dma.c +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index aa962ef827c4..f895d1508df8 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -5489,7 +5489,8 @@ void intel_gt_sanitize(struct drm_device *dev) + } + + /* BIOS often leaves RC6 enabled, but disable it for hw init */ +- intel_disable_gt_powersave(dev); ++ if (INTEL_INFO(dev)->gen >= 6) ++ intel_disable_gt_powersave(dev); + } + + void intel_gt_init(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0379-drm-i915-fix-hdmi-portclock-limits.patch b/patches.baytrail/0379-drm-i915-fix-hdmi-portclock-limits.patch new file mode 100644 index 000000000000..ca24b9b66d1c --- /dev/null +++ b/patches.baytrail/0379-drm-i915-fix-hdmi-portclock-limits.patch @@ -0,0 +1,101 @@ +From 88de448b0b06ea20c4c20e9285c71e1af5dc95a9 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 22 Jul 2013 18:02:39 +0200 +Subject: drm/i915: fix hdmi portclock limits + +In + +commit 325b9d048810f7689ec644595061c0b700e64bce +Author: Daniel Vetter +Date: Fri Apr 19 11:24:33 2013 +0200 + + drm/i915: fixup 12bpc hdmi dotclock handling + +I've errornously claimed that we don't yet support the hdmi 1.4 +dotclocks > 225 MHz on Haswell. But a bug report and a closer look at +the wrpll table showed that we've supported port clocks up to 300MHz. + +With the new code to dynamically compute wrpll limits we should have +no issues going up to the full 340 MHz range of hdmi 1.4, so let's +just use that to fix this regression. That'll allow 4k over hdmi for +free! + +v2: Drop the random hunk that somehow slipped in. + +v3: Cantiga has the original HDMI dotclock limit of 165MHz. And also +patch up the mode filtering. To do so extract the dotclock limits into +a little helper function. + +v4: Use 300MHz (from Bspec) instead of 340MHz (upper limit for hdmi +1.3), apparently hw is not required to be able to drive the highest +dotclocks. Suggested by Damien. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67048 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67030 +Tested-by: Andreas Reis (v2) +Cc: Damien Lespiau +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 7d148ef51a657fd04036c3ed7803da600dd0d451) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_hdmi.c | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 98df2a0c85bd..2fd3fd5b943e 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -785,10 +785,22 @@ static void intel_disable_hdmi(struct intel_encoder *encoder) + } + } + ++static int hdmi_portclock_limit(struct intel_hdmi *hdmi) ++{ ++ struct drm_device *dev = intel_hdmi_to_dev(hdmi); ++ ++ if (IS_G4X(dev)) ++ return 165000; ++ else if (IS_HASWELL(dev)) ++ return 300000; ++ else ++ return 225000; ++} ++ + static int intel_hdmi_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) + { +- if (mode->clock > 165000) ++ if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector))) + return MODE_CLOCK_HIGH; + if (mode->clock < 20000) + return MODE_CLOCK_LOW; +@@ -806,6 +818,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, + struct drm_device *dev = encoder->base.dev; + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; + int clock_12bpc = pipe_config->requested_mode.clock * 3 / 2; ++ int portclock_limit = hdmi_portclock_limit(intel_hdmi); + int desired_bpp; + + if (intel_hdmi->color_range_auto) { +@@ -829,7 +842,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, + * outputs. We also need to check that the higher clock still fits + * within limits. + */ +- if (pipe_config->pipe_bpp > 8*3 && clock_12bpc <= 225000 ++ if (pipe_config->pipe_bpp > 8*3 && clock_12bpc <= portclock_limit + && HAS_PCH_SPLIT(dev)) { + DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n"); + desired_bpp = 12*3; +@@ -846,7 +859,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, + pipe_config->pipe_bpp = desired_bpp; + } + +- if (adjusted_mode->clock > 225000) { ++ if (adjusted_mode->clock > portclock_limit) { + DRM_DEBUG_KMS("too high HDMI clock, rejecting mode\n"); + return false; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0380-drm-i915-update-last_vblank-when-disabling-the-power.patch b/patches.baytrail/0380-drm-i915-update-last_vblank-when-disabling-the-power.patch new file mode 100644 index 000000000000..38961d33c770 --- /dev/null +++ b/patches.baytrail/0380-drm-i915-update-last_vblank-when-disabling-the-power.patch @@ -0,0 +1,68 @@ +From ea02b4f5dce4566bf236c80e637bc7a07a5299de Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Tue, 23 Jul 2013 10:48:11 -0300 +Subject: drm/i915: update last_vblank when disabling the power well + +The DRM layer keeps track of our vblanks and it assumes our vblank +counters only go back to zero when they overflow. The problem is that +when we disable the power well our counters also go to zero, but it +doesn't mean they did overflow. So on this patch we grab the lock and +update last_vblank so the DRM layer won't think our counters +overflowed. + +This patch fixes the following intel-gpu-tools test: +./kms_flip --run-subtest blocking-absolute-wf_vblank + +Regression introduced by the following commit: + +commit bf51d5e2cda5d36d98e4b46ac7fca9461e512c41 +Author: Paulo Zanoni +Date: Wed Jul 3 17:12:13 2013 -0300 + drm/i915: switch disable_power_well default value to 1 + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66808 +Signed-off-by: Paulo Zanoni +[danvet: Added a comment that this might be better done in +drm_vblank_post_modeset in general.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 9dbd8febb4dbc9199fcf340b882eb930e36b65b6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index f895d1508df8..b0e4a0bd1313 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -5063,8 +5063,26 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) + } + } else { + if (enable_requested) { ++ unsigned long irqflags; ++ enum pipe p; ++ + I915_WRITE(HSW_PWR_WELL_DRIVER, 0); ++ POSTING_READ(HSW_PWR_WELL_DRIVER); + DRM_DEBUG_KMS("Requesting to disable the power well\n"); ++ ++ /* ++ * After this, the registers on the pipes that are part ++ * of the power well will become zero, so we have to ++ * adjust our counters according to that. ++ * ++ * FIXME: Should we do this in general in ++ * drm_vblank_post_modeset? ++ */ ++ spin_lock_irqsave(&dev->vbl_lock, irqflags); ++ for_each_pipe(p) ++ if (p != PIPE_A) ++ dev->last_vblank[p] = 0; ++ spin_unlock_irqrestore(&dev->vbl_lock, irqflags); + } + } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0381-drm-i915-avoid-brightness-overflow-when-doing-scale.patch b/patches.baytrail/0381-drm-i915-avoid-brightness-overflow-when-doing-scale.patch new file mode 100644 index 000000000000..f0959b9094df --- /dev/null +++ b/patches.baytrail/0381-drm-i915-avoid-brightness-overflow-when-doing-scale.patch @@ -0,0 +1,42 @@ +From 14e2b8a2e963c015372733d3d0950384ee5fa4fb Mon Sep 17 00:00:00 2001 +From: Aaron Lu +Date: Fri, 2 Aug 2013 09:16:03 +0800 +Subject: drm/i915: avoid brightness overflow when doing scale + +Some card's max brightness level is pretty large, e.g. on Acer Aspire +4732Z, the max level is 989910. If user space set a large enough level +then the current scale done in intel_panel_set_backlight will cause an +integer overflow and the scaled level will be mistakenly small, leaving +user with an almost black screen. This patch fixes this problem. + +Signed-off-by: Aaron Lu +[danvet: Add a comment to explain what's going on.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 22505b82a2800bddb67908522833bef96dd15845) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_panel.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index 67e2c1f1c9a8..5063eadac3ef 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -497,8 +497,11 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max) + goto out; + } + +- /* scale to hardware */ +- level = level * freq / max; ++ /* scale to hardware, but be careful to not overflow */ ++ if (freq < max) ++ level = level * freq / max; ++ else ++ level = freq / max * level; + + dev_priv->backlight.level = level; + if (dev_priv->backlight.device) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0382-drm-i915-Don-t-call-encoder-s-get_config-unless-enco.patch b/patches.baytrail/0382-drm-i915-Don-t-call-encoder-s-get_config-unless-enco.patch new file mode 100644 index 000000000000..385a502ad330 --- /dev/null +++ b/patches.baytrail/0382-drm-i915-Don-t-call-encoder-s-get_config-unless-enco.patch @@ -0,0 +1,72 @@ +From 51bd061c699974f196f8e13c602283ed55837d1c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Mon, 5 Aug 2013 17:57:48 +0300 +Subject: drm/i915: Don't call encoder's get_config unless encoder is active +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The SDVO code tries to compare the encoder's and crtc's idea of the +pixel_multiplier. Normally they have to match, but when transitioning +to DPMS off, we turn off the pipe before reading out the pipe_config, +so the pixel_multiplier in the pipe_config will be 0, whereas the +encoder will still have its pixel_multiplier set to whatever value we +were using when the display was active. This leads to a warning +from intel_modeset_check_state(). + +WARNING: CPU: 1 PID: 2846 at drivers/gpu/drm/i915/intel_sdvo.c:1378 intel_sdvo_get_config+0x158/0x160() +SDVO pixel multiplier mismatch, port: 0, encoder: 1 +Modules linked in: snd_hda_codec_idt snd_hda_intel snd_hda_codec snd_hwdep +CPU: 1 PID: 2846 Comm: Xorg Not tainted 3.11.0-rc3-00208-gbe1e8d7-dirty #19 +Hardware name: Apple Computer, Inc. Macmini1,1/Mac-F4208EC8, BIOS MM11.88Z.0055.B03.0604071521 04/07/06 + 00000000 00000000 ef0afa54 c1597bbb c1737ea4 ef0afa84 c10392ca c1737e6c + ef0afab0 00000b1e c1737ea4 00000562 c12dfbe8 c12dfbe8 ef0afb14 00000000 + f697ec00 ef0afa9c c103936e 00000009 ef0afa94 c1737e6c ef0afab0 ef0afadc +Call Trace: + [] dump_stack+0x41/0x56 + [] warn_slowpath_common+0x7a/0xa0 + [] warn_slowpath_fmt+0x2e/0x30 + [] intel_sdvo_get_config+0x158/0x160 + [] check_crtc_state+0x1e0/0xb10 + [] intel_modeset_check_state+0x29d/0x7c0 + [] intel_sdvo_dpms+0x5c/0xa0 + [] drm_mode_obj_set_property_ioctl+0x40e/0x420 + [] drm_mode_connector_property_set_ioctl+0x35/0x40 + [] drm_ioctl+0x3e4/0x540 + [] do_vfs_ioctl+0x72/0x570 + [] SyS_ioctl+0x8f/0xa0 + [] sysenter_do_call+0x12/0x22 +---[ end trace 7ce940aff1366d60 ]--- + +Fix the problem by skipping the encoder get_config() function for +inactive encoders. + +Tested-by: Linus Torvalds +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 3eaba51cd399f5362a9fd9ebd5fb8b625b454271) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index cd93b1b1840d..f0701147a68a 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8273,9 +8273,11 @@ check_crtc_state(struct drm_device *dev) + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, + base.head) { ++ enum pipe pipe; + if (encoder->base.crtc != &crtc->base) + continue; +- if (encoder->get_config) ++ if (encoder->get_config && ++ encoder->get_hw_state(encoder, &pipe)) + encoder->get_config(encoder, &pipe_config); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0383-drm-i915-do-not-disable-backlight-on-vgaswitcheroo-s.patch b/patches.baytrail/0383-drm-i915-do-not-disable-backlight-on-vgaswitcheroo-s.patch new file mode 100644 index 000000000000..7661df9d9156 --- /dev/null +++ b/patches.baytrail/0383-drm-i915-do-not-disable-backlight-on-vgaswitcheroo-s.patch @@ -0,0 +1,62 @@ +From 2df6459e273480b665df692627bf4611e68496ed Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Thu, 25 Jul 2013 14:31:30 +0300 +Subject: drm/i915: do not disable backlight on vgaswitcheroo switch off + +On muxed systems, the other vgaswitcheroo client may depend on i915 to +handle the backlight. We began switching off the backlight since + +commit a261b246ebd552fd5d5a8ed84cc931bb821c427f +Author: Daniel Vetter +Date: Thu Jul 26 19:21:47 2012 +0200 + + drm/i915: disable all crtcs at suspend time + +breaking backlight on discreet graphics in (some) muxed systems. + +Keep the backlight on when the state is changed through vgaswitcheroo. + +Note: The alternative would be to add a quirk table to achieve the same +based on system identifiers, but AFAICS it would asymptotically approach +effectively the same as this patch as more IDs are added, but with the +maintenance burden of the quirk table. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=55311 +Tested-by: Fede +Tested-by: Aximab +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=59785 +Tested-by: sfievet +Signed-off-by: Jani Nikula +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Vetter +(cherry picked from commit 3f577573cd5482a32f85bd131e52f7cb4b9ac518) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_panel.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index 5063eadac3ef..5950888ae1d0 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -518,6 +518,17 @@ void intel_panel_disable_backlight(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long flags; + ++ /* ++ * Do not disable backlight on the vgaswitcheroo path. When switching ++ * away from i915, the other client may depend on i915 to handle the ++ * backlight. This will leave the backlight on unnecessarily when ++ * another client is not activated. ++ */ ++ if (dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) { ++ DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n"); ++ return; ++ } ++ + spin_lock_irqsave(&dev_priv->backlight.lock, flags); + + dev_priv->backlight.enabled = false; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0384-drm-i915-unpin-backing-storage-in-dmabuf_unmap.patch b/patches.baytrail/0384-drm-i915-unpin-backing-storage-in-dmabuf_unmap.patch new file mode 100644 index 000000000000..5e6ebac28a7f --- /dev/null +++ b/patches.baytrail/0384-drm-i915-unpin-backing-storage-in-dmabuf_unmap.patch @@ -0,0 +1,56 @@ +From edb774d58c6b800ab1b7bbfebeca5eb96bf57e61 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 8 Aug 2013 09:10:37 +0200 +Subject: drm/i915: unpin backing storage in dmabuf_unmap + +This fixes a WARN in i915_gem_free_object when the +obj->pages_pin_count isn't 0. + +v2: Add locking to unmap, noticed by Chris Wilson. Note that even +though we call unmap with our own dev->struct_mutex held that won't +result in an immediate deadlock since we never go through the dma_buf +interfaces for our own, reimported buffers. But it's still easy to +blow up and anger lockdep, but that's already the case with our ->map +implementation. Fixing this for real will involve per dma-buf ww mutex +locking by the callers. And lots of fun. So go with the duct-tape +approach for now. + +Cc: Chris Wilson +Reported-by: Maarten Lankhorst +Cc: Maarten Lankhorst +Tested-by: Armin K. (v1) +Tested-by: Dave Airlie +Acked-by: Maarten Lankhorst +Signed-off-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit eb91626ac4b9af3d5602a7db888b8bc4cb23eb3b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_dmabuf.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c +index dc53a527126b..9e6578330801 100644 +--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c ++++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c +@@ -85,9 +85,17 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *sg, + enum dma_data_direction dir) + { ++ struct drm_i915_gem_object *obj = attachment->dmabuf->priv; ++ ++ mutex_lock(&obj->base.dev->struct_mutex); ++ + dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir); + sg_free_table(sg); + kfree(sg); ++ ++ i915_gem_object_unpin_pages(obj); ++ ++ mutex_unlock(&obj->base.dev->struct_mutex); + } + + static void i915_gem_dmabuf_release(struct dma_buf *dma_buf) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0385-drm-i915-Don-t-deref-pipe-cpu_transcoder-in-the-hang.patch b/patches.baytrail/0385-drm-i915-Don-t-deref-pipe-cpu_transcoder-in-the-hang.patch new file mode 100644 index 000000000000..1faf28765001 --- /dev/null +++ b/patches.baytrail/0385-drm-i915-Don-t-deref-pipe-cpu_transcoder-in-the-hang.patch @@ -0,0 +1,215 @@ +From 45c21a9c41e9dee8d3236f8fb3c9f7345121c0e1 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Thu, 8 Aug 2013 15:12:06 +0200 +Subject: drm/i915: Don't deref pipe->cpu_transcoder in the hangcheck code + +If we get an error event really early in the driver setup sequence, +which gen3 is especially prone to with various display GTT faults we +Oops. So try to avoid this. + +Additionally with Haswell the transcoders are a separate bank of +registers from the pipes (4 transcoders, 3 pipes). In event of an +error, we want to be sure we have a complete and accurate picture of +the machine state, so record all the transcoders in addition to all +the active pipes. + +This regression has been introduced in + +commit 702e7a56af3780d8b3a717f698209bef44187bb0 +Author: Paulo Zanoni +Date: Tue Oct 23 18:29:59 2012 -0200 + + drm/i915: convert PIPECONF to use transcoder instead of pipe + +Based on the patch "drm/i915: Dump all transcoder registers on error" +from Chris Wilson: + +v2: Rebase so that we don't try to be clever and try to figure out the +cpu transcoder from hw state. That exercise should be done when we +analyze the error state offline. + +The actual bugfix is to not call intel_pipe_to_cpu_transcoder in the +error state capture code in case the pipes aren't fully set up yet. + +v3: Simplifiy the err->num_transcoders computation a bit. While at it +make the error capture stuff save on systems without a display block. + +v4: Fix fail, spotted by Jani. + +v5: Completely new commit message, cc: stable. + +Cc: Paulo Zanoni +Cc: Damien Lespiau +Cc: Jani Nikula +Cc: Chris Wilson +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=60021 +Cc: stable@vger.kernel.org +Tested-by: Dustin King +Reviewed-by: Jani Nikula +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 63b66e5ba54b15a6592be00555d762db6db739ce) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 86 ++++++++++++++++++++++++------------ + 1 file changed, 57 insertions(+), 29 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index f0701147a68a..bde6a5547568 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -10046,6 +10046,8 @@ struct intel_display_error_state { + + u32 power_well_driver; + ++ int num_transcoders; ++ + struct intel_cursor_error_state { + u32 control; + u32 position; +@@ -10054,16 +10056,7 @@ struct intel_display_error_state { + } cursor[I915_MAX_PIPES]; + + struct intel_pipe_error_state { +- enum transcoder cpu_transcoder; +- u32 conf; + u32 source; +- +- u32 htotal; +- u32 hblank; +- u32 hsync; +- u32 vtotal; +- u32 vblank; +- u32 vsync; + } pipe[I915_MAX_PIPES]; + + struct intel_plane_error_state { +@@ -10075,6 +10068,19 @@ struct intel_display_error_state { + u32 surface; + u32 tile_offset; + } plane[I915_MAX_PIPES]; ++ ++ struct intel_transcoder_error_state { ++ enum transcoder cpu_transcoder; ++ ++ u32 conf; ++ ++ u32 htotal; ++ u32 hblank; ++ u32 hsync; ++ u32 vtotal; ++ u32 vblank; ++ u32 vsync; ++ } transcoder[4]; + }; + + struct intel_display_error_state * +@@ -10082,9 +10088,17 @@ intel_display_capture_error_state(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_display_error_state *error; +- enum transcoder cpu_transcoder; ++ int transcoders[] = { ++ TRANSCODER_A, ++ TRANSCODER_B, ++ TRANSCODER_C, ++ TRANSCODER_EDP, ++ }; + int i; + ++ if (INTEL_INFO(dev)->num_pipes == 0) ++ return NULL; ++ + error = kmalloc(sizeof(*error), GFP_ATOMIC); + if (error == NULL) + return NULL; +@@ -10093,9 +10107,6 @@ intel_display_capture_error_state(struct drm_device *dev) + error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER); + + for_each_pipe(i) { +- cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, i); +- error->pipe[i].cpu_transcoder = cpu_transcoder; +- + if (INTEL_INFO(dev)->gen <= 6 || IS_VALLEYVIEW(dev)) { + error->cursor[i].control = I915_READ(CURCNTR(i)); + error->cursor[i].position = I915_READ(CURPOS(i)); +@@ -10119,14 +10130,25 @@ intel_display_capture_error_state(struct drm_device *dev) + error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i)); + } + +- error->pipe[i].conf = I915_READ(PIPECONF(cpu_transcoder)); + error->pipe[i].source = I915_READ(PIPESRC(i)); +- error->pipe[i].htotal = I915_READ(HTOTAL(cpu_transcoder)); +- error->pipe[i].hblank = I915_READ(HBLANK(cpu_transcoder)); +- error->pipe[i].hsync = I915_READ(HSYNC(cpu_transcoder)); +- error->pipe[i].vtotal = I915_READ(VTOTAL(cpu_transcoder)); +- error->pipe[i].vblank = I915_READ(VBLANK(cpu_transcoder)); +- error->pipe[i].vsync = I915_READ(VSYNC(cpu_transcoder)); ++ } ++ ++ error->num_transcoders = INTEL_INFO(dev)->num_pipes; ++ if (HAS_DDI(dev_priv->dev)) ++ error->num_transcoders++; /* Account for eDP. */ ++ ++ for (i = 0; i < error->num_transcoders; i++) { ++ enum transcoder cpu_transcoder = transcoders[i]; ++ ++ error->transcoder[i].cpu_transcoder = cpu_transcoder; ++ ++ error->transcoder[i].conf = I915_READ(PIPECONF(cpu_transcoder)); ++ error->transcoder[i].htotal = I915_READ(HTOTAL(cpu_transcoder)); ++ error->transcoder[i].hblank = I915_READ(HBLANK(cpu_transcoder)); ++ error->transcoder[i].hsync = I915_READ(HSYNC(cpu_transcoder)); ++ error->transcoder[i].vtotal = I915_READ(VTOTAL(cpu_transcoder)); ++ error->transcoder[i].vblank = I915_READ(VBLANK(cpu_transcoder)); ++ error->transcoder[i].vsync = I915_READ(VSYNC(cpu_transcoder)); + } + + /* In the code above we read the registers without checking if the power +@@ -10148,22 +10170,16 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m, + { + int i; + ++ if (!error) ++ return; ++ + err_printf(m, "Num Pipes: %d\n", INTEL_INFO(dev)->num_pipes); + if (HAS_POWER_WELL(dev)) + err_printf(m, "PWR_WELL_CTL2: %08x\n", + error->power_well_driver); + for_each_pipe(i) { + err_printf(m, "Pipe [%d]:\n", i); +- err_printf(m, " CPU transcoder: %c\n", +- transcoder_name(error->pipe[i].cpu_transcoder)); +- err_printf(m, " CONF: %08x\n", error->pipe[i].conf); + err_printf(m, " SRC: %08x\n", error->pipe[i].source); +- err_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal); +- err_printf(m, " HBLANK: %08x\n", error->pipe[i].hblank); +- err_printf(m, " HSYNC: %08x\n", error->pipe[i].hsync); +- err_printf(m, " VTOTAL: %08x\n", error->pipe[i].vtotal); +- err_printf(m, " VBLANK: %08x\n", error->pipe[i].vblank); +- err_printf(m, " VSYNC: %08x\n", error->pipe[i].vsync); + + err_printf(m, "Plane [%d]:\n", i); + err_printf(m, " CNTR: %08x\n", error->plane[i].control); +@@ -10184,5 +10200,17 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m, + err_printf(m, " POS: %08x\n", error->cursor[i].position); + err_printf(m, " BASE: %08x\n", error->cursor[i].base); + } ++ ++ for (i = 0; i < error->num_transcoders; i++) { ++ err_printf(m, " CPU transcoder: %c\n", ++ transcoder_name(error->transcoder[i].cpu_transcoder)); ++ err_printf(m, " CONF: %08x\n", error->transcoder[i].conf); ++ err_printf(m, " HTOTAL: %08x\n", error->transcoder[i].htotal); ++ err_printf(m, " HBLANK: %08x\n", error->transcoder[i].hblank); ++ err_printf(m, " HSYNC: %08x\n", error->transcoder[i].hsync); ++ err_printf(m, " VTOTAL: %08x\n", error->transcoder[i].vtotal); ++ err_printf(m, " VBLANK: %08x\n", error->transcoder[i].vblank); ++ err_printf(m, " VSYNC: %08x\n", error->transcoder[i].vsync); ++ } + } + #endif +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0386-drm-i915-Fix-whitespace-issue-in-i915_gem_gtt.patch b/patches.baytrail/0386-drm-i915-Fix-whitespace-issue-in-i915_gem_gtt.patch new file mode 100644 index 000000000000..13af21c58c08 --- /dev/null +++ b/patches.baytrail/0386-drm-i915-Fix-whitespace-issue-in-i915_gem_gtt.patch @@ -0,0 +1,34 @@ +From 09323567097a7d0077577256c3819aa19b4c925c Mon Sep 17 00:00:00 2001 +From: James Ausmus +Date: Fri, 20 Sep 2013 15:40:40 -0700 +Subject: drm/i915: Fix whitespace issue in i915_gem_gtt + +This fixes the whitespace issue fixed up in the merge commit +e1b73cba13a0cc68dd4f746eced15bd6bb24cda4 ("Merge tag 'v3.10-rc2' into +drm-intel-next-queued") + +Signed-off-by: James Ausmus +(cherry picked from + https://chromium.googlesource.com/chromiumos/third_party/kernel-next + chromeos-3.10, 7ba2021ae44ef8d64d3d79b0b5f9e096395f160a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 95acae13b059..5101ab6869b4 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -269,7 +269,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) + /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 + * entries. For aliasing ppgtt support we just steal them at the end for + * now. */ +- first_pd_entry_in_global_pt = gtt_total_entries(dev_priv->gtt); ++ first_pd_entry_in_global_pt = gtt_total_entries(dev_priv->gtt); + + if (IS_HASWELL(dev)) { + ppgtt->pte_encode = hsw_pte_encode; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0387-drm-i915-invert-the-verbosity-of-intel_enable_fbc.patch b/patches.baytrail/0387-drm-i915-invert-the-verbosity-of-intel_enable_fbc.patch new file mode 100644 index 000000000000..fd1f23068e10 --- /dev/null +++ b/patches.baytrail/0387-drm-i915-invert-the-verbosity-of-intel_enable_fbc.patch @@ -0,0 +1,47 @@ +From 922bc2ad079155a1463179513bf881308329c070 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Wed, 12 Jun 2013 17:27:29 -0300 +Subject: drm/i915: invert the verbosity of intel_enable_fbc + +We currently print a DRM_DEBUG_KMS message on the happy path and don't +print anything on the "failed to allocate" path. On some desktop +environments (e.g., Unity) I see the "scheduling delayed FBC enable" +thousands and thousands of times on my dmesg. + +So kill the useless message for the happy case, saving a lot of dmesg +space, and properly signal the "kzalloc fail" case. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Zoltan Nyul +Signed-off-by: Daniel Vetter +(cherry picked from commit 6cdcb5e73fba29bf115f2677c59de63f95039e2b) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index b0e4a0bd1313..bd7e682e12aa 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -381,6 +381,7 @@ void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + + work = kzalloc(sizeof *work, GFP_KERNEL); + if (work == NULL) { ++ DRM_ERROR("Failed to allocate FBC work structure\n"); + dev_priv->display.enable_fbc(crtc, interval); + return; + } +@@ -392,8 +393,6 @@ void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + + dev_priv->fbc_work = work; + +- DRM_DEBUG_KMS("scheduling delayed FBC enable\n"); +- + /* Delay the actual enabling to let pageflipping cease and the + * display to settle before starting the compression. Note that + * this delay also serves a second purpose: it allows for a +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0388-drm-i915-Make-intel_enable_fbc-static.patch b/patches.baytrail/0388-drm-i915-Make-intel_enable_fbc-static.patch new file mode 100644 index 000000000000..7c8caba7ca9f --- /dev/null +++ b/patches.baytrail/0388-drm-i915-Make-intel_enable_fbc-static.patch @@ -0,0 +1,45 @@ +From 9425689ff1a2042db266d2f00b0dfef22b9eb483 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 24 Jun 2013 16:22:01 +0100 +Subject: drm/i915: Make intel_enable_fbc() static + +This function has no user outside of intel_pm.c. + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit b63fb44c65ac37ceac8acd258939fcdc9f223c42) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_drv.h | 1 - + drivers/gpu/drm/i915/intel_pm.c | 2 +- + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index b7d6e09456ce..d03c2c8a06b1 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -780,7 +780,6 @@ extern int intel_sprite_get_colorkey(struct drm_device *dev, void *data, + extern void intel_init_pm(struct drm_device *dev); + /* FBC */ + extern bool intel_fbc_enabled(struct drm_device *dev); +-extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); + extern void intel_update_fbc(struct drm_device *dev); + /* IPS */ + extern void intel_gpu_ips_init(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 bd7e682e12aa..692ebc89df17 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -368,7 +368,7 @@ static void intel_cancel_fbc_work(struct drm_i915_private *dev_priv) + dev_priv->fbc_work = NULL; + } + +-void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) ++static void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + { + struct intel_fbc_work *work; + struct drm_device *dev = crtc->dev; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0389-drm-i915-Fix-reason-for-per-chip-disabling-of-FBC.patch b/patches.baytrail/0389-drm-i915-Fix-reason-for-per-chip-disabling-of-FBC.patch new file mode 100644 index 000000000000..29eb3c516ca1 --- /dev/null +++ b/patches.baytrail/0389-drm-i915-Fix-reason-for-per-chip-disabling-of-FBC.patch @@ -0,0 +1,89 @@ +From 112f55523a93f5ab380c312344ed96b2ddd5fdca Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 24 Jun 2013 16:22:02 +0100 +Subject: drm/i915: Fix reason for per-chip disabling of FBC + +When running on my snb machine, recent kernels display successively: + +[drm:intel_update_fbc], fbc set to per-chip default +[drm:intel_update_fbc], fbc disabled per module param + +But no module param is set. This happens because the check for the +module parameter uses a variable that has been overridden inside the +"per-chip default" code. + +Fix up the logic and add another reason for the FBC to the be disabled. + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 8a5729a37375c20a196e14ce49b4390d42bdb87b) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 3 +++ + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/intel_pm.c | 14 ++++++-------- + 3 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 47d6c748057e..dca49828e3fc 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1518,6 +1518,9 @@ static int i915_fbc_status(struct seq_file *m, void *unused) + case FBC_MODULE_PARAM: + seq_printf(m, "disabled per module param (default off)"); + break; ++ case FBC_CHIP_DEFAULT: ++ seq_printf(m, "disabled per chip default"); ++ break; + default: + seq_printf(m, "unknown reason"); + } +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 1929bffc1c77..9ad49335e808 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -537,6 +537,7 @@ enum no_fbc_reason { + FBC_NOT_TILED, /* buffer not tiled */ + FBC_MULTIPLE_PIPES, /* more than one pipe active */ + FBC_MODULE_PARAM, ++ FBC_CHIP_DEFAULT, /* disabled by default on this chip */ + }; + + enum intel_pch { +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 692ebc89df17..941af917388b 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -447,7 +447,6 @@ void intel_update_fbc(struct drm_device *dev) + struct drm_framebuffer *fb; + struct intel_framebuffer *intel_fb; + struct drm_i915_gem_object *obj; +- int enable_fbc; + unsigned int max_hdisplay, max_vdisplay; + + if (!i915_powersave) +@@ -488,14 +487,13 @@ void intel_update_fbc(struct drm_device *dev) + intel_fb = to_intel_framebuffer(fb); + obj = intel_fb->obj; + +- enable_fbc = i915_enable_fbc; +- if (enable_fbc < 0) { +- DRM_DEBUG_KMS("fbc set to per-chip default\n"); +- enable_fbc = 1; +- if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) +- enable_fbc = 0; ++ if (i915_enable_fbc < 0 && ++ INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) { ++ DRM_DEBUG_KMS("disabled per chip default\n"); ++ dev_priv->no_fbc_reason = FBC_CHIP_DEFAULT; ++ goto out_disable; + } +- if (!enable_fbc) { ++ if (!i915_enable_fbc) { + DRM_DEBUG_KMS("fbc disabled per module param\n"); + dev_priv->no_fbc_reason = FBC_MODULE_PARAM; + goto out_disable; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0390-drm-i915-Use-seq_puts-seq_putc-when-possible.patch b/patches.baytrail/0390-drm-i915-Use-seq_puts-seq_putc-when-possible.patch new file mode 100644 index 000000000000..dad17e753457 --- /dev/null +++ b/patches.baytrail/0390-drm-i915-Use-seq_puts-seq_putc-when-possible.patch @@ -0,0 +1,342 @@ +From 5e7ecc7c730ed71c82383a66afb87307e5f5b7dd Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 24 Jun 2013 22:59:48 +0100 +Subject: drm/i915: Use seq_puts/seq_putc when possible +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Caught with checkpatch.pl. + +Suggested-by: Daniel Vetter +Signed-off-by: Damien Lespiau +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 267f0c90ac6728f70fade74ab89932a00e5e5a7e) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 110 ++++++++++++++++++------------------ + 1 file changed, 55 insertions(+), 55 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index dca49828e3fc..b1e91f33e377 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -157,11 +157,11 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) + + switch (list) { + case ACTIVE_LIST: +- seq_printf(m, "Active:\n"); ++ seq_puts(m, "Active:\n"); + head = &dev_priv->mm.active_list; + break; + case INACTIVE_LIST: +- seq_printf(m, "Inactive:\n"); ++ seq_puts(m, "Inactive:\n"); + head = &dev_priv->mm.inactive_list; + break; + default: +@@ -171,9 +171,9 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) + + total_obj_size = total_gtt_size = count = 0; + list_for_each_entry(obj, head, mm_list) { +- seq_printf(m, " "); ++ seq_puts(m, " "); + describe_obj(m, obj); +- seq_printf(m, "\n"); ++ seq_putc(m, '\n'); + total_obj_size += obj->base.size; + total_gtt_size += obj->gtt_space->size; + count++; +@@ -290,7 +290,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data) + dev_priv->gtt.total, + dev_priv->gtt.mappable_end - dev_priv->gtt.start); + +- seq_printf(m, "\n"); ++ seq_putc(m, '\n'); + list_for_each_entry_reverse(file, &dev->filelist, lhead) { + struct file_stats stats; + +@@ -329,9 +329,9 @@ static int i915_gem_gtt_info(struct seq_file *m, void* data) + if (list == PINNED_LIST && obj->pin_count == 0) + continue; + +- seq_printf(m, " "); ++ seq_puts(m, " "); + describe_obj(m, obj); +- seq_printf(m, "\n"); ++ seq_putc(m, '\n'); + total_obj_size += obj->base.size; + total_gtt_size += obj->gtt_space->size; + count++; +@@ -371,9 +371,9 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) + pipe, plane); + } + if (work->enable_stall_check) +- seq_printf(m, "Stall check enabled, "); ++ seq_puts(m, "Stall check enabled, "); + else +- seq_printf(m, "Stall check waiting for page flip ioctl, "); ++ seq_puts(m, "Stall check waiting for page flip ioctl, "); + seq_printf(m, "%d prepares\n", atomic_read(&work->pending)); + + if (work->old_fb_obj) { +@@ -424,7 +424,7 @@ static int i915_gem_request_info(struct seq_file *m, void *data) + mutex_unlock(&dev->struct_mutex); + + if (count == 0) +- seq_printf(m, "No requests\n"); ++ seq_puts(m, "No requests\n"); + + return 0; + } +@@ -574,10 +574,10 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) + seq_printf(m, "Fence %d, pin count = %d, object = ", + i, dev_priv->fence_regs[i].pin_count); + if (obj == NULL) +- seq_printf(m, "unused"); ++ seq_puts(m, "unused"); + else + describe_obj(m, obj); +- seq_printf(m, "\n"); ++ seq_putc(m, '\n'); + } + + mutex_unlock(&dev->struct_mutex); +@@ -1246,7 +1246,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) + (freq_sts >> 8) & 0xff)); + mutex_unlock(&dev_priv->rps.hw_lock); + } else { +- seq_printf(m, "no P-state info available\n"); ++ seq_puts(m, "no P-state info available\n"); + } + + return 0; +@@ -1341,28 +1341,28 @@ static int ironlake_drpc_info(struct seq_file *m) + seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f)); + seq_printf(m, "Render standby enabled: %s\n", + (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes"); +- seq_printf(m, "Current RS state: "); ++ seq_puts(m, "Current RS state: "); + switch (rstdbyctl & RSX_STATUS_MASK) { + case RSX_STATUS_ON: +- seq_printf(m, "on\n"); ++ seq_puts(m, "on\n"); + break; + case RSX_STATUS_RC1: +- seq_printf(m, "RC1\n"); ++ seq_puts(m, "RC1\n"); + break; + case RSX_STATUS_RC1E: +- seq_printf(m, "RC1E\n"); ++ seq_puts(m, "RC1E\n"); + break; + case RSX_STATUS_RS1: +- seq_printf(m, "RS1\n"); ++ seq_puts(m, "RS1\n"); + break; + case RSX_STATUS_RS2: +- seq_printf(m, "RS2 (RC6)\n"); ++ seq_puts(m, "RS2 (RC6)\n"); + break; + case RSX_STATUS_RS3: +- seq_printf(m, "RC3 (RC6+)\n"); ++ seq_puts(m, "RC3 (RC6+)\n"); + break; + default: +- seq_printf(m, "unknown\n"); ++ seq_puts(m, "unknown\n"); + break; + } + +@@ -1389,8 +1389,8 @@ static int gen6_drpc_info(struct seq_file *m) + spin_unlock_irq(&dev_priv->gt_lock); + + if (forcewake_count) { +- seq_printf(m, "RC information inaccurate because somebody " +- "holds a forcewake reference \n"); ++ seq_puts(m, "RC information inaccurate because somebody " ++ "holds a forcewake reference \n"); + } else { + /* NB: we cannot use forcewake, else we read the wrong values */ + while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) +@@ -1423,25 +1423,25 @@ static int gen6_drpc_info(struct seq_file *m) + yesno(rcctl1 & GEN6_RC_CTL_RC6p_ENABLE)); + seq_printf(m, "Deepest RC6 Enabled: %s\n", + yesno(rcctl1 & GEN6_RC_CTL_RC6pp_ENABLE)); +- seq_printf(m, "Current RC state: "); ++ seq_puts(m, "Current RC state: "); + switch (gt_core_status & GEN6_RCn_MASK) { + case GEN6_RC0: + if (gt_core_status & GEN6_CORE_CPD_STATE_MASK) +- seq_printf(m, "Core Power Down\n"); ++ seq_puts(m, "Core Power Down\n"); + else +- seq_printf(m, "on\n"); ++ seq_puts(m, "on\n"); + break; + case GEN6_RC3: +- seq_printf(m, "RC3\n"); ++ seq_puts(m, "RC3\n"); + break; + case GEN6_RC6: +- seq_printf(m, "RC6\n"); ++ seq_puts(m, "RC6\n"); + break; + case GEN6_RC7: +- seq_printf(m, "RC7\n"); ++ seq_puts(m, "RC7\n"); + break; + default: +- seq_printf(m, "Unknown\n"); ++ seq_puts(m, "Unknown\n"); + break; + } + +@@ -1485,46 +1485,46 @@ static int i915_fbc_status(struct seq_file *m, void *unused) + drm_i915_private_t *dev_priv = dev->dev_private; + + if (!I915_HAS_FBC(dev)) { +- seq_printf(m, "FBC unsupported on this chipset\n"); ++ seq_puts(m, "FBC unsupported on this chipset\n"); + return 0; + } + + if (intel_fbc_enabled(dev)) { +- seq_printf(m, "FBC enabled\n"); ++ seq_puts(m, "FBC enabled\n"); + } else { +- seq_printf(m, "FBC disabled: "); ++ seq_puts(m, "FBC disabled: "); + switch (dev_priv->no_fbc_reason) { + case FBC_NO_OUTPUT: +- seq_printf(m, "no outputs"); ++ seq_puts(m, "no outputs"); + break; + case FBC_STOLEN_TOO_SMALL: +- seq_printf(m, "not enough stolen memory"); ++ seq_puts(m, "not enough stolen memory"); + break; + case FBC_UNSUPPORTED_MODE: +- seq_printf(m, "mode not supported"); ++ seq_puts(m, "mode not supported"); + break; + case FBC_MODE_TOO_LARGE: +- seq_printf(m, "mode too large"); ++ seq_puts(m, "mode too large"); + break; + case FBC_BAD_PLANE: +- seq_printf(m, "FBC unsupported on plane"); ++ seq_puts(m, "FBC unsupported on plane"); + break; + case FBC_NOT_TILED: +- seq_printf(m, "scanout buffer not tiled"); ++ seq_puts(m, "scanout buffer not tiled"); + break; + case FBC_MULTIPLE_PIPES: +- seq_printf(m, "multiple pipes are enabled"); ++ seq_puts(m, "multiple pipes are enabled"); + break; + case FBC_MODULE_PARAM: +- seq_printf(m, "disabled per module param (default off)"); ++ seq_puts(m, "disabled per module param (default off)"); + break; + case FBC_CHIP_DEFAULT: +- seq_printf(m, "disabled per chip default"); ++ seq_puts(m, "disabled per chip default"); + break; + default: +- seq_printf(m, "unknown reason"); ++ seq_puts(m, "unknown reason"); + } +- seq_printf(m, "\n"); ++ seq_putc(m, '\n'); + } + return 0; + } +@@ -1607,7 +1607,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) + int gpu_freq, ia_freq; + + if (!(IS_GEN6(dev) || IS_GEN7(dev))) { +- seq_printf(m, "unsupported on this chipset\n"); ++ seq_puts(m, "unsupported on this chipset\n"); + return 0; + } + +@@ -1615,7 +1615,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) + if (ret) + return ret; + +- seq_printf(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n"); ++ seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n"); + + for (gpu_freq = dev_priv->rps.min_delay; + gpu_freq <= dev_priv->rps.max_delay; +@@ -1704,7 +1704,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) + fb->base.bits_per_pixel, + atomic_read(&fb->base.refcount.refcount)); + describe_obj(m, fb->obj); +- seq_printf(m, "\n"); ++ seq_putc(m, '\n'); + mutex_unlock(&dev->mode_config.mutex); + + mutex_lock(&dev->mode_config.fb_lock); +@@ -1719,7 +1719,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) + fb->base.bits_per_pixel, + atomic_read(&fb->base.refcount.refcount)); + describe_obj(m, fb->obj); +- seq_printf(m, "\n"); ++ seq_putc(m, '\n'); + } + mutex_unlock(&dev->mode_config.fb_lock); + +@@ -1739,22 +1739,22 @@ static int i915_context_status(struct seq_file *m, void *unused) + return ret; + + if (dev_priv->ips.pwrctx) { +- seq_printf(m, "power context "); ++ seq_puts(m, "power context "); + describe_obj(m, dev_priv->ips.pwrctx); +- seq_printf(m, "\n"); ++ seq_putc(m, '\n'); + } + + if (dev_priv->ips.renderctx) { +- seq_printf(m, "render context "); ++ seq_puts(m, "render context "); + describe_obj(m, dev_priv->ips.renderctx); +- seq_printf(m, "\n"); ++ seq_putc(m, '\n'); + } + + for_each_ring(ring, dev_priv, i) { + if (ring->default_context) { + seq_printf(m, "HW default context %s ring ", ring->name); + describe_obj(m, ring->default_context->obj); +- seq_printf(m, "\n"); ++ seq_putc(m, '\n'); + } + } + +@@ -1871,7 +1871,7 @@ static int i915_ppgtt_info(struct seq_file *m, void *data) + if (dev_priv->mm.aliasing_ppgtt) { + struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; + +- seq_printf(m, "aliasing PPGTT:\n"); ++ seq_puts(m, "aliasing PPGTT:\n"); + seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset); + } + seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK)); +@@ -1889,7 +1889,7 @@ static int i915_dpio_info(struct seq_file *m, void *data) + + + if (!IS_VALLEYVIEW(dev)) { +- seq_printf(m, "unsupported\n"); ++ seq_puts(m, "unsupported\n"); + return 0; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0391-drm-i915-Fix-a-few-style-issues-found-by-checkpatch..patch b/patches.baytrail/0391-drm-i915-Fix-a-few-style-issues-found-by-checkpatch..patch new file mode 100644 index 000000000000..f619fbb887e2 --- /dev/null +++ b/patches.baytrail/0391-drm-i915-Fix-a-few-style-issues-found-by-checkpatch..patch @@ -0,0 +1,64 @@ +From bfaa03679330bba834611cc9a79c733a6c4fc1f2 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 24 Jun 2013 22:59:49 +0100 +Subject: drm/i915: Fix a few style issues found by checkpatch.pl +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Missing spaces and misplaced '*'. + +Signed-off-by: Damien Lespiau +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit aee56cff333d15e14c5bb2ff3b1e5c7cd15c3805) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index b1e91f33e377..c16926ca15be 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -222,7 +222,7 @@ static int per_file_stats(int id, void *ptr, void *data) + return 0; + } + +-static int i915_gem_object_info(struct seq_file *m, void* data) ++static int i915_gem_object_info(struct seq_file *m, void *data) + { + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; +@@ -310,7 +310,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data) + return 0; + } + +-static int i915_gem_gtt_info(struct seq_file *m, void* data) ++static int i915_gem_gtt_info(struct seq_file *m, void *data) + { + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; +@@ -1377,8 +1377,7 @@ static int gen6_drpc_info(struct seq_file *m) + struct drm_i915_private *dev_priv = dev->dev_private; + u32 rpmodectl1, gt_core_status, rcctl1, rc6vids = 0; + unsigned forcewake_count; +- int count=0, ret; +- ++ int count = 0, ret; + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) +@@ -1781,7 +1780,7 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) + + static const char *swizzle_string(unsigned swizzle) + { +- switch(swizzle) { ++ switch (swizzle) { + case I915_BIT_6_SWIZZLE_NONE: + return "none"; + case I915_BIT_6_SWIZZLE_9: +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0392-drm-i915-Fix-a-couple-of-should-it-be-static-sparse-.patch b/patches.baytrail/0392-drm-i915-Fix-a-couple-of-should-it-be-static-sparse-.patch new file mode 100644 index 000000000000..13e52317447d --- /dev/null +++ b/patches.baytrail/0392-drm-i915-Fix-a-couple-of-should-it-be-static-sparse-.patch @@ -0,0 +1,47 @@ +From cb11cdbd87e83fed0cfe774604b11873dde3d3fe Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 24 Jun 2013 22:59:50 +0100 +Subject: drm/i915: Fix a couple of "should it be static?" sparse warnings +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A genuine 'static' omission and 2 other warnings triggered by not +including the header where those functions where defined. + +Signed-off-by: Damien Lespiau +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit f4db9321a77258587d70cccdd4ff556df48eba2e) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 941af917388b..217e5dd1b8ff 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -30,6 +30,7 @@ + #include "intel_drv.h" + #include "../../../platform/x86/intel_ips.h" + #include ++#include + + #define FORCEWAKE_ACK_TIMEOUT_MS 2 + +@@ -2465,8 +2466,8 @@ static void hsw_compute_wm_results(struct drm_device *dev, + + /* Find the result with the highest level enabled. Check for enable_fbc_wm in + * case both are at the same level. Prefer r1 in case they're the same. */ +-struct hsw_wm_values *hsw_find_best_result(struct hsw_wm_values *r1, +- struct hsw_wm_values *r2) ++static struct hsw_wm_values *hsw_find_best_result(struct hsw_wm_values *r1, ++ struct hsw_wm_values *r2) + { + int i, val_r1 = 0, val_r2 = 0; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0393-drm-i915-Bail-out-once-we-ve-found-the-context-objec.patch b/patches.baytrail/0393-drm-i915-Bail-out-once-we-ve-found-the-context-objec.patch new file mode 100644 index 000000000000..4d6f0950e9d2 --- /dev/null +++ b/patches.baytrail/0393-drm-i915-Bail-out-once-we-ve-found-the-context-objec.patch @@ -0,0 +1,32 @@ +From 7f5fb26d47788591bb68203917bb57971a6ec2f1 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 24 Jun 2013 14:54:50 +0100 +Subject: drm/i915: Bail out once we've found the context object + +Once we've found the the context object programmed in CCID, there's no +need to look the other objects in the list. + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 3ef8fb5ae296c3b626b87ec1422aeb66dd338ee8) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 7748dce240d8..6df227352fd3 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1839,6 +1839,7 @@ static void i915_gem_record_active_context(struct intel_ring_buffer *ring, + if ((error->ccid & PAGE_MASK) == obj->gtt_offset) { + ering->ctx = i915_error_object_create_sized(dev_priv, + obj, 1); ++ break; + } + } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0394-drm-i915-consolidate-pch-pll-enable-sequence.patch b/patches.baytrail/0394-drm-i915-consolidate-pch-pll-enable-sequence.patch new file mode 100644 index 000000000000..ba300962d488 --- /dev/null +++ b/patches.baytrail/0394-drm-i915-consolidate-pch-pll-enable-sequence.patch @@ -0,0 +1,207 @@ +From db2baccdbf1f9a5a60c4f117b9d9d1739ea843d4 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:23 +0200 +Subject: drm/i915: consolidate pch pll enable sequence + +It's been splattered over 3 different places all doing random things. +Now we have (mostly) the same sequence as i8xx/i9xx, but all called +from the crtc_enable hook (through the pll->enable function): +- write new dividers +- enable vco and wait for stable clocks +- write again for the pixel mutliplier + +I've left the seemingly random 200 usec delay in there, just in case. + +Also move the encoder->pre_pll_enable hook into the crtc_enable +function, at the same spot we currently have a hack to enable the lvds +port. Since that hack is now redundant, kill it. + +While doing this patch I've learned the hard way that we can only fire +up the LVDS port if both the pch dpll _and_ the fdi rc pll are not yet +enabled. Otherwise things go haywire, at least on cpt. + +v2: It is paramount to write the FPx divisors before we enable the +the vco by writing to the DPLL registers, for otherwise the divisors +won't get updated. This is in line with the i8xx/i9xx dpll. + +v3: To keep the nice abstraction add a ->mode_set callback to set the +divisors. Also streamline the enabling/disabling code a bit by +removing some cargo-cult duplication and clearing registers where +possible in the ->disable hook. + +v4: Remove now unused local variable. + +Acked-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 15bdd4cff43104cc0692f8694019c043cf19d102) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 + + drivers/gpu/drm/i915/intel_display.c | 75 +++++++++++++----------------------- + 2 files changed, 29 insertions(+), 48 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 9ad49335e808..6a45c0539d7d 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -156,6 +156,8 @@ struct intel_shared_dpll { + /* should match the index in the dev_priv->shared_dplls array */ + enum intel_dpll_id id; + struct intel_dpll_hw_state hw_state; ++ void (*mode_set)(struct drm_i915_private *dev_priv, ++ struct intel_shared_dpll *pll); + void (*enable)(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll); + void (*disable)(struct drm_i915_private *dev_priv, +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index bde6a5547568..d1d7b77de30b 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3096,13 +3096,7 @@ found: + WARN_ON(pll->on); + assert_shared_dpll_disabled(dev_priv, pll); + +- /* Wait for the clocks to stabilize before rewriting the regs */ +- I915_WRITE(PCH_DPLL(pll->id), dpll & ~DPLL_VCO_ENABLE); +- POSTING_READ(PCH_DPLL(pll->id)); +- udelay(150); +- +- I915_WRITE(PCH_FP0(pll->id), fp); +- I915_WRITE(PCH_DPLL(pll->id), dpll & ~DPLL_VCO_ENABLE); ++ pll->mode_set(dev_priv, pll); + } + pll->refcount++; + +@@ -3174,7 +3168,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + struct intel_encoder *encoder; + int pipe = intel_crtc->pipe; + int plane = intel_crtc->plane; +- u32 temp; + + WARN_ON(!crtc->enabled); + +@@ -3188,12 +3181,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + + intel_update_watermarks(dev); + +- if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { +- temp = I915_READ(PCH_LVDS); +- if ((temp & LVDS_PORT_EN) == 0) +- I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN); +- } +- ++ for_each_encoder_on_crtc(dev, crtc, encoder) ++ if (encoder->pre_pll_enable) ++ encoder->pre_pll_enable(encoder); + + if (intel_crtc->config.has_pch_encoder) { + /* Note: FDI PLL enabling _must_ be done before we enable the +@@ -5720,10 +5710,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + if (intel_crtc->config.has_dp_encoder) + intel_dp_set_m_n(intel_crtc); + +- for_each_encoder_on_crtc(dev, crtc, encoder) +- if (encoder->pre_pll_enable) +- encoder->pre_pll_enable(encoder); +- + if (is_lvds && has_reduced_clock && i915_powersave) + intel_crtc->lowfreq_avail = true; + else +@@ -5732,23 +5718,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + if (intel_crtc->config.has_pch_encoder) { + pll = intel_crtc_to_shared_dpll(intel_crtc); + +- I915_WRITE(PCH_DPLL(pll->id), dpll); +- +- /* Wait for the clocks to stabilize. */ +- POSTING_READ(PCH_DPLL(pll->id)); +- udelay(150); +- +- /* The pixel multiplier can only be updated once the +- * DPLL is enabled and the clocks are stable. +- * +- * So write it again. +- */ +- I915_WRITE(PCH_DPLL(pll->id), dpll); +- +- if (has_reduced_clock) +- I915_WRITE(PCH_FP1(pll->id), fp2); +- else +- I915_WRITE(PCH_FP1(pll->id), fp); + } + + intel_set_pipe_timings(intel_crtc); +@@ -8808,19 +8777,32 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv, + return val & DPLL_VCO_ENABLE; + } + ++static void ibx_pch_dpll_mode_set(struct drm_i915_private *dev_priv, ++ struct intel_shared_dpll *pll) ++{ ++ I915_WRITE(PCH_FP0(pll->id), pll->hw_state.fp0); ++ I915_WRITE(PCH_FP1(pll->id), pll->hw_state.fp1); ++} ++ + static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) + { +- uint32_t reg, val; +- + /* PCH refclock must be enabled first */ + assert_pch_refclk_enabled(dev_priv); + +- reg = PCH_DPLL(pll->id); +- val = I915_READ(reg); +- val |= DPLL_VCO_ENABLE; +- I915_WRITE(reg, val); +- POSTING_READ(reg); ++ I915_WRITE(PCH_DPLL(pll->id), pll->hw_state.dpll); ++ ++ /* Wait for the clocks to stabilize. */ ++ POSTING_READ(PCH_DPLL(pll->id)); ++ udelay(150); ++ ++ /* The pixel multiplier can only be updated once the ++ * DPLL is enabled and the clocks are stable. ++ * ++ * So write it again. ++ */ ++ I915_WRITE(PCH_DPLL(pll->id), pll->hw_state.dpll); ++ POSTING_READ(PCH_DPLL(pll->id)); + udelay(200); + } + +@@ -8829,7 +8811,6 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv, + { + struct drm_device *dev = dev_priv->dev; + struct intel_crtc *crtc; +- uint32_t reg, val; + + /* Make sure no transcoder isn't still depending on us. */ + list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { +@@ -8837,11 +8818,8 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv, + assert_pch_transcoder_disabled(dev_priv, crtc->pipe); + } + +- reg = PCH_DPLL(pll->id); +- val = I915_READ(reg); +- val &= ~DPLL_VCO_ENABLE; +- I915_WRITE(reg, val); +- POSTING_READ(reg); ++ I915_WRITE(PCH_DPLL(pll->id), 0); ++ POSTING_READ(PCH_DPLL(pll->id)); + udelay(200); + } + +@@ -8860,6 +8838,7 @@ static void ibx_pch_dpll_init(struct drm_device *dev) + for (i = 0; i < dev_priv->num_shared_dpll; i++) { + dev_priv->shared_dplls[i].id = i; + dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i]; ++ dev_priv->shared_dplls[i].mode_set = ibx_pch_dpll_mode_set; + dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable; + dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable; + dev_priv->shared_dplls[i].get_hw_state = +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0395-drm-i915-use-sw-tracked-state-to-select-shared-dplls.patch b/patches.baytrail/0395-drm-i915-use-sw-tracked-state-to-select-shared-dplls.patch new file mode 100644 index 000000000000..a802177aeedf --- /dev/null +++ b/patches.baytrail/0395-drm-i915-use-sw-tracked-state-to-select-shared-dplls.patch @@ -0,0 +1,54 @@ +From 3b87da7f4c6bf7a9d0ae23d1d63e509e0c757468 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:24 +0200 +Subject: drm/i915: use sw tracked state to select shared dplls + +Just yet another prep step to be able to do all this up-front, before +we've set up any of the shared dplls in the new state. This will +eventually be useful for atomic modesetting. + +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit b89a1d395bf8bd209f1e14265c5b1d34c4a98d57) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index d1d7b77de30b..60ae6d3c6d16 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3031,7 +3031,7 @@ static void intel_put_shared_dpll(struct intel_crtc *crtc) + crtc->config.shared_dpll = DPLL_ID_PRIVATE; + } + +-static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, u32 dpll, u32 fp) ++static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) + { + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); +@@ -3061,8 +3061,8 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, + if (pll->refcount == 0) + continue; + +- if (dpll == (I915_READ(PCH_DPLL(pll->id)) & 0x7fffffff) && +- fp == I915_READ(PCH_FP0(pll->id))) { ++ if (memcmp(&crtc->config.dpll_hw_state, &pll->hw_state, ++ sizeof(pll->hw_state)) == 0) { + DRM_DEBUG_KMS("CRTC:%d sharing existing %s (refcount %d, ative %d)\n", + crtc->base.base.id, + pll->name, pll->refcount, pll->active); +@@ -5698,7 +5698,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, + else + intel_crtc->config.dpll_hw_state.fp1 = fp; + +- pll = intel_get_shared_dpll(intel_crtc, dpll, fp); ++ pll = intel_get_shared_dpll(intel_crtc); + if (pll == NULL) { + DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", + pipe_name(pipe)); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0396-drm-i915-duplicate-intel_enable_pll-into-i9xx-and-vl.patch b/patches.baytrail/0396-drm-i915-duplicate-intel_enable_pll-into-i9xx-and-vl.patch new file mode 100644 index 000000000000..8514f02ef327 --- /dev/null +++ b/patches.baytrail/0396-drm-i915-duplicate-intel_enable_pll-into-i9xx-and-vl.patch @@ -0,0 +1,110 @@ +From 7259cc8ab017834f2307de356b9fa91629e2e266 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 6 Jun 2013 00:52:17 +0200 +Subject: drm/i915: duplicate intel_enable_pll into i9xx and vlv versions + +Mostly since I _really_ don't want to touch the vlv hell. + +No code change, just duplication. Also kill a now seriously outdated +code comment - the remark about the dvo encoder is now handled with +the pipe A quirk. + +v2: Update the BUG_ONs as suggested by Jani (both in vlv_ and i9xx_ +functions, since the split happens here). + +Cc: Jani Nikula +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 87442f732bfad16a8b65fb5d86f69bc0417dc9db) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++------------ + 1 file changed, 34 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 60ae6d3c6d16..370c720fd039 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1301,20 +1301,37 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, + assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMID); + } + +-/** +- * intel_enable_pll - enable a PLL +- * @dev_priv: i915 private structure +- * @pipe: pipe PLL to enable +- * +- * Enable @pipe's PLL so we can start pumping pixels from a plane. Check to +- * make sure the PLL reg is writable first though, since the panel write +- * protect mechanism may be enabled. +- * +- * Note! This is for pre-ILK only. +- * +- * Unfortunately needed by dvo_ns2501 since the dvo depends on it running. +- */ +-static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) ++static void vlv_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) ++{ ++ int reg; ++ u32 val; ++ ++ assert_pipe_disabled(dev_priv, pipe); ++ ++ /* No really, not for ILK+ */ ++ BUG_ON(!IS_VALLEYVIEW(dev_priv->dev)); ++ ++ /* PLL is protected by panel, make sure we can write it */ ++ if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev)) ++ assert_panel_unlocked(dev_priv, pipe); ++ ++ reg = DPLL(pipe); ++ val = I915_READ(reg); ++ val |= DPLL_VCO_ENABLE; ++ ++ /* We do this three times for luck */ ++ I915_WRITE(reg, val); ++ POSTING_READ(reg); ++ udelay(150); /* wait for warmup */ ++ I915_WRITE(reg, val); ++ POSTING_READ(reg); ++ udelay(150); /* wait for warmup */ ++ I915_WRITE(reg, val); ++ POSTING_READ(reg); ++ udelay(150); /* wait for warmup */ ++} ++ ++static void i9xx_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) + { + int reg; + u32 val; +@@ -1322,7 +1339,7 @@ static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) + assert_pipe_disabled(dev_priv, pipe); + + /* No really, not for ILK+ */ +- BUG_ON(!IS_VALLEYVIEW(dev_priv->dev) && dev_priv->info->gen >= 5); ++ BUG_ON(dev_priv->info->gen >= 5); + + /* PLL is protected by panel, make sure we can write it */ + if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev)) +@@ -3589,7 +3606,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) + if (encoder->pre_pll_enable) + encoder->pre_pll_enable(encoder); + +- intel_enable_pll(dev_priv, pipe); ++ vlv_enable_pll(dev_priv, pipe); + + for_each_encoder_on_crtc(dev, crtc, encoder) + if (encoder->pre_enable) +@@ -3630,7 +3647,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) + intel_crtc->active = true; + intel_update_watermarks(dev); + +- intel_enable_pll(dev_priv, pipe); ++ i9xx_enable_pll(dev_priv, pipe); + + for_each_encoder_on_crtc(dev, crtc, encoder) + if (encoder->pre_enable) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0397-drm-i915-asserts-for-lvds-pre_enable.patch b/patches.baytrail/0397-drm-i915-asserts-for-lvds-pre_enable.patch new file mode 100644 index 000000000000..8566233c4b93 --- /dev/null +++ b/patches.baytrail/0397-drm-i915-asserts-for-lvds-pre_enable.patch @@ -0,0 +1,179 @@ +From b68b60e412a03006f4cae3493a5a0a23fda5eb3f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 16 Jun 2013 21:42:39 +0200 +Subject: drm/i915: asserts for lvds pre_enable + +Lots of bangin my head against the wall^UExperiments have shown that +we really need to enable the lvds port before we enable plls. Strangely +that seems to include the fdi rx pll on the pch. + +Note that the pch pll assert can fire since the lvds port has it's own +special clock source settings in the DPLL register, which means it +will never have a shared dpll (since there's only one LVDS port). + +Anyway, encode this new evidence with a few nice WARNs. + +v2: Incorporate review comments from Imre. +- Explain why lvds can't have a shared dpll. +- Update the WARN output. + +Cc: Imre Deak +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 55607e8aaa86e68ed4f37d072ee9af404cc8a830) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 26 +++++++++++++------------- + drivers/gpu/drm/i915/intel_drv.h | 16 ++++++++++++++++ + drivers/gpu/drm/i915/intel_lvds.c | 17 ++++++++++++----- + 3 files changed, 41 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 370c720fd039..577882646b0f 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -892,8 +892,8 @@ static const char *state_string(bool enabled) + } + + /* Only for pre-ILK configs */ +-static void assert_pll(struct drm_i915_private *dev_priv, +- enum pipe pipe, bool state) ++void assert_pll(struct drm_i915_private *dev_priv, ++ enum pipe pipe, bool state) + { + int reg; + u32 val; +@@ -906,10 +906,8 @@ static void assert_pll(struct drm_i915_private *dev_priv, + "PLL state assertion failure (expected %s, current %s)\n", + state_string(state), state_string(cur_state)); + } +-#define assert_pll_enabled(d, p) assert_pll(d, p, true) +-#define assert_pll_disabled(d, p) assert_pll(d, p, false) + +-static struct intel_shared_dpll * ++struct intel_shared_dpll * + intel_crtc_to_shared_dpll(struct intel_crtc *crtc) + { + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; +@@ -921,9 +919,9 @@ intel_crtc_to_shared_dpll(struct intel_crtc *crtc) + } + + /* For ILK+ */ +-static void assert_shared_dpll(struct drm_i915_private *dev_priv, +- struct intel_shared_dpll *pll, +- bool state) ++void assert_shared_dpll(struct drm_i915_private *dev_priv, ++ struct intel_shared_dpll *pll, ++ bool state) + { + bool cur_state; + struct intel_dpll_hw_state hw_state; +@@ -942,8 +940,6 @@ static void assert_shared_dpll(struct drm_i915_private *dev_priv, + "%s assertion failure (expected %s, current %s)\n", + pll->name, state_string(state), state_string(cur_state)); + } +-#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true) +-#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false) + + static void assert_fdi_tx(struct drm_i915_private *dev_priv, + enum pipe pipe, bool state) +@@ -1007,15 +1003,19 @@ static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv, + WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n"); + } + +-static void assert_fdi_rx_pll_enabled(struct drm_i915_private *dev_priv, +- enum pipe pipe) ++void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, ++ enum pipe pipe, bool state) + { + int reg; + u32 val; ++ bool cur_state; + + reg = FDI_RX_CTL(pipe); + val = I915_READ(reg); +- WARN(!(val & FDI_RX_PLL_ENABLE), "FDI RX PLL assertion failure, should be active but is disabled\n"); ++ cur_state = !!(val & FDI_RX_PLL_ENABLE); ++ WARN(cur_state != state, ++ "FDI RX PLL assertion failure (expected %s, current %s)\n", ++ state_string(state), state_string(cur_state)); + } + + static void assert_panel_unlocked(struct drm_i915_private *dev_priv, +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index d03c2c8a06b1..16ad38fd859d 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -747,6 +747,22 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data, + extern void intel_fb_output_poll_changed(struct drm_device *dev); + extern void intel_fb_restore_mode(struct drm_device *dev); + ++struct intel_shared_dpll * ++intel_crtc_to_shared_dpll(struct intel_crtc *crtc); ++ ++void assert_shared_dpll(struct drm_i915_private *dev_priv, ++ struct intel_shared_dpll *pll, ++ bool state); ++#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true) ++#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false) ++void assert_pll(struct drm_i915_private *dev_priv, ++ enum pipe pipe, bool state); ++#define assert_pll_enabled(d, p) assert_pll(d, p, true) ++#define assert_pll_disabled(d, p) assert_pll(d, p, false) ++void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, ++ enum pipe pipe, bool state); ++#define assert_fdi_rx_pll_enabled(d, p) assert_fdi_rx_pll(d, p, true) ++#define assert_fdi_rx_pll_disabled(d, p) assert_fdi_rx_pll(d, p, false) + extern void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, + bool state); + #define assert_pipe_enabled(d, p) assert_pipe(d, p, true) +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 44533dde25c1..f2a5c898244c 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -127,12 +127,20 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder) + struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); ++ struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); + struct drm_display_mode *fixed_mode = + lvds_encoder->attached_connector->base.panel.fixed_mode; +- int pipe = intel_crtc->pipe; ++ int pipe = crtc->pipe; + u32 temp; + ++ if (HAS_PCH_SPLIT(dev)) { ++ assert_fdi_rx_pll_disabled(dev_priv, pipe); ++ assert_shared_dpll_disabled(dev_priv, ++ intel_crtc_to_shared_dpll(crtc)); ++ } else { ++ assert_pll_disabled(dev_priv, pipe); ++ } ++ + temp = I915_READ(lvds_encoder->reg); + temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; + +@@ -149,7 +157,7 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder) + + /* set the corresponsding LVDS_BORDER bit */ + temp &= ~LVDS_BORDER_ENABLE; +- temp |= intel_crtc->config.gmch_pfit.lvds_border_bits; ++ temp |= crtc->config.gmch_pfit.lvds_border_bits; + /* Set the B0-B3 data pairs corresponding to whether we're going to + * set the DPLLs for dual-channel mode or not. + */ +@@ -169,8 +177,7 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder) + if (INTEL_INFO(dev)->gen == 4) { + /* Bspec wording suggests that LVDS port dithering only exists + * for 18bpp panels. */ +- if (intel_crtc->config.dither && +- intel_crtc->config.pipe_bpp == 18) ++ if (crtc->config.dither && crtc->config.pipe_bpp == 18) + temp |= LVDS_ENABLE_DITHER; + else + temp &= ~LVDS_ENABLE_DITHER; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0398-drm-i915-move-encoder-pre-enable-hooks-togther-on-il.patch b/patches.baytrail/0398-drm-i915-move-encoder-pre-enable-hooks-togther-on-il.patch new file mode 100644 index 000000000000..83f1ed1974da --- /dev/null +++ b/patches.baytrail/0398-drm-i915-move-encoder-pre-enable-hooks-togther-on-il.patch @@ -0,0 +1,54 @@ +From cb814de7106959950cbebe2945925e6818d2db57 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:27 +0200 +Subject: drm/i915: move encoder pre enable hooks togther on ilk+ + +The ->pre_enable hook is only used for the cpu edp port on ilk-ivb, so +we can safely move it up across the fdi pll enabling. + +Unfortunately we can't (yet) merge in the pre_pll enable hook despite +that only lvds uses it on ilk-ivb: Since the same lvds hook is also +need on i9xx platforms we need to fix up the pll enabling sequence +there, too. + +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 952735ee416f686fac55957b221461dfbd80ce1c) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 577882646b0f..e5d24bfb2633 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3198,9 +3198,12 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + + intel_update_watermarks(dev); + +- for_each_encoder_on_crtc(dev, crtc, encoder) ++ for_each_encoder_on_crtc(dev, crtc, encoder) { + if (encoder->pre_pll_enable) + encoder->pre_pll_enable(encoder); ++ if (encoder->pre_enable) ++ encoder->pre_enable(encoder); ++ } + + if (intel_crtc->config.has_pch_encoder) { + /* Note: FDI PLL enabling _must_ be done before we enable the +@@ -3212,10 +3215,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + assert_fdi_rx_disabled(dev_priv, pipe); + } + +- for_each_encoder_on_crtc(dev, crtc, encoder) +- if (encoder->pre_enable) +- encoder->pre_enable(encoder); +- + ironlake_pfit_enable(intel_crtc); + + /* +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0399-drm-i915-hw-state-readout-for-i9xx-dplls.patch b/patches.baytrail/0399-drm-i915-hw-state-readout-for-i9xx-dplls.patch new file mode 100644 index 000000000000..03a4625e0102 --- /dev/null +++ b/patches.baytrail/0399-drm-i915-hw-state-readout-for-i9xx-dplls.patch @@ -0,0 +1,130 @@ +From 5e82822d0eae3c62c013bb93a3468749ac52cd5a Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:28 +0200 +Subject: drm/i915: hw state readout for i9xx dplls + +In addition to existing stuff we also need to track DPLL_MD on gen4 +and vlv. This is prep work so that we can move the dpll enable +sequence out from the ->mode_set callback into the crtc enabling +functions. + +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 8bcc2795a68ad9c2010fd5a2548432fad930fcc1) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/intel_display.c | 20 ++++++++++++++++++++ + 2 files changed, 21 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 6a45c0539d7d..3d98ed475a1f 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -144,6 +144,7 @@ enum intel_dpll_id { + + struct intel_dpll_hw_state { + uint32_t dpll; ++ uint32_t dpll_md; + uint32_t fp0; + uint32_t fp1; + }; +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index e5d24bfb2633..46bbd267e0a7 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4268,14 +4268,17 @@ static void i9xx_update_pll_dividers(struct intel_crtc *crtc, + } + + I915_WRITE(FP0(pipe), fp); ++ crtc->config.dpll_hw_state.fp0 = fp; + + crtc->lowfreq_avail = false; + if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) && + reduced_clock && i915_powersave) { + I915_WRITE(FP1(pipe), fp2); ++ crtc->config.dpll_hw_state.fp1 = fp2; + crtc->lowfreq_avail = true; + } else { + I915_WRITE(FP1(pipe), fp); ++ crtc->config.dpll_hw_state.fp1 = fp; + } + } + +@@ -4453,6 +4456,8 @@ static void vlv_update_pll(struct intel_crtc *crtc) + dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; + + dpll |= DPLL_VCO_ENABLE; ++ crtc->config.dpll_hw_state.dpll = dpll; ++ + I915_WRITE(DPLL(pipe), dpll); + POSTING_READ(DPLL(pipe)); + udelay(150); +@@ -4462,6 +4467,8 @@ static void vlv_update_pll(struct intel_crtc *crtc) + + dpll_md = (crtc->config.pixel_multiplier - 1) + << DPLL_MD_UDI_MULTIPLIER_SHIFT; ++ crtc->config.dpll_hw_state.dpll_md = dpll_md; ++ + I915_WRITE(DPLL_MD(pipe), dpll_md); + POSTING_READ(DPLL_MD(pipe)); + +@@ -4540,6 +4547,8 @@ static void i9xx_update_pll(struct intel_crtc *crtc, + dpll |= PLL_REF_INPUT_DREFCLK; + + dpll |= DPLL_VCO_ENABLE; ++ crtc->config.dpll_hw_state.dpll = dpll; ++ + I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); + POSTING_READ(DPLL(pipe)); + udelay(150); +@@ -4560,6 +4569,8 @@ static void i9xx_update_pll(struct intel_crtc *crtc, + if (INTEL_INFO(dev)->gen >= 4) { + u32 dpll_md = (crtc->config.pixel_multiplier - 1) + << DPLL_MD_UDI_MULTIPLIER_SHIFT; ++ crtc->config.dpll_hw_state.dpll_md = dpll_md; ++ + I915_WRITE(DPLL_MD(pipe), dpll_md); + } else { + /* The pixel multiplier can only be updated once the +@@ -4604,6 +4615,8 @@ static void i8xx_update_pll(struct intel_crtc *crtc, + dpll |= PLL_REF_INPUT_DREFCLK; + + dpll |= DPLL_VCO_ENABLE; ++ crtc->config.dpll_hw_state.dpll = dpll; ++ + I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); + POSTING_READ(DPLL(pipe)); + udelay(150); +@@ -4961,6 +4974,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, + pipe_config->pixel_multiplier = + ((tmp & DPLL_MD_UDI_MULTIPLIER_MASK) + >> DPLL_MD_UDI_MULTIPLIER_SHIFT) + 1; ++ pipe_config->dpll_hw_state.dpll_md = tmp; + } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { + tmp = I915_READ(DPLL(crtc->pipe)); + pipe_config->pixel_multiplier = +@@ -4972,6 +4986,11 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, + * function. */ + pipe_config->pixel_multiplier = 1; + } ++ pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(crtc->pipe)); ++ if (!IS_VALLEYVIEW(dev)) { ++ pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(crtc->pipe)); ++ pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(crtc->pipe)); ++ } + + return true; + } +@@ -8127,6 +8146,7 @@ intel_pipe_config_compare(struct drm_device *dev, + + PIPE_CONF_CHECK_I(shared_dpll); + PIPE_CONF_CHECK_X(dpll_hw_state.dpll); ++ PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md); + PIPE_CONF_CHECK_X(dpll_hw_state.fp0); + PIPE_CONF_CHECK_X(dpll_hw_state.fp1); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0400-drm-i915-move-i9xx-dpll-enabling-into-crtc-enable-fu.patch b/patches.baytrail/0400-drm-i915-move-i9xx-dpll-enabling-into-crtc-enable-fu.patch new file mode 100644 index 000000000000..9a386a2c335e --- /dev/null +++ b/patches.baytrail/0400-drm-i915-move-i9xx-dpll-enabling-into-crtc-enable-fu.patch @@ -0,0 +1,200 @@ +From 2b2567cafaf34da1f3a9e33d7ac38b1ff740a047 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 16 Jun 2013 21:24:16 +0200 +Subject: drm/i915: move i9xx dpll enabling into crtc enable function + +Now that we have the proper pipe config to track this, we don't need +to write any registers any more. + +Note that for platforms without DPLL_MD (pre-gen4) which store the +pixel mutliplier in the DPLL register I've decided to keep the +seemingly "redundant" write: The comment right below saying "do this +trice for luck" doesn't instill confidence ... + +v2: Drop a few now unnecessary local variables and switch the enable +function to take a struct intel_crtc * to simply arguments. + +v3: Rebase on top of the newly-colored BUG_ON. + +v4: Amend commit message to alliviate Imre's comment about the +redudant DPLL write for the pixel mutliplier. + +Cc: Imre Deak +Cc: Jani Nikula +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 66e3d5c09940d08d94b03e65b420fadaa7484318) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 100 +++++++++++++---------------------- + 1 file changed, 36 insertions(+), 64 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 46bbd267e0a7..608f04adb2c9 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1331,32 +1331,48 @@ static void vlv_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) + udelay(150); /* wait for warmup */ + } + +-static void i9xx_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) ++static void i9xx_enable_pll(struct intel_crtc *crtc) + { +- int reg; +- u32 val; ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int reg = DPLL(crtc->pipe); ++ u32 dpll = crtc->config.dpll_hw_state.dpll; + +- assert_pipe_disabled(dev_priv, pipe); ++ assert_pipe_disabled(dev_priv, crtc->pipe); + + /* No really, not for ILK+ */ + BUG_ON(dev_priv->info->gen >= 5); + + /* PLL is protected by panel, make sure we can write it */ +- if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev)) +- assert_panel_unlocked(dev_priv, pipe); ++ if (IS_MOBILE(dev) && !IS_I830(dev)) ++ assert_panel_unlocked(dev_priv, crtc->pipe); + +- reg = DPLL(pipe); +- val = I915_READ(reg); +- val |= DPLL_VCO_ENABLE; ++ I915_WRITE(reg, dpll); ++ ++ /* Wait for the clocks to stabilize. */ ++ POSTING_READ(reg); ++ udelay(150); ++ ++ if (INTEL_INFO(dev)->gen >= 4) { ++ I915_WRITE(DPLL_MD(crtc->pipe), ++ crtc->config.dpll_hw_state.dpll_md); ++ } else { ++ /* The pixel multiplier can only be updated once the ++ * DPLL is enabled and the clocks are stable. ++ * ++ * So write it again. ++ */ ++ I915_WRITE(reg, dpll); ++ } + + /* We do this three times for luck */ +- I915_WRITE(reg, val); ++ I915_WRITE(reg, dpll); + POSTING_READ(reg); + udelay(150); /* wait for warmup */ +- I915_WRITE(reg, val); ++ I915_WRITE(reg, dpll); + POSTING_READ(reg); + udelay(150); /* wait for warmup */ +- I915_WRITE(reg, val); ++ I915_WRITE(reg, dpll); + POSTING_READ(reg); + udelay(150); /* wait for warmup */ + } +@@ -3646,7 +3662,11 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) + intel_crtc->active = true; + intel_update_watermarks(dev); + +- i9xx_enable_pll(dev_priv, pipe); ++ for_each_encoder_on_crtc(dev, crtc, encoder) ++ if (encoder->pre_pll_enable) ++ encoder->pre_pll_enable(encoder); ++ ++ i9xx_enable_pll(intel_crtc); + + for_each_encoder_on_crtc(dev, crtc, encoder) + if (encoder->pre_enable) +@@ -4484,8 +4504,6 @@ static void i9xx_update_pll(struct intel_crtc *crtc, + { + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_encoder *encoder; +- int pipe = crtc->pipe; + u32 dpll; + bool is_sdvo; + struct dpll *clock = &crtc->config.dpll; +@@ -4549,37 +4567,14 @@ static void i9xx_update_pll(struct intel_crtc *crtc, + dpll |= DPLL_VCO_ENABLE; + crtc->config.dpll_hw_state.dpll = dpll; + +- I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); +- POSTING_READ(DPLL(pipe)); +- udelay(150); +- +- for_each_encoder_on_crtc(dev, &crtc->base, encoder) +- if (encoder->pre_pll_enable) +- encoder->pre_pll_enable(encoder); +- +- if (crtc->config.has_dp_encoder) +- intel_dp_set_m_n(crtc); +- +- I915_WRITE(DPLL(pipe), dpll); +- +- /* Wait for the clocks to stabilize. */ +- POSTING_READ(DPLL(pipe)); +- udelay(150); +- + if (INTEL_INFO(dev)->gen >= 4) { + u32 dpll_md = (crtc->config.pixel_multiplier - 1) + << DPLL_MD_UDI_MULTIPLIER_SHIFT; + crtc->config.dpll_hw_state.dpll_md = dpll_md; +- +- I915_WRITE(DPLL_MD(pipe), dpll_md); +- } else { +- /* The pixel multiplier can only be updated once the +- * DPLL is enabled and the clocks are stable. +- * +- * So write it again. +- */ +- I915_WRITE(DPLL(pipe), dpll); + } ++ ++ if (crtc->config.has_dp_encoder) ++ intel_dp_set_m_n(crtc); + } + + static void i8xx_update_pll(struct intel_crtc *crtc, +@@ -4588,8 +4583,6 @@ static void i8xx_update_pll(struct intel_crtc *crtc, + { + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_encoder *encoder; +- int pipe = crtc->pipe; + u32 dpll; + struct dpll *clock = &crtc->config.dpll; + +@@ -4616,27 +4609,6 @@ static void i8xx_update_pll(struct intel_crtc *crtc, + + dpll |= DPLL_VCO_ENABLE; + crtc->config.dpll_hw_state.dpll = dpll; +- +- I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); +- POSTING_READ(DPLL(pipe)); +- udelay(150); +- +- for_each_encoder_on_crtc(dev, &crtc->base, encoder) +- if (encoder->pre_pll_enable) +- encoder->pre_pll_enable(encoder); +- +- I915_WRITE(DPLL(pipe), dpll); +- +- /* Wait for the clocks to stabilize. */ +- POSTING_READ(DPLL(pipe)); +- udelay(150); +- +- /* The pixel multiplier can only be updated once the +- * DPLL is enabled and the clocks are stable. +- * +- * So write it again. +- */ +- I915_WRITE(DPLL(pipe), dpll); + } + + static void intel_set_pipe_timings(struct intel_crtc *intel_crtc) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0401-drm-i915-s-pre_pll-pre-on-the-lvds-port-enable-funct.patch b/patches.baytrail/0401-drm-i915-s-pre_pll-pre-on-the-lvds-port-enable-funct.patch new file mode 100644 index 000000000000..db290909d39a --- /dev/null +++ b/patches.baytrail/0401-drm-i915-s-pre_pll-pre-on-the-lvds-port-enable-funct.patch @@ -0,0 +1,78 @@ +From 85476373e8ea62fa091f5e336374dadc08a0b98e Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:30 +0200 +Subject: drm/i915: s/pre_pll/pre/ on the lvds port enable function + +i9xx doesn't use pre_enable at all, so we can fold this in now. + +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit f6736a1a7b846d0af90135c7a7f121ab3ada9ee1) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 13 +++---------- + drivers/gpu/drm/i915/intel_lvds.c | 4 ++-- + 2 files changed, 5 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 608f04adb2c9..d6dcd0162b53 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3214,12 +3214,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) + + intel_update_watermarks(dev); + +- for_each_encoder_on_crtc(dev, crtc, encoder) { +- if (encoder->pre_pll_enable) +- encoder->pre_pll_enable(encoder); ++ for_each_encoder_on_crtc(dev, crtc, encoder) + if (encoder->pre_enable) + encoder->pre_enable(encoder); +- } + + if (intel_crtc->config.has_pch_encoder) { + /* Note: FDI PLL enabling _must_ be done before we enable the +@@ -3663,15 +3660,11 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) + intel_update_watermarks(dev); + + for_each_encoder_on_crtc(dev, crtc, encoder) +- if (encoder->pre_pll_enable) +- encoder->pre_pll_enable(encoder); +- +- i9xx_enable_pll(intel_crtc); +- +- for_each_encoder_on_crtc(dev, crtc, encoder) + if (encoder->pre_enable) + encoder->pre_enable(encoder); + ++ i9xx_enable_pll(intel_crtc); ++ + i9xx_pfit_enable(intel_crtc); + + intel_crtc_load_lut(crtc); +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index f2a5c898244c..57ecc57a6fa4 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -122,7 +122,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, + * This is an exception to the general rule that mode_set doesn't turn + * things on. + */ +-static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder) ++static void intel_pre_enable_lvds(struct intel_encoder *encoder) + { + struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); + struct drm_device *dev = encoder->base.dev; +@@ -982,7 +982,7 @@ void intel_lvds_init(struct drm_device *dev) + DRM_MODE_ENCODER_LVDS); + + intel_encoder->enable = intel_enable_lvds; +- intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds; ++ intel_encoder->pre_enable = intel_pre_enable_lvds; + intel_encoder->compute_config = intel_lvds_compute_config; + intel_encoder->disable = intel_disable_lvds; + intel_encoder->get_hw_state = intel_lvds_get_hw_state; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0402-drm-i915-Mask-out-hardware-status-bits-from-VLV-DPLL.patch b/patches.baytrail/0402-drm-i915-Mask-out-hardware-status-bits-from-VLV-DPLL.patch new file mode 100644 index 000000000000..e93b6036d9dd --- /dev/null +++ b/patches.baytrail/0402-drm-i915-Mask-out-hardware-status-bits-from-VLV-DPLL.patch @@ -0,0 +1,45 @@ +From 50d940f3c03cea58e10dff26f21054a91bc1122e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 26 Jun 2013 17:44:15 +0300 +Subject: drm/i915: Mask out hardware status bits from VLV DPLL register +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The DPLL lock bit, and the DPIO phy status bits are read-only and +controlled by the hardware, so they will never be set by the driver. +Mask them out when reading the hw state, so that the state +comparison won't fail. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +[danvet: Jesse asked for a code comment and I wholeheartly agree, so +added one.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 165e901caa4c9d768dd572aab6b95f89a2e9e204) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index d6dcd0162b53..19b7189f2ba3 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4955,6 +4955,11 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, + if (!IS_VALLEYVIEW(dev)) { + pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(crtc->pipe)); + pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(crtc->pipe)); ++ } else { ++ /* Mask out read-only status bits. */ ++ pipe_config->dpll_hw_state.dpll &= ~(DPLL_LOCK_VLV | ++ DPLL_PORTC_READY_MASK | ++ DPLL_PORTB_READY_MASK); + } + + return true; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0403-drm-i915-Remove-extra-error-state-NULL.patch b/patches.baytrail/0403-drm-i915-Remove-extra-error-state-NULL.patch new file mode 100644 index 000000000000..0a2f88e50979 --- /dev/null +++ b/patches.baytrail/0403-drm-i915-Remove-extra-error-state-NULL.patch @@ -0,0 +1,44 @@ +From d3c7dbaab830e6221ef47717fdc0281390d28965 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 27 Jun 2013 16:30:02 -0700 +Subject: drm/i915: Remove extra error state NULL + +Not only was there an extra, but since we now kzalloc the error state, +we don't need either. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 5476f8505b4c4178dbb9f4e9d2bf17e52d8026ed) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 6df227352fd3..bdbbad92f495 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1965,10 +1965,6 @@ static void i915_capture_error_state(struct drm_device *dev) + i915_gem_record_fences(dev, error); + i915_gem_record_rings(dev, error); + +- /* Record buffers on the active and pinned lists. */ +- error->active_bo = NULL; +- error->pinned_bo = NULL; +- + i = 0; + list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) + i++; +@@ -1978,8 +1974,6 @@ static void i915_capture_error_state(struct drm_device *dev) + i++; + error->pinned_bo_count = i - error->active_bo_count; + +- error->active_bo = NULL; +- error->pinned_bo = NULL; + if (i) { + error->active_bo = kmalloc(sizeof(*error->active_bo)*i, + GFP_ATOMIC); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0404-drm-i915-Extract-error-buffer-capture.patch b/patches.baytrail/0404-drm-i915-Extract-error-buffer-capture.patch new file mode 100644 index 000000000000..2650f33a49b6 --- /dev/null +++ b/patches.baytrail/0404-drm-i915-Extract-error-buffer-capture.patch @@ -0,0 +1,118 @@ +From c337cb5b3187445c2a7fbc6a5112c0fa56be3daf Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 27 Jun 2013 16:30:03 -0700 +Subject: drm/i915: Extract error buffer capture + +This helps when we have per VM buffer capturing. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 26b7c22465cbfaa40d7f2de6d5933a66106eb778) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 69 +++++++++++++++++++++++------------------ + 1 file changed, 38 insertions(+), 31 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index bdbbad92f495..a53d1d3040eb 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1889,6 +1889,42 @@ static void i915_gem_record_rings(struct drm_device *dev, + } + } + ++static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv, ++ struct drm_i915_error_state *error) ++{ ++ struct drm_i915_gem_object *obj; ++ int i; ++ ++ i = 0; ++ list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) ++ i++; ++ error->active_bo_count = i; ++ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) ++ if (obj->pin_count) ++ i++; ++ error->pinned_bo_count = i - error->active_bo_count; ++ ++ if (i) { ++ error->active_bo = kmalloc(sizeof(*error->active_bo)*i, ++ GFP_ATOMIC); ++ if (error->active_bo) ++ error->pinned_bo = ++ error->active_bo + error->active_bo_count; ++ } ++ ++ if (error->active_bo) ++ error->active_bo_count = ++ capture_active_bo(error->active_bo, ++ error->active_bo_count, ++ &dev_priv->mm.active_list); ++ ++ if (error->pinned_bo) ++ error->pinned_bo_count = ++ capture_pinned_bo(error->pinned_bo, ++ error->pinned_bo_count, ++ &dev_priv->mm.bound_list); ++} ++ + /** + * i915_capture_error_state - capture an error record for later analysis + * @dev: drm device +@@ -1901,10 +1937,9 @@ static void i915_gem_record_rings(struct drm_device *dev, + static void i915_capture_error_state(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- struct drm_i915_gem_object *obj; + struct drm_i915_error_state *error; + unsigned long flags; +- int i, pipe; ++ int pipe; + + spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); + error = dev_priv->gpu_error.first_error; +@@ -1962,38 +1997,10 @@ static void i915_capture_error_state(struct drm_device *dev) + + i915_get_extra_instdone(dev, error->extra_instdone); + ++ i915_gem_capture_buffers(dev_priv, error); + i915_gem_record_fences(dev, error); + i915_gem_record_rings(dev, error); + +- i = 0; +- list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) +- i++; +- error->active_bo_count = i; +- list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) +- if (obj->pin_count) +- i++; +- error->pinned_bo_count = i - error->active_bo_count; +- +- if (i) { +- error->active_bo = kmalloc(sizeof(*error->active_bo)*i, +- GFP_ATOMIC); +- if (error->active_bo) +- error->pinned_bo = +- error->active_bo + error->active_bo_count; +- } +- +- if (error->active_bo) +- error->active_bo_count = +- capture_active_bo(error->active_bo, +- error->active_bo_count, +- &dev_priv->mm.active_list); +- +- if (error->pinned_bo) +- error->pinned_bo_count = +- capture_pinned_bo(error->pinned_bo, +- error->pinned_bo_count, +- &dev_priv->mm.bound_list); +- + do_gettimeofday(&error->time); + + error->overlay = intel_overlay_capture_error_state(dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0405-drm-i915-make-PDE-PTE-platform-specific.patch b/patches.baytrail/0405-drm-i915-make-PDE-PTE-platform-specific.patch new file mode 100644 index 000000000000..1b75f6c74cd8 --- /dev/null +++ b/patches.baytrail/0405-drm-i915-make-PDE-PTE-platform-specific.patch @@ -0,0 +1,87 @@ +From f45a4df9b3983ebb664e6da51edf491b7e2a604d Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 27 Jun 2013 16:30:04 -0700 +Subject: drm/i915: make PDE|PTE platform specific + +Nothing outside of i915_gem_gtt.c and more specifically, the relevant +gen specific init function should need to know about number of PDEs, or +PTEs per PD. Exposing this will only lead to circumventing using the +upcoming VM abstraction. + +To accomplish this, move the defines into the .c file, rename the PDE +define to be GEN6, and make the PTE count less of a magic number. + +The remaining code in the global gtt setup is a bit messy, but an +upcoming patch will clean that one up. + +v2: Don't hardcode number of PDEs (Daniel + Jesse) +Reworded commit message to reflect change. + +Reviewed-by: Jesse Barnes +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 6670a5a5c77b8fc17962742f9bcf6f47e489aa62) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 -- + drivers/gpu/drm/i915/i915_gem_gtt.c | 9 ++++++--- + 2 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 3d98ed475a1f..c38084df3313 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -486,8 +486,6 @@ struct i915_gtt { + }; + #define gtt_total_entries(gtt) ((gtt).total >> PAGE_SHIFT) + +-#define I915_PPGTT_PD_ENTRIES 512 +-#define I915_PPGTT_PT_ENTRIES 1024 + struct i915_hw_ppgtt { + struct drm_device *dev; + unsigned num_pd_entries; +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 5101ab6869b4..216e7a19e63d 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -28,6 +28,9 @@ + #include "i915_trace.h" + #include "intel_drv.h" + ++#define GEN6_PPGTT_PD_ENTRIES 512 ++#define I915_PPGTT_PT_ENTRIES (PAGE_SIZE / sizeof(gen6_gtt_pte_t)) ++ + /* PPGTT stuff */ + #define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) + +@@ -278,7 +281,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) + } else { + ppgtt->pte_encode = gen6_pte_encode; + } +- ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES; ++ ppgtt->num_pd_entries = GEN6_PPGTT_PD_ENTRIES; + ppgtt->enable = gen6_ppgtt_enable; + ppgtt->clear_range = gen6_ppgtt_clear_range; + ppgtt->insert_entries = gen6_ppgtt_insert_entries; +@@ -688,7 +691,7 @@ void i915_gem_init_global_gtt(struct drm_device *dev) + if (INTEL_INFO(dev)->gen <= 7) { + /* PPGTT pdes are stolen from global gtt ptes, so shrink the + * aperture accordingly when using aliasing ppgtt. */ +- gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE; ++ gtt_size -= GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE; + } + + i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size); +@@ -699,7 +702,7 @@ void i915_gem_init_global_gtt(struct drm_device *dev) + + DRM_ERROR("Aliased PPGTT setup failed %d\n", ret); + drm_mm_takedown(&dev_priv->mm.gtt_space); +- gtt_size += I915_PPGTT_PD_ENTRIES*PAGE_SIZE; ++ gtt_size += GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE; + } + i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0406-drm-i915-Really-share-scratch-page.patch b/patches.baytrail/0406-drm-i915-Really-share-scratch-page.patch new file mode 100644 index 000000000000..81df424113a5 --- /dev/null +++ b/patches.baytrail/0406-drm-i915-Really-share-scratch-page.patch @@ -0,0 +1,62 @@ +From aec87ca35c93140954c4e82732fa016686bc3f9e Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 27 Jun 2013 16:30:17 -0700 +Subject: drm/i915: Really share scratch page + +A previous patch had set up the ppgtt and ggtt to use the same scratch +page, but still kept around both pointers. Kill it, it's not needed and +gets in our way for upcoming cleanups. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 84f135605898708ab692fc84555c31fbfe2983c1) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 1 - + drivers/gpu/drm/i915/i915_gem_gtt.c | 4 ++-- + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index c38084df3313..cba5dec686c9 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -492,7 +492,6 @@ struct i915_hw_ppgtt { + struct page **pt_pages; + uint32_t pd_offset; + dma_addr_t *pt_dma_addr; +- dma_addr_t scratch_page_dma_addr; + + /* pte functions, mirroring the interface of the global gtt. */ + void (*clear_range)(struct i915_hw_ppgtt *ppgtt, +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 216e7a19e63d..46b9e32b1109 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -188,13 +188,14 @@ static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, + unsigned first_entry, + unsigned num_entries) + { ++ struct drm_i915_private *dev_priv = ppgtt->dev->dev_private; + gen6_gtt_pte_t *pt_vaddr, scratch_pte; + unsigned act_pt = first_entry / I915_PPGTT_PT_ENTRIES; + unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; + unsigned last_pte, i; + + scratch_pte = ppgtt->pte_encode(ppgtt->dev, +- ppgtt->scratch_page_dma_addr, ++ dev_priv->gtt.scratch_page_dma, + I915_CACHE_LLC); + + while (num_entries) { +@@ -351,7 +352,6 @@ static int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) + return -ENOMEM; + + ppgtt->dev = dev; +- ppgtt->scratch_page_dma_addr = dev_priv->gtt.scratch_page_dma; + + if (INTEL_INFO(dev)->gen < 8) + ret = gen6_ppgtt_init(ppgtt); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0407-drm-i915-Combine-scratch-members-into-a-struct.patch b/patches.baytrail/0407-drm-i915-Combine-scratch-members-into-a-struct.patch new file mode 100644 index 000000000000..76abc0480df7 --- /dev/null +++ b/patches.baytrail/0407-drm-i915-Combine-scratch-members-into-a-struct.patch @@ -0,0 +1,88 @@ +From 3ac343195fac1d6a3892b28368394d6307959b20 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 27 Jun 2013 16:30:18 -0700 +Subject: drm/i915: Combine scratch members into a struct + +There isn't any special reason to do this other than it makes it obvious +that the two members are connected. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 67167240063c9eff15d60754c8d786a7a237ffa2) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 6 ++++-- + drivers/gpu/drm/i915/i915_gem_gtt.c | 17 ++++++++--------- + 2 files changed, 12 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index cba5dec686c9..fc7f5a8355f4 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -465,8 +465,10 @@ struct i915_gtt { + void __iomem *gsm; + + bool do_idle_maps; +- dma_addr_t scratch_page_dma; +- struct page *scratch_page; ++ struct { ++ dma_addr_t addr; ++ struct page *page; ++ } scratch; + + /* global gtt ops */ + int (*gtt_probe)(struct drm_device *dev, size_t *gtt_total, +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 46b9e32b1109..cdd7b45cd501 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -195,7 +195,7 @@ static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, + unsigned last_pte, i; + + scratch_pte = ppgtt->pte_encode(ppgtt->dev, +- dev_priv->gtt.scratch_page_dma, ++ dev_priv->gtt.scratch.addr, + I915_CACHE_LLC); + + while (num_entries) { +@@ -521,8 +521,7 @@ static void gen6_ggtt_clear_range(struct drm_device *dev, + first_entry, num_entries, max_entries)) + num_entries = max_entries; + +- scratch_pte = dev_priv->gtt.pte_encode(dev, +- dev_priv->gtt.scratch_page_dma, ++ scratch_pte = dev_priv->gtt.pte_encode(dev, dev_priv->gtt.scratch.addr, + I915_CACHE_LLC); + for (i = 0; i < num_entries; i++) + iowrite32(scratch_pte, >t_base[i]); +@@ -727,8 +726,8 @@ static int setup_scratch_page(struct drm_device *dev) + #else + dma_addr = page_to_phys(page); + #endif +- dev_priv->gtt.scratch_page = page; +- dev_priv->gtt.scratch_page_dma = dma_addr; ++ dev_priv->gtt.scratch.page = page; ++ dev_priv->gtt.scratch.addr = dma_addr; + + return 0; + } +@@ -736,11 +735,11 @@ static int setup_scratch_page(struct drm_device *dev) + static void teardown_scratch_page(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- set_pages_wb(dev_priv->gtt.scratch_page, 1); +- pci_unmap_page(dev->pdev, dev_priv->gtt.scratch_page_dma, ++ set_pages_wb(dev_priv->gtt.scratch.page, 1); ++ pci_unmap_page(dev->pdev, dev_priv->gtt.scratch.addr, + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); +- put_page(dev_priv->gtt.scratch_page); +- __free_page(dev_priv->gtt.scratch_page); ++ put_page(dev_priv->gtt.scratch.page); ++ __free_page(dev_priv->gtt.scratch.page); + } + + static inline unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0408-drm-i915-Drop-dev-from-pte_encode.patch b/patches.baytrail/0408-drm-i915-Drop-dev-from-pte_encode.patch new file mode 100644 index 000000000000..5e87856439e6 --- /dev/null +++ b/patches.baytrail/0408-drm-i915-Drop-dev-from-pte_encode.patch @@ -0,0 +1,132 @@ +From ea90eddb18a4a02cd5eb89c2e327b6a6c18e8ad2 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 27 Jun 2013 16:30:19 -0700 +Subject: drm/i915: Drop dev from pte_encode + +The original pte_encode function needed the dev argument so we could do +platform specific handling via IS_GENX, etc. With the merging of a pte +encoding function there should never been a need to quirk away gen +specific details. + +The patch doesn't do much but makes the upcoming reworks in gtt/ppgtt/mm +slightly (albeit, ever so) easier. + +Reviewed-by: Kenneth Graunke +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 80a74f7f9c3e57123b6c3d314d4340fc8195a524) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 6 ++---- + drivers/gpu/drm/i915/i915_gem_gtt.c | 21 ++++++++------------- + 2 files changed, 10 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index fc7f5a8355f4..956849f594e0 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -482,8 +482,7 @@ struct i915_gtt { + struct sg_table *st, + unsigned int pg_start, + enum i915_cache_level cache_level); +- gen6_gtt_pte_t (*pte_encode)(struct drm_device *dev, +- dma_addr_t addr, ++ gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr, + enum i915_cache_level level); + }; + #define gtt_total_entries(gtt) ((gtt).total >> PAGE_SHIFT) +@@ -503,8 +502,7 @@ struct i915_hw_ppgtt { + struct sg_table *st, + unsigned int pg_start, + enum i915_cache_level cache_level); +- gen6_gtt_pte_t (*pte_encode)(struct drm_device *dev, +- dma_addr_t addr, ++ gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr, + enum i915_cache_level level); + int (*enable)(struct drm_device *dev); + void (*cleanup)(struct i915_hw_ppgtt *ppgtt); +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index cdd7b45cd501..42b5a4fc3932 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -45,8 +45,7 @@ + #define GEN6_PTE_CACHE_LLC_MLC (3 << 1) + #define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) + +-static gen6_gtt_pte_t gen6_pte_encode(struct drm_device *dev, +- dma_addr_t addr, ++static gen6_gtt_pte_t gen6_pte_encode(dma_addr_t addr, + enum i915_cache_level level) + { + gen6_gtt_pte_t pte = GEN6_PTE_VALID; +@@ -72,8 +71,7 @@ static gen6_gtt_pte_t gen6_pte_encode(struct drm_device *dev, + #define BYT_PTE_WRITEABLE (1 << 1) + #define BYT_PTE_SNOOPED_BY_CPU_CACHES (1 << 2) + +-static gen6_gtt_pte_t byt_pte_encode(struct drm_device *dev, +- dma_addr_t addr, ++static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr, + enum i915_cache_level level) + { + gen6_gtt_pte_t pte = GEN6_PTE_VALID; +@@ -90,8 +88,7 @@ static gen6_gtt_pte_t byt_pte_encode(struct drm_device *dev, + return pte; + } + +-static gen6_gtt_pte_t hsw_pte_encode(struct drm_device *dev, +- dma_addr_t addr, ++static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr, + enum i915_cache_level level) + { + gen6_gtt_pte_t pte = GEN6_PTE_VALID; +@@ -194,8 +191,7 @@ static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, + unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; + unsigned last_pte, i; + +- scratch_pte = ppgtt->pte_encode(ppgtt->dev, +- dev_priv->gtt.scratch.addr, ++ scratch_pte = ppgtt->pte_encode(dev_priv->gtt.scratch.addr, + I915_CACHE_LLC); + + while (num_entries) { +@@ -231,8 +227,7 @@ static void gen6_ppgtt_insert_entries(struct i915_hw_ppgtt *ppgtt, + dma_addr_t page_addr; + + page_addr = sg_page_iter_dma_address(&sg_iter); +- pt_vaddr[act_pte] = ppgtt->pte_encode(ppgtt->dev, page_addr, +- cache_level); ++ pt_vaddr[act_pte] = ppgtt->pte_encode(page_addr, cache_level); + if (++act_pte == I915_PPGTT_PT_ENTRIES) { + kunmap_atomic(pt_vaddr); + act_pt++; +@@ -483,7 +478,7 @@ static void gen6_ggtt_insert_entries(struct drm_device *dev, + + for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) { + addr = sg_page_iter_dma_address(&sg_iter); +- iowrite32(dev_priv->gtt.pte_encode(dev, addr, level), ++ iowrite32(dev_priv->gtt.pte_encode(addr, level), + >t_entries[i]); + i++; + } +@@ -496,7 +491,7 @@ static void gen6_ggtt_insert_entries(struct drm_device *dev, + */ + if (i != 0) + WARN_ON(readl(>t_entries[i-1]) +- != dev_priv->gtt.pte_encode(dev, addr, level)); ++ != dev_priv->gtt.pte_encode(addr, level)); + + /* This next bit makes the above posting read even more important. We + * want to flush the TLBs only after we're certain all the PTE updates +@@ -521,7 +516,7 @@ static void gen6_ggtt_clear_range(struct drm_device *dev, + first_entry, num_entries, max_entries)) + num_entries = max_entries; + +- scratch_pte = dev_priv->gtt.pte_encode(dev, dev_priv->gtt.scratch.addr, ++ scratch_pte = dev_priv->gtt.pte_encode(dev_priv->gtt.scratch.addr, + I915_CACHE_LLC); + for (i = 0; i < num_entries; i++) + iowrite32(scratch_pte, >t_base[i]); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0409-drm-i915-Use-gtt-shortform-where-possible.patch b/patches.baytrail/0409-drm-i915-Use-gtt-shortform-where-possible.patch new file mode 100644 index 000000000000..31ebc559ea5d --- /dev/null +++ b/patches.baytrail/0409-drm-i915-Use-gtt-shortform-where-possible.patch @@ -0,0 +1,73 @@ +From a06cef966fc5d8c8035d7fa86e2b00dbbd57c2dd Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 27 Jun 2013 16:30:20 -0700 +Subject: drm/i915: Use gtt shortform where possible + +Just for compactness. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit b2f21b4dfdd1e7396a99312c35092c8bb486a699) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_gtt.c | 36 +++++++++++++++--------------------- + 1 file changed, 15 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 42b5a4fc3932..66929eac6367 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -846,34 +846,28 @@ int i915_gem_gtt_init(struct drm_device *dev) + int ret; + + if (INTEL_INFO(dev)->gen <= 5) { +- dev_priv->gtt.gtt_probe = i915_gmch_probe; +- dev_priv->gtt.gtt_remove = i915_gmch_remove; ++ gtt->gtt_probe = i915_gmch_probe; ++ gtt->gtt_remove = i915_gmch_remove; + } else { +- dev_priv->gtt.gtt_probe = gen6_gmch_probe; +- dev_priv->gtt.gtt_remove = gen6_gmch_remove; +- if (IS_HASWELL(dev)) { +- dev_priv->gtt.pte_encode = hsw_pte_encode; +- } else if (IS_VALLEYVIEW(dev)) { +- dev_priv->gtt.pte_encode = byt_pte_encode; +- } else { +- dev_priv->gtt.pte_encode = gen6_pte_encode; +- } ++ gtt->gtt_probe = gen6_gmch_probe; ++ gtt->gtt_remove = gen6_gmch_remove; ++ if (IS_HASWELL(dev)) ++ gtt->pte_encode = hsw_pte_encode; ++ else if (IS_VALLEYVIEW(dev)) ++ gtt->pte_encode = byt_pte_encode; ++ else ++ gtt->pte_encode = gen6_pte_encode; + } + +- ret = dev_priv->gtt.gtt_probe(dev, &dev_priv->gtt.total, +- &dev_priv->gtt.stolen_size, +- >t->mappable_base, +- >t->mappable_end); ++ ret = gtt->gtt_probe(dev, >t->total, >t->stolen_size, ++ >t->mappable_base, >t->mappable_end); + if (ret) + return ret; + + /* GMADR is the PCI mmio aperture into the global GTT. */ +- DRM_INFO("Memory usable by graphics device = %zdM\n", +- dev_priv->gtt.total >> 20); +- DRM_DEBUG_DRIVER("GMADR size = %ldM\n", +- dev_priv->gtt.mappable_end >> 20); +- DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", +- dev_priv->gtt.stolen_size >> 20); ++ DRM_INFO("Memory usable by graphics device = %zdM\n", gtt->total >> 20); ++ DRM_DEBUG_DRIVER("GMADR size = %ldM\n", gtt->mappable_end >> 20); ++ DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", gtt->stolen_size >> 20); + + return 0; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0410-drm-i915-Move-fbc-members-out-of-line.patch b/patches.baytrail/0410-drm-i915-Move-fbc-members-out-of-line.patch new file mode 100644 index 000000000000..0c0a2ea5a570 --- /dev/null +++ b/patches.baytrail/0410-drm-i915-Move-fbc-members-out-of-line.patch @@ -0,0 +1,397 @@ +From e2663b379ed8acc083f1527fd8bcd4835a9648e1 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 27 Jun 2013 16:30:21 -0700 +Subject: drm/i915: Move fbc members out of line + +Signed-off-by: Ben Widawsky +[danvet: Resolve conflict with Damien's FBC_CHIP_DEFAULT no fbc +reason.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 5c3fe8b03ea6eb61617edb390d51c08609a495f7) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 2 +- + drivers/gpu/drm/i915/i915_drv.h | 50 +++++++++++++++++++-------------- + drivers/gpu/drm/i915/i915_gem_stolen.c | 20 ++++++------- + drivers/gpu/drm/i915/intel_display.c | 6 ++-- + drivers/gpu/drm/i915/intel_drv.h | 7 ----- + drivers/gpu/drm/i915/intel_pm.c | 51 +++++++++++++++++----------------- + 6 files changed, 69 insertions(+), 67 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index c16926ca15be..f82134f8e9fb 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1492,7 +1492,7 @@ static int i915_fbc_status(struct seq_file *m, void *unused) + seq_puts(m, "FBC enabled\n"); + } else { + seq_puts(m, "FBC disabled: "); +- switch (dev_priv->no_fbc_reason) { ++ switch (dev_priv->fbc.no_fbc_reason) { + case FBC_NO_OUTPUT: + seq_puts(m, "no outputs"); + break; +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 956849f594e0..4bd72bf26049 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -528,18 +528,36 @@ struct i915_hw_context { + struct i915_ctx_hang_stats hang_stats; + }; + +-enum no_fbc_reason { +- FBC_NO_OUTPUT, /* no outputs enabled to compress */ +- FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */ +- FBC_UNSUPPORTED_MODE, /* interlace or doublescanned mode */ +- FBC_MODE_TOO_LARGE, /* mode too large for compression */ +- FBC_BAD_PLANE, /* fbc not supported on plane */ +- FBC_NOT_TILED, /* buffer not tiled */ +- FBC_MULTIPLE_PIPES, /* more than one pipe active */ +- FBC_MODULE_PARAM, +- FBC_CHIP_DEFAULT, /* disabled by default on this chip */ ++struct i915_fbc { ++ unsigned long size; ++ unsigned int fb_id; ++ enum plane plane; ++ int y; ++ ++ struct drm_mm_node *compressed_fb; ++ struct drm_mm_node *compressed_llb; ++ ++ struct intel_fbc_work { ++ struct delayed_work work; ++ struct drm_crtc *crtc; ++ struct drm_framebuffer *fb; ++ int interval; ++ } *fbc_work; ++ ++ enum { ++ FBC_NO_OUTPUT, /* no outputs enabled to compress */ ++ FBC_STOLEN_TOO_SMALL, /* not enough space for buffers */ ++ FBC_UNSUPPORTED_MODE, /* interlace or doublescanned mode */ ++ FBC_MODE_TOO_LARGE, /* mode too large for compression */ ++ FBC_BAD_PLANE, /* fbc not supported on plane */ ++ FBC_NOT_TILED, /* buffer not tiled */ ++ FBC_MULTIPLE_PIPES, /* more than one pipe active */ ++ FBC_MODULE_PARAM, ++ FBC_CHIP_DEFAULT, /* disabled by default on this chip */ ++ } no_fbc_reason; + }; + ++ + enum intel_pch { + PCH_NONE = 0, /* No PCH present */ + PCH_IBX, /* Ibexpeak PCH */ +@@ -1060,12 +1078,7 @@ typedef struct drm_i915_private { + + int num_plane; + +- unsigned long cfb_size; +- unsigned int cfb_fb; +- enum plane cfb_plane; +- int cfb_y; +- struct intel_fbc_work *fbc_work; +- ++ struct i915_fbc fbc; + struct intel_opregion opregion; + struct intel_vbt_data vbt; + +@@ -1143,11 +1156,6 @@ typedef struct drm_i915_private { + /* Haswell power well */ + struct i915_power_well power_well; + +- enum no_fbc_reason no_fbc_reason; +- +- struct drm_mm_node *compressed_fb; +- struct drm_mm_node *compressed_llb; +- + struct i915_gpu_error gpu_error; + + struct drm_i915_gem_object *vlv_pctx; +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 982d4732cecf..0f8cf62a5b83 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -120,7 +120,7 @@ static int i915_setup_compression(struct drm_device *dev, int size) + if (!compressed_llb) + goto err_fb; + +- dev_priv->compressed_llb = compressed_llb; ++ dev_priv->fbc.compressed_llb = compressed_llb; + + I915_WRITE(FBC_CFB_BASE, + dev_priv->mm.stolen_base + compressed_fb->start); +@@ -128,8 +128,8 @@ static int i915_setup_compression(struct drm_device *dev, int size) + dev_priv->mm.stolen_base + compressed_llb->start); + } + +- dev_priv->compressed_fb = compressed_fb; +- dev_priv->cfb_size = size; ++ dev_priv->fbc.compressed_fb = compressed_fb; ++ dev_priv->fbc.size = size; + + DRM_DEBUG_KMS("reserved %d bytes of contiguous stolen space for FBC\n", + size); +@@ -150,7 +150,7 @@ int i915_gem_stolen_setup_compression(struct drm_device *dev, int size) + if (!drm_mm_initialized(&dev_priv->mm.stolen)) + return -ENODEV; + +- if (size < dev_priv->cfb_size) ++ if (size < dev_priv->fbc.size) + return 0; + + /* Release any current block */ +@@ -163,16 +163,16 @@ void i915_gem_stolen_cleanup_compression(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + +- if (dev_priv->cfb_size == 0) ++ if (dev_priv->fbc.size == 0) + return; + +- if (dev_priv->compressed_fb) +- drm_mm_put_block(dev_priv->compressed_fb); ++ if (dev_priv->fbc.compressed_fb) ++ drm_mm_put_block(dev_priv->fbc.compressed_fb); + +- if (dev_priv->compressed_llb) +- drm_mm_put_block(dev_priv->compressed_llb); ++ if (dev_priv->fbc.compressed_llb) ++ drm_mm_put_block(dev_priv->fbc.compressed_llb); + +- dev_priv->cfb_size = 0; ++ dev_priv->fbc.size = 0; + } + + void i915_gem_cleanup_stolen(struct drm_device *dev) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 19b7189f2ba3..2dff2112def1 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3408,7 +3408,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) + intel_crtc_wait_for_pending_flips(crtc); + drm_vblank_off(dev, pipe); + +- if (dev_priv->cfb_plane == plane) ++ if (dev_priv->fbc.plane == plane) + intel_disable_fbc(dev); + + intel_crtc_update_cursor(crtc, false); +@@ -3481,7 +3481,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) + drm_vblank_off(dev, pipe); + + /* FBC must be disabled before disabling the plane on HSW. */ +- if (dev_priv->cfb_plane == plane) ++ if (dev_priv->fbc.plane == plane) + intel_disable_fbc(dev); + + hsw_disable_ips(intel_crtc); +@@ -3720,7 +3720,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) + intel_crtc_wait_for_pending_flips(crtc); + drm_vblank_off(dev, pipe); + +- if (dev_priv->cfb_plane == plane) ++ if (dev_priv->fbc.plane == plane) + intel_disable_fbc(dev); + + intel_crtc_dpms_overlay(intel_crtc, false); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 16ad38fd859d..02fee4364e8a 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -549,13 +549,6 @@ struct intel_unpin_work { + bool enable_stall_check; + }; + +-struct intel_fbc_work { +- struct delayed_work work; +- struct drm_crtc *crtc; +- struct drm_framebuffer *fb; +- int interval; +-}; +- + int intel_pch_rawclk(struct drm_device *dev); + + int intel_connector_update_modes(struct drm_connector *connector, +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 217e5dd1b8ff..940311fcee64 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -87,7 +87,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + int plane, i; + u32 fbc_ctl, fbc_ctl2; + +- cfb_pitch = dev_priv->cfb_size / FBC_LL_SIZE; ++ cfb_pitch = dev_priv->fbc.size / FBC_LL_SIZE; + if (fb->pitches[0] < cfb_pitch) + cfb_pitch = fb->pitches[0]; + +@@ -326,7 +326,7 @@ static void intel_fbc_work_fn(struct work_struct *__work) + struct drm_i915_private *dev_priv = dev->dev_private; + + mutex_lock(&dev->struct_mutex); +- if (work == dev_priv->fbc_work) { ++ if (work == dev_priv->fbc.fbc_work) { + /* Double check that we haven't switched fb without cancelling + * the prior work. + */ +@@ -334,12 +334,12 @@ static void intel_fbc_work_fn(struct work_struct *__work) + dev_priv->display.enable_fbc(work->crtc, + work->interval); + +- dev_priv->cfb_plane = to_intel_crtc(work->crtc)->plane; +- dev_priv->cfb_fb = work->crtc->fb->base.id; +- dev_priv->cfb_y = work->crtc->y; ++ dev_priv->fbc.plane = to_intel_crtc(work->crtc)->plane; ++ dev_priv->fbc.fb_id = work->crtc->fb->base.id; ++ dev_priv->fbc.y = work->crtc->y; + } + +- dev_priv->fbc_work = NULL; ++ dev_priv->fbc.fbc_work = NULL; + } + mutex_unlock(&dev->struct_mutex); + +@@ -348,25 +348,25 @@ static void intel_fbc_work_fn(struct work_struct *__work) + + static void intel_cancel_fbc_work(struct drm_i915_private *dev_priv) + { +- if (dev_priv->fbc_work == NULL) ++ if (dev_priv->fbc.fbc_work == NULL) + return; + + DRM_DEBUG_KMS("cancelling pending FBC enable\n"); + + /* Synchronisation is provided by struct_mutex and checking of +- * dev_priv->fbc_work, so we can perform the cancellation ++ * dev_priv->fbc.fbc_work, so we can perform the cancellation + * entirely asynchronously. + */ +- if (cancel_delayed_work(&dev_priv->fbc_work->work)) ++ if (cancel_delayed_work(&dev_priv->fbc.fbc_work->work)) + /* tasklet was killed before being run, clean up */ +- kfree(dev_priv->fbc_work); ++ kfree(dev_priv->fbc.fbc_work); + + /* Mark the work as no longer wanted so that if it does + * wake-up (because the work was already running and waiting + * for our mutex), it will discover that is no longer + * necessary to run. + */ +- dev_priv->fbc_work = NULL; ++ dev_priv->fbc.fbc_work = NULL; + } + + static void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) +@@ -392,7 +392,7 @@ static void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + work->interval = interval; + INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn); + +- dev_priv->fbc_work = work; ++ dev_priv->fbc.fbc_work = work; + + /* Delay the actual enabling to let pageflipping cease and the + * display to settle before starting the compression. Note that +@@ -418,7 +418,7 @@ void intel_disable_fbc(struct drm_device *dev) + return; + + dev_priv->display.disable_fbc(dev); +- dev_priv->cfb_plane = -1; ++ dev_priv->fbc.plane = -1; + } + + /** +@@ -470,7 +470,8 @@ void intel_update_fbc(struct drm_device *dev) + !to_intel_crtc(tmp_crtc)->primary_disabled) { + if (crtc) { + DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); +- dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; ++ dev_priv->fbc.no_fbc_reason = ++ FBC_MULTIPLE_PIPES; + goto out_disable; + } + crtc = tmp_crtc; +@@ -479,7 +480,7 @@ void intel_update_fbc(struct drm_device *dev) + + if (!crtc || crtc->fb == NULL) { + DRM_DEBUG_KMS("no output, disabling\n"); +- dev_priv->no_fbc_reason = FBC_NO_OUTPUT; ++ dev_priv->fbc.no_fbc_reason = FBC_NO_OUTPUT; + goto out_disable; + } + +@@ -491,19 +492,19 @@ void intel_update_fbc(struct drm_device *dev) + if (i915_enable_fbc < 0 && + INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) { + DRM_DEBUG_KMS("disabled per chip default\n"); +- dev_priv->no_fbc_reason = FBC_CHIP_DEFAULT; ++ dev_priv->fbc.no_fbc_reason = FBC_CHIP_DEFAULT; + goto out_disable; + } + if (!i915_enable_fbc) { + DRM_DEBUG_KMS("fbc disabled per module param\n"); +- dev_priv->no_fbc_reason = FBC_MODULE_PARAM; ++ dev_priv->fbc.no_fbc_reason = FBC_MODULE_PARAM; + goto out_disable; + } + if ((crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) || + (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)) { + DRM_DEBUG_KMS("mode incompatible with compression, " + "disabling\n"); +- dev_priv->no_fbc_reason = FBC_UNSUPPORTED_MODE; ++ dev_priv->fbc.no_fbc_reason = FBC_UNSUPPORTED_MODE; + goto out_disable; + } + +@@ -517,13 +518,13 @@ void intel_update_fbc(struct drm_device *dev) + if ((crtc->mode.hdisplay > max_hdisplay) || + (crtc->mode.vdisplay > max_vdisplay)) { + DRM_DEBUG_KMS("mode too large for compression, disabling\n"); +- dev_priv->no_fbc_reason = FBC_MODE_TOO_LARGE; ++ dev_priv->fbc.no_fbc_reason = FBC_MODE_TOO_LARGE; + goto out_disable; + } + if ((IS_I915GM(dev) || IS_I945GM(dev) || IS_HASWELL(dev)) && + intel_crtc->plane != 0) { + DRM_DEBUG_KMS("plane not 0, disabling compression\n"); +- dev_priv->no_fbc_reason = FBC_BAD_PLANE; ++ dev_priv->fbc.no_fbc_reason = FBC_BAD_PLANE; + goto out_disable; + } + +@@ -533,7 +534,7 @@ void intel_update_fbc(struct drm_device *dev) + if (obj->tiling_mode != I915_TILING_X || + obj->fence_reg == I915_FENCE_REG_NONE) { + DRM_DEBUG_KMS("framebuffer not tiled or fenced, disabling compression\n"); +- dev_priv->no_fbc_reason = FBC_NOT_TILED; ++ dev_priv->fbc.no_fbc_reason = FBC_NOT_TILED; + goto out_disable; + } + +@@ -543,7 +544,7 @@ void intel_update_fbc(struct drm_device *dev) + + if (i915_gem_stolen_setup_compression(dev, intel_fb->obj->base.size)) { + DRM_DEBUG_KMS("framebuffer too large, disabling compression\n"); +- dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; ++ dev_priv->fbc.no_fbc_reason = FBC_STOLEN_TOO_SMALL; + goto out_disable; + } + +@@ -552,9 +553,9 @@ void intel_update_fbc(struct drm_device *dev) + * cannot be unpinned (and have its GTT offset and fence revoked) + * without first being decoupled from the scanout and FBC disabled. + */ +- if (dev_priv->cfb_plane == intel_crtc->plane && +- dev_priv->cfb_fb == fb->base.id && +- dev_priv->cfb_y == crtc->y) ++ if (dev_priv->fbc.plane == intel_crtc->plane && ++ dev_priv->fbc.fb_id == fb->base.id && ++ dev_priv->fbc.y == crtc->y) + return; + + if (intel_fbc_enabled(dev)) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0411-drm-i915-Move-gtt_mtrr-to-i915_gtt.patch b/patches.baytrail/0411-drm-i915-Move-gtt_mtrr-to-i915_gtt.patch new file mode 100644 index 000000000000..c27f6e2737de --- /dev/null +++ b/patches.baytrail/0411-drm-i915-Move-gtt_mtrr-to-i915_gtt.patch @@ -0,0 +1,77 @@ +From f1b3e46f84c991d61e999335f5a44168645430cd Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 27 Jun 2013 16:30:23 -0700 +Subject: drm/i915: Move gtt_mtrr to i915_gtt + +for file in `ls drivers/gpu/drm/i915/*.c` ; do + sed -i "s/mm.gtt_mtrr/gtt.mtrr/" $file; +done + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 911bdf0ae6405db3313c6e5798cf08640fdd0714) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 8 ++++---- + drivers/gpu/drm/i915/i915_drv.h | 4 ++-- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index f4669802a0fb..6995baca9b62 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1567,8 +1567,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + goto out_rmmap; + } + +- dev_priv->mm.gtt_mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base, +- aperture_size); ++ dev_priv->gtt.mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base, ++ aperture_size); + + /* The i915 workqueue is primarily used for batched retirement of + * requests (and thus managing bo) once the task has been completed +@@ -1669,7 +1669,7 @@ out_gem_unload: + intel_teardown_mchbar(dev); + destroy_workqueue(dev_priv->wq); + out_mtrrfree: +- arch_phys_wc_del(dev_priv->mm.gtt_mtrr); ++ arch_phys_wc_del(dev_priv->gtt.mtrr); + io_mapping_free(dev_priv->gtt.mappable); + dev_priv->gtt.gtt_remove(dev); + out_rmmap: +@@ -1707,7 +1707,7 @@ int i915_driver_unload(struct drm_device *dev) + cancel_delayed_work_sync(&dev_priv->mm.retire_work); + + io_mapping_free(dev_priv->gtt.mappable); +- arch_phys_wc_del(dev_priv->mm.gtt_mtrr); ++ arch_phys_wc_del(dev_priv->gtt.mtrr); + + acpi_video_unregister(); + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 4bd72bf26049..cd31abf92e1d 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -470,6 +470,8 @@ struct i915_gtt { + struct page *page; + } scratch; + ++ int mtrr; ++ + /* global gtt ops */ + int (*gtt_probe)(struct drm_device *dev, size_t *gtt_total, + size_t *stolen, phys_addr_t *mappable_base, +@@ -835,8 +837,6 @@ struct i915_gem_mm { + /** Usable portion of the GTT for GEM */ + unsigned long stolen_base; /* limited to low memory (32-bit) */ + +- int gtt_mtrr; +- + /** PPGTT used for aliasing the PPGTT with the GTT */ + struct i915_hw_ppgtt *aliasing_ppgtt; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0412-drm-i915-pixel-multiplier-readout-support-for-pch-po.patch b/patches.baytrail/0412-drm-i915-pixel-multiplier-readout-support-for-pch-po.patch new file mode 100644 index 000000000000..1e4d0e353ac3 --- /dev/null +++ b/patches.baytrail/0412-drm-i915-pixel-multiplier-readout-support-for-pch-po.patch @@ -0,0 +1,77 @@ +From 8a022b924d5437af2370924a2086969dadcaf1c8 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 27 Jun 2013 19:47:19 +0200 +Subject: drm/i915: pixel multiplier readout support for pch ports + +Now that we painstakingly track the shared pch dplls we can finally +implement pixel mutliplier readout support for pch ports, too. + +v2: Undo the temporary hack to disable the sdvo pixel multiplier +cross-checking. + +Cc: Imre Deak +Cc: Jesse Barnes +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit c93f54cf7de31d44b4036d0d1e291172b2bd5743) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 12 ++++++------ + drivers/gpu/drm/i915/intel_sdvo.c | 3 --- + 2 files changed, 6 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 2dff2112def1..8345c2441047 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5812,10 +5812,6 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + + ironlake_get_fdi_m_n_config(crtc, pipe_config); + +- /* XXX: Can't properly read out the pch dpll pixel multiplier +- * since we don't have state tracking for pch clocks yet. */ +- pipe_config->pixel_multiplier = 1; +- + if (HAS_PCH_IBX(dev_priv->dev)) { + pipe_config->shared_dpll = crtc->pipe; + } else { +@@ -5830,6 +5826,11 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + + WARN_ON(!pll->get_hw_state(dev_priv, pll, + &pipe_config->dpll_hw_state)); ++ ++ tmp = pipe_config->dpll_hw_state.dpll; ++ pipe_config->pixel_multiplier = ++ ((tmp & PLL_REF_SDVO_HDMI_MULTIPLIER_MASK) ++ >> PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT) + 1; + } else { + pipe_config->pixel_multiplier = 1; + } +@@ -8084,8 +8085,7 @@ intel_pipe_config_compare(struct drm_device *dev, + PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_start); + PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_end); + +- if (!HAS_PCH_SPLIT(dev)) +- PIPE_CONF_CHECK_I(pixel_multiplier); ++ PIPE_CONF_CHECK_I(pixel_multiplier); + + PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags, + DRM_MODE_FLAG_INTERLACE); +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 2628d5622449..8415d6a610dd 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1370,9 +1370,6 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, + break; + } + +- if(HAS_PCH_SPLIT(dev)) +- return; /* no pixel multiplier readout support yet */ +- + WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier, + "SDVO pixel multiplier mismatch, port: %i, encoder: %i\n", + pipe_config->pixel_multiplier, encoder_pixel_multiplier); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0413-drm-i915-add-fastboot-param-for-fast-loose-mode-sett.patch b/patches.baytrail/0413-drm-i915-add-fastboot-param-for-fast-loose-mode-sett.patch new file mode 100644 index 000000000000..b674be35e1c5 --- /dev/null +++ b/patches.baytrail/0413-drm-i915-add-fastboot-param-for-fast-loose-mode-sett.patch @@ -0,0 +1,52 @@ +From e2e034af7b76954f324b71d8d4832ff76eb4cf61 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Wed, 26 Jun 2013 01:38:15 +0300 +Subject: drm/i915: add fastboot param for fast & loose mode setting + +Handling all the state properly for fastboot is still not yet done by +far, but we need some way to be able to test what we currently have. +So hide the not-yet-quite-complete stuff behind a module option. + +Signed-off-by: Jesse Barnes +[danvet: Add a real commit message.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 2385bdf0787aef45ee1847b8508a417433da7e14) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 5 +++++ + drivers/gpu/drm/i915/i915_drv.h | 1 + + 2 files changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 45b3c030f483..d286785c1bab 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -132,6 +132,11 @@ int i915_enable_ips __read_mostly = 1; + module_param_named(enable_ips, i915_enable_ips, int, 0600); + MODULE_PARM_DESC(enable_ips, "Enable IPS (default: true)"); + ++bool i915_fastboot __read_mostly = 0; ++module_param_named(fastboot, i915_fastboot, bool, 0600); ++MODULE_PARM_DESC(fastboot, "Try to skip unnecessary mode sets at boot time " ++ "(default: false)"); ++ + static struct drm_driver driver; + extern int intel_agp_enabled; + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index cd31abf92e1d..45da73925d02 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1552,6 +1552,7 @@ extern int i915_enable_ppgtt __read_mostly; + extern unsigned int i915_preliminary_hw_support __read_mostly; + extern int i915_disable_power_well __read_mostly; + extern int i915_enable_ips __read_mostly; ++extern bool i915_fastboot __read_mostly; + + extern int i915_suspend(struct drm_device *dev, pm_message_t state); + extern int i915_resume(struct drm_device *dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0414-drm-i915-get-mode-clock-when-reading-the-pipe-config.patch b/patches.baytrail/0414-drm-i915-get-mode-clock-when-reading-the-pipe-config.patch new file mode 100644 index 000000000000..cf779c733894 --- /dev/null +++ b/patches.baytrail/0414-drm-i915-get-mode-clock-when-reading-the-pipe-config.patch @@ -0,0 +1,310 @@ +From c287947be1b0a603ce25bef17b88e23f98673334 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Thu, 27 Jun 2013 00:39:25 +0300 +Subject: drm/i915: get mode clock when reading the pipe config v9 + +We need this for comparing modes between configuration changes. + +The tricky part is to allow us to reuse the new get_clock stuff to +recover the lvds clock on gen2/3 when neither the vbt has an lvds mode +nor the panel a (useful) EDID. + +v2: try harder to calulate non-simple pixel clocks (Daniel) + call get_clock after getting the encoder config, needed for pixel multiply + (Jesse) +v3: drop get_clock now that the pixel_multiply has been moved into + get_pipe_config +v4: re-add get_clock; we need to get the pixel multiplier in the + encoder, so need to calculate the clock value after the encoder's + get_config is called +v5: drop hsw clock_get, still needs to be written +v6: add fuzzy clock check (Daniel) +v7: wrap fuzzy clock check under !IS_HASWELL + use port_clock field rather than a new CPU eDP clock field in crtc_config +v8: remove stale pixel_multiplier sets (Daniel) + multiply by pixel_multiplier in 9xx clock get too (Daniel) +v9: make sure we set pixel_multiplier before calling clock_get from mode_get + for LVDS (Daniel) + +Signed-off-by: Jesse Barnes +[danvet: Add some explanation to the commit message about why we have +to jump through a few hoops. Also remove the rebase-fail hunk from +intel_sdvo.c] +[danvet: Squash in the fixup from Jesse to also call ->get_clock in +the modeset state checker.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit f1f644dc66cbaf5a4c7dcde683361536b41885b9) +(cherry picked from drm-intel-next-queued) +Signed-off-by: James Ausmus + +Conflicts: + drivers/gpu/drm/i915/intel_display.c + (context changes) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/intel_display.c | 126 ++++++++++++++++++++++++++++++++--- + drivers/gpu/drm/i915/intel_dp.c | 7 ++ + 3 files changed, 123 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 45da73925d02..e90b919c0d32 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -367,6 +367,7 @@ struct drm_i915_display_funcs { + * fills out the pipe-config with the hw state. */ + bool (*get_pipe_config)(struct intel_crtc *, + struct intel_crtc_config *); ++ void (*get_clock)(struct intel_crtc *, struct intel_crtc_config *); + int (*crtc_mode_set)(struct drm_crtc *crtc, + int x, int y, + struct drm_framebuffer *old_fb); +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 8345c2441047..2841c79525db 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -45,6 +45,11 @@ bool intel_pipe_has_type(struct drm_crtc *crtc, int type); + static void intel_increase_pllclock(struct drm_crtc *crtc); + static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); + ++static void i9xx_crtc_clock_get(struct intel_crtc *crtc, ++ struct intel_crtc_config *pipe_config); ++static void ironlake_crtc_clock_get(struct intel_crtc *crtc, ++ struct intel_crtc_config *pipe_config); ++ + typedef struct { + int min, max; + } intel_range_t; +@@ -6854,11 +6859,12 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, + } + + /* Returns the clock of the currently programmed mode of the given pipe. */ +-static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) ++static void i9xx_crtc_clock_get(struct intel_crtc *crtc, ++ struct intel_crtc_config *pipe_config) + { ++ struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- int pipe = intel_crtc->pipe; ++ int pipe = pipe_config->cpu_transcoder; + u32 dpll = I915_READ(DPLL(pipe)); + u32 fp; + intel_clock_t clock; +@@ -6897,7 +6903,8 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) + default: + DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed " + "mode\n", (int)(dpll & DPLL_MODE_MASK)); +- return 0; ++ pipe_config->adjusted_mode.clock = 0; ++ return; + } + + if (IS_PINEVIEW(dev)) +@@ -6934,12 +6941,55 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) + } + } + +- /* XXX: It would be nice to validate the clocks, but we can't reuse +- * i830PllIsValid() because it relies on the xf86_config connector +- * configuration being accurate, which it isn't necessarily. ++ pipe_config->adjusted_mode.clock = clock.dot * ++ pipe_config->pixel_multiplier; ++} ++ ++static void ironlake_crtc_clock_get(struct intel_crtc *crtc, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; ++ int link_freq, repeat; ++ u64 clock; ++ u32 link_m, link_n; ++ ++ repeat = pipe_config->pixel_multiplier; ++ ++ /* ++ * The calculation for the data clock is: ++ * pixel_clock = ((m/n)*(link_clock * nr_lanes * repeat))/bpp ++ * But we want to avoid losing precison if possible, so: ++ * pixel_clock = ((m * link_clock * nr_lanes * repeat)/(n*bpp)) ++ * ++ * and the link clock is simpler: ++ * link_clock = (m * link_clock * repeat) / n ++ */ ++ ++ /* ++ * We need to get the FDI or DP link clock here to derive ++ * the M/N dividers. ++ * ++ * For FDI, we read it from the BIOS or use a fixed 2.7GHz. ++ * For DP, it's either 1.62GHz or 2.7GHz. ++ * We do our calculations in 10*MHz since we don't need much precison. + */ ++ if (pipe_config->has_pch_encoder) ++ link_freq = intel_fdi_link_freq(dev) * 10000; ++ else ++ link_freq = pipe_config->port_clock; ++ ++ link_m = I915_READ(PIPE_LINK_M1(cpu_transcoder)); ++ link_n = I915_READ(PIPE_LINK_N1(cpu_transcoder)); ++ ++ if (!link_m || !link_n) ++ return; ++ ++ clock = ((u64)link_m * (u64)link_freq * (u64)repeat); ++ do_div(clock, link_n); + +- return clock.dot; ++ pipe_config->adjusted_mode.clock = clock; + } + + /** Returns the currently programmed mode of the given pipe. */ +@@ -6950,6 +7000,7 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; + struct drm_display_mode *mode; ++ struct intel_crtc_config pipe_config; + int htot = I915_READ(HTOTAL(cpu_transcoder)); + int hsync = I915_READ(HSYNC(cpu_transcoder)); + int vtot = I915_READ(VTOTAL(cpu_transcoder)); +@@ -6959,7 +7010,18 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, + if (!mode) + return NULL; + +- mode->clock = intel_crtc_clock_get(dev, crtc); ++ /* ++ * Construct a pipe_config sufficient for getting the clock info ++ * back out of crtc_clock_get. ++ * ++ * Note, if LVDS ever uses a non-1 pixel multiplier, we'll need ++ * to use a real value here instead. ++ */ ++ pipe_config.cpu_transcoder = intel_crtc->pipe; ++ pipe_config.pixel_multiplier = 1; ++ i9xx_crtc_clock_get(intel_crtc, &pipe_config); ++ ++ mode->clock = pipe_config.adjusted_mode.clock; + mode->hdisplay = (htot & 0xffff) + 1; + mode->htotal = ((htot & 0xffff0000) >> 16) + 1; + mode->hsync_start = (hsync & 0xffff) + 1; +@@ -8020,6 +8082,28 @@ intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes) + + } + ++static bool intel_fuzzy_clock_check(struct intel_crtc_config *cur, ++ struct intel_crtc_config *new) ++{ ++ int clock1, clock2, diff; ++ ++ clock1 = cur->adjusted_mode.clock; ++ clock2 = new->adjusted_mode.clock; ++ ++ if (clock1 == clock2) ++ return true; ++ ++ if (!clock1 || !clock2) ++ return false; ++ ++ diff = abs(clock1 - clock2); ++ ++ if (((((diff + clock1 + clock2) * 100)) / (clock1 + clock2)) < 105) ++ return true; ++ ++ return false; ++} ++ + #define for_each_intel_crtc_masked(dev, mask, intel_crtc) \ + list_for_each_entry((intel_crtc), \ + &(dev)->mode_config.crtc_list, \ +@@ -8125,6 +8209,15 @@ intel_pipe_config_compare(struct drm_device *dev, + #undef PIPE_CONF_CHECK_FLAGS + #undef PIPE_CONF_QUIRK + ++ if (!IS_HASWELL(dev)) { ++ if (!intel_fuzzy_clock_check(current_config, pipe_config)) { ++ DRM_ERROR("mismatch in clock (expected %d, found %d\n", ++ current_config->adjusted_mode.clock, ++ pipe_config->adjusted_mode.clock); ++ return false; ++ } ++ } ++ + return true; + } + +@@ -8252,8 +8345,12 @@ check_crtc_state(struct drm_device *dev) + if (encoder->base.crtc != &crtc->base) + continue; + if (encoder->get_config && +- encoder->get_hw_state(encoder, &pipe)) ++ encoder->get_hw_state(encoder, &pipe) && ++ dev_priv->display.get_clock) { + encoder->get_config(encoder, &pipe_config); ++ dev_priv->display.get_clock(crtc, ++ &pipe_config); ++ } + } + + WARN(crtc->active != active, +@@ -9261,6 +9358,7 @@ static void intel_init_display(struct drm_device *dev) + dev_priv->display.update_plane = ironlake_update_plane; + } else if (HAS_PCH_SPLIT(dev)) { + dev_priv->display.get_pipe_config = ironlake_get_pipe_config; ++ dev_priv->display.get_clock = ironlake_crtc_clock_get; + dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set; + dev_priv->display.crtc_enable = ironlake_crtc_enable; + dev_priv->display.crtc_disable = ironlake_crtc_disable; +@@ -9268,6 +9366,7 @@ static void intel_init_display(struct drm_device *dev) + dev_priv->display.update_plane = ironlake_update_plane; + } else if (IS_VALLEYVIEW(dev)) { + dev_priv->display.get_pipe_config = i9xx_get_pipe_config; ++ dev_priv->display.get_clock = i9xx_crtc_clock_get; + dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; + dev_priv->display.crtc_enable = valleyview_crtc_enable; + dev_priv->display.crtc_disable = i9xx_crtc_disable; +@@ -9275,6 +9374,7 @@ static void intel_init_display(struct drm_device *dev) + dev_priv->display.update_plane = i9xx_update_plane; + } else { + dev_priv->display.get_pipe_config = i9xx_get_pipe_config; ++ dev_priv->display.get_clock = i9xx_crtc_clock_get; + dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; + dev_priv->display.crtc_enable = i9xx_crtc_enable; + dev_priv->display.crtc_disable = i9xx_crtc_disable; +@@ -9837,8 +9937,12 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) + if (encoder->get_hw_state(encoder, &pipe)) { + crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); + encoder->base.crtc = &crtc->base; +- if (encoder->get_config) ++ if (encoder->get_config && ++ dev_priv->display.get_clock) { + encoder->get_config(encoder, &crtc->config); ++ dev_priv->display.get_clock(crtc, ++ &crtc->config); ++ } + } else { + encoder->base.crtc = NULL; + } +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 3aed1fe0aa51..9d90d4350ebf 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1371,6 +1371,13 @@ static void intel_dp_get_config(struct intel_encoder *encoder, + } + + pipe_config->adjusted_mode.flags |= flags; ++ ++ if (dp_to_dig_port(intel_dp)->port == PORT_A) { ++ if ((I915_READ(DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_160MHZ) ++ pipe_config->port_clock = 162000; ++ else ++ pipe_config->port_clock = 270000; ++ } + } + + static void intel_disable_dp(struct intel_encoder *encoder) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0415-drm-i915-copy-fetched-mode-state-into-crtc-at-setup_.patch b/patches.baytrail/0415-drm-i915-copy-fetched-mode-state-into-crtc-at-setup_.patch new file mode 100644 index 000000000000..f9cc5f88b248 --- /dev/null +++ b/patches.baytrail/0415-drm-i915-copy-fetched-mode-state-into-crtc-at-setup_.patch @@ -0,0 +1,81 @@ +From dfa9d3dad396183266cd7a9e5197113a0fcbda0a Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Wed, 26 Jun 2013 18:57:38 +0300 +Subject: drm/i915: copy fetched mode state into crtc at setup_hw time v5 + +We already fetch and track other state into the main CRTC and encoder +structs, and for fastboot we need to do the same with the mode and clock +data we read out. + +v2: fix debug print +v3: use fastboot param around state copy +v4: set clock and flags for crtc here instead of in setup_hw_state +v5: rename function to intel_crtc_mode_from_pipe_config for consistency (Chris) + +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit babea61dfb82b4bdfdbc57ebf081ef6c16ffd524) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 37 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 2841c79525db..3199691d6a51 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4712,6 +4712,27 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc, + pipe_config->requested_mode.hdisplay = ((tmp >> 16) & 0xffff) + 1; + } + ++static void intel_crtc_mode_from_pipe_config(struct intel_crtc *intel_crtc, ++ struct intel_crtc_config *pipe_config) ++{ ++ struct drm_crtc *crtc = &intel_crtc->base; ++ ++ crtc->mode.hdisplay = pipe_config->adjusted_mode.crtc_hdisplay; ++ crtc->mode.htotal = pipe_config->adjusted_mode.crtc_htotal; ++ crtc->mode.hsync_start = pipe_config->adjusted_mode.crtc_hsync_start; ++ crtc->mode.hsync_end = pipe_config->adjusted_mode.crtc_hsync_end; ++ ++ crtc->mode.vdisplay = pipe_config->adjusted_mode.crtc_vdisplay; ++ crtc->mode.vtotal = pipe_config->adjusted_mode.crtc_vtotal; ++ crtc->mode.vsync_start = pipe_config->adjusted_mode.crtc_vsync_start; ++ crtc->mode.vsync_end = pipe_config->adjusted_mode.crtc_vsync_end; ++ ++ crtc->mode.flags = pipe_config->adjusted_mode.flags; ++ ++ crtc->mode.clock = pipe_config->adjusted_mode.clock; ++ crtc->mode.flags |= pipe_config->adjusted_mode.flags; ++} ++ + static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) + { + struct drm_device *dev = intel_crtc->base.dev; +@@ -9986,6 +10007,22 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, + + intel_modeset_readout_hw_state(dev); + ++ /* ++ * Now that we have the config, copy it to each CRTC struct ++ * Note that this could go away if we move to using crtc_config ++ * checking everywhere. ++ */ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, ++ base.head) { ++ if (crtc->active && i915_fastboot) { ++ intel_crtc_mode_from_pipe_config(crtc, &crtc->config); ++ ++ DRM_DEBUG_KMS("[CRTC:%d] found active mode: ", ++ crtc->base.base.id); ++ drm_mode_debug_printmodeline(&crtc->base.mode); ++ } ++ } ++ + /* HW state is read out, now we need to sanitize this mess. */ + list_for_each_entry(encoder, &dev->mode_config.encoder_list, + base.head) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0416-drm-i915-turn-off-panel-fitting-at-flip-time-if-need.patch b/patches.baytrail/0416-drm-i915-turn-off-panel-fitting-at-flip-time-if-need.patch new file mode 100644 index 000000000000..ff12b0e8ecd4 --- /dev/null +++ b/patches.baytrail/0416-drm-i915-turn-off-panel-fitting-at-flip-time-if-need.patch @@ -0,0 +1,46 @@ +From cc4427d0ef99f61802d2f3e4284f905dc67ab24f Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Wed, 26 Jun 2013 01:38:18 +0300 +Subject: drm/i915: turn off panel fitting at flip time if needed v2 + +Need better pfit tracking to do this right. + +v2: use fastboot param around this hack + +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 4d6a3e63bce0cb604864e36585ca8983160a421a) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 3199691d6a51..eddd57bb1673 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2221,6 +2221,20 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, + return ret; + } + ++ /* Update pipe size and adjust fitter if needed */ ++ if (i915_fastboot) { ++ I915_WRITE(PIPESRC(intel_crtc->pipe), ++ ((crtc->mode.hdisplay - 1) << 16) | ++ (crtc->mode.vdisplay - 1)); ++ if (!intel_crtc->config.pch_pfit.size && ++ (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || ++ intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { ++ I915_WRITE(PF_CTL(intel_crtc->pipe), 0); ++ I915_WRITE(PF_WIN_POS(intel_crtc->pipe), 0); ++ I915_WRITE(PF_WIN_SZ(intel_crtc->pipe), 0); ++ } ++ } ++ + ret = dev_priv->display.update_plane(crtc, fb, x, y); + if (ret) { + intel_unpin_fb_obj(to_intel_framebuffer(fb)->obj); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0417-drm-i915-flip-on-a-no-fb-fb-transition-if-crtc-is-ac.patch b/patches.baytrail/0417-drm-i915-flip-on-a-no-fb-fb-transition-if-crtc-is-ac.patch new file mode 100644 index 000000000000..1edd734e0a49 --- /dev/null +++ b/patches.baytrail/0417-drm-i915-flip-on-a-no-fb-fb-transition-if-crtc-is-ac.patch @@ -0,0 +1,47 @@ +From 3d05616831acc6afac7036387417554257a7e047 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Wed, 26 Jun 2013 01:38:19 +0300 +Subject: drm/i915: flip on a no fb -> fb transition if crtc is active v3 + +If the crtc is active, we can simply flip a new fb onto it, provided the +other mode setting reqs are met. Otherwise, we'll need to do a full +mode set to re-enable the crtc. + +v2: check for crtc active and set mode_changed accordingly +v3: add module parameter, i915.fastboot, to control no fb -> fb flip behavior + +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 319d9827ebb55d58d1b02d8a4eba48bbb2702376) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index eddd57bb1673..b902399f367f 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8684,8 +8684,16 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set, + } else if (set->crtc->fb != set->fb) { + /* If we have no fb then treat it as a full mode set */ + if (set->crtc->fb == NULL) { +- DRM_DEBUG_KMS("crtc has no fb, full mode set\n"); +- config->mode_changed = true; ++ struct intel_crtc *intel_crtc = ++ to_intel_crtc(set->crtc); ++ ++ if (intel_crtc->active && i915_fastboot) { ++ DRM_DEBUG_KMS("crtc has no fb, will flip\n"); ++ config->fb_changed = true; ++ } else { ++ DRM_DEBUG_KMS("inactive crtc, full mode set\n"); ++ config->mode_changed = true; ++ } + } else if (set->fb == NULL) { + config->mode_changed = true; + } else if (set->fb->pixel_format != +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0418-drm-i915-export-error-state-to-string-conversion.patch b/patches.baytrail/0418-drm-i915-export-error-state-to-string-conversion.patch new file mode 100644 index 000000000000..bb2b01cc17c2 --- /dev/null +++ b/patches.baytrail/0418-drm-i915-export-error-state-to-string-conversion.patch @@ -0,0 +1,107 @@ +From 25e27302c30bff1c1142f5947ca3514fb1efb447 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Thu, 6 Jun 2013 15:18:39 +0300 +Subject: drm/i915: export error state to string conversion + +In preparation for accessing error state from sysfs, export +error state to string conversion function. Also tuck buffer +error handling inside the function. + +Signed-off-by: Mika Kuoppala +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit fc16b48be665d94337a861486dd25499971742a2) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 24 ++++++++---------------- + drivers/gpu/drm/i915/i915_drv.h | 7 +++++++ + 2 files changed, 15 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index f82134f8e9fb..b64af15eb388 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -830,15 +830,8 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m, + err_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); + } + +-struct i915_error_state_file_priv { +- struct drm_device *dev; +- struct drm_i915_error_state *error; +-}; +- +- +-static int i915_error_state(struct i915_error_state_file_priv *error_priv, +- struct drm_i915_error_state_buf *m) +- ++int i915_error_state_to_str(struct drm_i915_error_state_buf *m, ++ const struct i915_error_state_file_priv *error_priv) + { + struct drm_device *dev = error_priv->dev; + drm_i915_private_t *dev_priv = dev->dev_private; +@@ -848,7 +841,7 @@ static int i915_error_state(struct i915_error_state_file_priv *error_priv, + + if (!error) { + err_printf(m, "no error state collected\n"); +- return 0; ++ goto out; + } + + err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, +@@ -958,6 +951,10 @@ static int i915_error_state(struct i915_error_state_file_priv *error_priv, + if (error->display) + intel_display_print_error_state(m, dev, error->display); + ++out: ++ if (m->bytes == 0 && m->err) ++ return m->err; ++ + return 0; + } + +@@ -1051,15 +1048,10 @@ static ssize_t i915_error_state_read(struct file *file, char __user *userbuf, + + error_str.start = *pos; + +- ret = i915_error_state(error_priv, &error_str); ++ ret = i915_error_state_to_str(&error_str, error_priv); + if (ret) + goto out; + +- if (error_str.bytes == 0 && error_str.err) { +- ret = error_str.err; +- goto out; +- } +- + ret_count = simple_read_from_buffer(userbuf, count, &tmp_pos, + error_str.buf, + error_str.bytes); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index e90b919c0d32..e4ac32298055 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -917,6 +917,11 @@ struct drm_i915_error_state_buf { + loff_t pos; + }; + ++struct i915_error_state_file_priv { ++ struct drm_device *dev; ++ struct drm_i915_error_state *error; ++}; ++ + struct i915_gpu_error { + /* For hangcheck timer */ + #define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */ +@@ -1925,6 +1930,8 @@ int i915_debugfs_init(struct drm_minor *minor); + void i915_debugfs_cleanup(struct drm_minor *minor); + __printf(2, 3) + void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...); ++int i915_error_state_to_str(struct drm_i915_error_state_buf *estr, ++ const struct i915_error_state_file_priv *error); + + /* i915_suspend.c */ + extern int i915_save_state(struct drm_device *dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0419-drm-i915-export-error-state-ref-handling.patch b/patches.baytrail/0419-drm-i915-export-error-state-ref-handling.patch new file mode 100644 index 000000000000..6933c95ec6ad --- /dev/null +++ b/patches.baytrail/0419-drm-i915-export-error-state-ref-handling.patch @@ -0,0 +1,96 @@ +From 3eeb61347413b883d9dfd0d2f98b97ecfd9429f0 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Thu, 6 Jun 2013 15:18:40 +0300 +Subject: drm/i915: export error state ref handling + +In preparation for sysfs error state access, +export ref error state ref counting interface. + +Signed-off-by: Mika Kuoppala +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 95d5bfb3ac4cf5d7311f496761506c676f6b6323) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 31 ++++++++++++++++++++++--------- + drivers/gpu/drm/i915/i915_drv.h | 3 +++ + 2 files changed, 25 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index b64af15eb388..eef4c01ab61a 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -980,12 +980,30 @@ i915_error_state_write(struct file *filp, + return cnt; + } + ++void i915_error_state_get(struct drm_device *dev, ++ struct i915_error_state_file_priv *error_priv) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); ++ error_priv->error = dev_priv->gpu_error.first_error; ++ if (error_priv->error) ++ kref_get(&error_priv->error->ref); ++ spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); ++ ++} ++ ++void i915_error_state_put(struct i915_error_state_file_priv *error_priv) ++{ ++ if (error_priv->error) ++ kref_put(&error_priv->error->ref, i915_error_state_free); ++} ++ + static int i915_error_state_open(struct inode *inode, struct file *file) + { + struct drm_device *dev = inode->i_private; +- drm_i915_private_t *dev_priv = dev->dev_private; + struct i915_error_state_file_priv *error_priv; +- unsigned long flags; + + error_priv = kzalloc(sizeof(*error_priv), GFP_KERNEL); + if (!error_priv) +@@ -993,11 +1011,7 @@ static int i915_error_state_open(struct inode *inode, struct file *file) + + error_priv->dev = dev; + +- spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); +- error_priv->error = dev_priv->gpu_error.first_error; +- if (error_priv->error) +- kref_get(&error_priv->error->ref); +- spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); ++ i915_error_state_get(dev, error_priv); + + file->private_data = error_priv; + +@@ -1008,8 +1022,7 @@ static int i915_error_state_release(struct inode *inode, struct file *file) + { + struct i915_error_state_file_priv *error_priv = file->private_data; + +- if (error_priv->error) +- kref_put(&error_priv->error->ref, i915_error_state_free); ++ i915_error_state_put(error_priv); + kfree(error_priv); + + return 0; +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index e4ac32298055..90ec48ed8052 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1932,6 +1932,9 @@ __printf(2, 3) + void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...); + int i915_error_state_to_str(struct drm_i915_error_state_buf *estr, + const struct i915_error_state_file_priv *error); ++void i915_error_state_get(struct drm_device *dev, ++ struct i915_error_state_file_priv *error_priv); ++void i915_error_state_put(struct i915_error_state_file_priv *error_priv); + + /* i915_suspend.c */ + extern int i915_save_state(struct drm_device *dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0420-drm-i915-introduce-i915_error_state_buf_init.patch b/patches.baytrail/0420-drm-i915-introduce-i915_error_state_buf_init.patch new file mode 100644 index 000000000000..e6daac194b31 --- /dev/null +++ b/patches.baytrail/0420-drm-i915-introduce-i915_error_state_buf_init.patch @@ -0,0 +1,121 @@ +From 4d17c0d8e4dc0176158bfe66d3520023de5252d0 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Thu, 6 Jun 2013 15:18:41 +0300 +Subject: drm/i915: introduce i915_error_state_buf_init + +Make function for struct i915_error_state_buf initialization +and export it, for sysfs and debugfs. + +Signed-off-by: Mika Kuoppala +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 4dc955f7f5241a92767e2b3ffd74f49a82938999) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 50 ++++++++++++++++++++++--------------- + drivers/gpu/drm/i915/i915_drv.h | 7 ++++++ + 2 files changed, 37 insertions(+), 20 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index eef4c01ab61a..3e36756d0439 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1028,38 +1028,48 @@ static int i915_error_state_release(struct inode *inode, struct file *file) + return 0; + } + +-static ssize_t i915_error_state_read(struct file *file, char __user *userbuf, +- size_t count, loff_t *pos) ++int i915_error_state_buf_init(struct drm_i915_error_state_buf *ebuf, ++ size_t count, loff_t pos) + { +- struct i915_error_state_file_priv *error_priv = file->private_data; +- struct drm_i915_error_state_buf error_str; +- loff_t tmp_pos = 0; +- ssize_t ret_count = 0; +- int ret = 0; +- +- memset(&error_str, 0, sizeof(error_str)); ++ memset(ebuf, 0, sizeof(*ebuf)); + + /* We need to have enough room to store any i915_error_state printf + * so that we can move it to start position. + */ +- error_str.size = count + 1 > PAGE_SIZE ? count + 1 : PAGE_SIZE; +- error_str.buf = kmalloc(error_str.size, ++ ebuf->size = count + 1 > PAGE_SIZE ? count + 1 : PAGE_SIZE; ++ ebuf->buf = kmalloc(ebuf->size, + GFP_TEMPORARY | __GFP_NORETRY | __GFP_NOWARN); + +- if (error_str.buf == NULL) { +- error_str.size = PAGE_SIZE; +- error_str.buf = kmalloc(error_str.size, GFP_TEMPORARY); ++ if (ebuf->buf == NULL) { ++ ebuf->size = PAGE_SIZE; ++ ebuf->buf = kmalloc(ebuf->size, GFP_TEMPORARY); + } + +- if (error_str.buf == NULL) { +- error_str.size = 128; +- error_str.buf = kmalloc(error_str.size, GFP_TEMPORARY); ++ if (ebuf->buf == NULL) { ++ ebuf->size = 128; ++ ebuf->buf = kmalloc(ebuf->size, GFP_TEMPORARY); + } + +- if (error_str.buf == NULL) ++ if (ebuf->buf == NULL) + return -ENOMEM; + +- error_str.start = *pos; ++ ebuf->start = pos; ++ ++ return 0; ++} ++ ++static ssize_t i915_error_state_read(struct file *file, char __user *userbuf, ++ size_t count, loff_t *pos) ++{ ++ struct i915_error_state_file_priv *error_priv = file->private_data; ++ struct drm_i915_error_state_buf error_str; ++ loff_t tmp_pos = 0; ++ ssize_t ret_count = 0; ++ int ret; ++ ++ ret = i915_error_state_buf_init(&error_str, count, *pos); ++ if (ret) ++ return ret; + + ret = i915_error_state_to_str(&error_str, error_priv); + if (ret) +@@ -1074,7 +1084,7 @@ static ssize_t i915_error_state_read(struct file *file, char __user *userbuf, + else + *pos = error_str.start + ret_count; + out: +- kfree(error_str.buf); ++ i915_error_state_buf_release(&error_str); + return ret ?: ret_count; + } + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 90ec48ed8052..98dfe0cbd2be 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1935,6 +1935,13 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *estr, + void i915_error_state_get(struct drm_device *dev, + struct i915_error_state_file_priv *error_priv); + void i915_error_state_put(struct i915_error_state_file_priv *error_priv); ++int i915_error_state_buf_init(struct drm_i915_error_state_buf *eb, ++ size_t count, loff_t pos); ++static inline void i915_error_state_buf_release( ++ struct drm_i915_error_state_buf *eb) ++{ ++ kfree(eb->buf); ++} + + /* i915_suspend.c */ + extern int i915_save_state(struct drm_device *dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0421-drm-i915-add-error_state-sysfs-entry.patch b/patches.baytrail/0421-drm-i915-add-error_state-sysfs-entry.patch new file mode 100644 index 000000000000..a1b31234a2dc --- /dev/null +++ b/patches.baytrail/0421-drm-i915-add-error_state-sysfs-entry.patch @@ -0,0 +1,138 @@ +From 76f8e27cd3b6f23dcf858f9adc0179cfd98cefb8 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Thu, 6 Jun 2013 17:38:54 +0300 +Subject: drm/i915: add error_state sysfs entry + +As getting error state doesn't anymore require big kmallocs, +make error state accessible also from sysfs. + +v2: - error state clearing (Chris Wilson) + - user hint, proper access mode bits and name (Daniel Vetter) + +v3: release resources in proper order (Chris Wilson) + +Suggested-by: Daniel Vetter +Signed-off-by: Mika Kuoppala +Reviewed-by: Chris Wilson +[danvet: Apply Chris' s/error_state/error/ bikeshed on the sysfs +name. Also update the dmesg message, spotted by Chris.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit ef86ddced720fddc3835558447a7f594d3609c73) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 3 +- + drivers/gpu/drm/i915/i915_sysfs.c | 71 +++++++++++++++++++++++++++++++++++++++ + 2 files changed, 72 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index a53d1d3040eb..7564063ecc70 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1955,8 +1955,7 @@ static void i915_capture_error_state(struct drm_device *dev) + } + + DRM_INFO("capturing error event; look for more information in " +- "/sys/kernel/debug/dri/%d/i915_error_state\n", +- dev->primary->index); ++ "/sys/class/drm/card%d/error\n", dev->primary->index); + + kref_init(&error->ref); + error->eir = I915_READ(EIR); +diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c +index 6875b5654c63..a777e7f3b0df 100644 +--- a/drivers/gpu/drm/i915/i915_sysfs.c ++++ b/drivers/gpu/drm/i915/i915_sysfs.c +@@ -409,6 +409,71 @@ static const struct attribute *gen6_attrs[] = { + NULL, + }; + ++static ssize_t error_state_read(struct file *filp, struct kobject *kobj, ++ struct bin_attribute *attr, char *buf, ++ loff_t off, size_t count) ++{ ++ ++ struct device *kdev = container_of(kobj, struct device, kobj); ++ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev); ++ struct drm_device *dev = minor->dev; ++ struct i915_error_state_file_priv error_priv; ++ struct drm_i915_error_state_buf error_str; ++ ssize_t ret_count = 0; ++ int ret; ++ ++ memset(&error_priv, 0, sizeof(error_priv)); ++ ++ ret = i915_error_state_buf_init(&error_str, count, off); ++ if (ret) ++ return ret; ++ ++ error_priv.dev = dev; ++ i915_error_state_get(dev, &error_priv); ++ ++ ret = i915_error_state_to_str(&error_str, &error_priv); ++ if (ret) ++ goto out; ++ ++ ret_count = count < error_str.bytes ? count : error_str.bytes; ++ ++ memcpy(buf, error_str.buf, ret_count); ++out: ++ i915_error_state_put(&error_priv); ++ i915_error_state_buf_release(&error_str); ++ ++ return ret ?: ret_count; ++} ++ ++static ssize_t error_state_write(struct file *file, struct kobject *kobj, ++ struct bin_attribute *attr, char *buf, ++ loff_t off, size_t count) ++{ ++ struct device *kdev = container_of(kobj, struct device, kobj); ++ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev); ++ struct drm_device *dev = minor->dev; ++ int ret; ++ ++ DRM_DEBUG_DRIVER("Resetting error state\n"); ++ ++ ret = mutex_lock_interruptible(&dev->struct_mutex); ++ if (ret) ++ return ret; ++ ++ i915_destroy_error_state(dev); ++ mutex_unlock(&dev->struct_mutex); ++ ++ return count; ++} ++ ++static struct bin_attribute error_state_attr = { ++ .attr.name = "error", ++ .attr.mode = S_IRUSR | S_IWUSR, ++ .size = 0, ++ .read = error_state_read, ++ .write = error_state_write, ++}; ++ + void i915_setup_sysfs(struct drm_device *dev) + { + int ret; +@@ -432,10 +497,16 @@ void i915_setup_sysfs(struct drm_device *dev) + if (ret) + DRM_ERROR("gen6 sysfs setup failed\n"); + } ++ ++ ret = sysfs_create_bin_file(&dev->primary->kdev.kobj, ++ &error_state_attr); ++ if (ret) ++ DRM_ERROR("error_state sysfs setup failed\n"); + } + + void i915_teardown_sysfs(struct drm_device *dev) + { ++ sysfs_remove_bin_file(&dev->primary->kdev.kobj, &error_state_attr); + sysfs_remove_files(&dev->primary->kdev.kobj, gen6_attrs); + device_remove_bin_file(&dev->primary->kdev, &dpf_attrs); + #ifdef CONFIG_PM +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0422-drm-i915-fixup-messages-in-pipe_config_compare.patch b/patches.baytrail/0422-drm-i915-fixup-messages-in-pipe_config_compare.patch new file mode 100644 index 000000000000..38f40ada7882 --- /dev/null +++ b/patches.baytrail/0422-drm-i915-fixup-messages-in-pipe_config_compare.patch @@ -0,0 +1,41 @@ +From 10a2b7443fcf4d6ee975d992252d2e1a1a55c009 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Mon, 1 Jul 2013 10:19:09 -0700 +Subject: drm/i915: fixup messages in pipe_config_compare + +Print out the flag that failed and fix up a mismatched paren. + +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 6f02488e3a5cbd76974b9d56140b11f3aa012124) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index b902399f367f..1910cc9725fa 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8170,7 +8170,7 @@ intel_pipe_config_compare(struct drm_device *dev, + + #define PIPE_CONF_CHECK_FLAGS(name, mask) \ + if ((current_config->name ^ pipe_config->name) & (mask)) { \ +- DRM_ERROR("mismatch in " #name " " \ ++ DRM_ERROR("mismatch in " #name "(" #mask ") " \ + "(expected %i, found %i)\n", \ + current_config->name & (mask), \ + pipe_config->name & (mask)); \ +@@ -8246,7 +8246,7 @@ intel_pipe_config_compare(struct drm_device *dev, + + if (!IS_HASWELL(dev)) { + if (!intel_fuzzy_clock_check(current_config, pipe_config)) { +- DRM_ERROR("mismatch in clock (expected %d, found %d\n", ++ DRM_ERROR("mismatch in clock (expected %d, found %d)\n", + current_config->adjusted_mode.clock, + pipe_config->adjusted_mode.clock); + return false; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0423-drm-i915-split-encoder-get_config-calls-from-crtc-ge.patch b/patches.baytrail/0423-drm-i915-split-encoder-get_config-calls-from-crtc-ge.patch new file mode 100644 index 000000000000..0d321e2fdb27 --- /dev/null +++ b/patches.baytrail/0423-drm-i915-split-encoder-get_config-calls-from-crtc-ge.patch @@ -0,0 +1,78 @@ +From 4c5e3cb13c3d32e550f87b4c7c088330be170a2a Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Mon, 1 Jul 2013 15:50:17 -0700 +Subject: drm/i915: split encoder get_config calls from crtc get_clock calls + +This should help on HSW, where we don't currently have a get_clock call. + +Reported-by: Paulo Zanoni +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 510d5f2f6b97eccbfa08234e21b0577c1748807d) +(cherry picked from drm-intel-next-queued) +Signed-off-by: James Ausmus + +Conflicts: + drivers/gpu/drm/i915/intel_display.c + (context changes) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 1910cc9725fa..87c5d76a7361 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8380,14 +8380,13 @@ check_crtc_state(struct drm_device *dev) + if (encoder->base.crtc != &crtc->base) + continue; + if (encoder->get_config && +- encoder->get_hw_state(encoder, &pipe) && +- dev_priv->display.get_clock) { ++ encoder->get_hw_state(encoder, &pipe)) + encoder->get_config(encoder, &pipe_config); +- dev_priv->display.get_clock(crtc, +- &pipe_config); +- } + } + ++ if (dev_priv->display.get_clock) ++ dev_priv->display.get_clock(crtc, &pipe_config); ++ + WARN(crtc->active != active, + "crtc active state doesn't match with hw state " + "(expected %i, found %i)\n", crtc->active, active); +@@ -9980,12 +9979,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) + if (encoder->get_hw_state(encoder, &pipe)) { + crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); + encoder->base.crtc = &crtc->base; +- if (encoder->get_config && +- dev_priv->display.get_clock) { ++ if (encoder->get_config) + encoder->get_config(encoder, &crtc->config); +- dev_priv->display.get_clock(crtc, +- &crtc->config); +- } + } else { + encoder->base.crtc = NULL; + } +@@ -9998,6 +9993,15 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) + pipe); + } + ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, ++ base.head) { ++ if (!crtc->active) ++ continue; ++ if (dev_priv->display.get_clock) ++ dev_priv->display.get_clock(crtc, ++ &crtc->config); ++ } ++ + list_for_each_entry(connector, &dev->mode_config.connector_list, + base.head) { + if (connector->get_hw_state(connector)) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0424-drm-i915-Use-wait_for-to-wait-for-Punit-to-change-GP.patch b/patches.baytrail/0424-drm-i915-Use-wait_for-to-wait-for-Punit-to-change-GP.patch new file mode 100644 index 000000000000..3829740b0f44 --- /dev/null +++ b/patches.baytrail/0424-drm-i915-Use-wait_for-to-wait-for-Punit-to-change-GP.patch @@ -0,0 +1,70 @@ +From 32a1e9c9ae4dfc6539b02de59424f48791bf83f9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 26 Jun 2013 17:43:24 +0300 +Subject: drm/i915: Use wait_for() to wait for Punit to change GPU freq on VLV +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use wait_for() instead of the open coded loop to avoid spreading the +same old timeout related bugs. + +This changes the loop to use msleep(1) instead of udelay(10) when the +Punit had not yet completed the frequency change. In practice that +doesn't seem to hurt performance as the Punit appears to be ready pretty +much always. + +Also give the status bit a name, instead of using the magic number 1. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit e8474409d7ab6dac38d4a3a6a365504b302f6c16) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 1 + + drivers/gpu/drm/i915/intel_pm.c | 11 ++--------- + 2 files changed, 3 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 342f1f336168..d8278254bca3 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -363,6 +363,7 @@ + #define PUNIT_REG_GPU_LFM 0xd3 + #define PUNIT_REG_GPU_FREQ_REQ 0xd4 + #define PUNIT_REG_GPU_FREQ_STS 0xd8 ++#define GENFREQSTATUS (1<<0) + #define PUNIT_REG_MEDIA_TURBO_FREQ_REQ 0xdc + + #define PUNIT_FUSE_BUS2 0xf6 /* bits 47:40 */ +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 940311fcee64..91471e6f23cd 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3075,19 +3075,12 @@ void gen6_set_rps(struct drm_device *dev, u8 val) + */ + static void vlv_update_rps_cur_delay(struct drm_i915_private *dev_priv) + { +- unsigned long timeout = jiffies + msecs_to_jiffies(10); + u32 pval; + + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); + +- do { +- pval = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); +- if (time_after(jiffies, timeout)) { +- DRM_DEBUG_DRIVER("timed out waiting for Punit\n"); +- break; +- } +- udelay(10); +- } while (pval & 1); ++ if (wait_for(((pval = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS)) & GENFREQSTATUS) == 0, 10)) ++ DRM_DEBUG_DRIVER("timed out waiting for Punit\n"); + + pval >>= 8; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0425-drm-i915-explicitly-cast-pipe-cpu_transcoder.patch b/patches.baytrail/0425-drm-i915-explicitly-cast-pipe-cpu_transcoder.patch new file mode 100644 index 000000000000..47fa16e703aa --- /dev/null +++ b/patches.baytrail/0425-drm-i915-explicitly-cast-pipe-cpu_transcoder.patch @@ -0,0 +1,72 @@ +From 738e64e47af0f3a3364a7142a27eaf78db2329fc Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 4 Jul 2013 12:01:15 +0200 +Subject: drm/i915: explicitly cast pipe -> cpu_transcoder + +This makes sparse happy and also makes it a bit more obvious where we +pull off this trick - after all we're only allowed to do it eithe as a +default or on platforms where there is no disdinction between the pipe +and the cpu transcoder. + +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit e143a21c4d60d13dbdad133b7b2c9d9bb2dfb982) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 87c5d76a7361..08217b92f33d 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4963,7 +4963,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t tmp; + +- pipe_config->cpu_transcoder = crtc->pipe; ++ pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; + pipe_config->shared_dpll = DPLL_ID_PRIVATE; + + tmp = I915_READ(PIPECONF(crtc->pipe)); +@@ -5834,7 +5834,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t tmp; + +- pipe_config->cpu_transcoder = crtc->pipe; ++ pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; + pipe_config->shared_dpll = DPLL_ID_PRIVATE; + + tmp = I915_READ(PIPECONF(crtc->pipe)); +@@ -5950,7 +5950,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, + enum intel_display_power_domain pfit_domain; + uint32_t tmp; + +- pipe_config->cpu_transcoder = crtc->pipe; ++ pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; + pipe_config->shared_dpll = DPLL_ID_PRIVATE; + + tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); +@@ -7052,7 +7052,7 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, + * Note, if LVDS ever uses a non-1 pixel multiplier, we'll need + * to use a real value here instead. + */ +- pipe_config.cpu_transcoder = intel_crtc->pipe; ++ pipe_config.cpu_transcoder = (enum transcoder) intel_crtc->pipe; + pipe_config.pixel_multiplier = 1; + i9xx_crtc_clock_get(intel_crtc, &pipe_config); + +@@ -7882,7 +7882,8 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, + + drm_mode_copy(&pipe_config->adjusted_mode, mode); + drm_mode_copy(&pipe_config->requested_mode, mode); +- pipe_config->cpu_transcoder = to_intel_crtc(crtc)->pipe; ++ pipe_config->cpu_transcoder = ++ (enum transcoder) to_intel_crtc(crtc)->pipe; + pipe_config->shared_dpll = DPLL_ID_PRIVATE; + + /* Compute a starting value for pipe_config->pipe_bpp taking the source +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0426-drm-i915-Explicitly-cast-pipe-intel_dpll_id.patch b/patches.baytrail/0426-drm-i915-Explicitly-cast-pipe-intel_dpll_id.patch new file mode 100644 index 000000000000..4cf584f7c86f --- /dev/null +++ b/patches.baytrail/0426-drm-i915-Explicitly-cast-pipe-intel_dpll_id.patch @@ -0,0 +1,44 @@ +From dca79cb257028b072d6b4d6964430d083853e4fb Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 4 Jul 2013 12:01:16 +0200 +Subject: drm/i915: Explicitly cast pipe -> intel_dpll_id + +We only do this on IBX where there's a fixed pch dpll to pipe +assignment. Being explicit about it can't really hurt and makes +sparse happy. + +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit d94ab068277bda17bfeb0e976049035153299a1a) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 08217b92f33d..9733f275454d 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3097,7 +3097,7 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) + + if (HAS_PCH_IBX(dev_priv->dev)) { + /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ +- i = crtc->pipe; ++ i = (enum intel_dpll_id) crtc->pipe; + pll = &dev_priv->shared_dplls[i]; + + DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", +@@ -5853,7 +5853,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + ironlake_get_fdi_m_n_config(crtc, pipe_config); + + if (HAS_PCH_IBX(dev_priv->dev)) { +- pipe_config->shared_dpll = crtc->pipe; ++ pipe_config->shared_dpll = ++ (enum intel_dpll_id) crtc->pipe; + } else { + tmp = I915_READ(PCH_DPLL_SEL); + if (tmp & TRANS_DPLLB_SEL(crtc->pipe)) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0427-drm-i915-less-magic-for-stolen-preallocated-objects-.patch b/patches.baytrail/0427-drm-i915-less-magic-for-stolen-preallocated-objects-.patch new file mode 100644 index 000000000000..a4e8fca8b94c --- /dev/null +++ b/patches.baytrail/0427-drm-i915-less-magic-for-stolen-preallocated-objects-.patch @@ -0,0 +1,75 @@ +From 49e32c99eef85615971b82cef11d52a8cdd6d948 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 4 Jul 2013 13:06:28 +0200 +Subject: drm/i915: less magic for stolen preallocated objects w/o gtt offset + +A magic -1 is a obscure, especially since it's actually passed as an +unsigned, so depends upon the magic sign extension rules in C. This has +been added in + +commit 3727d55e4d85836aa6cb759a965daaef88074150 +Author: Jesse Barnes +Date: Wed May 8 10:45:14 2013 -0700 + + drm/i915: allow stolen, pre-allocated objects to avoid GTT allocation v2 + +Use a proper #define instead. Spotted while reviewing Ben's +drm_mm_create_block changes. + +v2: Cast the constant to u32 since otherwise we again have a type +mismatch. Suggested by Chris Wilson. + +Cc: Ben Widawsky +Cc: Jesse Barnes +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 190d6cd5cd3606dd13a3ca5bf0c23dc520659c15) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/i915_gem_stolen.c | 2 +- + drivers/gpu/drm/i915/intel_pm.c | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 98dfe0cbd2be..8e40123f6a12 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1203,6 +1203,7 @@ enum hdmi_force_audio { + }; + + #define I915_GTT_RESERVED ((struct drm_mm_node *)0x1) ++#define I915_GTT_OFFSET_NONE ((u32)-1) + + struct drm_i915_gem_object_ops { + /* Interface between the GEM object and its backing storage. +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 0f8cf62a5b83..f1664f272fc3 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -363,7 +363,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + } + + /* Some objects just need physical mem from stolen space */ +- if (gtt_offset == -1) ++ if (gtt_offset == I915_GTT_OFFSET_NONE) + return obj; + + /* To simplify the initialisation sequence between KMS and GTT, +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 91471e6f23cd..f9d0afd4bd6c 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3474,7 +3474,7 @@ static void valleyview_setup_pctx(struct drm_device *dev) + pcbr_offset = (pcbr & (~4095)) - dev_priv->mm.stolen_base; + pctx = i915_gem_object_create_stolen_for_preallocated(dev_priv->dev, + pcbr_offset, +- -1, ++ I915_GTT_OFFSET_NONE, + pctx_size); + goto out; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0428-drm-i915-assert_spin_locked-for-pipestat-interrupt-e.patch b/patches.baytrail/0428-drm-i915-assert_spin_locked-for-pipestat-interrupt-e.patch new file mode 100644 index 000000000000..b86d4a23e76b --- /dev/null +++ b/patches.baytrail/0428-drm-i915-assert_spin_locked-for-pipestat-interrupt-e.patch @@ -0,0 +1,90 @@ +From 80ee4f01913713437683b8a30ead777c977da9cf Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 27 Jun 2013 17:52:10 +0200 +Subject: drm/i915: assert_spin_locked for pipestat interrupt enable/disable + +Just to keep the paranoia equal also sprinkle locking asserts over the +pipestat interrupt enable/disable functions. + +Again this results in false positives in the interrupt setup. Add +bogo-locking for these and a big comment explaining why it's there and +that it's indeed unnecessary. + +v2: Fix up the spelling fail Paulo spotted in comments. + +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit b79480ba5074ae81d1c32073bce3981652e0f717) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 7564063ecc70..4a98600c6f41 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -319,6 +319,8 @@ i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) + u32 reg = PIPESTAT(pipe); + u32 pipestat = I915_READ(reg) & 0x7fff0000; + ++ assert_spin_locked(&dev_priv->irq_lock); ++ + if ((pipestat & mask) == mask) + return; + +@@ -334,6 +336,8 @@ i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) + u32 reg = PIPESTAT(pipe); + u32 pipestat = I915_READ(reg) & 0x7fff0000; + ++ assert_spin_locked(&dev_priv->irq_lock); ++ + if ((pipestat & mask) == 0) + return; + +@@ -2864,6 +2868,7 @@ static int valleyview_irq_postinstall(struct drm_device *dev) + u32 gt_irqs; + u32 enable_mask; + u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV; ++ unsigned long irqflags; + + enable_mask = I915_DISPLAY_PORT_INTERRUPT; + enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | +@@ -2889,9 +2894,13 @@ static int valleyview_irq_postinstall(struct drm_device *dev) + I915_WRITE(PIPESTAT(1), 0xffff); + POSTING_READ(VLV_IER); + ++ /* Interrupt setup is already guaranteed to be single-threaded, this is ++ * just to make the assert_spin_locked check happy. */ ++ spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + i915_enable_pipestat(dev_priv, 0, pipestat_enable); + i915_enable_pipestat(dev_priv, 0, PIPE_GMBUS_EVENT_ENABLE); + i915_enable_pipestat(dev_priv, 1, pipestat_enable); ++ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + + I915_WRITE(VLV_IIR, 0xffffffff); + I915_WRITE(VLV_IIR, 0xffffffff); +@@ -3370,6 +3379,7 @@ static int i965_irq_postinstall(struct drm_device *dev) + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u32 enable_mask; + u32 error_mask; ++ unsigned long irqflags; + + /* Unmask the interrupts that we always want on. */ + dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | +@@ -3388,7 +3398,11 @@ static int i965_irq_postinstall(struct drm_device *dev) + if (IS_G4X(dev)) + enable_mask |= I915_BSD_USER_INTERRUPT; + ++ /* Interrupt setup is already guaranteed to be single-threaded, this is ++ * just to make the assert_spin_locked check happy. */ ++ spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + i915_enable_pipestat(dev_priv, 0, PIPE_GMBUS_EVENT_ENABLE); ++ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + + /* + * Enable some error detection, note the instruction error mask +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0429-drm-pre-allocate-node-for-create_block.patch b/patches.baytrail/0429-drm-pre-allocate-node-for-create_block.patch new file mode 100644 index 000000000000..302070751ca3 --- /dev/null +++ b/patches.baytrail/0429-drm-pre-allocate-node-for-create_block.patch @@ -0,0 +1,219 @@ +From 36e2ed3d4176d01b17c16c790931f2b50f60c8aa Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Fri, 5 Jul 2013 14:41:02 -0700 +Subject: drm: pre allocate node for create_block + +For an upcoming patch where we introduce the i915 VMA, it's ideal to +have the drm_mm_node as part of the VMA struct (ie. it's pre-allocated). +Part of the conversion to VMAs is to kill off obj->gtt_space. Doing this +will break a bunch of code, but amongst them are 2 callers of +drm_mm_create_block(), both related to stolen memory. + +It also allows us to embed the drm_mm_node into the object currently +which provides a nice transition over to the new code. + +v2: Reordered to do before ripping out obj->gtt_offset. +Some minor cleanups made available because of reordering. + +v3: s/continue/break on failed stolen node allocation (David) +Set obj->gtt_space on failed node allocation (David) +Only unref stolen (fix double free) on failed create_stolen (David) +Free node, and NULL it in failed create_stolen (David) +Add back accidentally removed newline (David) + +CC: +Reviewed-by: David Herrmann +Signed-off-by: Ben Widawsky +Acked-by: David Airlie +Signed-off-by: Daniel Vetter +(cherry picked from commit b3a070cccb9135f8bec63d9f194ddaa422136fb0) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_mm.c | 16 +++++---------- + drivers/gpu/drm/i915/i915_gem_gtt.c | 20 ++++++++++++++---- + drivers/gpu/drm/i915/i915_gem_stolen.c | 37 +++++++++++++++++++++++++--------- + include/drm/drm_mm.h | 9 +++++---- + 4 files changed, 53 insertions(+), 29 deletions(-) + +diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c +index 7917729ee61d..520f7463bb77 100644 +--- a/drivers/gpu/drm/drm_mm.c ++++ b/drivers/gpu/drm/drm_mm.c +@@ -147,12 +147,10 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node, + } + } + +-struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm, +- unsigned long start, +- unsigned long size, +- bool atomic) ++int drm_mm_create_block(struct drm_mm *mm, struct drm_mm_node *node, ++ unsigned long start, unsigned long size) + { +- struct drm_mm_node *hole, *node; ++ struct drm_mm_node *hole; + unsigned long end = start + size; + unsigned long hole_start; + unsigned long hole_end; +@@ -161,10 +159,6 @@ struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm, + if (hole_start > start || hole_end < end) + continue; + +- node = drm_mm_kmalloc(mm, atomic); +- if (unlikely(node == NULL)) +- return NULL; +- + node->start = start; + node->size = size; + node->mm = mm; +@@ -184,11 +178,11 @@ struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm, + node->hole_follows = 1; + } + +- return node; ++ return 0; + } + + WARN(1, "no hole found for block 0x%lx + 0x%lx\n", start, size); +- return NULL; ++ return -ENOSPC; + } + EXPORT_SYMBOL(drm_mm_create_block); + +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 66929eac6367..88180a597c0a 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -629,14 +629,26 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + + /* Mark any preallocated objects as occupied */ + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { ++ int ret; + DRM_DEBUG_KMS("reserving preallocated space: %x + %zx\n", + obj->gtt_offset, obj->base.size); + + BUG_ON(obj->gtt_space != I915_GTT_RESERVED); +- obj->gtt_space = drm_mm_create_block(&dev_priv->mm.gtt_space, +- obj->gtt_offset, +- obj->base.size, +- false); ++ obj->gtt_space = kzalloc(sizeof(*obj->gtt_space), GFP_KERNEL); ++ if (!obj->gtt_space) { ++ DRM_ERROR("Failed to preserve object at offset %x\n", ++ obj->gtt_offset); ++ continue; ++ } ++ ret = drm_mm_create_block(&dev_priv->mm.gtt_space, ++ obj->gtt_space, ++ obj->gtt_offset, ++ obj->base.size); ++ if (ret) { ++ DRM_DEBUG_KMS("Reservation failed\n"); ++ kfree(obj->gtt_space); ++ obj->gtt_space = NULL; ++ } + obj->has_global_gtt_mapping = 1; + } + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index f1664f272fc3..fdcc96b636b2 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -333,6 +333,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj; + struct drm_mm_node *stolen; ++ int ret; + + if (!drm_mm_initialized(&dev_priv->mm.stolen)) + return NULL; +@@ -347,11 +348,15 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + if (WARN_ON(size == 0)) + return NULL; + +- stolen = drm_mm_create_block(&dev_priv->mm.stolen, +- stolen_offset, size, +- false); +- if (stolen == NULL) { ++ stolen = kzalloc(sizeof(*stolen), GFP_KERNEL); ++ if (!stolen) ++ return NULL; ++ ++ ret = drm_mm_create_block(&dev_priv->mm.stolen, stolen, stolen_offset, ++ size); ++ if (ret) { + DRM_DEBUG_KMS("failed to allocate stolen space\n"); ++ kfree(stolen); + return NULL; + } + +@@ -372,13 +377,18 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + * later. + */ + if (drm_mm_initialized(&dev_priv->mm.gtt_space)) { +- obj->gtt_space = drm_mm_create_block(&dev_priv->mm.gtt_space, +- gtt_offset, size, +- false); +- if (obj->gtt_space == NULL) { ++ obj->gtt_space = kzalloc(sizeof(*obj->gtt_space), GFP_KERNEL); ++ if (!obj->gtt_space) { ++ DRM_DEBUG_KMS("-ENOMEM stolen GTT space\n"); ++ goto unref_out; ++ } ++ ++ ret = drm_mm_create_block(&dev_priv->mm.gtt_space, ++ obj->gtt_space, ++ gtt_offset, size); ++ if (ret) { + DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); +- drm_gem_object_unreference(&obj->base); +- return NULL; ++ goto free_out; + } + } else + obj->gtt_space = I915_GTT_RESERVED; +@@ -390,6 +400,13 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); + + return obj; ++ ++free_out: ++ kfree(obj->gtt_space); ++ obj->gtt_space = NULL; ++unref_out: ++ drm_gem_object_unreference(&obj->base); ++ return NULL; + } + + void +diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h +index de9242542f05..00904bfe1355 100644 +--- a/include/drm/drm_mm.h ++++ b/include/drm/drm_mm.h +@@ -138,10 +138,10 @@ static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) + /* + * Basic range manager support (drm_mm.c) + */ +-extern struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm, +- unsigned long start, +- unsigned long size, +- bool atomic); ++extern int drm_mm_create_block(struct drm_mm *mm, ++ struct drm_mm_node *node, ++ unsigned long start, ++ unsigned long size); + extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, + unsigned long size, + unsigned alignment, +@@ -155,6 +155,7 @@ extern struct drm_mm_node *drm_mm_get_block_range_generic( + unsigned long start, + unsigned long end, + int atomic); ++ + static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent, + unsigned long size, + unsigned alignment) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0430-drm-Change-create-block-to-reserve-node.patch b/patches.baytrail/0430-drm-Change-create-block-to-reserve-node.patch new file mode 100644 index 000000000000..e370ceafe0b9 --- /dev/null +++ b/patches.baytrail/0430-drm-Change-create-block-to-reserve-node.patch @@ -0,0 +1,149 @@ +From f212fd2daaa15e7a1c1cce9e196d75febf00046a Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Fri, 5 Jul 2013 14:41:03 -0700 +Subject: drm: Change create block to reserve node + +With the previous patch we no longer actually create a node, we simply +find the correct hole and occupy it. This very well could have been +squashed with the last patch, but since I already had David's review, I +figured it's easiest to keep it distinct. + +Also update the users in i915. Conveniently this is the only user of the +interface. + +CC: David Airlie +CC: +Signed-off-by: Ben Widawsky +Acked-by: David Airlie +Signed-off-by: Daniel Vetter +(cherry picked from commit 338710e7aff3428dc8170a03704a8ae981b58dcd) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_mm.c | 19 ++++++++++--------- + drivers/gpu/drm/i915/i915_gem_gtt.c | 8 ++++---- + drivers/gpu/drm/i915/i915_gem_stolen.c | 12 +++++++----- + include/drm/drm_mm.h | 5 +---- + 4 files changed, 22 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c +index 520f7463bb77..2f6b06b5a617 100644 +--- a/drivers/gpu/drm/drm_mm.c ++++ b/drivers/gpu/drm/drm_mm.c +@@ -147,27 +147,27 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node, + } + } + +-int drm_mm_create_block(struct drm_mm *mm, struct drm_mm_node *node, +- unsigned long start, unsigned long size) ++int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node) + { + struct drm_mm_node *hole; +- unsigned long end = start + size; ++ unsigned long end = node->start + node->size; + unsigned long hole_start; + unsigned long hole_end; + ++ BUG_ON(node == NULL); ++ ++ /* Find the relevant hole to add our node to */ + drm_mm_for_each_hole(hole, mm, hole_start, hole_end) { +- if (hole_start > start || hole_end < end) ++ if (hole_start > node->start || hole_end < end) + continue; + +- node->start = start; +- node->size = size; + node->mm = mm; + node->allocated = 1; + + INIT_LIST_HEAD(&node->hole_stack); + list_add(&node->node_list, &hole->node_list); + +- if (start == hole_start) { ++ if (node->start == hole_start) { + hole->hole_follows = 0; + list_del_init(&hole->hole_stack); + } +@@ -181,10 +181,11 @@ int drm_mm_create_block(struct drm_mm *mm, struct drm_mm_node *node, + return 0; + } + +- WARN(1, "no hole found for block 0x%lx + 0x%lx\n", start, size); ++ WARN(1, "no hole found for node 0x%lx + 0x%lx\n", ++ node->start, node->size); + return -ENOSPC; + } +-EXPORT_SYMBOL(drm_mm_create_block); ++EXPORT_SYMBOL(drm_mm_reserve_node); + + struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node, + unsigned long size, +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 88180a597c0a..afba7e5e7739 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -640,10 +640,10 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + obj->gtt_offset); + continue; + } +- ret = drm_mm_create_block(&dev_priv->mm.gtt_space, +- obj->gtt_space, +- obj->gtt_offset, +- obj->base.size); ++ obj->gtt_space->start = obj->gtt_offset; ++ obj->gtt_space->size = obj->base.size; ++ ret = drm_mm_reserve_node(&dev_priv->mm.gtt_space, ++ obj->gtt_space); + if (ret) { + DRM_DEBUG_KMS("Reservation failed\n"); + kfree(obj->gtt_space); +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index fdcc96b636b2..bc601c4fdc37 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -352,8 +352,9 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + if (!stolen) + return NULL; + +- ret = drm_mm_create_block(&dev_priv->mm.stolen, stolen, stolen_offset, +- size); ++ stolen->start = stolen_offset; ++ stolen->size = size; ++ ret = drm_mm_reserve_node(&dev_priv->mm.stolen, stolen); + if (ret) { + DRM_DEBUG_KMS("failed to allocate stolen space\n"); + kfree(stolen); +@@ -383,9 +384,10 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + goto unref_out; + } + +- ret = drm_mm_create_block(&dev_priv->mm.gtt_space, +- obj->gtt_space, +- gtt_offset, size); ++ obj->gtt_space->start = gtt_offset; ++ obj->gtt_space->size = size; ++ ret = drm_mm_reserve_node(&dev_priv->mm.gtt_space, ++ obj->gtt_space); + if (ret) { + DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); + goto free_out; +diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h +index 00904bfe1355..e3aceb350001 100644 +--- a/include/drm/drm_mm.h ++++ b/include/drm/drm_mm.h +@@ -138,10 +138,7 @@ static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) + /* + * Basic range manager support (drm_mm.c) + */ +-extern int drm_mm_create_block(struct drm_mm *mm, +- struct drm_mm_node *node, +- unsigned long start, +- unsigned long size); ++extern int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node); + extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, + unsigned long size, + unsigned alignment, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0431-drm-i915-Getter-setter-for-object-attributes.patch b/patches.baytrail/0431-drm-i915-Getter-setter-for-object-attributes.patch new file mode 100644 index 000000000000..1c59991fab57 --- /dev/null +++ b/patches.baytrail/0431-drm-i915-Getter-setter-for-object-attributes.patch @@ -0,0 +1,1051 @@ +From 08bb633ed0667bcf1c2479eb7811e720a65f3589 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Fri, 5 Jul 2013 14:41:04 -0700 +Subject: drm/i915: Getter/setter for object attributes + +Soon we want to gut a lot of our existing assumptions how many address +spaces an object can live in, and in doing so, embed the drm_mm_node in +the object (and later the VMA). + +It's possible in the future we'll want to add more getter/setter +methods, but for now this is enough to enable the VMAs. + +v2: Reworked commit message (Ben) +Added comments to the main functions (Ben) +sed -i "s/i915_gem_obj_set_color/i915_gem_obj_ggtt_set_color/" drivers/gpu/drm/i915/*.[ch] +sed -i "s/i915_gem_obj_bound/i915_gem_obj_ggtt_bound/" drivers/gpu/drm/i915/*.[ch] +sed -i "s/i915_gem_obj_size/i915_gem_obj_ggtt_size/" drivers/gpu/drm/i915/*.[ch] +sed -i "s/i915_gem_obj_offset/i915_gem_obj_ggtt_offset/" drivers/gpu/drm/i915/*.[ch] +(Daniel) + +v3: Rebased on new reserve_node patch +Changed DRM_DEBUG_KMS to actually work (will need fixing later) + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit f343c5f6477354967ee1e331a68a56b9fece2f36) +(cherry picked from drm-intel-next-queued) +Signed-off-by: James Ausmus + +Conflicts: + drivers/gpu/drm/i915/i915_gem.c + (used airlied's rerere from + e13af9a8340685cfe25d0c9f708da7121e0f51dd) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 26 +++++---- + drivers/gpu/drm/i915/i915_drv.h | 31 +++++++++++ + drivers/gpu/drm/i915/i915_gem.c | 89 +++++++++++++++--------------- + drivers/gpu/drm/i915/i915_gem_context.c | 2 +- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 19 ++++--- + drivers/gpu/drm/i915/i915_gem_gtt.c | 8 +-- + drivers/gpu/drm/i915/i915_gem_tiling.c | 14 ++--- + drivers/gpu/drm/i915/i915_irq.c | 15 +++-- + drivers/gpu/drm/i915/i915_trace.h | 8 +-- + drivers/gpu/drm/i915/intel_display.c | 28 +++++----- + drivers/gpu/drm/i915/intel_fb.c | 8 +-- + drivers/gpu/drm/i915/intel_overlay.c | 14 ++--- + drivers/gpu/drm/i915/intel_pm.c | 8 +-- + drivers/gpu/drm/i915/intel_ringbuffer.c | 12 ++-- + drivers/gpu/drm/i915/intel_sprite.c | 8 ++- + 15 files changed, 164 insertions(+), 126 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 3e36756d0439..396387ed207a 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -122,9 +122,9 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) + seq_printf(m, " (pinned x %d)", obj->pin_count); + if (obj->fence_reg != I915_FENCE_REG_NONE) + seq_printf(m, " (fence: %d)", obj->fence_reg); +- if (obj->gtt_space != NULL) +- seq_printf(m, " (gtt offset: %08x, size: %08x)", +- obj->gtt_offset, (unsigned int)obj->gtt_space->size); ++ if (i915_gem_obj_ggtt_bound(obj)) ++ seq_printf(m, " (gtt offset: %08lx, size: %08x)", ++ i915_gem_obj_ggtt_offset(obj), (unsigned int)i915_gem_obj_ggtt_size(obj)); + if (obj->stolen) + seq_printf(m, " (stolen: %08lx)", obj->stolen->start); + if (obj->pin_mappable || obj->fault_mappable) { +@@ -175,7 +175,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) + describe_obj(m, obj); + seq_putc(m, '\n'); + total_obj_size += obj->base.size; +- total_gtt_size += obj->gtt_space->size; ++ total_gtt_size += i915_gem_obj_ggtt_size(obj); + count++; + } + mutex_unlock(&dev->struct_mutex); +@@ -187,10 +187,10 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) + + #define count_objects(list, member) do { \ + list_for_each_entry(obj, list, member) { \ +- size += obj->gtt_space->size; \ ++ size += i915_gem_obj_ggtt_size(obj); \ + ++count; \ + if (obj->map_and_fenceable) { \ +- mappable_size += obj->gtt_space->size; \ ++ mappable_size += i915_gem_obj_ggtt_size(obj); \ + ++mappable_count; \ + } \ + } \ +@@ -209,7 +209,7 @@ static int per_file_stats(int id, void *ptr, void *data) + stats->count++; + stats->total += obj->base.size; + +- if (obj->gtt_space) { ++ if (i915_gem_obj_ggtt_bound(obj)) { + if (!list_empty(&obj->ring_list)) + stats->active += obj->base.size; + else +@@ -267,11 +267,11 @@ static int i915_gem_object_info(struct seq_file *m, void *data) + size = count = mappable_size = mappable_count = 0; + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { + if (obj->fault_mappable) { +- size += obj->gtt_space->size; ++ size += i915_gem_obj_ggtt_size(obj); + ++count; + } + if (obj->pin_mappable) { +- mappable_size += obj->gtt_space->size; ++ mappable_size += i915_gem_obj_ggtt_size(obj); + ++mappable_count; + } + if (obj->madv == I915_MADV_DONTNEED) { +@@ -333,7 +333,7 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data) + describe_obj(m, obj); + seq_putc(m, '\n'); + total_obj_size += obj->base.size; +- total_gtt_size += obj->gtt_space->size; ++ total_gtt_size += i915_gem_obj_ggtt_size(obj); + count++; + } + +@@ -379,12 +379,14 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) + if (work->old_fb_obj) { + struct drm_i915_gem_object *obj = work->old_fb_obj; + if (obj) +- seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj->gtt_offset); ++ seq_printf(m, "Old framebuffer gtt_offset 0x%08lx\n", ++ i915_gem_obj_ggtt_offset(obj)); + } + if (work->pending_flip_obj) { + struct drm_i915_gem_object *obj = work->pending_flip_obj; + if (obj) +- seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj->gtt_offset); ++ seq_printf(m, "New framebuffer gtt_offset 0x%08lx\n", ++ i915_gem_obj_ggtt_offset(obj)); + } + } + spin_unlock_irqrestore(&dev->event_lock, flags); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 8e40123f6a12..ccf9bfa54c08 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1362,6 +1362,37 @@ struct drm_i915_gem_object { + + #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) + ++/* Offset of the first PTE pointing to this object */ ++static inline unsigned long ++i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o) ++{ ++ return o->gtt_space->start; ++} ++ ++/* Whether or not this object is currently mapped by the translation tables */ ++static inline bool ++i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *o) ++{ ++ return o->gtt_space != NULL; ++} ++ ++/* The size used in the translation tables may be larger than the actual size of ++ * the object on GEN2/GEN3 because of the way tiling is handled. See ++ * i915_gem_get_gtt_size() for more details. ++ */ ++static inline unsigned long ++i915_gem_obj_ggtt_size(struct drm_i915_gem_object *o) ++{ ++ return o->gtt_space->size; ++} ++ ++static inline void ++i915_gem_obj_ggtt_set_color(struct drm_i915_gem_object *o, ++ enum i915_cache_level color) ++{ ++ o->gtt_space->color = color; ++} ++ + /** + * Request queue structure. + * +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index d9e2208cfe98..e43a35dcff63 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -135,7 +135,7 @@ int i915_mutex_lock_interruptible(struct drm_device *dev) + static inline bool + i915_gem_object_is_inactive(struct drm_i915_gem_object *obj) + { +- return obj->gtt_space && !obj->active; ++ return i915_gem_obj_ggtt_bound(obj) && !obj->active; + } + + int +@@ -178,7 +178,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, + mutex_lock(&dev->struct_mutex); + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) + if (obj->pin_count) +- pinned += obj->gtt_space->size; ++ pinned += i915_gem_obj_ggtt_size(obj); + mutex_unlock(&dev->struct_mutex); + + args->aper_size = dev_priv->gtt.total; +@@ -422,7 +422,7 @@ i915_gem_shmem_pread(struct drm_device *dev, + * anyway again before the next pread happens. */ + if (obj->cache_level == I915_CACHE_NONE) + needs_clflush = 1; +- if (obj->gtt_space) { ++ if (i915_gem_obj_ggtt_bound(obj)) { + ret = i915_gem_object_set_to_gtt_domain(obj, false); + if (ret) + return ret; +@@ -609,7 +609,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, + user_data = to_user_ptr(args->data_ptr); + remain = args->size; + +- offset = obj->gtt_offset + args->offset; ++ offset = i915_gem_obj_ggtt_offset(obj) + args->offset; + + while (remain > 0) { + /* Operation in this page +@@ -739,7 +739,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev, + * right away and we therefore have to clflush anyway. */ + if (obj->cache_level == I915_CACHE_NONE) + needs_clflush_after = 1; +- if (obj->gtt_space) { ++ if (i915_gem_obj_ggtt_bound(obj)) { + ret = i915_gem_object_set_to_gtt_domain(obj, true); + if (ret) + return ret; +@@ -1360,8 +1360,9 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + + obj->fault_mappable = true; + +- pfn = ((dev_priv->gtt.mappable_base + obj->gtt_offset) >> PAGE_SHIFT) + +- page_offset; ++ pfn = dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj); ++ pfn >>= PAGE_SHIFT; ++ pfn += page_offset; + + /* Finally, remap it using the new GTT offset */ + ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); +@@ -1667,7 +1668,7 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj) + if (obj->pages == NULL) + return 0; + +- BUG_ON(obj->gtt_space); ++ BUG_ON(i915_gem_obj_ggtt_bound(obj)); + + if (obj->pages_pin_count) + return -EBUSY; +@@ -2121,8 +2122,8 @@ i915_gem_request_remove_from_client(struct drm_i915_gem_request *request) + + static bool i915_head_inside_object(u32 acthd, struct drm_i915_gem_object *obj) + { +- if (acthd >= obj->gtt_offset && +- acthd < obj->gtt_offset + obj->base.size) ++ if (acthd >= i915_gem_obj_ggtt_offset(obj) && ++ acthd < i915_gem_obj_ggtt_offset(obj) + obj->base.size) + return true; + + return false; +@@ -2180,11 +2181,11 @@ static void i915_set_reset_status(struct intel_ring_buffer *ring, + + if (ring->hangcheck.action != wait && + i915_request_guilty(request, acthd, &inside)) { +- DRM_ERROR("%s hung %s bo (0x%x ctx %d) at 0x%x\n", ++ DRM_ERROR("%s hung %s bo (0x%lx ctx %d) at 0x%x\n", + ring->name, + inside ? "inside" : "flushing", + request->batch_obj ? +- request->batch_obj->gtt_offset : 0, ++ i915_gem_obj_ggtt_offset(request->batch_obj) : 0, + request->ctx ? request->ctx->id : 0, + acthd); + +@@ -2595,7 +2596,7 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) + drm_i915_private_t *dev_priv = obj->base.dev->dev_private; + int ret; + +- if (obj->gtt_space == NULL) ++ if (!i915_gem_obj_ggtt_bound(obj)) + return 0; + + if (obj->pin_count) +@@ -2691,12 +2692,12 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg, + POSTING_READ(fence_reg); + + if (obj) { +- u32 size = obj->gtt_space->size; ++ u32 size = i915_gem_obj_ggtt_size(obj); + uint64_t val; + +- val = (uint64_t)((obj->gtt_offset + size - 4096) & ++ val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) & + 0xfffff000) << 32; +- val |= obj->gtt_offset & 0xfffff000; ++ val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000; + val |= (uint64_t)((obj->stride / 128) - 1) << fence_pitch_shift; + if (obj->tiling_mode == I915_TILING_Y) + val |= 1 << I965_FENCE_TILING_Y_SHIFT; +@@ -2720,15 +2721,15 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg, + u32 val; + + if (obj) { +- u32 size = obj->gtt_space->size; ++ u32 size = i915_gem_obj_ggtt_size(obj); + int pitch_val; + int tile_width; + +- WARN((obj->gtt_offset & ~I915_FENCE_START_MASK) || ++ WARN((i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK) || + (size & -size) != size || +- (obj->gtt_offset & (size - 1)), +- "object 0x%08x [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n", +- obj->gtt_offset, obj->map_and_fenceable, size); ++ (i915_gem_obj_ggtt_offset(obj) & (size - 1)), ++ "object 0x%08lx [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n", ++ i915_gem_obj_ggtt_offset(obj), obj->map_and_fenceable, size); + + if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) + tile_width = 128; +@@ -2739,7 +2740,7 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg, + pitch_val = obj->stride / tile_width; + pitch_val = ffs(pitch_val) - 1; + +- val = obj->gtt_offset; ++ val = i915_gem_obj_ggtt_offset(obj); + if (obj->tiling_mode == I915_TILING_Y) + val |= 1 << I830_FENCE_TILING_Y_SHIFT; + val |= I915_FENCE_SIZE_BITS(size); +@@ -2764,19 +2765,19 @@ static void i830_write_fence_reg(struct drm_device *dev, int reg, + uint32_t val; + + if (obj) { +- u32 size = obj->gtt_space->size; ++ u32 size = i915_gem_obj_ggtt_size(obj); + uint32_t pitch_val; + +- WARN((obj->gtt_offset & ~I830_FENCE_START_MASK) || ++ WARN((i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK) || + (size & -size) != size || +- (obj->gtt_offset & (size - 1)), +- "object 0x%08x not 512K or pot-size 0x%08x aligned\n", +- obj->gtt_offset, size); ++ (i915_gem_obj_ggtt_offset(obj) & (size - 1)), ++ "object 0x%08lx not 512K or pot-size 0x%08x aligned\n", ++ i915_gem_obj_ggtt_offset(obj), size); + + pitch_val = obj->stride / 128; + pitch_val = ffs(pitch_val) - 1; + +- val = obj->gtt_offset; ++ val = i915_gem_obj_ggtt_offset(obj); + if (obj->tiling_mode == I915_TILING_Y) + val |= 1 << I830_FENCE_TILING_Y_SHIFT; + val |= I830_FENCE_SIZE_BITS(size); +@@ -3030,8 +3031,8 @@ static void i915_gem_verify_gtt(struct drm_device *dev) + + if (obj->cache_level != obj->gtt_space->color) { + printk(KERN_ERR "object reserved space [%08lx, %08lx] with wrong color, cache_level=%x, color=%lx\n", +- obj->gtt_space->start, +- obj->gtt_space->start + obj->gtt_space->size, ++ i915_gem_obj_ggtt_offset(obj), ++ i915_gem_obj_ggtt_offset(obj) + i915_gem_obj_ggtt_size(obj), + obj->cache_level, + obj->gtt_space->color); + err++; +@@ -3042,8 +3043,8 @@ static void i915_gem_verify_gtt(struct drm_device *dev) + obj->gtt_space, + obj->cache_level)) { + printk(KERN_ERR "invalid GTT space found at [%08lx, %08lx] - color=%x\n", +- obj->gtt_space->start, +- obj->gtt_space->start + obj->gtt_space->size, ++ i915_gem_obj_ggtt_offset(obj), ++ i915_gem_obj_ggtt_offset(obj) + i915_gem_obj_ggtt_size(obj), + obj->cache_level); + err++; + continue; +@@ -3155,8 +3156,8 @@ search_free: + node->size == fence_size && + (node->start & (fence_alignment - 1)) == 0; + +- mappable = +- obj->gtt_offset + obj->base.size <= dev_priv->gtt.mappable_end; ++ mappable = i915_gem_obj_ggtt_offset(obj) + obj->base.size <= ++ dev_priv->gtt.mappable_end; + + obj->map_and_fenceable = mappable && fenceable; + +@@ -3258,7 +3259,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) + int ret; + + /* Not valid to be called on unbound objects. */ +- if (obj->gtt_space == NULL) ++ if (!i915_gem_obj_ggtt_bound(obj)) + return -EINVAL; + + if (obj->base.write_domain == I915_GEM_DOMAIN_GTT) +@@ -3323,7 +3324,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + return ret; + } + +- if (obj->gtt_space) { ++ if (i915_gem_obj_ggtt_bound(obj)) { + ret = i915_gem_object_finish_gpu(obj); + if (ret) + return ret; +@@ -3346,7 +3347,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt, + obj, cache_level); + +- obj->gtt_space->color = cache_level; ++ i915_gem_obj_ggtt_set_color(obj, cache_level); + } + + if (cache_level == I915_CACHE_NONE) { +@@ -3627,14 +3628,14 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, + if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT)) + return -EBUSY; + +- if (obj->gtt_space != NULL) { +- if ((alignment && obj->gtt_offset & (alignment - 1)) || ++ if (i915_gem_obj_ggtt_bound(obj)) { ++ if ((alignment && i915_gem_obj_ggtt_offset(obj) & (alignment - 1)) || + (map_and_fenceable && !obj->map_and_fenceable)) { + WARN(obj->pin_count, + "bo is already pinned with incorrect alignment:" +- " offset=%x, req.alignment=%x, req.map_and_fenceable=%d," ++ " offset=%lx, req.alignment=%x, req.map_and_fenceable=%d," + " obj->map_and_fenceable=%d\n", +- obj->gtt_offset, alignment, ++ i915_gem_obj_ggtt_offset(obj), alignment, + map_and_fenceable, + obj->map_and_fenceable); + ret = i915_gem_object_unbind(obj); +@@ -3643,7 +3644,7 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, + } + } + +- if (obj->gtt_space == NULL) { ++ if (!i915_gem_obj_ggtt_bound(obj)) { + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + + ret = i915_gem_object_bind_to_gtt(obj, alignment, +@@ -3669,7 +3670,7 @@ void + i915_gem_object_unpin(struct drm_i915_gem_object *obj) + { + BUG_ON(obj->pin_count == 0); +- BUG_ON(obj->gtt_space == NULL); ++ BUG_ON(!i915_gem_obj_ggtt_bound(obj)); + + if (--obj->pin_count == 0) + obj->pin_mappable = false; +@@ -3719,7 +3720,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, + * as the X server doesn't manage domains yet + */ + i915_gem_object_flush_cpu_write_domain(obj); +- args->offset = obj->gtt_offset; ++ args->offset = i915_gem_obj_ggtt_offset(obj); + out: + drm_gem_object_unreference(&obj->base); + unlock: +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index 51b7a2171cae..2074544682cf 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -377,7 +377,7 @@ mi_set_context(struct intel_ring_buffer *ring, + + intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(ring, MI_SET_CONTEXT); +- intel_ring_emit(ring, new_context->obj->gtt_offset | ++ intel_ring_emit(ring, i915_gem_obj_ggtt_offset(new_context->obj) | + MI_MM_SPACE_GTT | + MI_SAVE_EXT_STATE_EN | + MI_RESTORE_EXT_STATE_EN | +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 87a3227e5179..5aeb447ead6b 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -188,7 +188,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, + return -ENOENT; + + target_i915_obj = to_intel_bo(target_obj); +- target_offset = target_i915_obj->gtt_offset; ++ target_offset = i915_gem_obj_ggtt_offset(target_i915_obj); + + /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and + * pipe_control writes because the gpu doesn't properly redirect them +@@ -280,7 +280,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, + return ret; + + /* Map the page containing the relocation we're going to perform. */ +- reloc->offset += obj->gtt_offset; ++ reloc->offset += i915_gem_obj_ggtt_offset(obj); + reloc_page = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, + reloc->offset & PAGE_MASK); + reloc_entry = (uint32_t __iomem *) +@@ -436,8 +436,8 @@ i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj, + obj->has_aliasing_ppgtt_mapping = 1; + } + +- if (entry->offset != obj->gtt_offset) { +- entry->offset = obj->gtt_offset; ++ if (entry->offset != i915_gem_obj_ggtt_offset(obj)) { ++ entry->offset = i915_gem_obj_ggtt_offset(obj); + *need_reloc = true; + } + +@@ -458,7 +458,7 @@ i915_gem_execbuffer_unreserve_object(struct drm_i915_gem_object *obj) + { + struct drm_i915_gem_exec_object2 *entry; + +- if (!obj->gtt_space) ++ if (!i915_gem_obj_ggtt_bound(obj)) + return; + + entry = obj->exec_entry; +@@ -530,7 +530,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, + struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; + bool need_fence, need_mappable; + +- if (!obj->gtt_space) ++ if (!i915_gem_obj_ggtt_bound(obj)) + continue; + + need_fence = +@@ -539,7 +539,8 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, + obj->tiling_mode != I915_TILING_NONE; + need_mappable = need_fence || need_reloc_mappable(obj); + +- if ((entry->alignment && obj->gtt_offset & (entry->alignment - 1)) || ++ if ((entry->alignment && ++ i915_gem_obj_ggtt_offset(obj) & (entry->alignment - 1)) || + (need_mappable && !obj->map_and_fenceable)) + ret = i915_gem_object_unbind(obj); + else +@@ -550,7 +551,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, + + /* Bind fresh objects */ + list_for_each_entry(obj, objects, exec_list) { +- if (obj->gtt_space) ++ if (i915_gem_obj_ggtt_bound(obj)) + continue; + + ret = i915_gem_execbuffer_reserve_object(obj, ring, need_relocs); +@@ -1058,7 +1059,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + goto err; + } + +- exec_start = batch_obj->gtt_offset + args->batch_start_offset; ++ exec_start = i915_gem_obj_ggtt_offset(batch_obj) + args->batch_start_offset; + exec_len = args->batch_len; + if (cliprects) { + for (i = 0; i < args->num_cliprects; i++) { +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index afba7e5e7739..6f0a4c09e26a 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -378,7 +378,7 @@ void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, + enum i915_cache_level cache_level) + { + ppgtt->insert_entries(ppgtt, obj->pages, +- obj->gtt_space->start >> PAGE_SHIFT, ++ i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT, + cache_level); + } + +@@ -386,7 +386,7 @@ void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, + struct drm_i915_gem_object *obj) + { + ppgtt->clear_range(ppgtt, +- obj->gtt_space->start >> PAGE_SHIFT, ++ i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT, + obj->base.size >> PAGE_SHIFT); + } + +@@ -551,7 +551,7 @@ void i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj, + struct drm_i915_private *dev_priv = dev->dev_private; + + dev_priv->gtt.gtt_insert_entries(dev, obj->pages, +- obj->gtt_space->start >> PAGE_SHIFT, ++ i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT, + cache_level); + + obj->has_global_gtt_mapping = 1; +@@ -563,7 +563,7 @@ void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj) + struct drm_i915_private *dev_priv = dev->dev_private; + + dev_priv->gtt.gtt_clear_range(obj->base.dev, +- obj->gtt_space->start >> PAGE_SHIFT, ++ i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT, + obj->base.size >> PAGE_SHIFT); + + obj->has_global_gtt_mapping = 0; +diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c +index 537545be69db..92a8d279ca39 100644 +--- a/drivers/gpu/drm/i915/i915_gem_tiling.c ++++ b/drivers/gpu/drm/i915/i915_gem_tiling.c +@@ -268,18 +268,18 @@ i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode) + return true; + + if (INTEL_INFO(obj->base.dev)->gen == 3) { +- if (obj->gtt_offset & ~I915_FENCE_START_MASK) ++ if (i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK) + return false; + } else { +- if (obj->gtt_offset & ~I830_FENCE_START_MASK) ++ if (i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK) + return false; + } + + size = i915_gem_get_gtt_size(obj->base.dev, obj->base.size, tiling_mode); +- if (obj->gtt_space->size != size) ++ if (i915_gem_obj_ggtt_size(obj) != size) + return false; + +- if (obj->gtt_offset & (size - 1)) ++ if (i915_gem_obj_ggtt_offset(obj) & (size - 1)) + return false; + + return true; +@@ -359,8 +359,8 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, + */ + + obj->map_and_fenceable = +- obj->gtt_space == NULL || +- (obj->gtt_offset + obj->base.size <= dev_priv->gtt.mappable_end && ++ !i915_gem_obj_ggtt_bound(obj) || ++ (i915_gem_obj_ggtt_offset(obj) + obj->base.size <= dev_priv->gtt.mappable_end && + i915_gem_object_fence_ok(obj, args->tiling_mode)); + + /* Rebind if we need a change of alignment */ +@@ -369,7 +369,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, + i915_gem_get_gtt_alignment(dev, obj->base.size, + args->tiling_mode, + false); +- if (obj->gtt_offset & (unfenced_alignment - 1)) ++ if (i915_gem_obj_ggtt_offset(obj) & (unfenced_alignment - 1)) + ret = i915_gem_object_unbind(obj); + } + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 4a98600c6f41..eaa8c1eda17f 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1554,7 +1554,7 @@ i915_error_object_create_sized(struct drm_i915_private *dev_priv, + if (dst == NULL) + return NULL; + +- reloc_offset = src->gtt_offset; ++ reloc_offset = dst->gtt_offset = i915_gem_obj_ggtt_offset(src); + for (i = 0; i < num_pages; i++) { + unsigned long flags; + void *d; +@@ -1606,7 +1606,6 @@ i915_error_object_create_sized(struct drm_i915_private *dev_priv, + reloc_offset += PAGE_SIZE; + } + dst->page_count = num_pages; +- dst->gtt_offset = src->gtt_offset; + + return dst; + +@@ -1660,7 +1659,7 @@ static void capture_bo(struct drm_i915_error_buffer *err, + err->name = obj->base.name; + err->rseqno = obj->last_read_seqno; + err->wseqno = obj->last_write_seqno; +- err->gtt_offset = obj->gtt_offset; ++ err->gtt_offset = i915_gem_obj_ggtt_offset(obj); + err->read_domains = obj->base.read_domains; + err->write_domain = obj->base.write_domain; + err->fence_reg = obj->fence_reg; +@@ -1758,8 +1757,8 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, + return NULL; + + obj = ring->private; +- if (acthd >= obj->gtt_offset && +- acthd < obj->gtt_offset + obj->base.size) ++ if (acthd >= i915_gem_obj_ggtt_offset(obj) && ++ acthd < i915_gem_obj_ggtt_offset(obj) + obj->base.size) + return i915_error_object_create(dev_priv, obj); + } + +@@ -1840,7 +1839,7 @@ static void i915_gem_record_active_context(struct intel_ring_buffer *ring, + return; + + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { +- if ((error->ccid & PAGE_MASK) == obj->gtt_offset) { ++ if ((error->ccid & PAGE_MASK) == i915_gem_obj_ggtt_offset(obj)) { + ering->ctx = i915_error_object_create_sized(dev_priv, + obj, 1); + break; +@@ -2206,10 +2205,10 @@ static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, in + if (INTEL_INFO(dev)->gen >= 4) { + int dspsurf = DSPSURF(intel_crtc->plane); + stall_detected = I915_HI_DISPBASE(I915_READ(dspsurf)) == +- obj->gtt_offset; ++ i915_gem_obj_ggtt_offset(obj); + } else { + int dspaddr = DSPADDR(intel_crtc->plane); +- stall_detected = I915_READ(dspaddr) == (obj->gtt_offset + ++ stall_detected = I915_READ(dspaddr) == (i915_gem_obj_ggtt_offset(obj) + + crtc->y * crtc->fb->pitches[0] + + crtc->x * crtc->fb->bits_per_pixel/8); + } +diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h +index 3db4a6817713..7d283b5fcbf9 100644 +--- a/drivers/gpu/drm/i915/i915_trace.h ++++ b/drivers/gpu/drm/i915/i915_trace.h +@@ -46,8 +46,8 @@ TRACE_EVENT(i915_gem_object_bind, + + TP_fast_assign( + __entry->obj = obj; +- __entry->offset = obj->gtt_space->start; +- __entry->size = obj->gtt_space->size; ++ __entry->offset = i915_gem_obj_ggtt_offset(obj); ++ __entry->size = i915_gem_obj_ggtt_size(obj); + __entry->mappable = mappable; + ), + +@@ -68,8 +68,8 @@ TRACE_EVENT(i915_gem_object_unbind, + + TP_fast_assign( + __entry->obj = obj; +- __entry->offset = obj->gtt_space->start; +- __entry->size = obj->gtt_space->size; ++ __entry->offset = i915_gem_obj_ggtt_offset(obj); ++ __entry->size = i915_gem_obj_ggtt_size(obj); + ), + + TP_printk("obj=%p, offset=%08x size=%x", +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 9733f275454d..3886db95a688 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1980,16 +1980,17 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, + intel_crtc->dspaddr_offset = linear_offset; + } + +- DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n", +- obj->gtt_offset, linear_offset, x, y, fb->pitches[0]); ++ DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", ++ i915_gem_obj_ggtt_offset(obj), linear_offset, x, y, ++ fb->pitches[0]); + I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); + if (INTEL_INFO(dev)->gen >= 4) { + I915_MODIFY_DISPBASE(DSPSURF(plane), +- obj->gtt_offset + intel_crtc->dspaddr_offset); ++ i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); + I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); + I915_WRITE(DSPLINOFF(plane), linear_offset); + } else +- I915_WRITE(DSPADDR(plane), obj->gtt_offset + linear_offset); ++ I915_WRITE(DSPADDR(plane), i915_gem_obj_ggtt_offset(obj) + linear_offset); + POSTING_READ(reg); + + return 0; +@@ -2069,11 +2070,12 @@ static int ironlake_update_plane(struct drm_crtc *crtc, + fb->pitches[0]); + linear_offset -= intel_crtc->dspaddr_offset; + +- DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n", +- obj->gtt_offset, linear_offset, x, y, fb->pitches[0]); ++ DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", ++ i915_gem_obj_ggtt_offset(obj), linear_offset, x, y, ++ fb->pitches[0]); + I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); + I915_MODIFY_DISPBASE(DSPSURF(plane), +- obj->gtt_offset + intel_crtc->dspaddr_offset); ++ i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); + if (IS_HASWELL(dev)) { + I915_WRITE(DSPOFFSET(plane), (y << 16) | x); + } else { +@@ -6568,7 +6570,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, + goto fail_unpin; + } + +- addr = obj->gtt_offset; ++ addr = i915_gem_obj_ggtt_offset(obj); + } else { + int align = IS_I830(dev) ? 16 * 1024 : 256; + ret = i915_gem_attach_phys_object(dev, obj, +@@ -7340,7 +7342,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev, + intel_ring_emit(ring, MI_DISPLAY_FLIP | + MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); + intel_ring_emit(ring, fb->pitches[0]); +- intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset); ++ intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); + intel_ring_emit(ring, 0); /* aux display base address, unused */ + + intel_mark_page_flip_active(intel_crtc); +@@ -7381,7 +7383,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev, + intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | + MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); + intel_ring_emit(ring, fb->pitches[0]); +- intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset); ++ intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); + intel_ring_emit(ring, MI_NOOP); + + intel_mark_page_flip_active(intel_crtc); +@@ -7421,7 +7423,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev, + MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); + intel_ring_emit(ring, fb->pitches[0]); + intel_ring_emit(ring, +- (obj->gtt_offset + intel_crtc->dspaddr_offset) | ++ (i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset) | + obj->tiling_mode); + + /* XXX Enabling the panel-fitter across page-flip is so far +@@ -7464,7 +7466,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev, + intel_ring_emit(ring, MI_DISPLAY_FLIP | + MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); + intel_ring_emit(ring, fb->pitches[0] | obj->tiling_mode); +- intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset); ++ intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); + + /* Contrary to the suggestions in the documentation, + * "Enable Panel Fitter" does not seem to be required when page +@@ -7529,7 +7531,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev, + + intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit); + intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); +- intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset); ++ intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); + intel_ring_emit(ring, (MI_NOOP)); + + intel_mark_page_flip_active(intel_crtc); +diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c +index dff669e2387f..f3c97e05b0d8 100644 +--- a/drivers/gpu/drm/i915/intel_fb.c ++++ b/drivers/gpu/drm/i915/intel_fb.c +@@ -139,11 +139,11 @@ static int intelfb_create(struct drm_fb_helper *helper, + info->apertures->ranges[0].base = dev->mode_config.fb_base; + info->apertures->ranges[0].size = dev_priv->gtt.mappable_end; + +- info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset; ++ info->fix.smem_start = dev->mode_config.fb_base + i915_gem_obj_ggtt_offset(obj); + info->fix.smem_len = size; + + info->screen_base = +- ioremap_wc(dev_priv->gtt.mappable_base + obj->gtt_offset, ++ ioremap_wc(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj), + size); + if (!info->screen_base) { + ret = -ENOSPC; +@@ -166,9 +166,9 @@ static int intelfb_create(struct drm_fb_helper *helper, + + /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ + +- DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", ++ DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08lx, bo %p\n", + fb->width, fb->height, +- obj->gtt_offset, obj); ++ i915_gem_obj_ggtt_offset(obj), obj); + + + mutex_unlock(&dev->struct_mutex); +diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c +index a3698812e9c7..81c3ca14fa92 100644 +--- a/drivers/gpu/drm/i915/intel_overlay.c ++++ b/drivers/gpu/drm/i915/intel_overlay.c +@@ -196,7 +196,7 @@ intel_overlay_map_regs(struct intel_overlay *overlay) + regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_obj->handle->vaddr; + else + regs = io_mapping_map_wc(dev_priv->gtt.mappable, +- overlay->reg_bo->gtt_offset); ++ i915_gem_obj_ggtt_offset(overlay->reg_bo)); + + return regs; + } +@@ -740,7 +740,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, + swidth = params->src_w; + swidthsw = calc_swidthsw(overlay->dev, params->offset_Y, tmp_width); + sheight = params->src_h; +- iowrite32(new_bo->gtt_offset + params->offset_Y, ®s->OBUF_0Y); ++ iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_Y, ®s->OBUF_0Y); + ostride = params->stride_Y; + + if (params->format & I915_OVERLAY_YUV_PLANAR) { +@@ -754,8 +754,8 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, + params->src_w/uv_hscale); + swidthsw |= max_t(u32, tmp_U, tmp_V) << 16; + sheight |= (params->src_h/uv_vscale) << 16; +- iowrite32(new_bo->gtt_offset + params->offset_U, ®s->OBUF_0U); +- iowrite32(new_bo->gtt_offset + params->offset_V, ®s->OBUF_0V); ++ iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_U, ®s->OBUF_0U); ++ iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_V, ®s->OBUF_0V); + ostride |= params->stride_UV << 16; + } + +@@ -1355,7 +1355,7 @@ void intel_setup_overlay(struct drm_device *dev) + DRM_ERROR("failed to pin overlay register bo\n"); + goto out_free_bo; + } +- overlay->flip_addr = reg_bo->gtt_offset; ++ overlay->flip_addr = i915_gem_obj_ggtt_offset(reg_bo); + + ret = i915_gem_object_set_to_gtt_domain(reg_bo, true); + if (ret) { +@@ -1435,7 +1435,7 @@ intel_overlay_map_regs_atomic(struct intel_overlay *overlay) + overlay->reg_bo->phys_obj->handle->vaddr; + else + regs = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, +- overlay->reg_bo->gtt_offset); ++ i915_gem_obj_ggtt_offset(overlay->reg_bo)); + + return regs; + } +@@ -1468,7 +1468,7 @@ intel_overlay_capture_error_state(struct drm_device *dev) + if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) + error->base = (__force long)overlay->reg_bo->phys_obj->handle->vaddr; + else +- error->base = overlay->reg_bo->gtt_offset; ++ error->base = i915_gem_obj_ggtt_offset(overlay->reg_bo); + + regs = intel_overlay_map_regs_atomic(overlay); + if (!regs) +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index f9d0afd4bd6c..613923a75abe 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -218,7 +218,7 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | + (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); + I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); +- I915_WRITE(ILK_FBC_RT_BASE, obj->gtt_offset | ILK_FBC_RT_VALID); ++ I915_WRITE(ILK_FBC_RT_BASE, i915_gem_obj_ggtt_offset(obj) | ILK_FBC_RT_VALID); + /* enable it... */ + I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); + +@@ -275,7 +275,7 @@ static void gen7_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + struct drm_i915_gem_object *obj = intel_fb->obj; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + +- I915_WRITE(IVB_FBC_RT_BASE, obj->gtt_offset); ++ I915_WRITE(IVB_FBC_RT_BASE, i915_gem_obj_ggtt_offset(obj)); + + I915_WRITE(ILK_DPFC_CONTROL, DPFC_CTL_EN | DPFC_CTL_LIMIT_1X | + IVB_DPFC_CTL_FENCE_EN | +@@ -3700,7 +3700,7 @@ static void ironlake_enable_rc6(struct drm_device *dev) + + intel_ring_emit(ring, MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN); + intel_ring_emit(ring, MI_SET_CONTEXT); +- intel_ring_emit(ring, dev_priv->ips.renderctx->gtt_offset | ++ intel_ring_emit(ring, i915_gem_obj_ggtt_offset(dev_priv->ips.renderctx) | + MI_MM_SPACE_GTT | + MI_SAVE_EXT_STATE_EN | + MI_RESTORE_EXT_STATE_EN | +@@ -3723,7 +3723,7 @@ static void ironlake_enable_rc6(struct drm_device *dev) + return; + } + +- I915_WRITE(PWRCTXA, dev_priv->ips.pwrctx->gtt_offset | PWRCTX_EN); ++ I915_WRITE(PWRCTXA, i915_gem_obj_ggtt_offset(dev_priv->ips.pwrctx) | PWRCTX_EN); + I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); + } + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 079ef0129e74..ea6aef5e6fea 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -440,14 +440,14 @@ static int init_ring_common(struct intel_ring_buffer *ring) + * registers with the above sequence (the readback of the HEAD registers + * also enforces ordering), otherwise the hw might lose the new ring + * register values. */ +- I915_WRITE_START(ring, obj->gtt_offset); ++ I915_WRITE_START(ring, i915_gem_obj_ggtt_offset(obj)); + I915_WRITE_CTL(ring, + ((ring->size - PAGE_SIZE) & RING_NR_PAGES) + | RING_VALID); + + /* If the head is still not zero, the ring is dead */ + if (wait_for((I915_READ_CTL(ring) & RING_VALID) != 0 && +- I915_READ_START(ring) == obj->gtt_offset && ++ I915_READ_START(ring) == i915_gem_obj_ggtt_offset(obj) && + (I915_READ_HEAD(ring) & HEAD_ADDR) == 0, 50)) { + DRM_ERROR("%s initialization failed " + "ctl %08x head %08x tail %08x start %08x\n", +@@ -505,7 +505,7 @@ init_pipe_control(struct intel_ring_buffer *ring) + if (ret) + goto err_unref; + +- pc->gtt_offset = obj->gtt_offset; ++ pc->gtt_offset = i915_gem_obj_ggtt_offset(obj); + pc->cpu_page = kmap(sg_page(obj->pages->sgl)); + if (pc->cpu_page == NULL) { + ret = -ENOMEM; +@@ -1156,7 +1156,7 @@ i830_dispatch_execbuffer(struct intel_ring_buffer *ring, + intel_ring_advance(ring); + } else { + struct drm_i915_gem_object *obj = ring->private; +- u32 cs_offset = obj->gtt_offset; ++ u32 cs_offset = i915_gem_obj_ggtt_offset(obj); + + if (len > I830_BATCH_LIMIT) + return -ENOSPC; +@@ -1241,7 +1241,7 @@ static int init_status_page(struct intel_ring_buffer *ring) + goto err_unref; + } + +- ring->status_page.gfx_addr = obj->gtt_offset; ++ ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(obj); + ring->status_page.page_addr = kmap(sg_page(obj->pages->sgl)); + if (ring->status_page.page_addr == NULL) { + ret = -ENOMEM; +@@ -1328,7 +1328,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, + goto err_unpin; + + ring->virtual_start = +- ioremap_wc(dev_priv->gtt.mappable_base + obj->gtt_offset, ++ ioremap_wc(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj), + ring->size); + if (ring->virtual_start == NULL) { + DRM_ERROR("Failed to map ringbuffer.\n"); +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index 1fa5612a4572..55bdf70b548b 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -133,7 +133,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb, + + I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); + I915_WRITE(SPCNTR(pipe, plane), sprctl); +- I915_MODIFY_DISPBASE(SPSURF(pipe, plane), obj->gtt_offset + ++ I915_MODIFY_DISPBASE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + + sprsurf_offset); + POSTING_READ(SPSURF(pipe, plane)); + } +@@ -308,7 +308,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, + if (intel_plane->can_scale) + I915_WRITE(SPRSCALE(pipe), sprscale); + I915_WRITE(SPRCTL(pipe), sprctl); +- I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset + sprsurf_offset); ++ I915_MODIFY_DISPBASE(SPRSURF(pipe), ++ i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); + POSTING_READ(SPRSURF(pipe)); + + /* potentially re-enable LP watermarks */ +@@ -478,7 +479,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, + I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); + I915_WRITE(DVSSCALE(pipe), dvsscale); + I915_WRITE(DVSCNTR(pipe), dvscntr); +- I915_MODIFY_DISPBASE(DVSSURF(pipe), obj->gtt_offset + dvssurf_offset); ++ I915_MODIFY_DISPBASE(DVSSURF(pipe), ++ i915_gem_obj_ggtt_offset(obj) + dvssurf_offset); + POSTING_READ(DVSSURF(pipe)); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0432-drm-i915-Kill-obj-gtt_offset.patch b/patches.baytrail/0432-drm-i915-Kill-obj-gtt_offset.patch new file mode 100644 index 000000000000..e1bfb5c085f9 --- /dev/null +++ b/patches.baytrail/0432-drm-i915-Kill-obj-gtt_offset.patch @@ -0,0 +1,131 @@ +From 2181bd42613113ce8c43f1e1d3fe573f254ab008 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Fri, 5 Jul 2013 14:41:05 -0700 +Subject: drm/i915: Kill obj->gtt_offset + +With the getters in place from the previous patch this members serves no +purpose other than saving one spare pointer chase, which will be killed +in the next patch anyway. + +Moving to VMAs, this members adds unnecessary confusion since an object +may exist at different offsets in different VMs. + +v2: Properly preserve the stolen offset. This code is a bit hacky but it +all goes away when we embed the drm_mm_node and removes the need for the +incorrect patch I submitted previously: "Use gtt_space->start for stolen +reservation" + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit edd41a870f11157a1bf4c15080421f9770912e09) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 9 +-------- + drivers/gpu/drm/i915/i915_gem.c | 2 -- + drivers/gpu/drm/i915/i915_gem_gtt.c | 14 ++++++++------ + drivers/gpu/drm/i915/i915_gem_stolen.c | 9 ++++++--- + 4 files changed, 15 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index ccf9bfa54c08..83946426f3d9 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1202,7 +1202,7 @@ enum hdmi_force_audio { + HDMI_AUDIO_ON, /* force turn on HDMI audio */ + }; + +-#define I915_GTT_RESERVED ((struct drm_mm_node *)0x1) ++#define I915_GTT_RESERVED (1<<0) + #define I915_GTT_OFFSET_NONE ((u32)-1) + + struct drm_i915_gem_object_ops { +@@ -1330,13 +1330,6 @@ struct drm_i915_gem_object { + unsigned long exec_handle; + struct drm_i915_gem_exec_object2 *exec_entry; + +- /** +- * Current offset of the object in GTT space. +- * +- * This is the same as gtt_space->start +- */ +- uint32_t gtt_offset; +- + struct intel_ring_buffer *ring; + + /** Breadcrumb of last rendering to the buffer. */ +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index e43a35dcff63..468a08060020 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2637,7 +2637,6 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) + + drm_mm_put_block(obj->gtt_space); + obj->gtt_space = NULL; +- obj->gtt_offset = 0; + + return 0; + } +@@ -3150,7 +3149,6 @@ search_free: + list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); + + obj->gtt_space = node; +- obj->gtt_offset = node->start; + + fenceable = + node->size == fence_size && +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 6f0a4c09e26a..76a4095452c7 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -629,18 +629,20 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + + /* Mark any preallocated objects as occupied */ + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { ++ uintptr_t offset = (uintptr_t) obj->gtt_space; + int ret; +- DRM_DEBUG_KMS("reserving preallocated space: %x + %zx\n", +- obj->gtt_offset, obj->base.size); ++ DRM_DEBUG_KMS("reserving preallocated space: %lx + %zx\n", ++ offset, obj->base.size); + +- BUG_ON(obj->gtt_space != I915_GTT_RESERVED); ++ BUG_ON((offset & I915_GTT_RESERVED) != 0); ++ offset &= ~I915_GTT_RESERVED; + obj->gtt_space = kzalloc(sizeof(*obj->gtt_space), GFP_KERNEL); + if (!obj->gtt_space) { +- DRM_ERROR("Failed to preserve object at offset %x\n", +- obj->gtt_offset); ++ DRM_ERROR("Failed to preserve object at offset %lx\n", ++ offset); + continue; + } +- obj->gtt_space->start = obj->gtt_offset; ++ obj->gtt_space->start = (unsigned long)offset; + obj->gtt_space->size = obj->base.size; + ret = drm_mm_reserve_node(&dev_priv->mm.gtt_space, + obj->gtt_space); +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index bc601c4fdc37..ee3d619ac2a3 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -392,10 +392,13 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); + goto free_out; + } +- } else +- obj->gtt_space = I915_GTT_RESERVED; ++ } else { ++ if (WARN_ON(gtt_offset & ~PAGE_MASK)) ++ DRM_DEBUG_KMS("Cannot preserve non page aligned offset\n"); ++ obj->gtt_space = ++ (struct drm_mm_node *)((uintptr_t)(I915_GTT_RESERVED | gtt_offset)); ++ } + +- obj->gtt_offset = gtt_offset; + obj->has_global_gtt_mapping = 1; + + list_add_tail(&obj->global_list, &dev_priv->mm.bound_list); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0433-drm-i915-Embed-drm_mm_node-in-i915-gem-obj.patch b/patches.baytrail/0433-drm-i915-Embed-drm_mm_node-in-i915-gem-obj.patch new file mode 100644 index 000000000000..7987912271f2 --- /dev/null +++ b/patches.baytrail/0433-drm-i915-Embed-drm_mm_node-in-i915-gem-obj.patch @@ -0,0 +1,304 @@ +From e81aa7d263996c1af86e0493b1753dd401577239 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Fri, 5 Jul 2013 14:41:06 -0700 +Subject: drm/i915: Embed drm_mm_node in i915 gem obj + +Embedding the node in the obj is more natural in the transition to VMAs +which will also have embedded nodes. This change also helps transition +away from put_block to remove node. + +Though it's quite an uncommon occurrence, it's somewhat convenient to not +fail at bind time because we cannot allocate the node. Though in +practice there are other allocations (like the request structure) which +would probably make this point not terribly useful. + +Quoting Daniel: +Note that the only difference between put_block and remove_node is +that the former fills up the preallocation cache. Which we don't need +anyway and hence is just wasted space. + +v2: Clean up the stolen preallocation code. +Rebased on the reserve_node patches +renames ggtt_ stuff to gtt_ stuff +WARN_ON if the object is already bound (which doesn't mean it's in the +bound list, tricky) + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit c6cfb325677ea6305fb19acf3a4d14ea267f923e) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 11 +++++------ + drivers/gpu/drm/i915/i915_gem.c | 31 +++++++++++-------------------- + drivers/gpu/drm/i915/i915_gem_evict.c | 6 +++--- + drivers/gpu/drm/i915/i915_gem_gtt.c | 23 +++++------------------ + drivers/gpu/drm/i915/i915_gem_stolen.c | 22 ++++------------------ + 5 files changed, 28 insertions(+), 65 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 83946426f3d9..db64bfefe8c5 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1202,7 +1202,6 @@ enum hdmi_force_audio { + HDMI_AUDIO_ON, /* force turn on HDMI audio */ + }; + +-#define I915_GTT_RESERVED (1<<0) + #define I915_GTT_OFFSET_NONE ((u32)-1) + + struct drm_i915_gem_object_ops { +@@ -1229,7 +1228,7 @@ struct drm_i915_gem_object { + const struct drm_i915_gem_object_ops *ops; + + /** Current space allocated to this object in the GTT, if any. */ +- struct drm_mm_node *gtt_space; ++ struct drm_mm_node gtt_space; + /** Stolen memory for this object, instead of being backed by shmem. */ + struct drm_mm_node *stolen; + struct list_head global_list; +@@ -1359,14 +1358,14 @@ struct drm_i915_gem_object { + static inline unsigned long + i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o) + { +- return o->gtt_space->start; ++ return o->gtt_space.start; + } + + /* Whether or not this object is currently mapped by the translation tables */ + static inline bool + i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *o) + { +- return o->gtt_space != NULL; ++ return drm_mm_node_allocated(&o->gtt_space); + } + + /* The size used in the translation tables may be larger than the actual size of +@@ -1376,14 +1375,14 @@ i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *o) + static inline unsigned long + i915_gem_obj_ggtt_size(struct drm_i915_gem_object *o) + { +- return o->gtt_space->size; ++ return o->gtt_space.size; + } + + static inline void + i915_gem_obj_ggtt_set_color(struct drm_i915_gem_object *o, + enum i915_cache_level color) + { +- o->gtt_space->color = color; ++ o->gtt_space.color = color; + } + + /** +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 468a08060020..ee1f4add3430 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2635,8 +2635,7 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) + /* Avoid an unnecessary call to unbind on rebind. */ + obj->map_and_fenceable = true; + +- drm_mm_put_block(obj->gtt_space); +- obj->gtt_space = NULL; ++ drm_mm_remove_node(&obj->gtt_space); + + return 0; + } +@@ -2997,7 +2996,7 @@ static bool i915_gem_valid_gtt_space(struct drm_device *dev, + if (HAS_LLC(dev)) + return true; + +- if (gtt_space == NULL) ++ if (!drm_mm_node_allocated(gtt_space)) + return true; + + if (list_empty(>t_space->node_list)) +@@ -3065,7 +3064,6 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + { + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; +- struct drm_mm_node *node; + u32 size, fence_size, fence_alignment, unfenced_alignment; + bool mappable, fenceable; + size_t gtt_max = map_and_fenceable ? +@@ -3110,14 +3108,9 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + + i915_gem_object_pin_pages(obj); + +- node = kzalloc(sizeof(*node), GFP_KERNEL); +- if (node == NULL) { +- i915_gem_object_unpin_pages(obj); +- return -ENOMEM; +- } +- + search_free: +- ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space, node, ++ ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space, ++ &obj->gtt_space, + size, alignment, + obj->cache_level, 0, gtt_max); + if (ret) { +@@ -3129,30 +3122,28 @@ search_free: + goto search_free; + + i915_gem_object_unpin_pages(obj); +- kfree(node); + return ret; + } +- if (WARN_ON(!i915_gem_valid_gtt_space(dev, node, obj->cache_level))) { ++ if (WARN_ON(!i915_gem_valid_gtt_space(dev, &obj->gtt_space, ++ obj->cache_level))) { + i915_gem_object_unpin_pages(obj); +- drm_mm_put_block(node); ++ drm_mm_remove_node(&obj->gtt_space); + return -EINVAL; + } + + ret = i915_gem_gtt_prepare_object(obj); + if (ret) { + i915_gem_object_unpin_pages(obj); +- drm_mm_put_block(node); ++ drm_mm_remove_node(&obj->gtt_space); + return ret; + } + + list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); + list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); + +- obj->gtt_space = node; +- + fenceable = +- node->size == fence_size && +- (node->start & (fence_alignment - 1)) == 0; ++ i915_gem_obj_ggtt_size(obj) == fence_size && ++ (i915_gem_obj_ggtt_offset(obj) & (fence_alignment - 1)) == 0; + + mappable = i915_gem_obj_ggtt_offset(obj) + obj->base.size <= + dev_priv->gtt.mappable_end; +@@ -3316,7 +3307,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + return -EBUSY; + } + +- if (!i915_gem_valid_gtt_space(dev, obj->gtt_space, cache_level)) { ++ if (!i915_gem_valid_gtt_space(dev, &obj->gtt_space, cache_level)) { + ret = i915_gem_object_unbind(obj); + if (ret) + return ret; +diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c +index c86d5d9356fd..5f8afc48bb7e 100644 +--- a/drivers/gpu/drm/i915/i915_gem_evict.c ++++ b/drivers/gpu/drm/i915/i915_gem_evict.c +@@ -38,7 +38,7 @@ mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind) + return false; + + list_add(&obj->exec_list, unwind); +- return drm_mm_scan_add_block(obj->gtt_space); ++ return drm_mm_scan_add_block(&obj->gtt_space); + } + + int +@@ -107,7 +107,7 @@ none: + struct drm_i915_gem_object, + exec_list); + +- ret = drm_mm_scan_remove_block(obj->gtt_space); ++ ret = drm_mm_scan_remove_block(&obj->gtt_space); + BUG_ON(ret); + + list_del_init(&obj->exec_list); +@@ -127,7 +127,7 @@ found: + obj = list_first_entry(&unwind_list, + struct drm_i915_gem_object, + exec_list); +- if (drm_mm_scan_remove_block(obj->gtt_space)) { ++ if (drm_mm_scan_remove_block(&obj->gtt_space)) { + list_move(&obj->exec_list, &eviction_list); + drm_gem_object_reference(&obj->base); + continue; +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 76a4095452c7..242d0f9bb9e4 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -629,28 +629,15 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + + /* Mark any preallocated objects as occupied */ + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { +- uintptr_t offset = (uintptr_t) obj->gtt_space; + int ret; + DRM_DEBUG_KMS("reserving preallocated space: %lx + %zx\n", +- offset, obj->base.size); +- +- BUG_ON((offset & I915_GTT_RESERVED) != 0); +- offset &= ~I915_GTT_RESERVED; +- obj->gtt_space = kzalloc(sizeof(*obj->gtt_space), GFP_KERNEL); +- if (!obj->gtt_space) { +- DRM_ERROR("Failed to preserve object at offset %lx\n", +- offset); +- continue; +- } +- obj->gtt_space->start = (unsigned long)offset; +- obj->gtt_space->size = obj->base.size; ++ i915_gem_obj_ggtt_offset(obj), obj->base.size); ++ ++ WARN_ON(i915_gem_obj_ggtt_bound(obj)); + ret = drm_mm_reserve_node(&dev_priv->mm.gtt_space, +- obj->gtt_space); +- if (ret) { ++ &obj->gtt_space); ++ if (ret) + DRM_DEBUG_KMS("Reservation failed\n"); +- kfree(obj->gtt_space); +- obj->gtt_space = NULL; +- } + obj->has_global_gtt_mapping = 1; + } + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index ee3d619ac2a3..bbe4391f904f 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -377,26 +377,15 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + * setting up the GTT space. The actual reservation will occur + * later. + */ ++ obj->gtt_space.start = gtt_offset; ++ obj->gtt_space.size = size; + if (drm_mm_initialized(&dev_priv->mm.gtt_space)) { +- obj->gtt_space = kzalloc(sizeof(*obj->gtt_space), GFP_KERNEL); +- if (!obj->gtt_space) { +- DRM_DEBUG_KMS("-ENOMEM stolen GTT space\n"); +- goto unref_out; +- } +- +- obj->gtt_space->start = gtt_offset; +- obj->gtt_space->size = size; + ret = drm_mm_reserve_node(&dev_priv->mm.gtt_space, +- obj->gtt_space); ++ &obj->gtt_space); + if (ret) { + DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); +- goto free_out; ++ goto unref_out; + } +- } else { +- if (WARN_ON(gtt_offset & ~PAGE_MASK)) +- DRM_DEBUG_KMS("Cannot preserve non page aligned offset\n"); +- obj->gtt_space = +- (struct drm_mm_node *)((uintptr_t)(I915_GTT_RESERVED | gtt_offset)); + } + + obj->has_global_gtt_mapping = 1; +@@ -406,9 +395,6 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + + return obj; + +-free_out: +- kfree(obj->gtt_space); +- obj->gtt_space = NULL; + unref_out: + drm_gem_object_unreference(&obj->base); + return NULL; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0434-drm-i915-fix-dvo-DPLL-regression.patch b/patches.baytrail/0434-drm-i915-fix-dvo-DPLL-regression.patch new file mode 100644 index 000000000000..b76bfce664b9 --- /dev/null +++ b/patches.baytrail/0434-drm-i915-fix-dvo-DPLL-regression.patch @@ -0,0 +1,118 @@ +From 1d9af76730003a1defef3b2386964c90c80c3297 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sat, 6 Jul 2013 12:52:05 +0200 +Subject: drm/i915: fix dvo DPLL regression + +I've missed that intel_dvo_mode_set changes the dpll configuration. +Hence when I've reworked the sequence to only enable the dpll in the +crtc_enable callback in + +commit 66e3d5c09940d08d94b03e65b420fadaa7484318 +Author: Daniel Vetter +Date: Sun Jun 16 21:24:16 2013 +0200 + + drm/i915: move i9xx dpll enabling into crtc enable function + +that special DVO bit was lost. Some BSpec reading confirms that it's +only needed for DVO encoders. Section 1.5.4, "DPLL A Control Register" +for bit 30: + +"2X Clock Enable. When driving In non-gang DVO modes such as a +connected flat panel or TV, a 2X" version of the clock is needed. When +not using the 2X output it should be disabled. This bit cannot be set +when driving the integrated LVDS port on devices such as Montara-GM." + +Fix this regression up. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66516 +Cc: Chris Wilson +Reported-by: Chris Wilson +Reviewed-by: Chris Wilson +Partially-tested-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 4a33e48d0e121953342194b45d33dc752353d62b) +(cherry picked from drm-intel-next-queued) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 3 ++- + drivers/gpu/drm/i915/intel_display.c | 11 +++++++---- + drivers/gpu/drm/i915/intel_dvo.c | 3 --- + 3 files changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index d8278254bca3..0f604881a3b4 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -1128,7 +1128,8 @@ + #define _DPLL_B (dev_priv->info->display_mmio_offset + 0x6018) + #define DPLL(pipe) _PIPE(pipe, _DPLL_A, _DPLL_B) + #define DPLL_VCO_ENABLE (1 << 31) +-#define DPLL_DVO_HIGH_SPEED (1 << 30) ++#define DPLL_SDVO_HIGH_SPEED (1 << 30) ++#define DPLL_DVO_2X_MODE (1 << 30) + #define DPLL_EXT_BUFFER_ENABLE_VLV (1 << 30) + #define DPLL_SYNCLOCK_ENABLE (1 << 29) + #define DPLL_REFA_CLK_ENABLE_VLV (1 << 29) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 3886db95a688..9be6594e7f06 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4540,10 +4540,10 @@ static void i9xx_update_pll(struct intel_crtc *crtc, + } + + if (is_sdvo) +- dpll |= DPLL_DVO_HIGH_SPEED; ++ dpll |= DPLL_SDVO_HIGH_SPEED; + + if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)) +- dpll |= DPLL_DVO_HIGH_SPEED; ++ dpll |= DPLL_SDVO_HIGH_SPEED; + + /* compute bitmask from p1 value */ + if (IS_PINEVIEW(dev)) +@@ -4615,6 +4615,9 @@ static void i8xx_update_pll(struct intel_crtc *crtc, + dpll |= PLL_P2_DIVIDE_BY_4; + } + ++ if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DVO)) ++ dpll |= DPLL_DVO_2X_MODE; ++ + if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) && + intel_panel_use_ssc(dev_priv) && num_connectors < 2) + dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; +@@ -5647,9 +5650,9 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, + << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; + + if (is_sdvo) +- dpll |= DPLL_DVO_HIGH_SPEED; ++ dpll |= DPLL_SDVO_HIGH_SPEED; + if (intel_crtc->config.has_dp_encoder) +- dpll |= DPLL_DVO_HIGH_SPEED; ++ dpll |= DPLL_SDVO_HIGH_SPEED; + + /* compute bitmask from p1 value */ + dpll |= (1 << (intel_crtc->config.dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; +diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c +index eb2020eb2b7e..cbbc49dc03be 100644 +--- a/drivers/gpu/drm/i915/intel_dvo.c ++++ b/drivers/gpu/drm/i915/intel_dvo.c +@@ -283,7 +283,6 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, + int pipe = intel_crtc->pipe; + u32 dvo_val; + u32 dvo_reg = intel_dvo->dev.dvo_reg, dvo_srcdim_reg; +- int dpll_reg = DPLL(pipe); + + switch (dvo_reg) { + case DVOA: +@@ -314,8 +313,6 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, + if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) + dvo_val |= DVO_VSYNC_ACTIVE_HIGH; + +- I915_WRITE(dpll_reg, I915_READ(dpll_reg) | DPLL_DVO_HIGH_SPEED); +- + /*I915_WRITE(DVOB_SRCDIM, + (adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | + (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0435-drm-i915-dvo-needs-a-P2-divisor-of-4.patch b/patches.baytrail/0435-drm-i915-dvo-needs-a-P2-divisor-of-4.patch new file mode 100644 index 000000000000..088a4e561502 --- /dev/null +++ b/patches.baytrail/0435-drm-i915-dvo-needs-a-P2-divisor-of-4.patch @@ -0,0 +1,70 @@ +From 4c47f5e1da55a659db8511ef3b2a34080b031b16 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sat, 6 Jul 2013 12:52:06 +0200 +Subject: drm/i915: dvo needs a P2 divisor of 4 + +Section 1.5.4, "DPLL A Control Register" from Bspec about bit 23 +"FPA0/A1 P2 Clock Divide": + +0 = Divide by 2 +1 = Divide by 4. This bit must be set in DVO non-gang mode + +So copy the current limits (which should be good for i8xx) and create +a new set for dvo encoders. + +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 5d536e2858ead64ea945552ec6a491f968c55888) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 9be6594e7f06..15f72adde61d 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -89,7 +89,7 @@ intel_fdi_link_freq(struct drm_device *dev) + return 27; + } + +-static const intel_limit_t intel_limits_i8xx_dvo = { ++static const intel_limit_t intel_limits_i8xx_dac = { + .dot = { .min = 25000, .max = 350000 }, + .vco = { .min = 930000, .max = 1400000 }, + .n = { .min = 3, .max = 16 }, +@@ -102,6 +102,19 @@ static const intel_limit_t intel_limits_i8xx_dvo = { + .p2_slow = 4, .p2_fast = 2 }, + }; + ++static const intel_limit_t intel_limits_i8xx_dvo = { ++ .dot = { .min = 25000, .max = 350000 }, ++ .vco = { .min = 930000, .max = 1400000 }, ++ .n = { .min = 3, .max = 16 }, ++ .m = { .min = 96, .max = 140 }, ++ .m1 = { .min = 18, .max = 26 }, ++ .m2 = { .min = 6, .max = 16 }, ++ .p = { .min = 4, .max = 128 }, ++ .p1 = { .min = 2, .max = 33 }, ++ .p2 = { .dot_limit = 165000, ++ .p2_slow = 4, .p2_fast = 4 }, ++}; ++ + static const intel_limit_t intel_limits_i8xx_lvds = { + .dot = { .min = 25000, .max = 350000 }, + .vco = { .min = 930000, .max = 1400000 }, +@@ -410,8 +423,10 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk) + } else { + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) + limit = &intel_limits_i8xx_lvds; +- else ++ else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO)) + limit = &intel_limits_i8xx_dvo; ++ else ++ limit = &intel_limits_i8xx_dac; + } + return limit; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0436-drm-i915-convert-debugfs-creation-destruction-to-tab.patch b/patches.baytrail/0436-drm-i915-convert-debugfs-creation-destruction-to-tab.patch new file mode 100644 index 000000000000..e0444f29f1e1 --- /dev/null +++ b/patches.baytrail/0436-drm-i915-convert-debugfs-creation-destruction-to-tab.patch @@ -0,0 +1,146 @@ +From 84533bd99dfd6e65ad34703c2f2bf9c906821ffb Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 4 Jul 2013 20:49:44 +0200 +Subject: drm/i915: convert debugfs creation/destruction to table + +At least for the common cases where we only need special file +operations. The forcewake file is still rather more special. + +v2: Fix up the debugfs unregister code. + +v3: Actually squash in the right fixup. + +Acked-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 34b9674c786c73e5472e8b98a729bcdde9197859) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 94 ++++++++++++------------------------- + 1 file changed, 30 insertions(+), 64 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 396387ed207a..d4138124d993 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -2375,61 +2375,35 @@ static struct drm_info_list i915_debugfs_list[] = { + }; + #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) + ++struct i915_debugfs_files { ++ const char *name; ++ const struct file_operations *fops; ++} i915_debugfs_files[] = { ++ {"i915_wedged", &i915_wedged_fops}, ++ {"i915_max_freq", &i915_max_freq_fops}, ++ {"i915_min_freq", &i915_min_freq_fops}, ++ {"i915_cache_sharing", &i915_cache_sharing_fops}, ++ {"i915_ring_stop", &i915_ring_stop_fops}, ++ {"i915_gem_drop_caches", &i915_drop_caches_fops}, ++ {"i915_error_state", &i915_error_state_fops}, ++ {"i915_next_seqno", &i915_next_seqno_fops}, ++}; ++ + int i915_debugfs_init(struct drm_minor *minor) + { +- int ret; +- +- ret = i915_debugfs_create(minor->debugfs_root, minor, +- "i915_wedged", +- &i915_wedged_fops); +- if (ret) +- return ret; ++ int ret, i; + + ret = i915_forcewake_create(minor->debugfs_root, minor); + if (ret) + return ret; + +- ret = i915_debugfs_create(minor->debugfs_root, minor, +- "i915_max_freq", +- &i915_max_freq_fops); +- if (ret) +- return ret; +- +- ret = i915_debugfs_create(minor->debugfs_root, minor, +- "i915_min_freq", +- &i915_min_freq_fops); +- if (ret) +- return ret; +- +- ret = i915_debugfs_create(minor->debugfs_root, minor, +- "i915_cache_sharing", +- &i915_cache_sharing_fops); +- if (ret) +- return ret; +- +- ret = i915_debugfs_create(minor->debugfs_root, minor, +- "i915_ring_stop", +- &i915_ring_stop_fops); +- if (ret) +- return ret; +- +- ret = i915_debugfs_create(minor->debugfs_root, minor, +- "i915_gem_drop_caches", +- &i915_drop_caches_fops); +- if (ret) +- return ret; +- +- ret = i915_debugfs_create(minor->debugfs_root, minor, +- "i915_error_state", +- &i915_error_state_fops); +- if (ret) +- return ret; +- +- ret = i915_debugfs_create(minor->debugfs_root, minor, +- "i915_next_seqno", +- &i915_next_seqno_fops); +- if (ret) +- return ret; ++ for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) { ++ ret = i915_debugfs_create(minor->debugfs_root, minor, ++ i915_debugfs_files[i].name, ++ i915_debugfs_files[i].fops); ++ if (ret) ++ return ret; ++ } + + return drm_debugfs_create_files(i915_debugfs_list, + I915_DEBUGFS_ENTRIES, +@@ -2438,26 +2412,18 @@ int i915_debugfs_init(struct drm_minor *minor) + + void i915_debugfs_cleanup(struct drm_minor *minor) + { ++ int i; ++ + drm_debugfs_remove_files(i915_debugfs_list, + I915_DEBUGFS_ENTRIES, minor); + drm_debugfs_remove_files((struct drm_info_list *) &i915_forcewake_fops, + 1, minor); +- drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops, +- 1, minor); +- drm_debugfs_remove_files((struct drm_info_list *) &i915_max_freq_fops, +- 1, minor); +- drm_debugfs_remove_files((struct drm_info_list *) &i915_min_freq_fops, +- 1, minor); +- drm_debugfs_remove_files((struct drm_info_list *) &i915_cache_sharing_fops, +- 1, minor); +- drm_debugfs_remove_files((struct drm_info_list *) &i915_drop_caches_fops, +- 1, minor); +- drm_debugfs_remove_files((struct drm_info_list *) &i915_ring_stop_fops, +- 1, minor); +- drm_debugfs_remove_files((struct drm_info_list *) &i915_error_state_fops, +- 1, minor); +- drm_debugfs_remove_files((struct drm_info_list *) &i915_next_seqno_fops, +- 1, minor); ++ for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) { ++ struct drm_info_list *info_list = ++ (struct drm_info_list *) i915_debugfs_files[i].fops; ++ ++ drm_debugfs_remove_files(info_list, 1, minor); ++ } + } + + #endif /* CONFIG_DEBUG_FS */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0437-drm-i915-Verify-that-our-stolen-memory-doesn-t-confl.patch b/patches.baytrail/0437-drm-i915-Verify-that-our-stolen-memory-doesn-t-confl.patch new file mode 100644 index 000000000000..c3634ed09091 --- /dev/null +++ b/patches.baytrail/0437-drm-i915-Verify-that-our-stolen-memory-doesn-t-confl.patch @@ -0,0 +1,62 @@ +From de3d30956679caeeb67be4f5891883fb20819c7c Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Thu, 4 Jul 2013 12:28:35 +0100 +Subject: drm/i915: Verify that our stolen memory doesn't conflict + +Sanity check that the memory region found through the Graphics Base +of Stolen Memory is reserved and hidden from the rest of the system +through the use of the resource API. + +v2: "Graphics Stolen Memory" is such a more bodacious name than the lame + "i915 stolen", and convert to using devres for automagical cleanup of + the resource. (danvet) + +Signed-off-by: Chris Wilson +Cc: Daniel Vetter +[danvet: Dump proper hexcodes.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit eaba1b8f3379b5d100bd146b9a41d28348bdfd09) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_stolen.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index bbe4391f904f..24cae1c17e5a 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -46,6 +46,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct pci_dev *pdev = dev_priv->bridge_dev; ++ struct resource *r; + u32 base; + + /* On the machines I have tested the Graphics Base of Stolen Memory +@@ -88,6 +89,22 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) + #endif + } + ++ if (base == 0) ++ return 0; ++ ++ /* Verify that nothing else uses this physical address. Stolen ++ * memory should be reserved by the BIOS and hidden from the ++ * kernel. So if the region is already marked as busy, something ++ * is seriously wrong. ++ */ ++ r = devm_request_mem_region(dev->dev, base, dev_priv->gtt.stolen_size, ++ "Graphics Stolen Memory"); ++ if (r == NULL) { ++ DRM_ERROR("conflict detected with stolen region: [0x%08x - 0x%08x]\n", ++ base, base + (uint32_t)dev_priv->gtt.stolen_size); ++ base = 0; ++ } ++ + return base; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0438-drm-i915-clean-up-media-reset-on-gm45.patch b/patches.baytrail/0438-drm-i915-clean-up-media-reset-on-gm45.patch new file mode 100644 index 000000000000..a748033be5e2 --- /dev/null +++ b/patches.baytrail/0438-drm-i915-clean-up-media-reset-on-gm45.patch @@ -0,0 +1,77 @@ +From 673c7631ef372793cd0bd8718caea4eaccd6dc6a Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 9 Jul 2013 14:44:26 +0200 +Subject: drm/i915: clean up media reset on gm45 + +Originally I've thought that this fixes up the reset issues on my +gm45, but that was just a red herring due to b0rked testing. + +Still I much prefer writing the right values (all other fields are +reserved) instead of potentially dragging gunk around. Hence also +clear the register to 0 after a reset. + +Note that Cspec is a bit confused and doesn't explicitly say that all +the other bits in this register are "reserved, mbz" like usually. +Instead they're marked as "r/o, default value = 0" which semantically +amounts to the same thing. + +v2: Stop claiming this fixes anything and return 0 if successful +instead of stack garbage. + +v3: Pimp the commit message to explain exactly why I think the docs +allow us to ditch the rmw cycle, spurred by a discussion with Chris. + +Cc: Chris Wilson +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 36c0cc616e518bfc2b685bed7fb3243d1242eca4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index d286785c1bab..95fe9c2a1449 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -798,28 +798,29 @@ static int i965_reset_complete(struct drm_device *dev) + static int i965_do_reset(struct drm_device *dev) + { + int ret; +- u8 gdrst; + + /* + * Set the domains we want to reset (GRDOM/bits 2 and 3) as + * well as the reset bit (GR/bit 0). Setting the GR bit + * triggers the reset; when done, the hardware will clear it. + */ +- pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst); + pci_write_config_byte(dev->pdev, I965_GDRST, +- gdrst | GRDOM_RENDER | +- GRDOM_RESET_ENABLE); ++ GRDOM_RENDER | GRDOM_RESET_ENABLE); + ret = wait_for(i965_reset_complete(dev), 500); + if (ret) + return ret; + + /* We can't reset render&media without also resetting display ... */ +- pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst); + pci_write_config_byte(dev->pdev, I965_GDRST, +- gdrst | GRDOM_MEDIA | +- GRDOM_RESET_ENABLE); ++ GRDOM_MEDIA | GRDOM_RESET_ENABLE); + +- return wait_for(i965_reset_complete(dev), 500); ++ ret = wait_for(i965_reset_complete(dev), 500); ++ if (ret) ++ return ret; ++ ++ pci_write_config_byte(dev->pdev, I965_GDRST, 0); ++ ++ return 0; + } + + static int ironlake_do_reset(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0439-drm-i915-WARN-if-the-bios-reserved-range-is-bigger-t.patch b/patches.baytrail/0439-drm-i915-WARN-if-the-bios-reserved-range-is-bigger-t.patch new file mode 100644 index 000000000000..e3b68055e2e8 --- /dev/null +++ b/patches.baytrail/0439-drm-i915-WARN-if-the-bios-reserved-range-is-bigger-t.patch @@ -0,0 +1,35 @@ +From 327cf4f35a050d41ea17900d3b74956e5e2bd8b8 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 9 Jul 2013 14:44:27 +0200 +Subject: drm/i915: WARN if the bios reserved range is bigger than stolen size + +v2: Bail out if we hit the WARN_ON to avoid fallout later on. Spotted +by Chris Wilson. + +Suggested-by: Chris Wilson +Cc: Chris Wilson +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 897f9ed00a906dd3edc69f64d590bba87c45617b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_stolen.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 24cae1c17e5a..5c1a535d5072 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -218,6 +218,9 @@ int i915_gem_init_stolen(struct drm_device *dev) + if (IS_VALLEYVIEW(dev)) + bios_reserved = 1024*1024; /* top 1M on VLV/BYT */ + ++ if (WARN_ON(bios_reserved > dev_priv->gtt.stolen_size)) ++ return 0; ++ + /* Basic memrange allocator for stolen space */ + drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_size - + bios_reserved); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0440-drm-i915-Fix-VLV-DP-RBR-HDMI-DAC-PLL-LPF-coefficient.patch b/patches.baytrail/0440-drm-i915-Fix-VLV-DP-RBR-HDMI-DAC-PLL-LPF-coefficient.patch new file mode 100644 index 000000000000..ea994e0b64a6 --- /dev/null +++ b/patches.baytrail/0440-drm-i915-Fix-VLV-DP-RBR-HDMI-DAC-PLL-LPF-coefficient.patch @@ -0,0 +1,43 @@ +From bd1283dde3e950c3403364ee2f32cb68a30280a1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 5 Jul 2013 19:21:38 +0300 +Subject: drm/i915: Fix VLV DP RBR/HDMI/DAC PLL LPF coefficients +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +I just got confirmation that we're using some old values for the PLL +LPF coefficients for DP RBR/HDMI/DAC on VLV. The +VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_9 document lists both values +by mistake, and apparently we had picked the wrong one. Change the +coefficients to the recommended values. + +Changing the value doesn't appear to destabilize the VGA output picture +even with my sensitive HP ZR24w display. Also HDMI output to my TV still +works fine. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 885b012008583ba70e5537d479454450f5bdfa09) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 15f72adde61d..7ab60c74dff4 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4461,7 +4461,7 @@ static void vlv_update_pll(struct intel_crtc *crtc) + intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_ANALOG) || + intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI)) + vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe), +- 0x005f0021); ++ 0x009f0003); + else + vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe), + 0x00d0000f); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0441-drm-i915-don-t-frob-mm.suspended-when-not-using-ums.patch b/patches.baytrail/0441-drm-i915-don-t-frob-mm.suspended-when-not-using-ums.patch new file mode 100644 index 000000000000..2c6c19fbe29b --- /dev/null +++ b/patches.baytrail/0441-drm-i915-don-t-frob-mm.suspended-when-not-using-ums.patch @@ -0,0 +1,315 @@ +From 4370ef17e5269a02647a350abbdcb6ae171a41b7 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 9 Jul 2013 16:51:37 +0200 +Subject: drm/i915: don't frob mm.suspended when not using ums + +In kernel modeset driver mode we're in full control of the chip, +always. So there's no need at all to set mm.suspended in +i915_gem_idle. Hence move that out into the leavevt ioctl. Since +i915_gem_idle doesn't suspend gem any more we can also drop the +re-enabling for KMS in the thaw function. + +Also clean up the handling of mm.suspend at driver load by coalescing +all the assignments. + +Stumbled over while reading through our resume code for unrelated +reasons. + +v2: Shovel mm.suspended into the (newly created) ums dungeon as +suggested by Chris Wilson. The plan is that once we've completely +stopped relying on the register save/restore code we could shovel even +that in there. + +v3: Improve the locking for the entervt/leavevt ioctls a bit by moving +the dev->struct_mutex locking outside of i915_gem_idle. Also don't +clear dev_priv->ums.mm_suspended for the kms case, we allocate it with +kzalloc. Both suggested by Chris Wilson. + +Cc: Chris Wilson +Reviewed-by: Chris Wilson (v2) +Signed-off-by: Daniel Vetter +(cherry picked from commit db1b76ca6a79c774074ae87bee7afc0825a478f5) +Signed-off-by: James Ausmus + +Conflicts: + drivers/gpu/drm/i915/i915_gem.c + (used airlied's rerere from + e13af9a8340685cfe25d0c9f708da7121e0f51dd) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 13 +++------- + drivers/gpu/drm/i915/i915_drv.c | 11 +++++--- + drivers/gpu/drm/i915/i915_drv.h | 24 ++++++++++-------- + drivers/gpu/drm/i915/i915_gem.c | 40 ++++++++++++++++++------------ + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- + 5 files changed, 50 insertions(+), 40 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 6995baca9b62..240e1ef3c993 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1323,10 +1323,8 @@ static int i915_load_modeset_init(struct drm_device *dev) + /* Always safe in the mode setting case. */ + /* FIXME: do pre/post-mode set stuff in core KMS code */ + dev->vblank_disable_allowed = 1; +- if (INTEL_INFO(dev)->num_pipes == 0) { +- dev_priv->mm.suspended = 0; ++ if (INTEL_INFO(dev)->num_pipes == 0) + return 0; +- } + + ret = intel_fbdev_init(dev); + if (ret) +@@ -1352,9 +1350,6 @@ static int i915_load_modeset_init(struct drm_device *dev) + + drm_kms_helper_poll_init(dev); + +- /* We're off and running w/KMS */ +- dev_priv->mm.suspended = 0; +- + return 0; + + cleanup_gem: +@@ -1631,9 +1626,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + goto out_gem_unload; + } + +- /* Start out suspended */ +- dev_priv->mm.suspended = 1; +- + if (HAS_POWER_WELL(dev)) + i915_init_power_well(dev); + +@@ -1643,6 +1635,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + DRM_ERROR("failed to init modeset\n"); + goto out_gem_unload; + } ++ } else { ++ /* Start out suspended in ums mode. */ ++ dev_priv->ums.mm_suspended = 1; + } + + i915_setup_sysfs(dev); +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 95fe9c2a1449..370f2da5d9c0 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -556,7 +556,11 @@ static int i915_drm_freeze(struct drm_device *dev) + + /* If KMS is active, we do the leavevt stuff here */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { +- int error = i915_gem_idle(dev); ++ int error; ++ ++ mutex_lock(&dev->struct_mutex); ++ error = i915_gem_idle(dev); ++ mutex_unlock(&dev->struct_mutex); + if (error) { + dev_err(&dev->pdev->dev, + "GEM idle failed, resume might fail\n"); +@@ -661,7 +665,6 @@ static int __i915_drm_thaw(struct drm_device *dev) + intel_init_pch_refclk(dev); + + mutex_lock(&dev->struct_mutex); +- dev_priv->mm.suspended = 0; + + error = i915_gem_init_hw(dev); + mutex_unlock(&dev->struct_mutex); +@@ -961,11 +964,11 @@ int i915_reset(struct drm_device *dev) + * switched away). + */ + if (drm_core_check_feature(dev, DRIVER_MODESET) || +- !dev_priv->mm.suspended) { ++ !dev_priv->ums.mm_suspended) { + struct intel_ring_buffer *ring; + int i; + +- dev_priv->mm.suspended = 0; ++ dev_priv->ums.mm_suspended = 0; + + i915_gem_init_swizzling(dev); + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index db64bfefe8c5..eab408e66584 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -815,6 +815,18 @@ struct i915_dri1_state { + uint32_t counter; + }; + ++struct i915_ums_state { ++ /** ++ * Flag if the X Server, and thus DRM, is not currently in ++ * control of the device. ++ * ++ * This is set between LeaveVT and EnterVT. It needs to be ++ * replaced with a semaphore. It also needs to be ++ * transitioned away from for kernel modesetting. ++ */ ++ int mm_suspended; ++}; ++ + struct intel_l3_parity { + u32 *remap_info; + struct work_struct error_work; +@@ -885,16 +897,6 @@ struct i915_gem_mm { + */ + bool interruptible; + +- /** +- * Flag if the X Server, and thus DRM, is not currently in +- * control of the device. +- * +- * This is set between LeaveVT and EnterVT. It needs to be +- * replaced with a semaphore. It also needs to be +- * transitioned away from for kernel modesetting. +- */ +- int suspended; +- + /** Bit 6 swizzling required for X tiling */ + uint32_t bit_6_swizzle_x; + /** Bit 6 swizzling required for Y tiling */ +@@ -1188,6 +1190,8 @@ typedef struct drm_i915_private { + /* Old dri1 support infrastructure, beware the dragons ya fools entering + * here! */ + struct i915_dri1_state dri1; ++ /* Old ums support infrastructure, same warning applies. */ ++ struct i915_ums_state ums; + } drm_i915_private_t; + + /* Iterate over initialised rings */ +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index ee1f4add3430..5846134574f1 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2086,7 +2086,7 @@ int __i915_add_request(struct intel_ring_buffer *ring, + trace_i915_gem_request_add(ring, request->seqno); + ring->outstanding_lazy_request = 0; + +- if (!dev_priv->mm.suspended) { ++ if (!dev_priv->ums.mm_suspended) { + if (i915_enable_hangcheck) { + mod_timer(&dev_priv->gpu_error.hangcheck_timer, + round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES)); +@@ -2401,7 +2401,7 @@ i915_gem_retire_work_handler(struct work_struct *work) + idle &= list_empty(&ring->request_list); + } + +- if (!dev_priv->mm.suspended && !idle) ++ if (!dev_priv->ums.mm_suspended && !idle) + queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, + round_jiffies_up_relative(HZ)); + if (idle) +@@ -3978,9 +3978,7 @@ i915_gem_idle(struct drm_device *dev) + drm_i915_private_t *dev_priv = dev->dev_private; + int ret; + +- mutex_lock(&dev->struct_mutex); +- +- if (dev_priv->mm.suspended) { ++ if (dev_priv->ums.mm_suspended) { + mutex_unlock(&dev->struct_mutex); + return 0; + } +@@ -3996,18 +3994,11 @@ i915_gem_idle(struct drm_device *dev) + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + i915_gem_evict_everything(dev); + +- /* Hack! Don't let anybody do execbuf while we don't control the chip. +- * We need to replace this with a semaphore, or something. +- * And not confound mm.suspended! +- */ +- dev_priv->mm.suspended = 1; + del_timer_sync(&dev_priv->gpu_error.hangcheck_timer); + + i915_kernel_lost_context(dev); + i915_gem_cleanup_ringbuffer(dev); + +- mutex_unlock(&dev->struct_mutex); +- + /* Cancel the retire work handler, which should be idle now. */ + cancel_delayed_work_sync(&dev_priv->mm.retire_work); + +@@ -4217,7 +4208,7 @@ int + i915_gem_entervt_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { +- drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = dev->dev_private; + int ret; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) +@@ -4229,7 +4220,7 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, + } + + mutex_lock(&dev->struct_mutex); +- dev_priv->mm.suspended = 0; ++ dev_priv->ums.mm_suspended = 0; + + ret = i915_gem_init_hw(dev); + if (ret != 0) { +@@ -4249,7 +4240,7 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, + cleanup_ringbuffer: + mutex_lock(&dev->struct_mutex); + i915_gem_cleanup_ringbuffer(dev); +- dev_priv->mm.suspended = 1; ++ dev_priv->ums.mm_suspended = 1; + mutex_unlock(&dev->struct_mutex); + + return ret; +@@ -4259,11 +4250,26 @@ int + i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int ret; ++ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + + drm_irq_uninstall(dev); +- return i915_gem_idle(dev); ++ ++ mutex_lock(&dev->struct_mutex); ++ ret = i915_gem_idle(dev); ++ ++ /* Hack! Don't let anybody do execbuf while we don't control the chip. ++ * We need to replace this with a semaphore, or something. ++ * And not confound ums.mm_suspended! ++ */ ++ if (ret != 0) ++ dev_priv->ums.mm_suspended = 1; ++ mutex_unlock(&dev->struct_mutex); ++ ++ return ret; + } + + void +@@ -4274,9 +4280,11 @@ i915_gem_lastclose(struct drm_device *dev) + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return; + ++ mutex_lock(&dev->struct_mutex); + ret = i915_gem_idle(dev); + if (ret) + DRM_ERROR("failed to idle hardware: %d\n", ret); ++ mutex_unlock(&dev->struct_mutex); + } + + static void +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 5aeb447ead6b..64eda4463b70 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -973,7 +973,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + if (ret) + goto pre_mutex_err; + +- if (dev_priv->mm.suspended) { ++ if (dev_priv->ums.mm_suspended) { + mutex_unlock(&dev->struct_mutex); + ret = -EBUSY; + goto pre_mutex_err; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0442-drm-i915-remove-unused-members-from-drm_i915_private.patch b/patches.baytrail/0442-drm-i915-remove-unused-members-from-drm_i915_private.patch new file mode 100644 index 000000000000..db3ad96ee6ce --- /dev/null +++ b/patches.baytrail/0442-drm-i915-remove-unused-members-from-drm_i915_private.patch @@ -0,0 +1,29 @@ +From 0a81dc6e95de43d04684f735430f81dc23ac725d Mon Sep 17 00:00:00 2001 +From: Maarten Lankhorst +Date: Wed, 10 Jul 2013 14:27:31 +0200 +Subject: drm/i915: remove unused members from drm_i915_private + +Signed-off-by: Maarten Lankhorst +Signed-off-by: Daniel Vetter +(cherry picked from commit 12f56f51925dfca7caf079a6e6ccd22b63cdb39a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index eab408e66584..876ba7d7efd5 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1103,8 +1103,6 @@ typedef struct drm_i915_private { + } backlight; + + /* LVDS info */ +- struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */ +- struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */ + bool no_aux_handshake; + + struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0443-drm-i915-extract-ibx_display_interrupt_update.patch b/patches.baytrail/0443-drm-i915-extract-ibx_display_interrupt_update.patch new file mode 100644 index 000000000000..6c9e662e1476 --- /dev/null +++ b/patches.baytrail/0443-drm-i915-extract-ibx_display_interrupt_update.patch @@ -0,0 +1,130 @@ +From 872526a9fec83c9d09af066fd0ca1697326d3a27 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 4 Jul 2013 23:35:21 +0200 +Subject: drm/i915: extract ibx_display_interrupt_update + +This way all changes to SDEIMR all go through the same function, with +the exception of the (single-threaded) setup/teardown code. + +For paranoia again add an assert_spin_locked. + +v2: For even more paranoia also sprinkle a spinlock assert over +cpt_can_enable_serr_int since we need to have that one there, too. + +v3: Fix the logic of interrupt enabling, add enable/disable macros for +the simple cases in the fifo code and add a comment. All requested by +Paulo. + +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit fee884ed285a110b665c00b07b134cd2616122bc) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 51 +++++++++++++++++++++++++++++------------ + 1 file changed, 36 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index eaa8c1eda17f..079408a56c4e 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -128,6 +128,8 @@ static bool cpt_can_enable_serr_int(struct drm_device *dev) + enum pipe pipe; + struct intel_crtc *crtc; + ++ assert_spin_locked(&dev_priv->irq_lock); ++ + for_each_pipe(pipe) { + crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); + +@@ -170,6 +172,30 @@ static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, + } + } + ++/** ++ * ibx_display_interrupt_update - update SDEIMR ++ * @dev_priv: driver private ++ * @interrupt_mask: mask of interrupt bits to update ++ * @enabled_irq_mask: mask of interrupt bits to enable ++ */ ++static void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, ++ uint32_t interrupt_mask, ++ uint32_t enabled_irq_mask) ++{ ++ uint32_t sdeimr = I915_READ(SDEIMR); ++ sdeimr &= ~interrupt_mask; ++ sdeimr |= (~enabled_irq_mask & interrupt_mask); ++ ++ assert_spin_locked(&dev_priv->irq_lock); ++ ++ I915_WRITE(SDEIMR, sdeimr); ++ POSTING_READ(SDEIMR); ++} ++#define ibx_enable_display_interrupt(dev_priv, bits) \ ++ ibx_display_interrupt_update((dev_priv), (bits), (bits)) ++#define ibx_disable_display_interrupt(dev_priv, bits) \ ++ ibx_display_interrupt_update((dev_priv), (bits), 0) ++ + static void ibx_set_fifo_underrun_reporting(struct intel_crtc *crtc, + bool enable) + { +@@ -179,11 +205,9 @@ static void ibx_set_fifo_underrun_reporting(struct intel_crtc *crtc, + SDE_TRANSB_FIFO_UNDER; + + if (enable) +- I915_WRITE(SDEIMR, I915_READ(SDEIMR) & ~bit); ++ ibx_enable_display_interrupt(dev_priv, bit); + else +- I915_WRITE(SDEIMR, I915_READ(SDEIMR) | bit); +- +- POSTING_READ(SDEIMR); ++ ibx_disable_display_interrupt(dev_priv, bit); + } + + static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, +@@ -200,12 +224,10 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, + SERR_INT_TRANS_B_FIFO_UNDERRUN | + SERR_INT_TRANS_C_FIFO_UNDERRUN); + +- I915_WRITE(SDEIMR, I915_READ(SDEIMR) & ~SDE_ERROR_CPT); ++ ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT); + } else { +- I915_WRITE(SDEIMR, I915_READ(SDEIMR) | SDE_ERROR_CPT); ++ ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT); + } +- +- POSTING_READ(SDEIMR); + } + + /** +@@ -2698,22 +2720,21 @@ static void ibx_hpd_irq_setup(struct drm_device *dev) + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + struct drm_mode_config *mode_config = &dev->mode_config; + struct intel_encoder *intel_encoder; +- u32 mask = ~I915_READ(SDEIMR); +- u32 hotplug; ++ u32 hotplug_irqs, hotplug, enabled_irqs = 0; + + if (HAS_PCH_IBX(dev)) { +- mask &= ~SDE_HOTPLUG_MASK; ++ hotplug_irqs = SDE_HOTPLUG_MASK; + list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) + if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED) +- mask |= hpd_ibx[intel_encoder->hpd_pin]; ++ enabled_irqs |= hpd_ibx[intel_encoder->hpd_pin]; + } else { +- mask &= ~SDE_HOTPLUG_MASK_CPT; ++ hotplug_irqs = SDE_HOTPLUG_MASK_CPT; + list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) + if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED) +- mask |= hpd_cpt[intel_encoder->hpd_pin]; ++ enabled_irqs |= hpd_cpt[intel_encoder->hpd_pin]; + } + +- I915_WRITE(SDEIMR, ~mask); ++ ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs); + + /* + * Enable digital hotplug on the PCH, and configure the DP short pulse +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0444-drm-i915-improve-SERR_INT-clearing-for-fifo-underrun.patch b/patches.baytrail/0444-drm-i915-improve-SERR_INT-clearing-for-fifo-underrun.patch new file mode 100644 index 000000000000..eb1aa1f39001 --- /dev/null +++ b/patches.baytrail/0444-drm-i915-improve-SERR_INT-clearing-for-fifo-underrun.patch @@ -0,0 +1,103 @@ +From 1a82876919a51de9776e3d05088ec401775e6242 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 10 Jul 2013 08:30:23 +0200 +Subject: drm/i915: improve SERR_INT clearing for fifo underrun reporting + +The current code won't report any fifo underruns on cpt if just one +pipe has fifo underrun reporting disabled. We can't enable the +interrupts, but we can still check the per-transcoder bits and so +report the underrun delayed if: +- We always clear the transcoder's bit (and none of the other bits) + when enabling. +- We check the transcoder's bit after disabling (to avoid racing with + the interrupt handler). + +v2: I've forgotten to actually remove the old SERR_INT clearing. + +v3: Use transcoder_name as suggested by Paulo Zanoni. Paulo also +noticed a logic bug: When an underrun interrupt fires we report it +both in the interrupt handler and when checking for underruns when +disabling it in cpt_set_fifo_underrun_reporting. But that second check +is only required if the interrupt is disabled and we're switching of +underrun reporting (e.g. because we're disabling the crtc). Hence +check for that condition. + +At first I wanted to rework the code to pass that bit of information +from the uppper functions down to cpt_set_fifo_underrun_reporting. But +that turned out too messy. Hence the quick&dirty check whether the +south error interrupt source is masked off or not. + +v4: Streamline the control flow a bit. + +v5: s/pipe/pch transcoder/ in the dmesg output, suggested by Paulo. + +v6: Review from Paulo: +- Reorder the was_enabled assignment to only read the register when we + need it. Also add a comment that we need to do that before updating + the register. +- s/%i/%c/ fix for the debug output. +- Fix the checkpath complaint in the SERR_INT_TRANS_FIFO_UNDERRUN + #define. + +v7: Hopefully put that elusive SERR hunk back into this patch, spotted +by Paulo. + +Cc: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 1dd246fb165819d31119e988c2887934c255fadc) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 17 +++++++++++++---- + drivers/gpu/drm/i915/i915_reg.h | 1 + + 2 files changed, 14 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 079408a56c4e..d41b7a87c129 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -217,16 +217,25 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, + struct drm_i915_private *dev_priv = dev->dev_private; + + if (enable) { ++ I915_WRITE(SERR_INT, ++ SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)); ++ + if (!cpt_can_enable_serr_int(dev)) + return; + +- I915_WRITE(SERR_INT, SERR_INT_TRANS_A_FIFO_UNDERRUN | +- SERR_INT_TRANS_B_FIFO_UNDERRUN | +- SERR_INT_TRANS_C_FIFO_UNDERRUN); +- + ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT); + } else { ++ uint32_t tmp = I915_READ(SERR_INT); ++ bool was_enabled = !(I915_READ(SDEIMR) & SDE_ERROR_CPT); ++ ++ /* Change the state _after_ we've read out the current one. */ + ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT); ++ ++ if (!was_enabled && ++ (tmp & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder))) { ++ DRM_DEBUG_KMS("uncleared pch fifo underrun on pch transcoder %c\n", ++ transcoder_name(pch_transcoder)); ++ } + } + } + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 0f604881a3b4..beb5d119b7e6 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -3890,6 +3890,7 @@ + #define SERR_INT_TRANS_C_FIFO_UNDERRUN (1<<6) + #define SERR_INT_TRANS_B_FIFO_UNDERRUN (1<<3) + #define SERR_INT_TRANS_A_FIFO_UNDERRUN (1<<0) ++#define SERR_INT_TRANS_FIFO_UNDERRUN(pipe) (1<<(pipe*3)) + + /* digital port hotplug */ + #define PCH_PORT_HOTPLUG 0xc4030 /* SHOTPLUG_CTL */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0445-drm-i915-improve-GEN7_ERR_INT-clearing-for-fifo-unde.patch b/patches.baytrail/0445-drm-i915-improve-GEN7_ERR_INT-clearing-for-fifo-unde.patch new file mode 100644 index 000000000000..b2dc46b55aa9 --- /dev/null +++ b/patches.baytrail/0445-drm-i915-improve-GEN7_ERR_INT-clearing-for-fifo-unde.patch @@ -0,0 +1,94 @@ +From 14056959f1898894f882665f3361ba1014de4e9e Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 9 Jul 2013 22:59:16 +0200 +Subject: drm/i915: improve GEN7_ERR_INT clearing for fifo underrun reporting + +Same treatment as for SERR_INT: If we clear only the bit for the pipe +we're enabling (but unconditionally) then we can always check for +possible underruns after having disabled the interrupt. That way pipe +underruns won't be lost, but at worst only get reported in a delayed +fashion. + +v2: The same logic bug as in the SERR handling change also existed +here. The same bugfix of only reporting missed underruns when the +error interrupt was masked applies, too. + +v3: Do the same fixes as for the SERR handling that Paulo suggested in +his review: +- s/%i/%c/ fix in the debug output +- move the DE_ERR_INT_IVB read into the respective if block + +Cc: Paulo Zanoni +Reviewed-by: Paulo Zanoni +[danvet: Fix up the checkpatch bikeshed Paulo noticed.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 7336df6512440a494d3a705dfc6a883a42733c8f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 20 +++++++++++++------- + drivers/gpu/drm/i915/i915_reg.h | 1 + + 2 files changed, 14 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index d41b7a87c129..c21ea44ede4e 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -154,21 +154,27 @@ static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev, + } + + static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, +- bool enable) ++ enum pipe pipe, bool enable) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- + if (enable) { ++ I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); ++ + if (!ivb_can_enable_err_int(dev)) + return; + +- I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN_A | +- ERR_INT_FIFO_UNDERRUN_B | +- ERR_INT_FIFO_UNDERRUN_C); +- + ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB); + } else { ++ bool was_enabled = !(I915_READ(DEIMR) & DE_ERR_INT_IVB); ++ ++ /* Change the state _after_ we've read out the current one. */ + ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); ++ ++ if (!was_enabled && ++ (I915_READ(GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe))) { ++ DRM_DEBUG_KMS("uncleared fifo underrun on pipe %c\n", ++ pipe_name(pipe)); ++ } + } + } + +@@ -274,7 +280,7 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, + if (IS_GEN5(dev) || IS_GEN6(dev)) + ironlake_set_fifo_underrun_reporting(dev, pipe, enable); + else if (IS_GEN7(dev)) +- ivybridge_set_fifo_underrun_reporting(dev, enable); ++ ivybridge_set_fifo_underrun_reporting(dev, pipe, enable); + + done: + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index beb5d119b7e6..b131773190f3 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -681,6 +681,7 @@ + #define ERR_INT_FIFO_UNDERRUN_C (1<<6) + #define ERR_INT_FIFO_UNDERRUN_B (1<<3) + #define ERR_INT_FIFO_UNDERRUN_A (1<<0) ++#define ERR_INT_FIFO_UNDERRUN(pipe) (1<<(pipe*3)) + + #define FPGA_DBG 0x42300 + #define FPGA_DBG_RM_NOCLAIM (1<<31) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0446-drm-i915-kill-lpt-pch-transcoder-crtc-mapping-code-f.patch b/patches.baytrail/0446-drm-i915-kill-lpt-pch-transcoder-crtc-mapping-code-f.patch new file mode 100644 index 000000000000..681c466d4808 --- /dev/null +++ b/patches.baytrail/0446-drm-i915-kill-lpt-pch-transcoder-crtc-mapping-code-f.patch @@ -0,0 +1,106 @@ +From 6f409609ee19f1cb08c9a6212a6287a59f526657 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 4 Jul 2013 23:35:24 +0200 +Subject: drm/i915: kill lpt pch transcoder->crtc mapping code for fifo + underruns + +It's racy: There's no guarantee that we won't walk this code (due to a +pch fifo underrun interrupt) while someone is changing the pointers +around. + +The only reason we do this is to use the righ crtc for the pch fifo +underrun accounting. But we never expose this to userspace, so +essentially no one really cares if we use the "wrong" crtc. + +So let's just rip it out. + +With this patch fifo underrun code will always use crtc A for tracking +underruns on the (only) pch transcoder on LPT. + +v2: Add a big comment explaining what's going on. Requested by Paulo. + +v3: Fixup spelling in comment as spotted by Paulo. + +Cc: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit de28075d5bb3e1e9f92d19da214b6a96f544b66d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 40 +++++++++++++++------------------------- + 1 file changed, 15 insertions(+), 25 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index c21ea44ede4e..aeb2232a9e76 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -202,13 +202,13 @@ static void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, + #define ibx_disable_display_interrupt(dev_priv, bits) \ + ibx_display_interrupt_update((dev_priv), (bits), 0) + +-static void ibx_set_fifo_underrun_reporting(struct intel_crtc *crtc, ++static void ibx_set_fifo_underrun_reporting(struct drm_device *dev, ++ enum transcoder pch_transcoder, + bool enable) + { +- struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- uint32_t bit = (crtc->pipe == PIPE_A) ? SDE_TRANSA_FIFO_UNDER : +- SDE_TRANSB_FIFO_UNDER; ++ uint32_t bit = (pch_transcoder == TRANSCODER_A) ? ++ SDE_TRANSA_FIFO_UNDER : SDE_TRANSB_FIFO_UNDER; + + if (enable) + ibx_enable_display_interrupt(dev_priv, bit); +@@ -306,29 +306,19 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, + bool enable) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- enum pipe p; +- struct drm_crtc *crtc; +- struct intel_crtc *intel_crtc; ++ struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder]; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + unsigned long flags; + bool ret; + +- if (HAS_PCH_LPT(dev)) { +- crtc = NULL; +- for_each_pipe(p) { +- struct drm_crtc *c = dev_priv->pipe_to_crtc_mapping[p]; +- if (intel_pipe_has_type(c, INTEL_OUTPUT_ANALOG)) { +- crtc = c; +- break; +- } +- } +- if (!crtc) { +- DRM_ERROR("PCH FIFO underrun, but no CRTC using the PCH found\n"); +- return false; +- } +- } else { +- crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder]; +- } +- intel_crtc = to_intel_crtc(crtc); ++ /* ++ * NOTE: Pre-LPT has a fixed cpu pipe -> pch transcoder mapping, but LPT ++ * has only one pch transcoder A that all pipes can use. To avoid racy ++ * pch transcoder -> pipe lookups from interrupt code simply store the ++ * underrun statistics in crtc A. Since we never expose this anywhere ++ * nor use it outside of the fifo underrun code here using the "wrong" ++ * crtc on LPT won't cause issues. ++ */ + + spin_lock_irqsave(&dev_priv->irq_lock, flags); + +@@ -340,7 +330,7 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, + intel_crtc->pch_fifo_underrun_disabled = !enable; + + if (HAS_PCH_IBX(dev)) +- ibx_set_fifo_underrun_reporting(intel_crtc, enable); ++ ibx_set_fifo_underrun_reporting(dev, pch_transcoder, enable); + else + cpt_set_fifo_underrun_reporting(dev, pch_transcoder, enable); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0447-drm-i915-irq-handlers-don-t-need-interrupt-safe-spin.patch b/patches.baytrail/0447-drm-i915-irq-handlers-don-t-need-interrupt-safe-spin.patch new file mode 100644 index 000000000000..e8ff154fcf53 --- /dev/null +++ b/patches.baytrail/0447-drm-i915-irq-handlers-don-t-need-interrupt-safe-spin.patch @@ -0,0 +1,173 @@ +From bd0d40aee3ddd369389f22cc0166a7c480e073eb Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 4 Jul 2013 23:35:25 +0200 +Subject: drm/i915: irq handlers don't need interrupt-safe spinlocks + +Since we only have one interrupt handler and interrupt handlers are +non-reentrant. + +To drive the point really home give them all an _irq_handler suffix. + +This is a tiny micro-optimization but even more important it makes it +clearer what locking we actually need. And in case someone screws this +up: lockdep will catch hardirq vs. other context deadlocks. + +v2: Fix up compile fail. + +Reviewed-by: Paulo Zanoni +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit d0ecd7e221c87514b1eca84b11fee1e262f5d816) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 42 ++++++++++++++++++----------------------- + 1 file changed, 18 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index aeb2232a9e76..4eaa79f7b49d 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -656,14 +656,13 @@ static void i915_hotplug_work_func(struct work_struct *work) + drm_kms_helper_hotplug_event(dev); + } + +-static void ironlake_handle_rps_change(struct drm_device *dev) ++static void ironlake_rps_change_irq_handler(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; + u32 busy_up, busy_down, max_avg, min_avg; + u8 new_delay; +- unsigned long flags; + +- spin_lock_irqsave(&mchdev_lock, flags); ++ spin_lock(&mchdev_lock); + + I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS)); + +@@ -691,7 +690,7 @@ static void ironlake_handle_rps_change(struct drm_device *dev) + if (ironlake_set_drps(dev, new_delay)) + dev_priv->ips.cur_delay = new_delay; + +- spin_unlock_irqrestore(&mchdev_lock, flags); ++ spin_unlock(&mchdev_lock); + + return; + } +@@ -835,18 +834,17 @@ static void ivybridge_parity_work(struct work_struct *work) + kfree(parity_event[1]); + } + +-static void ivybridge_handle_parity_error(struct drm_device *dev) ++static void ivybridge_parity_error_irq_handler(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +- unsigned long flags; + + if (!HAS_L3_GPU_CACHE(dev)) + return; + +- spin_lock_irqsave(&dev_priv->irq_lock, flags); ++ spin_lock(&dev_priv->irq_lock); + dev_priv->gt_irq_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); +- spin_unlock_irqrestore(&dev_priv->irq_lock, flags); ++ spin_unlock(&dev_priv->irq_lock); + + queue_work(dev_priv->wq, &dev_priv->l3_parity.error_work); + } +@@ -872,15 +870,13 @@ static void snb_gt_irq_handler(struct drm_device *dev, + } + + if (gt_iir & GT_RENDER_L3_PARITY_ERROR_INTERRUPT) +- ivybridge_handle_parity_error(dev); ++ ivybridge_parity_error_irq_handler(dev); + } + + /* Legacy way of handling PM interrupts */ +-static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, +- u32 pm_iir) ++static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, ++ u32 pm_iir) + { +- unsigned long flags; +- + /* + * IIR bits should never already be set because IMR should + * prevent an interrupt from being shown in IIR. The warning +@@ -891,11 +887,11 @@ static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, + * The mask bit in IMR is cleared by dev_priv->rps.work. + */ + +- spin_lock_irqsave(&dev_priv->rps.lock, flags); ++ spin_lock(&dev_priv->rps.lock); + dev_priv->rps.pm_iir |= pm_iir; + I915_WRITE(GEN6_PMIMR, dev_priv->rps.pm_iir); + POSTING_READ(GEN6_PMIMR); +- spin_unlock_irqrestore(&dev_priv->rps.lock, flags); ++ spin_unlock(&dev_priv->rps.lock); + + queue_work(dev_priv->wq, &dev_priv->rps.work); + } +@@ -959,7 +955,7 @@ static void dp_aux_irq_handler(struct drm_device *dev) + wake_up_all(&dev_priv->gmbus_wait_queue); + } + +-/* Unlike gen6_queue_rps_work() from which this function is originally derived, ++/* Unlike gen6_rps_irq_handler() from which this function is originally derived, + * we must be able to deal with other PM interrupts. This is complicated because + * of the way in which we use the masks to defer the RPS work (which for + * posterity is necessary because of forcewake). +@@ -967,9 +963,7 @@ static void dp_aux_irq_handler(struct drm_device *dev) + static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv, + u32 pm_iir) + { +- unsigned long flags; +- +- spin_lock_irqsave(&dev_priv->rps.lock, flags); ++ spin_lock(&dev_priv->rps.lock); + dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS; + if (dev_priv->rps.pm_iir) { + I915_WRITE(GEN6_PMIMR, dev_priv->rps.pm_iir); +@@ -978,7 +972,7 @@ static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv, + /* TODO: if queue_work is slow, move it out of the spinlock */ + queue_work(dev_priv->wq, &dev_priv->rps.work); + } +- spin_unlock_irqrestore(&dev_priv->rps.lock, flags); ++ spin_unlock(&dev_priv->rps.lock); + + if (pm_iir & ~GEN6_PM_RPS_EVENTS) { + if (pm_iir & PM_VEBOX_USER_INTERRUPT) +@@ -1060,7 +1054,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) + gmbus_irq_handler(dev); + + if (pm_iir & GEN6_PM_RPS_EVENTS) +- gen6_queue_rps_work(dev_priv, pm_iir); ++ gen6_rps_irq_handler(dev_priv, pm_iir); + + I915_WRITE(GTIIR, gt_iir); + I915_WRITE(GEN6_PMIIR, pm_iir); +@@ -1298,7 +1292,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + if (IS_HASWELL(dev)) + hsw_pm_irq_handler(dev_priv, pm_iir); + else if (pm_iir & GEN6_PM_RPS_EVENTS) +- gen6_queue_rps_work(dev_priv, pm_iir); ++ gen6_rps_irq_handler(dev_priv, pm_iir); + I915_WRITE(GEN6_PMIIR, pm_iir); + ret = IRQ_HANDLED; + } +@@ -1415,10 +1409,10 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + } + + if (IS_GEN5(dev) && de_iir & DE_PCU_EVENT) +- ironlake_handle_rps_change(dev); ++ ironlake_rps_change_irq_handler(dev); + + if (IS_GEN6(dev) && pm_iir & GEN6_PM_RPS_EVENTS) +- gen6_queue_rps_work(dev_priv, pm_iir); ++ gen6_rps_irq_handler(dev_priv, pm_iir); + + I915_WRITE(GTIIR, gt_iir); + I915_WRITE(DEIIR, de_iir); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0448-drm-i915-streamline-hsw_pm_irq_handler.patch b/patches.baytrail/0448-drm-i915-streamline-hsw_pm_irq_handler.patch new file mode 100644 index 000000000000..7a8465dbe032 --- /dev/null +++ b/patches.baytrail/0448-drm-i915-streamline-hsw_pm_irq_handler.patch @@ -0,0 +1,61 @@ +From 7c9542eac46e653b530245dc8972590a6eae2b7d Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 4 Jul 2013 23:35:26 +0200 +Subject: drm/i915: streamline hsw_pm_irq_handler + +The if (pm_iir & ~GEN6_PM_RPS_EVENTS) check was redunandant. Otoh +adding a check for rps events allows us to avoid the spinlock grabbing +for VECS interrupts. + +v2: Drop misplaced hunk which now moved to the right patch. + +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 41a05a3a5cdc5d731014588b9a24759af1804d48) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 4eaa79f7b49d..b6a53950099d 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -963,25 +963,23 @@ static void dp_aux_irq_handler(struct drm_device *dev) + static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv, + u32 pm_iir) + { +- spin_lock(&dev_priv->rps.lock); +- dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS; +- if (dev_priv->rps.pm_iir) { ++ if (pm_iir & GEN6_PM_RPS_EVENTS) { ++ spin_lock(&dev_priv->rps.lock); ++ dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS; + I915_WRITE(GEN6_PMIMR, dev_priv->rps.pm_iir); + /* never want to mask useful interrupts. (also posting read) */ + WARN_ON(I915_READ_NOTRACE(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS); + /* TODO: if queue_work is slow, move it out of the spinlock */ + queue_work(dev_priv->wq, &dev_priv->rps.work); ++ spin_unlock(&dev_priv->rps.lock); + } +- spin_unlock(&dev_priv->rps.lock); + +- if (pm_iir & ~GEN6_PM_RPS_EVENTS) { +- if (pm_iir & PM_VEBOX_USER_INTERRUPT) +- notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); ++ if (pm_iir & PM_VEBOX_USER_INTERRUPT) ++ notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); + +- if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) { +- DRM_ERROR("VEBOX CS error interrupt 0x%08x\n", pm_iir); +- i915_handle_error(dev_priv->dev, false); +- } ++ if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) { ++ DRM_ERROR("VEBOX CS error interrupt 0x%08x\n", pm_iir); ++ i915_handle_error(dev_priv->dev, false); + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0449-drm-i915-queue-work-outside-spinlock-in-hsw_pm_irq_h.patch b/patches.baytrail/0449-drm-i915-queue-work-outside-spinlock-in-hsw_pm_irq_h.patch new file mode 100644 index 000000000000..485e05045e51 --- /dev/null +++ b/patches.baytrail/0449-drm-i915-queue-work-outside-spinlock-in-hsw_pm_irq_h.patch @@ -0,0 +1,42 @@ +From 4e8341154892efef0fa6558245694a3f8ffd619a Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 4 Jul 2013 23:35:27 +0200 +Subject: drm/i915: queue work outside spinlock in hsw_pm_irq_handler + +And kill the comment about it. Queueing work is a barrier type event, +no amount of locking will help in ordering things (as long as we queue +the work after having updated all relevant data structures). Also, the +queue_work works itself as a sufficient memory barrier. + +Again on the surface this is just a tiny micro-optimization to reduce +the hold-time of dev_priv->irq_lock. But the better reason is that it +reduces superficial locking and so makes it clearer what we actually +need for correctness. + +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 2adbee62e00d869a30cb93ea2269e5ea26a9bbc4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index b6a53950099d..b08ce0b9f0bb 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -969,9 +969,9 @@ static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv, + I915_WRITE(GEN6_PMIMR, dev_priv->rps.pm_iir); + /* never want to mask useful interrupts. (also posting read) */ + WARN_ON(I915_READ_NOTRACE(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS); +- /* TODO: if queue_work is slow, move it out of the spinlock */ +- queue_work(dev_priv->wq, &dev_priv->rps.work); + spin_unlock(&dev_priv->rps.lock); ++ ++ queue_work(dev_priv->wq, &dev_priv->rps.work); + } + + if (pm_iir & PM_VEBOX_USER_INTERRUPT) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0450-drm-i915-kill-dev_priv-rps.lock.patch b/patches.baytrail/0450-drm-i915-kill-dev_priv-rps.lock.patch new file mode 100644 index 000000000000..b2fa01f18b6e --- /dev/null +++ b/patches.baytrail/0450-drm-i915-kill-dev_priv-rps.lock.patch @@ -0,0 +1,229 @@ +From 83eddc48ea173ba5cf9f3fdd5b6488801e3a6fb1 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 4 Jul 2013 23:35:28 +0200 +Subject: drm/i915: kill dev_priv->rps.lock + +Now that the rps interrupt locking isn't clearly separated (at elast +conceptually) from all the other interrupt locking having a different +lock stopped making sense: It protects much more than just the rps +workqueue it started out with. But with the addition of VECS the +separation started to blurr and resulted in some more complex locking +for the ring interrupt refcount. + +With this we can (again) unifiy the ringbuffer irq refcounts without +causing a massive confusion, but that's for the next patch. + +v2: Explain better why the rps.lock once made sense and why no longer, +requested by Ben. + +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 59cdb63d529c81fc8ac0620ad50f29d5fb4411c9) +Signed-off-by: James Ausmus + +Conflicts: + drivers/gpu/drm/i915/i915_dma.c + (context changes) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 1 - + drivers/gpu/drm/i915/i915_drv.h | 8 ++++---- + drivers/gpu/drm/i915/i915_irq.c | 12 ++++++------ + drivers/gpu/drm/i915/intel_pm.c | 16 ++++++++-------- + drivers/gpu/drm/i915/intel_ringbuffer.c | 8 ++++---- + drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +- + 6 files changed, 23 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 240e1ef3c993..b290daba28cf 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1492,7 +1492,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + + spin_lock_init(&dev_priv->irq_lock); + spin_lock_init(&dev_priv->gpu_error.lock); +- spin_lock_init(&dev_priv->rps.lock); + spin_lock_init(&dev_priv->gt_lock); + spin_lock_init(&dev_priv->backlight.lock); + mutex_init(&dev_priv->dpio_lock); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 876ba7d7efd5..380d5799146c 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -744,12 +744,12 @@ struct i915_suspend_saved_registers { + }; + + struct intel_gen6_power_mgmt { ++ /* work and pm_iir are protected by dev_priv->irq_lock */ + struct work_struct work; +- struct delayed_work vlv_work; + u32 pm_iir; +- /* lock - irqsave spinlock that protectects the work_struct and +- * pm_iir. */ +- spinlock_t lock; ++ ++ /* On vlv we need to manually drop to Vmin with a delayed work. */ ++ struct delayed_work vlv_work; + + /* The below variables an all the rps hw state are protected by + * dev->struct mutext. */ +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index b08ce0b9f0bb..2da9e68db4f3 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -719,13 +719,13 @@ static void gen6_pm_rps_work(struct work_struct *work) + u32 pm_iir, pm_imr; + u8 new_delay; + +- spin_lock_irq(&dev_priv->rps.lock); ++ spin_lock_irq(&dev_priv->irq_lock); + pm_iir = dev_priv->rps.pm_iir; + dev_priv->rps.pm_iir = 0; + pm_imr = I915_READ(GEN6_PMIMR); + /* Make sure not to corrupt PMIMR state used by ringbuffer code */ + I915_WRITE(GEN6_PMIMR, pm_imr & ~GEN6_PM_RPS_EVENTS); +- spin_unlock_irq(&dev_priv->rps.lock); ++ spin_unlock_irq(&dev_priv->irq_lock); + + if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0) + return; +@@ -887,11 +887,11 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, + * The mask bit in IMR is cleared by dev_priv->rps.work. + */ + +- spin_lock(&dev_priv->rps.lock); ++ spin_lock(&dev_priv->irq_lock); + dev_priv->rps.pm_iir |= pm_iir; + I915_WRITE(GEN6_PMIMR, dev_priv->rps.pm_iir); + POSTING_READ(GEN6_PMIMR); +- spin_unlock(&dev_priv->rps.lock); ++ spin_unlock(&dev_priv->irq_lock); + + queue_work(dev_priv->wq, &dev_priv->rps.work); + } +@@ -964,12 +964,12 @@ static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv, + u32 pm_iir) + { + if (pm_iir & GEN6_PM_RPS_EVENTS) { +- spin_lock(&dev_priv->rps.lock); ++ spin_lock(&dev_priv->irq_lock); + dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS; + I915_WRITE(GEN6_PMIMR, dev_priv->rps.pm_iir); + /* never want to mask useful interrupts. (also posting read) */ + WARN_ON(I915_READ_NOTRACE(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS); +- spin_unlock(&dev_priv->rps.lock); ++ spin_unlock(&dev_priv->irq_lock); + + queue_work(dev_priv->wq, &dev_priv->rps.work); + } +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 613923a75abe..886da760df06 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3135,9 +3135,9 @@ static void gen6_disable_rps(struct drm_device *dev) + * register (PMIMR) to mask PM interrupts. The only risk is in leaving + * stale bits in PMIIR and PMIMR which gen6_enable_rps will clean up. */ + +- spin_lock_irq(&dev_priv->rps.lock); ++ spin_lock_irq(&dev_priv->irq_lock); + dev_priv->rps.pm_iir = 0; +- spin_unlock_irq(&dev_priv->rps.lock); ++ spin_unlock_irq(&dev_priv->irq_lock); + + I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); + } +@@ -3154,9 +3154,9 @@ static void valleyview_disable_rps(struct drm_device *dev) + * register (PMIMR) to mask PM interrupts. The only risk is in leaving + * stale bits in PMIIR and PMIMR which gen6_enable_rps will clean up. */ + +- spin_lock_irq(&dev_priv->rps.lock); ++ spin_lock_irq(&dev_priv->irq_lock); + dev_priv->rps.pm_iir = 0; +- spin_unlock_irq(&dev_priv->rps.lock); ++ spin_unlock_irq(&dev_priv->irq_lock); + + I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); + +@@ -3321,13 +3321,13 @@ static void gen6_enable_rps(struct drm_device *dev) + + /* requires MSI enabled */ + I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) | GEN6_PM_RPS_EVENTS); +- spin_lock_irq(&dev_priv->rps.lock); ++ spin_lock_irq(&dev_priv->irq_lock); + /* FIXME: Our interrupt enabling sequence is bonghits. + * dev_priv->rps.pm_iir really should be 0 here. */ + dev_priv->rps.pm_iir = 0; + I915_WRITE(GEN6_PMIMR, I915_READ(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS); + I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); +- spin_unlock_irq(&dev_priv->rps.lock); ++ spin_unlock_irq(&dev_priv->irq_lock); + /* unmask all PM interrupts */ + I915_WRITE(GEN6_PMINTRMSK, 0); + +@@ -3601,10 +3601,10 @@ static void valleyview_enable_rps(struct drm_device *dev) + + /* requires MSI enabled */ + I915_WRITE(GEN6_PMIER, GEN6_PM_RPS_EVENTS); +- spin_lock_irq(&dev_priv->rps.lock); ++ spin_lock_irq(&dev_priv->irq_lock); + WARN_ON(dev_priv->rps.pm_iir != 0); + I915_WRITE(GEN6_PMIMR, 0); +- spin_unlock_irq(&dev_priv->rps.lock); ++ spin_unlock_irq(&dev_priv->irq_lock); + /* enable all PM interrupts */ + I915_WRITE(GEN6_PMINTRMSK, 0); + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index ea6aef5e6fea..ad439afdcc6d 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -1082,14 +1082,14 @@ hsw_vebox_get_irq(struct intel_ring_buffer *ring) + if (!dev->irq_enabled) + return false; + +- spin_lock_irqsave(&dev_priv->rps.lock, flags); ++ spin_lock_irqsave(&dev_priv->irq_lock, flags); + if (ring->irq_refcount.pm++ == 0) { + u32 pm_imr = I915_READ(GEN6_PMIMR); + I915_WRITE_IMR(ring, ~ring->irq_enable_mask); + I915_WRITE(GEN6_PMIMR, pm_imr & ~ring->irq_enable_mask); + POSTING_READ(GEN6_PMIMR); + } +- spin_unlock_irqrestore(&dev_priv->rps.lock, flags); ++ spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + + return true; + } +@@ -1104,14 +1104,14 @@ hsw_vebox_put_irq(struct intel_ring_buffer *ring) + if (!dev->irq_enabled) + return; + +- spin_lock_irqsave(&dev_priv->rps.lock, flags); ++ spin_lock_irqsave(&dev_priv->irq_lock, flags); + if (--ring->irq_refcount.pm == 0) { + u32 pm_imr = I915_READ(GEN6_PMIMR); + I915_WRITE_IMR(ring, ~0); + I915_WRITE(GEN6_PMIMR, pm_imr | ring->irq_enable_mask); + POSTING_READ(GEN6_PMIMR); + } +- spin_unlock_irqrestore(&dev_priv->rps.lock, flags); ++ spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + } + + static int +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index 799f04c9da45..8a87b3f9974c 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -80,7 +80,7 @@ struct intel_ring_buffer { + + struct { + u32 gt; /* protected by dev_priv->irq_lock */ +- u32 pm; /* protected by dev_priv->rps.lock (sucks) */ ++ u32 pm; /* protected by dev_priv->irq_lock */ + } irq_refcount; + u32 irq_enable_mask; /* bitmask to enable ring interrupt */ + u32 trace_irq_seqno; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0451-drm-i915-unify-ring-irq-refcounts-again.patch b/patches.baytrail/0451-drm-i915-unify-ring-irq-refcounts-again.patch new file mode 100644 index 000000000000..b4ba30c539c6 --- /dev/null +++ b/patches.baytrail/0451-drm-i915-unify-ring-irq-refcounts-again.patch @@ -0,0 +1,133 @@ +From dc81fb3d61796b23bd7b6296a2fe10b6d8821fbe Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 4 Jul 2013 23:35:29 +0200 +Subject: drm/i915: unify ring irq refcounts (again) + +With the simplified locking there's no reason any more to keep the +refcounts seperate. + +v2: Readd the lost comment that ring->irq_refcount is protected by +dev_priv->irq_lock. + +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit c7113cc35f59b46b301367b947c4f71ac8f0d5bb) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ringbuffer.c | 20 ++++++++++---------- + drivers/gpu/drm/i915/intel_ringbuffer.h | 5 +---- + 2 files changed, 11 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index ad439afdcc6d..e97a7a0455c2 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -836,7 +836,7 @@ gen5_ring_get_irq(struct intel_ring_buffer *ring) + return false; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (ring->irq_refcount.gt++ == 0) { ++ if (ring->irq_refcount++ == 0) { + dev_priv->gt_irq_mask &= ~ring->irq_enable_mask; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + POSTING_READ(GTIMR); +@@ -854,7 +854,7 @@ gen5_ring_put_irq(struct intel_ring_buffer *ring) + unsigned long flags; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (--ring->irq_refcount.gt == 0) { ++ if (--ring->irq_refcount == 0) { + dev_priv->gt_irq_mask |= ring->irq_enable_mask; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); + POSTING_READ(GTIMR); +@@ -873,7 +873,7 @@ i9xx_ring_get_irq(struct intel_ring_buffer *ring) + return false; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (ring->irq_refcount.gt++ == 0) { ++ if (ring->irq_refcount++ == 0) { + dev_priv->irq_mask &= ~ring->irq_enable_mask; + I915_WRITE(IMR, dev_priv->irq_mask); + POSTING_READ(IMR); +@@ -891,7 +891,7 @@ i9xx_ring_put_irq(struct intel_ring_buffer *ring) + unsigned long flags; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (--ring->irq_refcount.gt == 0) { ++ if (--ring->irq_refcount == 0) { + dev_priv->irq_mask |= ring->irq_enable_mask; + I915_WRITE(IMR, dev_priv->irq_mask); + POSTING_READ(IMR); +@@ -910,7 +910,7 @@ i8xx_ring_get_irq(struct intel_ring_buffer *ring) + return false; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (ring->irq_refcount.gt++ == 0) { ++ if (ring->irq_refcount++ == 0) { + dev_priv->irq_mask &= ~ring->irq_enable_mask; + I915_WRITE16(IMR, dev_priv->irq_mask); + POSTING_READ16(IMR); +@@ -928,7 +928,7 @@ i8xx_ring_put_irq(struct intel_ring_buffer *ring) + unsigned long flags; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (--ring->irq_refcount.gt == 0) { ++ if (--ring->irq_refcount == 0) { + dev_priv->irq_mask |= ring->irq_enable_mask; + I915_WRITE16(IMR, dev_priv->irq_mask); + POSTING_READ16(IMR); +@@ -1033,7 +1033,7 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring) + gen6_gt_force_wake_get(dev_priv); + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (ring->irq_refcount.gt++ == 0) { ++ if (ring->irq_refcount++ == 0) { + if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS) + I915_WRITE_IMR(ring, + ~(ring->irq_enable_mask | +@@ -1057,7 +1057,7 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring) + unsigned long flags; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (--ring->irq_refcount.gt == 0) { ++ if (--ring->irq_refcount == 0) { + if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS) + I915_WRITE_IMR(ring, + ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT); +@@ -1083,7 +1083,7 @@ hsw_vebox_get_irq(struct intel_ring_buffer *ring) + return false; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (ring->irq_refcount.pm++ == 0) { ++ if (ring->irq_refcount++ == 0) { + u32 pm_imr = I915_READ(GEN6_PMIMR); + I915_WRITE_IMR(ring, ~ring->irq_enable_mask); + I915_WRITE(GEN6_PMIMR, pm_imr & ~ring->irq_enable_mask); +@@ -1105,7 +1105,7 @@ hsw_vebox_put_irq(struct intel_ring_buffer *ring) + return; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (--ring->irq_refcount.pm == 0) { ++ if (--ring->irq_refcount == 0) { + u32 pm_imr = I915_READ(GEN6_PMIMR); + I915_WRITE_IMR(ring, ~0); + I915_WRITE(GEN6_PMIMR, pm_imr | ring->irq_enable_mask); +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index 8a87b3f9974c..6e38256d41e1 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -78,10 +78,7 @@ struct intel_ring_buffer { + */ + u32 last_retired_head; + +- struct { +- u32 gt; /* protected by dev_priv->irq_lock */ +- u32 pm; /* protected by dev_priv->irq_lock */ +- } irq_refcount; ++ unsigned irq_refcount; /* protected by dev_priv->irq_lock */ + u32 irq_enable_mask; /* bitmask to enable ring interrupt */ + u32 trace_irq_seqno; + u32 sync_seqno[I915_NUM_RINGS-1]; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0452-drm-i915-don-t-enable-PM_VEBOX_CS_ERROR_INTERRUPT.patch b/patches.baytrail/0452-drm-i915-don-t-enable-PM_VEBOX_CS_ERROR_INTERRUPT.patch new file mode 100644 index 000000000000..dffb21cacb39 --- /dev/null +++ b/patches.baytrail/0452-drm-i915-don-t-enable-PM_VEBOX_CS_ERROR_INTERRUPT.patch @@ -0,0 +1,62 @@ +From 0c4b34c049b3ff05e65bd2f75ddafb84365d8b8f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 4 Jul 2013 23:35:30 +0200 +Subject: drm/i915: don't enable PM_VEBOX_CS_ERROR_INTERRUPT + +The code to handle it is broken - there's simply no code to clear CS +parser errors on gen5+. And behold, for all the other rings we also +don't enable it! + +Leave the handling code itself in place just to be consistent with the +existing mess though. And in case someone feels like fixing it all up. + +This has been errornously enabled in + +commit 12638c57f31952127c734c26315e1348fa1334c2 +Author: Ben Widawsky +Date: Tue May 28 19:22:31 2013 -0700 + + drm/i915: Enable vebox interrupts + +Cc: Damien Lespiau +Cc: Ben Widawsky +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit c0d6a3dd61d46a640ead0a9d38b78ca22d37a304) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 3 +-- + drivers/gpu/drm/i915/intel_ringbuffer.c | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 2da9e68db4f3..f77e87365480 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2860,8 +2860,7 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) + + I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); + if (HAS_VEBOX(dev)) +- pm_irqs |= PM_VEBOX_USER_INTERRUPT | +- PM_VEBOX_CS_ERROR_INTERRUPT; ++ pm_irqs |= PM_VEBOX_USER_INTERRUPT; + + /* Our enable/disable rps functions may touch these registers so + * make sure to set a known state for only the non-RPS bits. +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index e97a7a0455c2..bc78c794ae81 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -2020,8 +2020,7 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) + ring->add_request = gen6_add_request; + ring->get_seqno = gen6_ring_get_seqno; + ring->set_seqno = ring_set_seqno; +- ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT | +- PM_VEBOX_CS_ERROR_INTERRUPT; ++ ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT; + ring->irq_get = hsw_vebox_get_irq; + ring->irq_put = hsw_vebox_put_irq; + ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0453-drm-i915-Use-for_each_pipe-when-possible.patch b/patches.baytrail/0453-drm-i915-Use-for_each_pipe-when-possible.patch new file mode 100644 index 000000000000..e76e3c868411 --- /dev/null +++ b/patches.baytrail/0453-drm-i915-Use-for_each_pipe-when-possible.patch @@ -0,0 +1,41 @@ +From 7b59d9e8ca7135f620eaf6d829bcc0c2a97bba4a Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Thu, 11 Jul 2013 20:10:54 +0100 +Subject: drm/i915: Use for_each_pipe() when possible + +Came accross two open coding of for_each_pipe(), might as well use the +macro. + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 08e2a7de8ec86054a1272e4fc9d15fa6c18d3b16) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 7ab60c74dff4..861dcc5d4ebf 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1131,7 +1131,7 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv, + } + + /* Need to check both planes against the pipe */ +- for (i = 0; i < INTEL_INFO(dev)->num_pipes; i++) { ++ for_each_pipe(i) { + reg = DSPCNTR(i); + val = I915_READ(reg); + cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >> +@@ -9739,7 +9739,7 @@ void intel_modeset_init(struct drm_device *dev) + INTEL_INFO(dev)->num_pipes, + INTEL_INFO(dev)->num_pipes > 1 ? "s" : ""); + +- for (i = 0; i < INTEL_INFO(dev)->num_pipes; i++) { ++ for_each_pipe(i) { + intel_crtc_init(dev, i); + for (j = 0; j < dev_priv->num_plane; j++) { + ret = intel_plane_init(dev, i, j); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0454-drm-i915-Don-t-attempt-to-read-an-unitialized-stack-.patch b/patches.baytrail/0454-drm-i915-Don-t-attempt-to-read-an-unitialized-stack-.patch new file mode 100644 index 000000000000..bae79b49eb4f --- /dev/null +++ b/patches.baytrail/0454-drm-i915-Don-t-attempt-to-read-an-unitialized-stack-.patch @@ -0,0 +1,61 @@ +From 5463eed827d33a796298cd360ea5663c1aecaba5 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Fri, 12 Jul 2013 16:24:40 +0100 +Subject: drm/i915: Don't attempt to read an unitialized stack value + +If intel_sdvo_get_value() fails here, val is unitialized and the cross +check will compare the pipe config multiplier with a bogus value. + +Instead, only set encoder_pixel_multiplier when the sdvo command has +been successful. The cross check will compare the pipe config value with +0 otherwise. + +v2: Do the cross check with the initial value of encoder_pixel_multiplier (0) +if the sdvo command fails (and thus keep the warning) (Daniel Vetter) + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 53b914084950e5766b40228c4e08706e28745fa5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sdvo.c | 24 +++++++++++++----------- + 1 file changed, 13 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 8415d6a610dd..798df114cfd3 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1357,17 +1357,19 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, + } + + /* Cross check the port pixel multiplier with the sdvo encoder state. */ +- intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT, &val, 1); +- switch (val) { +- case SDVO_CLOCK_RATE_MULT_1X: +- encoder_pixel_multiplier = 1; +- break; +- case SDVO_CLOCK_RATE_MULT_2X: +- encoder_pixel_multiplier = 2; +- break; +- case SDVO_CLOCK_RATE_MULT_4X: +- encoder_pixel_multiplier = 4; +- break; ++ if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT, ++ &val, 1)) { ++ switch (val) { ++ case SDVO_CLOCK_RATE_MULT_1X: ++ encoder_pixel_multiplier = 1; ++ break; ++ case SDVO_CLOCK_RATE_MULT_2X: ++ encoder_pixel_multiplier = 2; ++ break; ++ case SDVO_CLOCK_RATE_MULT_4X: ++ encoder_pixel_multiplier = 4; ++ break; ++ } + } + + WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0455-drm-i915-move-error-state-to-own-compilation-unit.patch b/patches.baytrail/0455-drm-i915-move-error-state-to-own-compilation-unit.patch new file mode 100644 index 000000000000..33838e795ace --- /dev/null +++ b/patches.baytrail/0455-drm-i915-move-error-state-to-own-compilation-unit.patch @@ -0,0 +1,2138 @@ +From 9a93870372ecf1f32901e1a1cae23f64cdf412fd Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Fri, 12 Jul 2013 16:50:57 +0300 +Subject: drm/i915: move error state to own compilation unit + +Move error state generation and stringification to it's +own compilation unit. Sysfs also uses this so it can't be +under CONFIG_DEBUG_FS + +This fixes a regression introduced in + +commit ef86ddced720fddc3835558447a7f594d3609c73 +Author: Mika Kuoppala +Date: Thu Jun 6 17:38:54 2013 +0300 + + drm/i915: add error_state sysfs entry + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66814 +Signed-off-by: Mika Kuoppala +Reported-by: kbuild test robot +Signed-off-by: Daniel Vetter +(cherry picked from commit 84734a049d0ef2f6f5fb0a1fe060cd51480dd855) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/Makefile | 1 + + drivers/gpu/drm/i915/i915_debugfs.c | 415 +-------------- + drivers/gpu/drm/i915/i915_drv.h | 24 +- + drivers/gpu/drm/i915/i915_gpu_error.c | 971 ++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/i915/i915_irq.c | 529 ------------------ + drivers/gpu/drm/i915/intel_display.c | 4 - + drivers/gpu/drm/i915/intel_overlay.c | 4 - + 7 files changed, 983 insertions(+), 965 deletions(-) + create mode 100644 drivers/gpu/drm/i915/i915_gpu_error.c + +diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile +index 40034ecefd3b..9d1da7cceb21 100644 +--- a/drivers/gpu/drm/i915/Makefile ++++ b/drivers/gpu/drm/i915/Makefile +@@ -5,6 +5,7 @@ + ccflags-y := -Iinclude/drm + i915-y := i915_drv.o i915_dma.o i915_irq.o \ + i915_debugfs.o \ ++ i915_gpu_error.o \ + i915_suspend.o \ + i915_gem.o \ + i915_gem_context.o \ +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index d4138124d993..86379799dab8 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -30,7 +30,6 @@ + #include + #include + #include +-#include + #include + #include "intel_drv.h" + #include "intel_ringbuffer.h" +@@ -90,16 +89,6 @@ static const char *get_tiling_flag(struct drm_i915_gem_object *obj) + } + } + +-static const char *cache_level_str(int type) +-{ +- switch (type) { +- case I915_CACHE_NONE: return " uncached"; +- case I915_CACHE_LLC: return " snooped (LLC)"; +- case I915_CACHE_LLC_MLC: return " snooped (LLC+MLC)"; +- default: return ""; +- } +-} +- + static void + describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) + { +@@ -113,7 +102,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) + obj->last_read_seqno, + obj->last_write_seqno, + obj->last_fenced_seqno, +- cache_level_str(obj->cache_level), ++ i915_cache_level_str(obj->cache_level), + obj->dirty ? " dirty" : "", + obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); + if (obj->base.name) +@@ -608,358 +597,6 @@ static int i915_hws_info(struct seq_file *m, void *data) + return 0; + } + +-static const char *ring_str(int ring) +-{ +- switch (ring) { +- case RCS: return "render"; +- case VCS: return "bsd"; +- case BCS: return "blt"; +- case VECS: return "vebox"; +- default: return ""; +- } +-} +- +-static const char *pin_flag(int pinned) +-{ +- if (pinned > 0) +- return " P"; +- else if (pinned < 0) +- return " p"; +- else +- return ""; +-} +- +-static const char *tiling_flag(int tiling) +-{ +- switch (tiling) { +- default: +- case I915_TILING_NONE: return ""; +- case I915_TILING_X: return " X"; +- case I915_TILING_Y: return " Y"; +- } +-} +- +-static const char *dirty_flag(int dirty) +-{ +- return dirty ? " dirty" : ""; +-} +- +-static const char *purgeable_flag(int purgeable) +-{ +- return purgeable ? " purgeable" : ""; +-} +- +-static bool __i915_error_ok(struct drm_i915_error_state_buf *e) +-{ +- +- if (!e->err && WARN(e->bytes > (e->size - 1), "overflow")) { +- e->err = -ENOSPC; +- return false; +- } +- +- if (e->bytes == e->size - 1 || e->err) +- return false; +- +- return true; +-} +- +-static bool __i915_error_seek(struct drm_i915_error_state_buf *e, +- unsigned len) +-{ +- if (e->pos + len <= e->start) { +- e->pos += len; +- return false; +- } +- +- /* First vsnprintf needs to fit in its entirety for memmove */ +- if (len >= e->size) { +- e->err = -EIO; +- return false; +- } +- +- return true; +-} +- +-static void __i915_error_advance(struct drm_i915_error_state_buf *e, +- unsigned len) +-{ +- /* If this is first printf in this window, adjust it so that +- * start position matches start of the buffer +- */ +- +- if (e->pos < e->start) { +- const size_t off = e->start - e->pos; +- +- /* Should not happen but be paranoid */ +- if (off > len || e->bytes) { +- e->err = -EIO; +- return; +- } +- +- memmove(e->buf, e->buf + off, len - off); +- e->bytes = len - off; +- e->pos = e->start; +- return; +- } +- +- e->bytes += len; +- e->pos += len; +-} +- +-static void i915_error_vprintf(struct drm_i915_error_state_buf *e, +- const char *f, va_list args) +-{ +- unsigned len; +- +- if (!__i915_error_ok(e)) +- return; +- +- /* Seek the first printf which is hits start position */ +- if (e->pos < e->start) { +- len = vsnprintf(NULL, 0, f, args); +- if (!__i915_error_seek(e, len)) +- return; +- } +- +- len = vsnprintf(e->buf + e->bytes, e->size - e->bytes, f, args); +- if (len >= e->size - e->bytes) +- len = e->size - e->bytes - 1; +- +- __i915_error_advance(e, len); +-} +- +-static void i915_error_puts(struct drm_i915_error_state_buf *e, +- const char *str) +-{ +- unsigned len; +- +- if (!__i915_error_ok(e)) +- return; +- +- len = strlen(str); +- +- /* Seek the first printf which is hits start position */ +- if (e->pos < e->start) { +- if (!__i915_error_seek(e, len)) +- return; +- } +- +- if (len >= e->size - e->bytes) +- len = e->size - e->bytes - 1; +- memcpy(e->buf + e->bytes, str, len); +- +- __i915_error_advance(e, len); +-} +- +-void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...) +-{ +- va_list args; +- +- va_start(args, f); +- i915_error_vprintf(e, f, args); +- va_end(args); +-} +- +-#define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__) +-#define err_puts(e, s) i915_error_puts(e, s) +- +-static void print_error_buffers(struct drm_i915_error_state_buf *m, +- const char *name, +- struct drm_i915_error_buffer *err, +- int count) +-{ +- err_printf(m, "%s [%d]:\n", name, count); +- +- while (count--) { +- err_printf(m, " %08x %8u %02x %02x %x %x", +- err->gtt_offset, +- err->size, +- err->read_domains, +- err->write_domain, +- err->rseqno, err->wseqno); +- err_puts(m, pin_flag(err->pinned)); +- err_puts(m, tiling_flag(err->tiling)); +- err_puts(m, dirty_flag(err->dirty)); +- err_puts(m, purgeable_flag(err->purgeable)); +- err_puts(m, err->ring != -1 ? " " : ""); +- err_puts(m, ring_str(err->ring)); +- err_puts(m, cache_level_str(err->cache_level)); +- +- if (err->name) +- err_printf(m, " (name: %d)", err->name); +- if (err->fence_reg != I915_FENCE_REG_NONE) +- err_printf(m, " (fence: %d)", err->fence_reg); +- +- err_puts(m, "\n"); +- err++; +- } +-} +- +-static void i915_ring_error_state(struct drm_i915_error_state_buf *m, +- struct drm_device *dev, +- struct drm_i915_error_state *error, +- unsigned ring) +-{ +- BUG_ON(ring >= I915_NUM_RINGS); /* shut up confused gcc */ +- err_printf(m, "%s command stream:\n", ring_str(ring)); +- err_printf(m, " HEAD: 0x%08x\n", error->head[ring]); +- err_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); +- err_printf(m, " CTL: 0x%08x\n", error->ctl[ring]); +- err_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); +- err_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); +- err_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); +- err_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); +- if (ring == RCS && INTEL_INFO(dev)->gen >= 4) +- err_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr); +- +- if (INTEL_INFO(dev)->gen >= 4) +- err_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); +- err_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); +- err_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); +- if (INTEL_INFO(dev)->gen >= 6) { +- err_printf(m, " RC PSMI: 0x%08x\n", error->rc_psmi[ring]); +- err_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); +- err_printf(m, " SYNC_0: 0x%08x [last synced 0x%08x]\n", +- error->semaphore_mboxes[ring][0], +- error->semaphore_seqno[ring][0]); +- err_printf(m, " SYNC_1: 0x%08x [last synced 0x%08x]\n", +- error->semaphore_mboxes[ring][1], +- error->semaphore_seqno[ring][1]); +- } +- err_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); +- err_printf(m, " waiting: %s\n", yesno(error->waiting[ring])); +- err_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]); +- err_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); +-} +- +-int i915_error_state_to_str(struct drm_i915_error_state_buf *m, +- const struct i915_error_state_file_priv *error_priv) +-{ +- struct drm_device *dev = error_priv->dev; +- drm_i915_private_t *dev_priv = dev->dev_private; +- struct drm_i915_error_state *error = error_priv->error; +- struct intel_ring_buffer *ring; +- int i, j, page, offset, elt; +- +- if (!error) { +- err_printf(m, "no error state collected\n"); +- goto out; +- } +- +- err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, +- error->time.tv_usec); +- err_printf(m, "Kernel: " UTS_RELEASE "\n"); +- err_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); +- err_printf(m, "EIR: 0x%08x\n", error->eir); +- err_printf(m, "IER: 0x%08x\n", error->ier); +- err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); +- err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake); +- err_printf(m, "DERRMR: 0x%08x\n", error->derrmr); +- err_printf(m, "CCID: 0x%08x\n", error->ccid); +- +- for (i = 0; i < dev_priv->num_fence_regs; i++) +- err_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); +- +- for (i = 0; i < ARRAY_SIZE(error->extra_instdone); i++) +- err_printf(m, " INSTDONE_%d: 0x%08x\n", i, +- error->extra_instdone[i]); +- +- if (INTEL_INFO(dev)->gen >= 6) { +- err_printf(m, "ERROR: 0x%08x\n", error->error); +- err_printf(m, "DONE_REG: 0x%08x\n", error->done_reg); +- } +- +- if (INTEL_INFO(dev)->gen == 7) +- err_printf(m, "ERR_INT: 0x%08x\n", error->err_int); +- +- for_each_ring(ring, dev_priv, i) +- i915_ring_error_state(m, dev, error, i); +- +- if (error->active_bo) +- print_error_buffers(m, "Active", +- error->active_bo, +- error->active_bo_count); +- +- if (error->pinned_bo) +- print_error_buffers(m, "Pinned", +- error->pinned_bo, +- error->pinned_bo_count); +- +- for (i = 0; i < ARRAY_SIZE(error->ring); i++) { +- struct drm_i915_error_object *obj; +- +- if ((obj = error->ring[i].batchbuffer)) { +- err_printf(m, "%s --- gtt_offset = 0x%08x\n", +- dev_priv->ring[i].name, +- obj->gtt_offset); +- offset = 0; +- for (page = 0; page < obj->page_count; page++) { +- for (elt = 0; elt < PAGE_SIZE/4; elt++) { +- err_printf(m, "%08x : %08x\n", offset, +- obj->pages[page][elt]); +- offset += 4; +- } +- } +- } +- +- if (error->ring[i].num_requests) { +- err_printf(m, "%s --- %d requests\n", +- dev_priv->ring[i].name, +- error->ring[i].num_requests); +- for (j = 0; j < error->ring[i].num_requests; j++) { +- err_printf(m, " seqno 0x%08x, emitted %ld, tail 0x%08x\n", +- error->ring[i].requests[j].seqno, +- error->ring[i].requests[j].jiffies, +- error->ring[i].requests[j].tail); +- } +- } +- +- if ((obj = error->ring[i].ringbuffer)) { +- err_printf(m, "%s --- ringbuffer = 0x%08x\n", +- dev_priv->ring[i].name, +- obj->gtt_offset); +- offset = 0; +- for (page = 0; page < obj->page_count; page++) { +- for (elt = 0; elt < PAGE_SIZE/4; elt++) { +- err_printf(m, "%08x : %08x\n", +- offset, +- obj->pages[page][elt]); +- offset += 4; +- } +- } +- } +- +- obj = error->ring[i].ctx; +- if (obj) { +- err_printf(m, "%s --- HW Context = 0x%08x\n", +- dev_priv->ring[i].name, +- obj->gtt_offset); +- offset = 0; +- for (elt = 0; elt < PAGE_SIZE/16; elt += 4) { +- err_printf(m, "[%04x] %08x %08x %08x %08x\n", +- offset, +- obj->pages[0][elt], +- obj->pages[0][elt+1], +- obj->pages[0][elt+2], +- obj->pages[0][elt+3]); +- offset += 16; +- } +- } +- } +- +- if (error->overlay) +- intel_overlay_print_error_state(m, error->overlay); +- +- if (error->display) +- intel_display_print_error_state(m, dev, error->display); +- +-out: +- if (m->bytes == 0 && m->err) +- return m->err; +- +- return 0; +-} +- + static ssize_t + i915_error_state_write(struct file *filp, + const char __user *ubuf, +@@ -982,26 +619,6 @@ i915_error_state_write(struct file *filp, + return cnt; + } + +-void i915_error_state_get(struct drm_device *dev, +- struct i915_error_state_file_priv *error_priv) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- unsigned long flags; +- +- spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); +- error_priv->error = dev_priv->gpu_error.first_error; +- if (error_priv->error) +- kref_get(&error_priv->error->ref); +- spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); +- +-} +- +-void i915_error_state_put(struct i915_error_state_file_priv *error_priv) +-{ +- if (error_priv->error) +- kref_put(&error_priv->error->ref, i915_error_state_free); +-} +- + static int i915_error_state_open(struct inode *inode, struct file *file) + { + struct drm_device *dev = inode->i_private; +@@ -1030,36 +647,6 @@ static int i915_error_state_release(struct inode *inode, struct file *file) + return 0; + } + +-int i915_error_state_buf_init(struct drm_i915_error_state_buf *ebuf, +- size_t count, loff_t pos) +-{ +- memset(ebuf, 0, sizeof(*ebuf)); +- +- /* We need to have enough room to store any i915_error_state printf +- * so that we can move it to start position. +- */ +- ebuf->size = count + 1 > PAGE_SIZE ? count + 1 : PAGE_SIZE; +- ebuf->buf = kmalloc(ebuf->size, +- GFP_TEMPORARY | __GFP_NORETRY | __GFP_NOWARN); +- +- if (ebuf->buf == NULL) { +- ebuf->size = PAGE_SIZE; +- ebuf->buf = kmalloc(ebuf->size, GFP_TEMPORARY); +- } +- +- if (ebuf->buf == NULL) { +- ebuf->size = 128; +- ebuf->buf = kmalloc(ebuf->size, GFP_TEMPORARY); +- } +- +- if (ebuf->buf == NULL) +- return -ENOMEM; +- +- ebuf->start = pos; +- +- return 0; +-} +- + static ssize_t i915_error_state_read(struct file *file, char __user *userbuf, + size_t count, loff_t *pos) + { +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 380d5799146c..a7fbefaa1c4a 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1629,21 +1629,12 @@ extern void intel_hpd_init(struct drm_device *dev); + extern void intel_gt_init(struct drm_device *dev); + extern void intel_gt_sanitize(struct drm_device *dev); + +-void i915_error_state_free(struct kref *error_ref); +- + void + i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); + + void + i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); + +-#ifdef CONFIG_DEBUG_FS +-extern void i915_destroy_error_state(struct drm_device *dev); +-#else +-#define i915_destroy_error_state(x) +-#endif +- +- + /* i915_gem.c */ + int i915_gem_init_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +@@ -1954,13 +1945,12 @@ void i915_gem_dump_object(struct drm_i915_gem_object *obj, int len, + /* i915_debugfs.c */ + int i915_debugfs_init(struct drm_minor *minor); + void i915_debugfs_cleanup(struct drm_minor *minor); ++ ++/* i915_gpu_error.c */ + __printf(2, 3) + void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...); + int i915_error_state_to_str(struct drm_i915_error_state_buf *estr, + const struct i915_error_state_file_priv *error); +-void i915_error_state_get(struct drm_device *dev, +- struct i915_error_state_file_priv *error_priv); +-void i915_error_state_put(struct i915_error_state_file_priv *error_priv); + int i915_error_state_buf_init(struct drm_i915_error_state_buf *eb, + size_t count, loff_t pos); + static inline void i915_error_state_buf_release( +@@ -1968,6 +1958,14 @@ static inline void i915_error_state_buf_release( + { + kfree(eb->buf); + } ++void i915_capture_error_state(struct drm_device *dev); ++void i915_error_state_get(struct drm_device *dev, ++ struct i915_error_state_file_priv *error_priv); ++void i915_error_state_put(struct i915_error_state_file_priv *error_priv); ++void i915_destroy_error_state(struct drm_device *dev); ++ ++void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone); ++const char *i915_cache_level_str(int type); + + /* i915_suspend.c */ + extern int i915_save_state(struct drm_device *dev); +@@ -2047,7 +2045,6 @@ int i915_reg_read_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); + + /* overlay */ +-#ifdef CONFIG_DEBUG_FS + extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); + extern void intel_overlay_print_error_state(struct drm_i915_error_state_buf *e, + struct intel_overlay_error_state *error); +@@ -2056,7 +2053,6 @@ extern struct intel_display_error_state *intel_display_capture_error_state(struc + extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e, + struct drm_device *dev, + struct intel_display_error_state *error); +-#endif + + /* On SNB platform, before reading ring registers forcewake bit + * must be set to prevent GT core from power down and stale values being +diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c +new file mode 100644 +index 000000000000..58386cebb865 +--- /dev/null ++++ b/drivers/gpu/drm/i915/i915_gpu_error.c +@@ -0,0 +1,971 @@ ++/* ++ * Copyright (c) 2008 Intel Corporation ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ * ++ * Authors: ++ * Eric Anholt ++ * Keith Packard ++ * Mika Kuoppala ++ * ++ */ ++ ++#include ++#include "i915_drv.h" ++ ++static const char *yesno(int v) ++{ ++ return v ? "yes" : "no"; ++} ++ ++static const char *ring_str(int ring) ++{ ++ switch (ring) { ++ case RCS: return "render"; ++ case VCS: return "bsd"; ++ case BCS: return "blt"; ++ case VECS: return "vebox"; ++ default: return ""; ++ } ++} ++ ++static const char *pin_flag(int pinned) ++{ ++ if (pinned > 0) ++ return " P"; ++ else if (pinned < 0) ++ return " p"; ++ else ++ return ""; ++} ++ ++static const char *tiling_flag(int tiling) ++{ ++ switch (tiling) { ++ default: ++ case I915_TILING_NONE: return ""; ++ case I915_TILING_X: return " X"; ++ case I915_TILING_Y: return " Y"; ++ } ++} ++ ++static const char *dirty_flag(int dirty) ++{ ++ return dirty ? " dirty" : ""; ++} ++ ++static const char *purgeable_flag(int purgeable) ++{ ++ return purgeable ? " purgeable" : ""; ++} ++ ++static bool __i915_error_ok(struct drm_i915_error_state_buf *e) ++{ ++ ++ if (!e->err && WARN(e->bytes > (e->size - 1), "overflow")) { ++ e->err = -ENOSPC; ++ return false; ++ } ++ ++ if (e->bytes == e->size - 1 || e->err) ++ return false; ++ ++ return true; ++} ++ ++static bool __i915_error_seek(struct drm_i915_error_state_buf *e, ++ unsigned len) ++{ ++ if (e->pos + len <= e->start) { ++ e->pos += len; ++ return false; ++ } ++ ++ /* First vsnprintf needs to fit in its entirety for memmove */ ++ if (len >= e->size) { ++ e->err = -EIO; ++ return false; ++ } ++ ++ return true; ++} ++ ++static void __i915_error_advance(struct drm_i915_error_state_buf *e, ++ unsigned len) ++{ ++ /* If this is first printf in this window, adjust it so that ++ * start position matches start of the buffer ++ */ ++ ++ if (e->pos < e->start) { ++ const size_t off = e->start - e->pos; ++ ++ /* Should not happen but be paranoid */ ++ if (off > len || e->bytes) { ++ e->err = -EIO; ++ return; ++ } ++ ++ memmove(e->buf, e->buf + off, len - off); ++ e->bytes = len - off; ++ e->pos = e->start; ++ return; ++ } ++ ++ e->bytes += len; ++ e->pos += len; ++} ++ ++static void i915_error_vprintf(struct drm_i915_error_state_buf *e, ++ const char *f, va_list args) ++{ ++ unsigned len; ++ ++ if (!__i915_error_ok(e)) ++ return; ++ ++ /* Seek the first printf which is hits start position */ ++ if (e->pos < e->start) { ++ len = vsnprintf(NULL, 0, f, args); ++ if (!__i915_error_seek(e, len)) ++ return; ++ } ++ ++ len = vsnprintf(e->buf + e->bytes, e->size - e->bytes, f, args); ++ if (len >= e->size - e->bytes) ++ len = e->size - e->bytes - 1; ++ ++ __i915_error_advance(e, len); ++} ++ ++static void i915_error_puts(struct drm_i915_error_state_buf *e, ++ const char *str) ++{ ++ unsigned len; ++ ++ if (!__i915_error_ok(e)) ++ return; ++ ++ len = strlen(str); ++ ++ /* Seek the first printf which is hits start position */ ++ if (e->pos < e->start) { ++ if (!__i915_error_seek(e, len)) ++ return; ++ } ++ ++ if (len >= e->size - e->bytes) ++ len = e->size - e->bytes - 1; ++ memcpy(e->buf + e->bytes, str, len); ++ ++ __i915_error_advance(e, len); ++} ++ ++#define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__) ++#define err_puts(e, s) i915_error_puts(e, s) ++ ++static void print_error_buffers(struct drm_i915_error_state_buf *m, ++ const char *name, ++ struct drm_i915_error_buffer *err, ++ int count) ++{ ++ err_printf(m, "%s [%d]:\n", name, count); ++ ++ while (count--) { ++ err_printf(m, " %08x %8u %02x %02x %x %x", ++ err->gtt_offset, ++ err->size, ++ err->read_domains, ++ err->write_domain, ++ err->rseqno, err->wseqno); ++ err_puts(m, pin_flag(err->pinned)); ++ err_puts(m, tiling_flag(err->tiling)); ++ err_puts(m, dirty_flag(err->dirty)); ++ err_puts(m, purgeable_flag(err->purgeable)); ++ err_puts(m, err->ring != -1 ? " " : ""); ++ err_puts(m, ring_str(err->ring)); ++ err_puts(m, i915_cache_level_str(err->cache_level)); ++ ++ if (err->name) ++ err_printf(m, " (name: %d)", err->name); ++ if (err->fence_reg != I915_FENCE_REG_NONE) ++ err_printf(m, " (fence: %d)", err->fence_reg); ++ ++ err_puts(m, "\n"); ++ err++; ++ } ++} ++ ++static void i915_ring_error_state(struct drm_i915_error_state_buf *m, ++ struct drm_device *dev, ++ struct drm_i915_error_state *error, ++ unsigned ring) ++{ ++ BUG_ON(ring >= I915_NUM_RINGS); /* shut up confused gcc */ ++ err_printf(m, "%s command stream:\n", ring_str(ring)); ++ err_printf(m, " HEAD: 0x%08x\n", error->head[ring]); ++ err_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); ++ err_printf(m, " CTL: 0x%08x\n", error->ctl[ring]); ++ err_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); ++ err_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); ++ err_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); ++ err_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); ++ if (ring == RCS && INTEL_INFO(dev)->gen >= 4) ++ err_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr); ++ ++ if (INTEL_INFO(dev)->gen >= 4) ++ err_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); ++ err_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); ++ err_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); ++ if (INTEL_INFO(dev)->gen >= 6) { ++ err_printf(m, " RC PSMI: 0x%08x\n", error->rc_psmi[ring]); ++ err_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); ++ err_printf(m, " SYNC_0: 0x%08x [last synced 0x%08x]\n", ++ error->semaphore_mboxes[ring][0], ++ error->semaphore_seqno[ring][0]); ++ err_printf(m, " SYNC_1: 0x%08x [last synced 0x%08x]\n", ++ error->semaphore_mboxes[ring][1], ++ error->semaphore_seqno[ring][1]); ++ } ++ err_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); ++ err_printf(m, " waiting: %s\n", yesno(error->waiting[ring])); ++ err_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]); ++ err_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); ++} ++ ++void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...) ++{ ++ va_list args; ++ ++ va_start(args, f); ++ i915_error_vprintf(e, f, args); ++ va_end(args); ++} ++ ++int i915_error_state_to_str(struct drm_i915_error_state_buf *m, ++ const struct i915_error_state_file_priv *error_priv) ++{ ++ struct drm_device *dev = error_priv->dev; ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_error_state *error = error_priv->error; ++ struct intel_ring_buffer *ring; ++ int i, j, page, offset, elt; ++ ++ if (!error) { ++ err_printf(m, "no error state collected\n"); ++ goto out; ++ } ++ ++ err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, ++ error->time.tv_usec); ++ err_printf(m, "Kernel: " UTS_RELEASE "\n"); ++ err_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); ++ err_printf(m, "EIR: 0x%08x\n", error->eir); ++ err_printf(m, "IER: 0x%08x\n", error->ier); ++ err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); ++ err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake); ++ err_printf(m, "DERRMR: 0x%08x\n", error->derrmr); ++ err_printf(m, "CCID: 0x%08x\n", error->ccid); ++ ++ for (i = 0; i < dev_priv->num_fence_regs; i++) ++ err_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); ++ ++ for (i = 0; i < ARRAY_SIZE(error->extra_instdone); i++) ++ err_printf(m, " INSTDONE_%d: 0x%08x\n", i, ++ error->extra_instdone[i]); ++ ++ if (INTEL_INFO(dev)->gen >= 6) { ++ err_printf(m, "ERROR: 0x%08x\n", error->error); ++ err_printf(m, "DONE_REG: 0x%08x\n", error->done_reg); ++ } ++ ++ if (INTEL_INFO(dev)->gen == 7) ++ err_printf(m, "ERR_INT: 0x%08x\n", error->err_int); ++ ++ for_each_ring(ring, dev_priv, i) ++ i915_ring_error_state(m, dev, error, i); ++ ++ if (error->active_bo) ++ print_error_buffers(m, "Active", ++ error->active_bo, ++ error->active_bo_count); ++ ++ if (error->pinned_bo) ++ print_error_buffers(m, "Pinned", ++ error->pinned_bo, ++ error->pinned_bo_count); ++ ++ for (i = 0; i < ARRAY_SIZE(error->ring); i++) { ++ struct drm_i915_error_object *obj; ++ ++ if ((obj = error->ring[i].batchbuffer)) { ++ err_printf(m, "%s --- gtt_offset = 0x%08x\n", ++ dev_priv->ring[i].name, ++ obj->gtt_offset); ++ offset = 0; ++ for (page = 0; page < obj->page_count; page++) { ++ for (elt = 0; elt < PAGE_SIZE/4; elt++) { ++ err_printf(m, "%08x : %08x\n", offset, ++ obj->pages[page][elt]); ++ offset += 4; ++ } ++ } ++ } ++ ++ if (error->ring[i].num_requests) { ++ err_printf(m, "%s --- %d requests\n", ++ dev_priv->ring[i].name, ++ error->ring[i].num_requests); ++ for (j = 0; j < error->ring[i].num_requests; j++) { ++ err_printf(m, " seqno 0x%08x, emitted %ld, tail 0x%08x\n", ++ error->ring[i].requests[j].seqno, ++ error->ring[i].requests[j].jiffies, ++ error->ring[i].requests[j].tail); ++ } ++ } ++ ++ if ((obj = error->ring[i].ringbuffer)) { ++ err_printf(m, "%s --- ringbuffer = 0x%08x\n", ++ dev_priv->ring[i].name, ++ obj->gtt_offset); ++ offset = 0; ++ for (page = 0; page < obj->page_count; page++) { ++ for (elt = 0; elt < PAGE_SIZE/4; elt++) { ++ err_printf(m, "%08x : %08x\n", ++ offset, ++ obj->pages[page][elt]); ++ offset += 4; ++ } ++ } ++ } ++ ++ obj = error->ring[i].ctx; ++ if (obj) { ++ err_printf(m, "%s --- HW Context = 0x%08x\n", ++ dev_priv->ring[i].name, ++ obj->gtt_offset); ++ offset = 0; ++ for (elt = 0; elt < PAGE_SIZE/16; elt += 4) { ++ err_printf(m, "[%04x] %08x %08x %08x %08x\n", ++ offset, ++ obj->pages[0][elt], ++ obj->pages[0][elt+1], ++ obj->pages[0][elt+2], ++ obj->pages[0][elt+3]); ++ offset += 16; ++ } ++ } ++ } ++ ++ if (error->overlay) ++ intel_overlay_print_error_state(m, error->overlay); ++ ++ if (error->display) ++ intel_display_print_error_state(m, dev, error->display); ++ ++out: ++ if (m->bytes == 0 && m->err) ++ return m->err; ++ ++ return 0; ++} ++ ++int i915_error_state_buf_init(struct drm_i915_error_state_buf *ebuf, ++ size_t count, loff_t pos) ++{ ++ memset(ebuf, 0, sizeof(*ebuf)); ++ ++ /* We need to have enough room to store any i915_error_state printf ++ * so that we can move it to start position. ++ */ ++ ebuf->size = count + 1 > PAGE_SIZE ? count + 1 : PAGE_SIZE; ++ ebuf->buf = kmalloc(ebuf->size, ++ GFP_TEMPORARY | __GFP_NORETRY | __GFP_NOWARN); ++ ++ if (ebuf->buf == NULL) { ++ ebuf->size = PAGE_SIZE; ++ ebuf->buf = kmalloc(ebuf->size, GFP_TEMPORARY); ++ } ++ ++ if (ebuf->buf == NULL) { ++ ebuf->size = 128; ++ ebuf->buf = kmalloc(ebuf->size, GFP_TEMPORARY); ++ } ++ ++ if (ebuf->buf == NULL) ++ return -ENOMEM; ++ ++ ebuf->start = pos; ++ ++ return 0; ++} ++ ++static void i915_error_object_free(struct drm_i915_error_object *obj) ++{ ++ int page; ++ ++ if (obj == NULL) ++ return; ++ ++ for (page = 0; page < obj->page_count; page++) ++ kfree(obj->pages[page]); ++ ++ kfree(obj); ++} ++ ++static void i915_error_state_free(struct kref *error_ref) ++{ ++ struct drm_i915_error_state *error = container_of(error_ref, ++ typeof(*error), ref); ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(error->ring); i++) { ++ i915_error_object_free(error->ring[i].batchbuffer); ++ i915_error_object_free(error->ring[i].ringbuffer); ++ i915_error_object_free(error->ring[i].ctx); ++ kfree(error->ring[i].requests); ++ } ++ ++ kfree(error->active_bo); ++ kfree(error->overlay); ++ kfree(error->display); ++ kfree(error); ++} ++ ++static struct drm_i915_error_object * ++i915_error_object_create_sized(struct drm_i915_private *dev_priv, ++ struct drm_i915_gem_object *src, ++ const int num_pages) ++{ ++ struct drm_i915_error_object *dst; ++ int i; ++ u32 reloc_offset; ++ ++ if (src == NULL || src->pages == NULL) ++ return NULL; ++ ++ dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *), GFP_ATOMIC); ++ if (dst == NULL) ++ return NULL; ++ ++ reloc_offset = dst->gtt_offset = i915_gem_obj_ggtt_offset(src); ++ for (i = 0; i < num_pages; i++) { ++ unsigned long flags; ++ void *d; ++ ++ d = kmalloc(PAGE_SIZE, GFP_ATOMIC); ++ if (d == NULL) ++ goto unwind; ++ ++ local_irq_save(flags); ++ if (reloc_offset < dev_priv->gtt.mappable_end && ++ src->has_global_gtt_mapping) { ++ void __iomem *s; ++ ++ /* Simply ignore tiling or any overlapping fence. ++ * It's part of the error state, and this hopefully ++ * captures what the GPU read. ++ */ ++ ++ s = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, ++ reloc_offset); ++ memcpy_fromio(d, s, PAGE_SIZE); ++ io_mapping_unmap_atomic(s); ++ } else if (src->stolen) { ++ unsigned long offset; ++ ++ offset = dev_priv->mm.stolen_base; ++ offset += src->stolen->start; ++ offset += i << PAGE_SHIFT; ++ ++ memcpy_fromio(d, (void __iomem *) offset, PAGE_SIZE); ++ } else { ++ struct page *page; ++ void *s; ++ ++ page = i915_gem_object_get_page(src, i); ++ ++ drm_clflush_pages(&page, 1); ++ ++ s = kmap_atomic(page); ++ memcpy(d, s, PAGE_SIZE); ++ kunmap_atomic(s); ++ ++ drm_clflush_pages(&page, 1); ++ } ++ local_irq_restore(flags); ++ ++ dst->pages[i] = d; ++ ++ reloc_offset += PAGE_SIZE; ++ } ++ dst->page_count = num_pages; ++ ++ return dst; ++ ++unwind: ++ while (i--) ++ kfree(dst->pages[i]); ++ kfree(dst); ++ return NULL; ++} ++#define i915_error_object_create(dev_priv, src) \ ++ i915_error_object_create_sized((dev_priv), (src), \ ++ (src)->base.size>>PAGE_SHIFT) ++ ++static void capture_bo(struct drm_i915_error_buffer *err, ++ struct drm_i915_gem_object *obj) ++{ ++ err->size = obj->base.size; ++ err->name = obj->base.name; ++ err->rseqno = obj->last_read_seqno; ++ err->wseqno = obj->last_write_seqno; ++ err->gtt_offset = i915_gem_obj_ggtt_offset(obj); ++ err->read_domains = obj->base.read_domains; ++ err->write_domain = obj->base.write_domain; ++ err->fence_reg = obj->fence_reg; ++ err->pinned = 0; ++ if (obj->pin_count > 0) ++ err->pinned = 1; ++ if (obj->user_pin_count > 0) ++ err->pinned = -1; ++ err->tiling = obj->tiling_mode; ++ err->dirty = obj->dirty; ++ err->purgeable = obj->madv != I915_MADV_WILLNEED; ++ err->ring = obj->ring ? obj->ring->id : -1; ++ err->cache_level = obj->cache_level; ++} ++ ++static u32 capture_active_bo(struct drm_i915_error_buffer *err, ++ int count, struct list_head *head) ++{ ++ struct drm_i915_gem_object *obj; ++ int i = 0; ++ ++ list_for_each_entry(obj, head, mm_list) { ++ capture_bo(err++, obj); ++ if (++i == count) ++ break; ++ } ++ ++ return i; ++} ++ ++static u32 capture_pinned_bo(struct drm_i915_error_buffer *err, ++ int count, struct list_head *head) ++{ ++ struct drm_i915_gem_object *obj; ++ int i = 0; ++ ++ list_for_each_entry(obj, head, global_list) { ++ if (obj->pin_count == 0) ++ continue; ++ ++ capture_bo(err++, obj); ++ if (++i == count) ++ break; ++ } ++ ++ return i; ++} ++ ++static void i915_gem_record_fences(struct drm_device *dev, ++ struct drm_i915_error_state *error) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int i; ++ ++ /* Fences */ ++ switch (INTEL_INFO(dev)->gen) { ++ case 7: ++ case 6: ++ for (i = 0; i < dev_priv->num_fence_regs; i++) ++ error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); ++ break; ++ case 5: ++ case 4: ++ for (i = 0; i < 16; i++) ++ error->fence[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); ++ break; ++ case 3: ++ if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) ++ for (i = 0; i < 8; i++) ++ error->fence[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); ++ case 2: ++ for (i = 0; i < 8; i++) ++ error->fence[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); ++ break; ++ ++ default: ++ BUG(); ++ } ++} ++ ++static struct drm_i915_error_object * ++i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, ++ struct intel_ring_buffer *ring) ++{ ++ struct drm_i915_gem_object *obj; ++ u32 seqno; ++ ++ if (!ring->get_seqno) ++ return NULL; ++ ++ if (HAS_BROKEN_CS_TLB(dev_priv->dev)) { ++ u32 acthd = I915_READ(ACTHD); ++ ++ if (WARN_ON(ring->id != RCS)) ++ return NULL; ++ ++ obj = ring->private; ++ if (acthd >= i915_gem_obj_ggtt_offset(obj) && ++ acthd < i915_gem_obj_ggtt_offset(obj) + obj->base.size) ++ return i915_error_object_create(dev_priv, obj); ++ } ++ ++ seqno = ring->get_seqno(ring, false); ++ list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { ++ if (obj->ring != ring) ++ continue; ++ ++ if (i915_seqno_passed(seqno, obj->last_read_seqno)) ++ continue; ++ ++ if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0) ++ continue; ++ ++ /* We need to copy these to an anonymous buffer as the simplest ++ * method to avoid being overwritten by userspace. ++ */ ++ return i915_error_object_create(dev_priv, obj); ++ } ++ ++ return NULL; ++} ++ ++static void i915_record_ring_state(struct drm_device *dev, ++ struct drm_i915_error_state *error, ++ struct intel_ring_buffer *ring) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (INTEL_INFO(dev)->gen >= 6) { ++ error->rc_psmi[ring->id] = I915_READ(ring->mmio_base + 0x50); ++ error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring)); ++ error->semaphore_mboxes[ring->id][0] ++ = I915_READ(RING_SYNC_0(ring->mmio_base)); ++ error->semaphore_mboxes[ring->id][1] ++ = I915_READ(RING_SYNC_1(ring->mmio_base)); ++ error->semaphore_seqno[ring->id][0] = ring->sync_seqno[0]; ++ error->semaphore_seqno[ring->id][1] = ring->sync_seqno[1]; ++ } ++ ++ if (INTEL_INFO(dev)->gen >= 4) { ++ error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); ++ error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); ++ error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); ++ error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); ++ error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base)); ++ if (ring->id == RCS) ++ error->bbaddr = I915_READ64(BB_ADDR); ++ } else { ++ error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX); ++ error->ipeir[ring->id] = I915_READ(IPEIR); ++ error->ipehr[ring->id] = I915_READ(IPEHR); ++ error->instdone[ring->id] = I915_READ(INSTDONE); ++ } ++ ++ error->waiting[ring->id] = waitqueue_active(&ring->irq_queue); ++ error->instpm[ring->id] = I915_READ(RING_INSTPM(ring->mmio_base)); ++ error->seqno[ring->id] = ring->get_seqno(ring, false); ++ error->acthd[ring->id] = intel_ring_get_active_head(ring); ++ error->head[ring->id] = I915_READ_HEAD(ring); ++ error->tail[ring->id] = I915_READ_TAIL(ring); ++ error->ctl[ring->id] = I915_READ_CTL(ring); ++ ++ error->cpu_ring_head[ring->id] = ring->head; ++ error->cpu_ring_tail[ring->id] = ring->tail; ++} ++ ++ ++static void i915_gem_record_active_context(struct intel_ring_buffer *ring, ++ struct drm_i915_error_state *error, ++ struct drm_i915_error_ring *ering) ++{ ++ struct drm_i915_private *dev_priv = ring->dev->dev_private; ++ struct drm_i915_gem_object *obj; ++ ++ /* Currently render ring is the only HW context user */ ++ if (ring->id != RCS || !error->ccid) ++ return; ++ ++ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { ++ if ((error->ccid & PAGE_MASK) == i915_gem_obj_ggtt_offset(obj)) { ++ ering->ctx = i915_error_object_create_sized(dev_priv, ++ obj, 1); ++ break; ++ } ++ } ++} ++ ++static void i915_gem_record_rings(struct drm_device *dev, ++ struct drm_i915_error_state *error) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct intel_ring_buffer *ring; ++ struct drm_i915_gem_request *request; ++ int i, count; ++ ++ for_each_ring(ring, dev_priv, i) { ++ i915_record_ring_state(dev, error, ring); ++ ++ error->ring[i].batchbuffer = ++ i915_error_first_batchbuffer(dev_priv, ring); ++ ++ error->ring[i].ringbuffer = ++ i915_error_object_create(dev_priv, ring->obj); ++ ++ ++ i915_gem_record_active_context(ring, error, &error->ring[i]); ++ ++ count = 0; ++ list_for_each_entry(request, &ring->request_list, list) ++ count++; ++ ++ error->ring[i].num_requests = count; ++ error->ring[i].requests = ++ kmalloc(count*sizeof(struct drm_i915_error_request), ++ GFP_ATOMIC); ++ if (error->ring[i].requests == NULL) { ++ error->ring[i].num_requests = 0; ++ continue; ++ } ++ ++ count = 0; ++ list_for_each_entry(request, &ring->request_list, list) { ++ struct drm_i915_error_request *erq; ++ ++ erq = &error->ring[i].requests[count++]; ++ erq->seqno = request->seqno; ++ erq->jiffies = request->emitted_jiffies; ++ erq->tail = request->tail; ++ } ++ } ++} ++ ++static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv, ++ struct drm_i915_error_state *error) ++{ ++ struct drm_i915_gem_object *obj; ++ int i; ++ ++ i = 0; ++ list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) ++ i++; ++ error->active_bo_count = i; ++ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) ++ if (obj->pin_count) ++ i++; ++ error->pinned_bo_count = i - error->active_bo_count; ++ ++ if (i) { ++ error->active_bo = kmalloc(sizeof(*error->active_bo)*i, ++ GFP_ATOMIC); ++ if (error->active_bo) ++ error->pinned_bo = ++ error->active_bo + error->active_bo_count; ++ } ++ ++ if (error->active_bo) ++ error->active_bo_count = ++ capture_active_bo(error->active_bo, ++ error->active_bo_count, ++ &dev_priv->mm.active_list); ++ ++ if (error->pinned_bo) ++ error->pinned_bo_count = ++ capture_pinned_bo(error->pinned_bo, ++ error->pinned_bo_count, ++ &dev_priv->mm.bound_list); ++} ++ ++/** ++ * i915_capture_error_state - capture an error record for later analysis ++ * @dev: drm device ++ * ++ * Should be called when an error is detected (either a hang or an error ++ * interrupt) to capture error state from the time of the error. Fills ++ * out a structure which becomes available in debugfs for user level tools ++ * to pick up. ++ */ ++void i915_capture_error_state(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_i915_error_state *error; ++ unsigned long flags; ++ int pipe; ++ ++ spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); ++ error = dev_priv->gpu_error.first_error; ++ spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); ++ if (error) ++ return; ++ ++ /* Account for pipe specific data like PIPE*STAT */ ++ error = kzalloc(sizeof(*error), GFP_ATOMIC); ++ if (!error) { ++ DRM_DEBUG_DRIVER("out of memory, not capturing error state\n"); ++ return; ++ } ++ ++ DRM_INFO("capturing error event; look for more information in " ++ "/sys/class/drm/card%d/error\n", dev->primary->index); ++ ++ kref_init(&error->ref); ++ error->eir = I915_READ(EIR); ++ error->pgtbl_er = I915_READ(PGTBL_ER); ++ if (HAS_HW_CONTEXTS(dev)) ++ error->ccid = I915_READ(CCID); ++ ++ if (HAS_PCH_SPLIT(dev)) ++ error->ier = I915_READ(DEIER) | I915_READ(GTIER); ++ else if (IS_VALLEYVIEW(dev)) ++ error->ier = I915_READ(GTIER) | I915_READ(VLV_IER); ++ else if (IS_GEN2(dev)) ++ error->ier = I915_READ16(IER); ++ else ++ error->ier = I915_READ(IER); ++ ++ if (INTEL_INFO(dev)->gen >= 6) ++ error->derrmr = I915_READ(DERRMR); ++ ++ if (IS_VALLEYVIEW(dev)) ++ error->forcewake = I915_READ(FORCEWAKE_VLV); ++ else if (INTEL_INFO(dev)->gen >= 7) ++ error->forcewake = I915_READ(FORCEWAKE_MT); ++ else if (INTEL_INFO(dev)->gen == 6) ++ error->forcewake = I915_READ(FORCEWAKE); ++ ++ if (!HAS_PCH_SPLIT(dev)) ++ for_each_pipe(pipe) ++ error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); ++ ++ if (INTEL_INFO(dev)->gen >= 6) { ++ error->error = I915_READ(ERROR_GEN6); ++ error->done_reg = I915_READ(DONE_REG); ++ } ++ ++ if (INTEL_INFO(dev)->gen == 7) ++ error->err_int = I915_READ(GEN7_ERR_INT); ++ ++ i915_get_extra_instdone(dev, error->extra_instdone); ++ ++ i915_gem_capture_buffers(dev_priv, error); ++ i915_gem_record_fences(dev, error); ++ i915_gem_record_rings(dev, error); ++ ++ do_gettimeofday(&error->time); ++ ++ error->overlay = intel_overlay_capture_error_state(dev); ++ error->display = intel_display_capture_error_state(dev); ++ ++ spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); ++ if (dev_priv->gpu_error.first_error == NULL) { ++ dev_priv->gpu_error.first_error = error; ++ error = NULL; ++ } ++ spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); ++ ++ if (error) ++ i915_error_state_free(&error->ref); ++} ++ ++void i915_error_state_get(struct drm_device *dev, ++ struct i915_error_state_file_priv *error_priv) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); ++ error_priv->error = dev_priv->gpu_error.first_error; ++ if (error_priv->error) ++ kref_get(&error_priv->error->ref); ++ spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); ++ ++} ++ ++void i915_error_state_put(struct i915_error_state_file_priv *error_priv) ++{ ++ if (error_priv->error) ++ kref_put(&error_priv->error->ref, i915_error_state_free); ++} ++ ++void i915_destroy_error_state(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_i915_error_state *error; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); ++ error = dev_priv->gpu_error.first_error; ++ dev_priv->gpu_error.first_error = NULL; ++ spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); ++ ++ if (error) ++ kref_put(&error->ref, i915_error_state_free); ++} ++ ++const char *i915_cache_level_str(int type) ++{ ++ switch (type) { ++ case I915_CACHE_NONE: return " uncached"; ++ case I915_CACHE_LLC: return " snooped (LLC)"; ++ case I915_CACHE_LLC_MLC: return " snooped (LLC+MLC)"; ++ default: return ""; ++ } ++} ++ ++/* NB: please notice the memset */ ++void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ memset(instdone, 0, sizeof(*instdone) * I915_NUM_INSTDONE_REG); ++ ++ switch (INTEL_INFO(dev)->gen) { ++ case 2: ++ case 3: ++ instdone[0] = I915_READ(INSTDONE); ++ break; ++ case 4: ++ case 5: ++ case 6: ++ instdone[0] = I915_READ(INSTDONE_I965); ++ instdone[1] = I915_READ(INSTDONE1); ++ break; ++ default: ++ WARN_ONCE(1, "Unsupported platform\n"); ++ case 7: ++ instdone[0] = I915_READ(GEN7_INSTDONE_1); ++ instdone[1] = I915_READ(GEN7_SC_INSTDONE); ++ instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE); ++ instdone[3] = I915_READ(GEN7_ROW_INSTDONE); ++ break; ++ } ++} +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index f77e87365480..a710ec29781b 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1527,535 +1527,6 @@ static void i915_error_work_func(struct work_struct *work) + } + } + +-/* NB: please notice the memset */ +-static void i915_get_extra_instdone(struct drm_device *dev, +- uint32_t *instdone) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- memset(instdone, 0, sizeof(*instdone) * I915_NUM_INSTDONE_REG); +- +- switch(INTEL_INFO(dev)->gen) { +- case 2: +- case 3: +- instdone[0] = I915_READ(INSTDONE); +- break; +- case 4: +- case 5: +- case 6: +- instdone[0] = I915_READ(INSTDONE_I965); +- instdone[1] = I915_READ(INSTDONE1); +- break; +- default: +- WARN_ONCE(1, "Unsupported platform\n"); +- case 7: +- instdone[0] = I915_READ(GEN7_INSTDONE_1); +- instdone[1] = I915_READ(GEN7_SC_INSTDONE); +- instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE); +- instdone[3] = I915_READ(GEN7_ROW_INSTDONE); +- break; +- } +-} +- +-#ifdef CONFIG_DEBUG_FS +-static struct drm_i915_error_object * +-i915_error_object_create_sized(struct drm_i915_private *dev_priv, +- struct drm_i915_gem_object *src, +- const int num_pages) +-{ +- struct drm_i915_error_object *dst; +- int i; +- u32 reloc_offset; +- +- if (src == NULL || src->pages == NULL) +- return NULL; +- +- dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *), GFP_ATOMIC); +- if (dst == NULL) +- return NULL; +- +- reloc_offset = dst->gtt_offset = i915_gem_obj_ggtt_offset(src); +- for (i = 0; i < num_pages; i++) { +- unsigned long flags; +- void *d; +- +- d = kmalloc(PAGE_SIZE, GFP_ATOMIC); +- if (d == NULL) +- goto unwind; +- +- local_irq_save(flags); +- if (reloc_offset < dev_priv->gtt.mappable_end && +- src->has_global_gtt_mapping) { +- void __iomem *s; +- +- /* Simply ignore tiling or any overlapping fence. +- * It's part of the error state, and this hopefully +- * captures what the GPU read. +- */ +- +- s = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, +- reloc_offset); +- memcpy_fromio(d, s, PAGE_SIZE); +- io_mapping_unmap_atomic(s); +- } else if (src->stolen) { +- unsigned long offset; +- +- offset = dev_priv->mm.stolen_base; +- offset += src->stolen->start; +- offset += i << PAGE_SHIFT; +- +- memcpy_fromio(d, (void __iomem *) offset, PAGE_SIZE); +- } else { +- struct page *page; +- void *s; +- +- page = i915_gem_object_get_page(src, i); +- +- drm_clflush_pages(&page, 1); +- +- s = kmap_atomic(page); +- memcpy(d, s, PAGE_SIZE); +- kunmap_atomic(s); +- +- drm_clflush_pages(&page, 1); +- } +- local_irq_restore(flags); +- +- dst->pages[i] = d; +- +- reloc_offset += PAGE_SIZE; +- } +- dst->page_count = num_pages; +- +- return dst; +- +-unwind: +- while (i--) +- kfree(dst->pages[i]); +- kfree(dst); +- return NULL; +-} +-#define i915_error_object_create(dev_priv, src) \ +- i915_error_object_create_sized((dev_priv), (src), \ +- (src)->base.size>>PAGE_SHIFT) +- +-static void +-i915_error_object_free(struct drm_i915_error_object *obj) +-{ +- int page; +- +- if (obj == NULL) +- return; +- +- for (page = 0; page < obj->page_count; page++) +- kfree(obj->pages[page]); +- +- kfree(obj); +-} +- +-void +-i915_error_state_free(struct kref *error_ref) +-{ +- struct drm_i915_error_state *error = container_of(error_ref, +- typeof(*error), ref); +- int i; +- +- for (i = 0; i < ARRAY_SIZE(error->ring); i++) { +- i915_error_object_free(error->ring[i].batchbuffer); +- i915_error_object_free(error->ring[i].ringbuffer); +- i915_error_object_free(error->ring[i].ctx); +- kfree(error->ring[i].requests); +- } +- +- kfree(error->active_bo); +- kfree(error->overlay); +- kfree(error->display); +- kfree(error); +-} +-static void capture_bo(struct drm_i915_error_buffer *err, +- struct drm_i915_gem_object *obj) +-{ +- err->size = obj->base.size; +- err->name = obj->base.name; +- err->rseqno = obj->last_read_seqno; +- err->wseqno = obj->last_write_seqno; +- err->gtt_offset = i915_gem_obj_ggtt_offset(obj); +- err->read_domains = obj->base.read_domains; +- err->write_domain = obj->base.write_domain; +- err->fence_reg = obj->fence_reg; +- err->pinned = 0; +- if (obj->pin_count > 0) +- err->pinned = 1; +- if (obj->user_pin_count > 0) +- err->pinned = -1; +- err->tiling = obj->tiling_mode; +- err->dirty = obj->dirty; +- err->purgeable = obj->madv != I915_MADV_WILLNEED; +- err->ring = obj->ring ? obj->ring->id : -1; +- err->cache_level = obj->cache_level; +-} +- +-static u32 capture_active_bo(struct drm_i915_error_buffer *err, +- int count, struct list_head *head) +-{ +- struct drm_i915_gem_object *obj; +- int i = 0; +- +- list_for_each_entry(obj, head, mm_list) { +- capture_bo(err++, obj); +- if (++i == count) +- break; +- } +- +- return i; +-} +- +-static u32 capture_pinned_bo(struct drm_i915_error_buffer *err, +- int count, struct list_head *head) +-{ +- struct drm_i915_gem_object *obj; +- int i = 0; +- +- list_for_each_entry(obj, head, global_list) { +- if (obj->pin_count == 0) +- continue; +- +- capture_bo(err++, obj); +- if (++i == count) +- break; +- } +- +- return i; +-} +- +-static void i915_gem_record_fences(struct drm_device *dev, +- struct drm_i915_error_state *error) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- int i; +- +- /* Fences */ +- switch (INTEL_INFO(dev)->gen) { +- case 7: +- case 6: +- for (i = 0; i < dev_priv->num_fence_regs; i++) +- error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); +- break; +- case 5: +- case 4: +- for (i = 0; i < 16; i++) +- error->fence[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); +- break; +- case 3: +- if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) +- for (i = 0; i < 8; i++) +- error->fence[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); +- case 2: +- for (i = 0; i < 8; i++) +- error->fence[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); +- break; +- +- default: +- BUG(); +- } +-} +- +-static struct drm_i915_error_object * +-i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, +- struct intel_ring_buffer *ring) +-{ +- struct drm_i915_gem_object *obj; +- u32 seqno; +- +- if (!ring->get_seqno) +- return NULL; +- +- if (HAS_BROKEN_CS_TLB(dev_priv->dev)) { +- u32 acthd = I915_READ(ACTHD); +- +- if (WARN_ON(ring->id != RCS)) +- return NULL; +- +- obj = ring->private; +- if (acthd >= i915_gem_obj_ggtt_offset(obj) && +- acthd < i915_gem_obj_ggtt_offset(obj) + obj->base.size) +- return i915_error_object_create(dev_priv, obj); +- } +- +- seqno = ring->get_seqno(ring, false); +- list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { +- if (obj->ring != ring) +- continue; +- +- if (i915_seqno_passed(seqno, obj->last_read_seqno)) +- continue; +- +- if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0) +- continue; +- +- /* We need to copy these to an anonymous buffer as the simplest +- * method to avoid being overwritten by userspace. +- */ +- return i915_error_object_create(dev_priv, obj); +- } +- +- return NULL; +-} +- +-static void i915_record_ring_state(struct drm_device *dev, +- struct drm_i915_error_state *error, +- struct intel_ring_buffer *ring) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- +- if (INTEL_INFO(dev)->gen >= 6) { +- error->rc_psmi[ring->id] = I915_READ(ring->mmio_base + 0x50); +- error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring)); +- error->semaphore_mboxes[ring->id][0] +- = I915_READ(RING_SYNC_0(ring->mmio_base)); +- error->semaphore_mboxes[ring->id][1] +- = I915_READ(RING_SYNC_1(ring->mmio_base)); +- error->semaphore_seqno[ring->id][0] = ring->sync_seqno[0]; +- error->semaphore_seqno[ring->id][1] = ring->sync_seqno[1]; +- } +- +- if (INTEL_INFO(dev)->gen >= 4) { +- error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); +- error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); +- error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); +- error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); +- error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base)); +- if (ring->id == RCS) +- error->bbaddr = I915_READ64(BB_ADDR); +- } else { +- error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX); +- error->ipeir[ring->id] = I915_READ(IPEIR); +- error->ipehr[ring->id] = I915_READ(IPEHR); +- error->instdone[ring->id] = I915_READ(INSTDONE); +- } +- +- error->waiting[ring->id] = waitqueue_active(&ring->irq_queue); +- error->instpm[ring->id] = I915_READ(RING_INSTPM(ring->mmio_base)); +- error->seqno[ring->id] = ring->get_seqno(ring, false); +- error->acthd[ring->id] = intel_ring_get_active_head(ring); +- error->head[ring->id] = I915_READ_HEAD(ring); +- error->tail[ring->id] = I915_READ_TAIL(ring); +- error->ctl[ring->id] = I915_READ_CTL(ring); +- +- error->cpu_ring_head[ring->id] = ring->head; +- error->cpu_ring_tail[ring->id] = ring->tail; +-} +- +- +-static void i915_gem_record_active_context(struct intel_ring_buffer *ring, +- struct drm_i915_error_state *error, +- struct drm_i915_error_ring *ering) +-{ +- struct drm_i915_private *dev_priv = ring->dev->dev_private; +- struct drm_i915_gem_object *obj; +- +- /* Currently render ring is the only HW context user */ +- if (ring->id != RCS || !error->ccid) +- return; +- +- list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { +- if ((error->ccid & PAGE_MASK) == i915_gem_obj_ggtt_offset(obj)) { +- ering->ctx = i915_error_object_create_sized(dev_priv, +- obj, 1); +- break; +- } +- } +-} +- +-static void i915_gem_record_rings(struct drm_device *dev, +- struct drm_i915_error_state *error) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_ring_buffer *ring; +- struct drm_i915_gem_request *request; +- int i, count; +- +- for_each_ring(ring, dev_priv, i) { +- i915_record_ring_state(dev, error, ring); +- +- error->ring[i].batchbuffer = +- i915_error_first_batchbuffer(dev_priv, ring); +- +- error->ring[i].ringbuffer = +- i915_error_object_create(dev_priv, ring->obj); +- +- +- i915_gem_record_active_context(ring, error, &error->ring[i]); +- +- count = 0; +- list_for_each_entry(request, &ring->request_list, list) +- count++; +- +- error->ring[i].num_requests = count; +- error->ring[i].requests = +- kmalloc(count*sizeof(struct drm_i915_error_request), +- GFP_ATOMIC); +- if (error->ring[i].requests == NULL) { +- error->ring[i].num_requests = 0; +- continue; +- } +- +- count = 0; +- list_for_each_entry(request, &ring->request_list, list) { +- struct drm_i915_error_request *erq; +- +- erq = &error->ring[i].requests[count++]; +- erq->seqno = request->seqno; +- erq->jiffies = request->emitted_jiffies; +- erq->tail = request->tail; +- } +- } +-} +- +-static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv, +- struct drm_i915_error_state *error) +-{ +- struct drm_i915_gem_object *obj; +- int i; +- +- i = 0; +- list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) +- i++; +- error->active_bo_count = i; +- list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) +- if (obj->pin_count) +- i++; +- error->pinned_bo_count = i - error->active_bo_count; +- +- if (i) { +- error->active_bo = kmalloc(sizeof(*error->active_bo)*i, +- GFP_ATOMIC); +- if (error->active_bo) +- error->pinned_bo = +- error->active_bo + error->active_bo_count; +- } +- +- if (error->active_bo) +- error->active_bo_count = +- capture_active_bo(error->active_bo, +- error->active_bo_count, +- &dev_priv->mm.active_list); +- +- if (error->pinned_bo) +- error->pinned_bo_count = +- capture_pinned_bo(error->pinned_bo, +- error->pinned_bo_count, +- &dev_priv->mm.bound_list); +-} +- +-/** +- * i915_capture_error_state - capture an error record for later analysis +- * @dev: drm device +- * +- * Should be called when an error is detected (either a hang or an error +- * interrupt) to capture error state from the time of the error. Fills +- * out a structure which becomes available in debugfs for user level tools +- * to pick up. +- */ +-static void i915_capture_error_state(struct drm_device *dev) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- struct drm_i915_error_state *error; +- unsigned long flags; +- int pipe; +- +- spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); +- error = dev_priv->gpu_error.first_error; +- spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); +- if (error) +- return; +- +- /* Account for pipe specific data like PIPE*STAT */ +- error = kzalloc(sizeof(*error), GFP_ATOMIC); +- if (!error) { +- DRM_DEBUG_DRIVER("out of memory, not capturing error state\n"); +- return; +- } +- +- DRM_INFO("capturing error event; look for more information in " +- "/sys/class/drm/card%d/error\n", dev->primary->index); +- +- kref_init(&error->ref); +- error->eir = I915_READ(EIR); +- error->pgtbl_er = I915_READ(PGTBL_ER); +- if (HAS_HW_CONTEXTS(dev)) +- error->ccid = I915_READ(CCID); +- +- if (HAS_PCH_SPLIT(dev)) +- error->ier = I915_READ(DEIER) | I915_READ(GTIER); +- else if (IS_VALLEYVIEW(dev)) +- error->ier = I915_READ(GTIER) | I915_READ(VLV_IER); +- else if (IS_GEN2(dev)) +- error->ier = I915_READ16(IER); +- else +- error->ier = I915_READ(IER); +- +- if (INTEL_INFO(dev)->gen >= 6) +- error->derrmr = I915_READ(DERRMR); +- +- if (IS_VALLEYVIEW(dev)) +- error->forcewake = I915_READ(FORCEWAKE_VLV); +- else if (INTEL_INFO(dev)->gen >= 7) +- error->forcewake = I915_READ(FORCEWAKE_MT); +- else if (INTEL_INFO(dev)->gen == 6) +- error->forcewake = I915_READ(FORCEWAKE); +- +- if (!HAS_PCH_SPLIT(dev)) +- for_each_pipe(pipe) +- error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); +- +- if (INTEL_INFO(dev)->gen >= 6) { +- error->error = I915_READ(ERROR_GEN6); +- error->done_reg = I915_READ(DONE_REG); +- } +- +- if (INTEL_INFO(dev)->gen == 7) +- error->err_int = I915_READ(GEN7_ERR_INT); +- +- i915_get_extra_instdone(dev, error->extra_instdone); +- +- i915_gem_capture_buffers(dev_priv, error); +- i915_gem_record_fences(dev, error); +- i915_gem_record_rings(dev, error); +- +- do_gettimeofday(&error->time); +- +- error->overlay = intel_overlay_capture_error_state(dev); +- error->display = intel_display_capture_error_state(dev); +- +- spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); +- if (dev_priv->gpu_error.first_error == NULL) { +- dev_priv->gpu_error.first_error = error; +- error = NULL; +- } +- spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); +- +- if (error) +- i915_error_state_free(&error->ref); +-} +- +-void i915_destroy_error_state(struct drm_device *dev) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- struct drm_i915_error_state *error; +- unsigned long flags; +- +- spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); +- error = dev_priv->gpu_error.first_error; +- dev_priv->gpu_error.first_error = NULL; +- spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); +- +- if (error) +- kref_put(&error->ref, i915_error_state_free); +-} +-#else +-#define i915_capture_error_state(x) +-#endif +- + static void i915_report_and_clear_eir(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 861dcc5d4ebf..7b52eaab0dc4 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -10213,9 +10213,6 @@ int intel_modeset_vga_set_state(struct drm_device *dev, bool state) + return 0; + } + +-#ifdef CONFIG_DEBUG_FS +-#include +- + struct intel_display_error_state { + + u32 power_well_driver; +@@ -10387,4 +10384,3 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m, + err_printf(m, " VSYNC: %08x\n", error->transcoder[i].vsync); + } + } +-#endif +diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c +index 81c3ca14fa92..2abb53e6f1e0 100644 +--- a/drivers/gpu/drm/i915/intel_overlay.c ++++ b/drivers/gpu/drm/i915/intel_overlay.c +@@ -1412,9 +1412,6 @@ void intel_cleanup_overlay(struct drm_device *dev) + kfree(dev_priv->overlay); + } + +-#ifdef CONFIG_DEBUG_FS +-#include +- + struct intel_overlay_error_state { + struct overlay_registers regs; + unsigned long base; +@@ -1537,4 +1534,3 @@ intel_overlay_print_error_state(struct drm_i915_error_state_buf *m, + P(UVSCALEV); + #undef P + } +-#endif +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0456-drm-i915-clean-up-vlv-pre_pll_enable-and-pll-enable-.patch b/patches.baytrail/0456-drm-i915-clean-up-vlv-pre_pll_enable-and-pll-enable-.patch new file mode 100644 index 000000000000..7dd40420e0c7 --- /dev/null +++ b/patches.baytrail/0456-drm-i915-clean-up-vlv-pre_pll_enable-and-pll-enable-.patch @@ -0,0 +1,130 @@ +From 3ed81defe5fab6e99bcfb957594814147923929e Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 11 Jul 2013 22:13:42 +0200 +Subject: drm/i915: clean up vlv ->pre_pll_enable and pll enable sequence + +No need to call the ->pre_pll_enable hook twice if we don't enable the +dpll too early. This should make Jani a bit less grumpy. + +v2: Rebase on top of the newly-colored BUG_ONs. + +v3: Reinstate the lost write of the DPLL_MD register, spotted by Imre. + +Cc: Imre Deak +Cc: Jani Nikula +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 426115cf5dd81d17a6322c493ca337e637ce2aed) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 47 +++++++++++++++--------------------- + 1 file changed, 20 insertions(+), 27 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 7b52eaab0dc4..ddf3d3292eb6 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1321,32 +1321,40 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, + assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMID); + } + +-static void vlv_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) ++static void vlv_enable_pll(struct intel_crtc *crtc) + { +- int reg; +- u32 val; ++ struct drm_device *dev = crtc->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int reg = DPLL(crtc->pipe); ++ u32 dpll = crtc->config.dpll_hw_state.dpll; + +- assert_pipe_disabled(dev_priv, pipe); ++ assert_pipe_disabled(dev_priv, crtc->pipe); + + /* No really, not for ILK+ */ + BUG_ON(!IS_VALLEYVIEW(dev_priv->dev)); + + /* PLL is protected by panel, make sure we can write it */ + if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev)) +- assert_panel_unlocked(dev_priv, pipe); ++ assert_panel_unlocked(dev_priv, crtc->pipe); + +- reg = DPLL(pipe); +- val = I915_READ(reg); +- val |= DPLL_VCO_ENABLE; ++ I915_WRITE(reg, dpll); ++ POSTING_READ(reg); ++ udelay(150); ++ ++ if (wait_for(((I915_READ(reg) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) ++ DRM_ERROR("DPLL %d failed to lock\n", crtc->pipe); ++ ++ I915_WRITE(DPLL_MD(crtc->pipe), crtc->config.dpll_hw_state.dpll_md); ++ POSTING_READ(DPLL_MD(crtc->pipe)); + + /* We do this three times for luck */ +- I915_WRITE(reg, val); ++ I915_WRITE(reg, dpll); + POSTING_READ(reg); + udelay(150); /* wait for warmup */ +- I915_WRITE(reg, val); ++ I915_WRITE(reg, dpll); + POSTING_READ(reg); + udelay(150); /* wait for warmup */ +- I915_WRITE(reg, val); ++ I915_WRITE(reg, dpll); + POSTING_READ(reg); + udelay(150); /* wait for warmup */ + } +@@ -3654,7 +3662,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) + if (encoder->pre_pll_enable) + encoder->pre_pll_enable(encoder); + +- vlv_enable_pll(dev_priv, pipe); ++ vlv_enable_pll(intel_crtc); + + for_each_encoder_on_crtc(dev, crtc, encoder) + if (encoder->pre_enable) +@@ -4405,7 +4413,6 @@ static void vlv_update_pll(struct intel_crtc *crtc) + { + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_encoder *encoder; + int pipe = crtc->pipe; + u32 dpll, mdiv; + u32 bestn, bestm1, bestm2, bestp1, bestp2; +@@ -4494,10 +4501,6 @@ static void vlv_update_pll(struct intel_crtc *crtc) + + vlv_dpio_write(dev_priv, DPIO_PLL_CML(pipe), 0x87871000); + +- for_each_encoder_on_crtc(dev, &crtc->base, encoder) +- if (encoder->pre_pll_enable) +- encoder->pre_pll_enable(encoder); +- + /* Enable DPIO clock input */ + dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV | + DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV; +@@ -4507,20 +4510,10 @@ static void vlv_update_pll(struct intel_crtc *crtc) + dpll |= DPLL_VCO_ENABLE; + crtc->config.dpll_hw_state.dpll = dpll; + +- I915_WRITE(DPLL(pipe), dpll); +- POSTING_READ(DPLL(pipe)); +- udelay(150); +- +- if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) +- DRM_ERROR("DPLL %d failed to lock\n", pipe); +- + dpll_md = (crtc->config.pixel_multiplier - 1) + << DPLL_MD_UDI_MULTIPLIER_SHIFT; + crtc->config.dpll_hw_state.dpll_md = dpll_md; + +- I915_WRITE(DPLL_MD(pipe), dpll_md); +- POSTING_READ(DPLL_MD(pipe)); +- + if (crtc->config.has_dp_encoder) + intel_dp_set_m_n(crtc); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0457-drm-i915-Fix-up-cpt-pixel-multiplier-enable-sequence.patch b/patches.baytrail/0457-drm-i915-Fix-up-cpt-pixel-multiplier-enable-sequence.patch new file mode 100644 index 000000000000..21aa99d063f6 --- /dev/null +++ b/patches.baytrail/0457-drm-i915-Fix-up-cpt-pixel-multiplier-enable-sequence.patch @@ -0,0 +1,63 @@ +From e966974d3ccc47ddd2b6f2bc372c50bb79b0ccec Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:32 +0200 +Subject: drm/i915: Fix up cpt pixel multiplier enable sequence + +Bspec for the "DPLL HDMI multiplier" field says: + +"Restriction : The DPLL must be enabled and stable before setting these bits. +These bits must be programmed after DPLL_SEL is programmed." + +There is apparently no restriction on programming the DPLL_SEL +register wrt the DPLL. So let's just move that up before we enable the +pch dpll. + +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 3ad8a208abbe1bdfe31512053a81ac4938aed447) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index ddf3d3292eb6..0448b4899ea4 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3004,15 +3004,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) + /* For PCH output, training FDI link */ + dev_priv->display.fdi_link_train(crtc); + +- /* XXX: pch pll's can be enabled any time before we enable the PCH +- * transcoder, and we actually should do this to not upset any PCH +- * transcoder that already use the clock when we share it. +- * +- * Note that enable_shared_dpll tries to do the right thing, but +- * get_shared_dpll unconditionally resets the pll - we need that to have +- * the right LVDS enable sequence. */ +- ironlake_enable_shared_dpll(intel_crtc); +- ++ /* We need to program the right clock selection before writing the pixel ++ * mutliplier into the DPLL. */ + if (HAS_PCH_CPT(dev)) { + u32 sel; + +@@ -3026,6 +3019,15 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) + I915_WRITE(PCH_DPLL_SEL, temp); + } + ++ /* XXX: pch pll's can be enabled any time before we enable the PCH ++ * transcoder, and we actually should do this to not upset any PCH ++ * transcoder that already use the clock when we share it. ++ * ++ * Note that enable_shared_dpll tries to do the right thing, but ++ * get_shared_dpll unconditionally resets the pll - we need that to have ++ * the right LVDS enable sequence. */ ++ ironlake_enable_shared_dpll(intel_crtc); ++ + /* set transcoder timing, panel must allow it */ + assert_panel_unlocked(dev_priv, pipe); + ironlake_pch_transcoder_set_timings(intel_crtc, pipe); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0458-drm-i915-clear-DPLL-reg-when-disabling-i9xx-dplls.patch b/patches.baytrail/0458-drm-i915-clear-DPLL-reg-when-disabling-i9xx-dplls.patch new file mode 100644 index 000000000000..bb4742637f19 --- /dev/null +++ b/patches.baytrail/0458-drm-i915-clear-DPLL-reg-when-disabling-i9xx-dplls.patch @@ -0,0 +1,73 @@ +From febaa69de1410d2360f8f9c7f7a0a21e8c074dfd Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 5 Jun 2013 13:34:33 +0200 +Subject: drm/i915: clear DPLL reg when disabling i9xx dplls + +Toghether with the hw state readout this should catch cases where we +don't properly updated the pll state (either in sw or hw). At least +for the shared dpll code the equivalent tricke helped a lot in +catching bugs. + +Also rename the function prefix, it's not a generic piece of +infrastructure. + +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 50b44a449ff1a19712ebc36ffccf9ac0a68033bf) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 16 +++++----------- + 1 file changed, 5 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 0448b4899ea4..5363ff059ec9 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1406,7 +1406,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc) + } + + /** +- * intel_disable_pll - disable a PLL ++ * i9xx_disable_pll - disable a PLL + * @dev_priv: i915 private structure + * @pipe: pipe PLL to disable + * +@@ -1414,11 +1414,8 @@ static void i9xx_enable_pll(struct intel_crtc *crtc) + * + * Note! This is for pre-ILK only. + */ +-static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) ++static void i9xx_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) + { +- int reg; +- u32 val; +- + /* Don't disable pipe A or pipe A PLLs if needed */ + if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) + return; +@@ -1426,11 +1423,8 @@ static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) + /* Make sure the pipe isn't still relying on us */ + assert_pipe_disabled(dev_priv, pipe); + +- reg = DPLL(pipe); +- val = I915_READ(reg); +- val &= ~DPLL_VCO_ENABLE; +- I915_WRITE(reg, val); +- POSTING_READ(reg); ++ I915_WRITE(DPLL(pipe), 0); ++ POSTING_READ(DPLL(pipe)); + } + + void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port) +@@ -3782,7 +3776,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) + if (encoder->post_disable) + encoder->post_disable(encoder); + +- intel_disable_pll(dev_priv, pipe); ++ i9xx_disable_pll(dev_priv, pipe); + + intel_crtc->active = false; + intel_update_fbc(dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0459-drm-i915-hsw-Set-correct-Haswell-PTE-encodings.patch b/patches.baytrail/0459-drm-i915-hsw-Set-correct-Haswell-PTE-encodings.patch new file mode 100644 index 000000000000..e130537eba88 --- /dev/null +++ b/patches.baytrail/0459-drm-i915-hsw-Set-correct-Haswell-PTE-encodings.patch @@ -0,0 +1,78 @@ +From 81c6997e1293f4294566100af157f13b4c654428 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 4 Jul 2013 11:02:03 -0700 +Subject: drm/i915/hsw: Set correct Haswell PTE encodings. + +The cacheability controls have changed, and the bits have been +rearranged in general. + +Note that age 0 is the oldest (most likely to get evicted) and age 3 +is the youngest (most likely to stick around for a bit). We've picked +0 for no reason, but atm it shouldn't matter anyway (since we don't +yet try to differentiate between different objects). + +v2: Remove comments for snb/ivb cache leves, that's a separate change. + +v3: Resolve conflicts due to patch series reordering. + +v4: Rebased on top of Kenneth Graunke's ->pte_encode refactoring. + +v5: Removed eLLC bits for separate patch. + +In the internal repository this was: +Signed-off-by: Ben Widawsky +Signed-off-by: Kenneth Graunke +Reviewed-by: Damien Lespiau +[danvet: Add comment about cache ages as requested by Ben provoked due +to a question from Damien.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 0d8ff15e9a15f2b393e53337a107b7a1e5919b6d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_gtt.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 242d0f9bb9e4..5534dd5cea58 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -33,6 +33,7 @@ + + /* PPGTT stuff */ + #define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) ++#define HSW_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0x7f0)) + + #define GEN6_PDE_VALID (1 << 0) + /* gen6+ has bit 11-4 for physical addr bit 39-32 */ +@@ -44,6 +45,14 @@ + #define GEN6_PTE_CACHE_LLC (2 << 1) + #define GEN6_PTE_CACHE_LLC_MLC (3 << 1) + #define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) ++#define HSW_PTE_ADDR_ENCODE(addr) HSW_GTT_ADDR_ENCODE(addr) ++ ++/* Cacheability Control is a 4-bit value. The low three bits are stored in * ++ * bits 3:1 of the PTE, while the fourth bit is stored in bit 11 of the PTE. ++ */ ++#define HSW_CACHEABILITY_CONTROL(bits) ((((bits) & 0x7) << 1) | \ ++ (((bits) & 0x8) << (11 - 3))) ++#define HSW_WB_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x3) + + static gen6_gtt_pte_t gen6_pte_encode(dma_addr_t addr, + enum i915_cache_level level) +@@ -92,10 +101,10 @@ static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr, + enum i915_cache_level level) + { + gen6_gtt_pte_t pte = GEN6_PTE_VALID; +- pte |= GEN6_PTE_ADDR_ENCODE(addr); ++ pte |= HSW_PTE_ADDR_ENCODE(addr); + + if (level != I915_CACHE_NONE) +- pte |= GEN6_PTE_CACHE_LLC; ++ pte |= HSW_WB_LLC_AGE0; + + return pte; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0460-drm-i915-Define-some-of-the-eLLC-magic.patch b/patches.baytrail/0460-drm-i915-Define-some-of-the-eLLC-magic.patch new file mode 100644 index 000000000000..215603f8a54d --- /dev/null +++ b/patches.baytrail/0460-drm-i915-Define-some-of-the-eLLC-magic.patch @@ -0,0 +1,51 @@ +From 6b30fedf8f6c31c1a0744fad8b10d0c0894cb114 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 4 Jul 2013 11:02:04 -0700 +Subject: drm/i915: Define some of the eLLC magic + +The EDRAM present register isn't really defined in the docs. It just +says check to see if it's set to 1. So I haven't defined the 1 value not +knowing what it actually means. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 05e21cc43da5a1a58b34a2cfad13d22bcfeb1f2b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 4 ++-- + drivers/gpu/drm/i915/i915_reg.h | 4 ++++ + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 5846134574f1..a7039e69395b 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -4131,8 +4131,8 @@ i915_gem_init_hw(struct drm_device *dev) + if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt()) + return -EIO; + +- if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1)) +- I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000); ++ if (IS_HASWELL(dev) && (I915_READ(HSW_EDRAM_PRESENT) == 1)) ++ I915_WRITE(HSW_IDICR, I915_READ(HSW_IDICR) | IDIHASHMSK(0xf)); + + if (HAS_PCH_NOP(dev)) { + u32 temp = I915_READ(GEN7_MSG_CTL); +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index b131773190f3..9fb32dfbfeb9 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -4480,6 +4480,10 @@ + #define GT_FIFO_FREE_ENTRIES 0x120008 + #define GT_FIFO_NUM_RESERVED_ENTRIES 20 + ++#define HSW_IDICR 0x9008 ++#define IDIHASHMSK(x) (((x) & 0x3f) << 16) ++#define HSW_EDRAM_PRESENT 0x120010 ++ + #define GEN6_UCGCTL1 0x9400 + # define GEN6_BLBUNIT_CLOCK_GATE_DISABLE (1 << 5) + # define GEN6_CSUNIT_CLOCK_GATE_DISABLE (1 << 7) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0461-drm-i915-store-eLLC-size.patch b/patches.baytrail/0461-drm-i915-store-eLLC-size.patch new file mode 100644 index 000000000000..319d8db09fed --- /dev/null +++ b/patches.baytrail/0461-drm-i915-store-eLLC-size.patch @@ -0,0 +1,90 @@ +From 0da26735bb0eadfe8905c5c59022f1ba36375f1f Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 4 Jul 2013 11:02:05 -0700 +Subject: drm/i915: store eLLC size + +The eLLC cannot be determined by PCIID because as far as we know, even +machines supporting eLLC may not have it enabled, or fused off or +whatever. It's possible this isn't actually true, and at that point we +can switch to a DEV_INFO flag instead. + +I've defined everything where the docs are clear, and left the rest as +magic. + +But we need it before we set the pte_encode function pointers, which +happens really early, in gtt_init. + +The problem with just doing the normal sequence earlier is we don't have +the ability to use forcewake until after the pte functions have been set +up. + +Since all solutions are somewhat ugly (barring rewriting all the init +ordering), I've opted to do the detection really early, and the enabling +later - since the register to detect doesn't require forcewake. + +Signed-off-by: Ben Widawsky +[danvet: Move dev_priv->ellc_size away from the dri1 dungeon to a nice +place right next to the l3 parity stuff. Also squash in the follow-up +commit to read out the eLLC size a bit earlier.] +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter + +(cherry picked from commit 59124506ba5297e48410e410c3bce83784fddf58) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 10 ++++++++++ + drivers/gpu/drm/i915/i915_drv.h | 3 +++ + drivers/gpu/drm/i915/i915_gem.c | 2 +- + 3 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index b290daba28cf..db56ee7f27d5 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1527,6 +1527,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + + intel_early_sanitize_regs(dev); + ++ if (IS_HASWELL(dev) && (I915_READ(HSW_EDRAM_PRESENT) == 1)) { ++ /* The docs do not explain exactly how the calculation can be ++ * made. It is somewhat guessable, but for now, it's always ++ * 128MB. ++ * NB: We can't write IDICR yet because we do not have gt funcs ++ * set up */ ++ dev_priv->ellc_size = 128; ++ DRM_INFO("Found %zuMB of eLLC\n", dev_priv->ellc_size); ++ } ++ + ret = i915_gem_gtt_init(dev); + if (ret) + goto put_bridge; +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index a7fbefaa1c4a..7adf2b45b185 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1152,6 +1152,9 @@ typedef struct drm_i915_private { + + struct intel_l3_parity l3_parity; + ++ /* Cannot be determined by PCIID. You must always read a register. */ ++ size_t ellc_size; ++ + /* gen6+ rps state */ + struct intel_gen6_power_mgmt rps; + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index a7039e69395b..791c238a6b01 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -4131,7 +4131,7 @@ i915_gem_init_hw(struct drm_device *dev) + if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt()) + return -EIO; + +- if (IS_HASWELL(dev) && (I915_READ(HSW_EDRAM_PRESENT) == 1)) ++ if (dev_priv->ellc_size) + I915_WRITE(HSW_IDICR, I915_READ(HSW_IDICR) | IDIHASHMSK(0xf)); + + if (HAS_PCH_NOP(dev)) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0462-drm-i915-Use-eLLC-LLC-by-default-when-available.patch b/patches.baytrail/0462-drm-i915-Use-eLLC-LLC-by-default-when-available.patch new file mode 100644 index 000000000000..22231546c930 --- /dev/null +++ b/patches.baytrail/0462-drm-i915-Use-eLLC-LLC-by-default-when-available.patch @@ -0,0 +1,70 @@ +From a2a4cf92146ca96a4ebc5021348ec8fa7e4326ac Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 4 Jul 2013 11:02:06 -0700 +Subject: drm/i915: Use eLLC/LLC by default when available + +DRI clients really should be using MOCS to get fine grained streaming +cache controls. With that note, I *hope* that this patch doesn't improve +performance overwhelmingly, because if it does - it means there is a +problem elsewhere. + +In any case, the kernel, and old userspace should get some benefit from +this, so let's do it. eLLC is always a good default, and really not +using it is the special case for MOCS. + +References: http://www.intel.com/newsroom/kits/restricted/ha$well!/pdfs/4th_Gen_Intel_Core_PressBriefing_5-29.pdf (page 57) + +Signed-off-by: Ben Widawsky +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 4d15c145a6234d999c0452eec0d275c1fbf0688c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_gtt.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 5534dd5cea58..422273328302 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -53,6 +53,7 @@ + #define HSW_CACHEABILITY_CONTROL(bits) ((((bits) & 0x7) << 1) | \ + (((bits) & 0x8) << (11 - 3))) + #define HSW_WB_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x3) ++#define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb) + + static gen6_gtt_pte_t gen6_pte_encode(dma_addr_t addr, + enum i915_cache_level level) +@@ -109,6 +110,18 @@ static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr, + return pte; + } + ++static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr, ++ enum i915_cache_level level) ++{ ++ gen6_gtt_pte_t pte = GEN6_PTE_VALID; ++ pte |= HSW_PTE_ADDR_ENCODE(addr); ++ ++ if (level != I915_CACHE_NONE) ++ pte |= HSW_WB_ELLC_LLC_AGE0; ++ ++ return pte; ++} ++ + static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt) + { + struct drm_i915_private *dev_priv = ppgtt->dev->dev_private; +@@ -861,7 +874,9 @@ int i915_gem_gtt_init(struct drm_device *dev) + } else { + gtt->gtt_probe = gen6_gmch_probe; + gtt->gtt_remove = gen6_gmch_remove; +- if (IS_HASWELL(dev)) ++ if (IS_HASWELL(dev) && dev_priv->ellc_size) ++ gtt->pte_encode = iris_pte_encode; ++ else if (IS_HASWELL(dev)) + gtt->pte_encode = hsw_pte_encode; + else if (IS_VALLEYVIEW(dev)) + gtt->pte_encode = byt_pte_encode; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0463-drm-i915-debugfs-entries-for-e-LLC.patch b/patches.baytrail/0463-drm-i915-debugfs-entries-for-e-LLC.patch new file mode 100644 index 000000000000..2304451024f2 --- /dev/null +++ b/patches.baytrail/0463-drm-i915-debugfs-entries-for-e-LLC.patch @@ -0,0 +1,55 @@ +From c3eba28ecf9223901660808cc044dd312c8fdc36 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Thu, 4 Jul 2013 11:02:07 -0700 +Subject: drm/i915: debugfs entries for [e]LLC + +To make users life a little easier figuring out what they have on their +system. + +Ideally, I'd really like to report LLC size, but it turned out to be a +bit of a pain. Maybe I'll revisit it in the future. + +Signed-off-by: Ben Widawsky +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 63573eb7ba3d1bdc1db25fe79314609a4189a306) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 86379799dab8..8819f851e996 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1530,6 +1530,19 @@ static int i915_dpio_info(struct seq_file *m, void *data) + return 0; + } + ++static int i915_llc(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ /* Size calculation for LLC is a bit of a pain. Ignore for now. */ ++ seq_printf(m, "LLC: %s\n", yesno(HAS_LLC(dev))); ++ seq_printf(m, "eLLC: %zuMB\n", dev_priv->ellc_size); ++ ++ return 0; ++} ++ + static int + i915_wedged_get(void *data, u64 *val) + { +@@ -1959,6 +1972,7 @@ static struct drm_info_list i915_debugfs_list[] = { + {"i915_swizzle_info", i915_swizzle_info, 0}, + {"i915_ppgtt_info", i915_ppgtt_info, 0}, + {"i915_dpio", i915_dpio_info, 0}, ++ {"i915_llc", i915_llc, 0}, + }; + #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0464-drm-i915-unify-PM-interrupt-preinstall-sequence.patch b/patches.baytrail/0464-drm-i915-unify-PM-interrupt-preinstall-sequence.patch new file mode 100644 index 000000000000..9c7f6b5ffb9e --- /dev/null +++ b/patches.baytrail/0464-drm-i915-unify-PM-interrupt-preinstall-sequence.patch @@ -0,0 +1,121 @@ +From 1ae26ca5c6065f48c418016a20e28fb354f2da76 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 12 Jul 2013 22:43:25 +0200 +Subject: drm/i915: unify PM interrupt preinstall sequence + +Since the addition of VECS we have a slightly different enable +sequence for PM interrupts on ivb/hsw vs snb and vlv. Usually that +will end up in hard to track down surprises. + +Hence unifiy things and since we have copies of this code in 3 places +now, extract it into its own little helper. + +Note that this changes the irq preinstall sequence a bit for snb and +vlv: We now also clear the PM registers in the preinstall hook, in +addition to the PM register clearing/setup already done when actually +enabling rps. So this doesn't fix a bug but simply unifies the code +across all platforms. After the postinstall hook is similarly unified +we can rip out the then redundant PM interrupt setup from the rps +code. + +v3: Rebase on top of the retained double-GTIIR clearing. Also +resurrect the masking/disabling of the gen6+ PM interrupts as spotted +by Ben Widaswky. + +v4: Move the DE interrupt reset code out of gen5_gt_irq_preinstall +back to ironlake_irq_preinstall where it really belongs. Spotted by +Paulo. + +v3: Improve the commit message to more clearly spell out why we want +to unify the code and what exactly changes. + +Cc: Paulo Zanoni +Reviewed-by: Ben Widawsky +[danvet: s/GT/PM/ to fix up a comment which Ben spotted while +reviewing.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit d18ea1b58a5003eb6fca03aff03c4c01321e6cb1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 39 +++++++++++++++++++++------------------ + 1 file changed, 21 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index a710ec29781b..64ff74990db9 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2100,6 +2100,23 @@ static void ibx_irq_preinstall(struct drm_device *dev) + POSTING_READ(SDEIER); + } + ++static void gen5_gt_irq_preinstall(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ /* and GT */ ++ I915_WRITE(GTIMR, 0xffffffff); ++ I915_WRITE(GTIER, 0x0); ++ POSTING_READ(GTIER); ++ ++ if (INTEL_INFO(dev)->gen >= 6) { ++ /* and PM */ ++ I915_WRITE(GEN6_PMIMR, 0xffffffff); ++ I915_WRITE(GEN6_PMIER, 0x0); ++ POSTING_READ(GEN6_PMIER); ++ } ++} ++ + /* drm_dma.h hooks + */ + static void ironlake_irq_preinstall(struct drm_device *dev) +@@ -2110,16 +2127,11 @@ static void ironlake_irq_preinstall(struct drm_device *dev) + + I915_WRITE(HWSTAM, 0xeffe); + +- /* XXX hotplug from PCH */ +- + I915_WRITE(DEIMR, 0xffffffff); + I915_WRITE(DEIER, 0x0); + POSTING_READ(DEIER); + +- /* and GT */ +- I915_WRITE(GTIMR, 0xffffffff); +- I915_WRITE(GTIER, 0x0); +- POSTING_READ(GTIER); ++ gen5_gt_irq_preinstall(dev); + + ibx_irq_preinstall(dev); + } +@@ -2138,15 +2150,7 @@ static void ivybridge_irq_preinstall(struct drm_device *dev) + I915_WRITE(DEIER, 0x0); + POSTING_READ(DEIER); + +- /* and GT */ +- I915_WRITE(GTIMR, 0xffffffff); +- I915_WRITE(GTIER, 0x0); +- POSTING_READ(GTIER); +- +- /* Power management */ +- I915_WRITE(GEN6_PMIMR, 0xffffffff); +- I915_WRITE(GEN6_PMIER, 0x0); +- POSTING_READ(GEN6_PMIER); ++ gen5_gt_irq_preinstall(dev); + + ibx_irq_preinstall(dev); + } +@@ -2167,9 +2171,8 @@ static void valleyview_irq_preinstall(struct drm_device *dev) + /* and GT */ + I915_WRITE(GTIIR, I915_READ(GTIIR)); + I915_WRITE(GTIIR, I915_READ(GTIIR)); +- I915_WRITE(GTIMR, 0xffffffff); +- I915_WRITE(GTIER, 0x0); +- POSTING_READ(GTIER); ++ ++ gen5_gt_irq_preinstall(dev); + + I915_WRITE(DPINVGTT, 0xff); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0465-drm-i915-unify-GT-PM-irq-postinstall-code.patch b/patches.baytrail/0465-drm-i915-unify-GT-PM-irq-postinstall-code.patch new file mode 100644 index 000000000000..e52ccad6158d --- /dev/null +++ b/patches.baytrail/0465-drm-i915-unify-GT-PM-irq-postinstall-code.patch @@ -0,0 +1,233 @@ +From d440c3fb9446923253e27d31fa6fb4e0d64bfe45 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 12 Jul 2013 22:43:26 +0200 +Subject: drm/i915: unify GT/PM irq postinstall code + +Again extract a common helper. For the postinstall hook things are a +bit more complicated since we have more cases on ilk-hsw/vlv here. + +But since vlv was clearly broken by failing to initialize +dev_priv->gt_irq_mask correctly the shared code is clearly justified. + +Also kill the PMIER setting in the async rps enable work. I should +have been save, but also clearly looked rather fragile. PMIER setup is +now all down in the irq pre/postinstall hooks. + +With this we now have the usual interrupt register sequence for GT/PM +irq registers: + +- IER is setup once with all the interrupts we ever need in the + postinstall hook and never touched again. Exceptions are SDEIER, + which is touched in the preinstall hook (when the irq handler isn't + enabled) and then only from the irq handler. And DEIER/VLV_IER with + is used in the irq handler but also written to once in the + postinstall hook. But since that write is essentially what enables + the interrupt and we should always have MSI interrupts we should be + save. In case we ever have non-MSI interrupts we'd be screwed. + +- IIR is cleared in the postinstall hook before we enable/unmask the + respective interrupt sources. Hence we can't steal an interrupt + event an accidentally trigger the spurious interrupt logic in the + core kernel. Note that after some discussion with Ben Widawsky we + think that we actually should clear the IIR registers in the + preinstall hook. But doing that is a much larger patch series. + +- IMR regs are (usually) all masked off. Those are the only regs + changed at runtime, which is all protected by dev_priv->irq_lock. + +This unification also kills the cargo-culted read-modify-write PM +register setup for VECS. Interrupt setup is done without userspace +being able to interfere, so we better know what values we want to put +into those registers. RMW cycles otoh are really good at papering over +races, until stuff magically blows up and no one has a clue why. + +v2: Touch the gen6+ PM interrupt registers only on gen6+. + +v3: Improve the commit message to more clearly spell out why we want +to unify the code and what exactly changes. + +Cc: Ben Widawsky +Cc: Paulo Zanoni +Reviewed-by: Ben Widawsky +[danvet: Add a comment to explain why the l3 parity interrupt is +special.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 0a9a8c91a5f9617d6fa319fe052de38691fb29cb) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 93 +++++++++++++++++++---------------------- + drivers/gpu/drm/i915/intel_pm.c | 4 -- + 2 files changed, 43 insertions(+), 54 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 64ff74990db9..70cd3053fac5 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2242,6 +2242,46 @@ static void ibx_irq_postinstall(struct drm_device *dev) + I915_WRITE(SDEIMR, ~mask); + } + ++static void gen5_gt_irq_postinstall(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ u32 pm_irqs, gt_irqs; ++ ++ pm_irqs = gt_irqs = 0; ++ ++ dev_priv->gt_irq_mask = ~0; ++ if (HAS_L3_GPU_CACHE(dev)) { ++ /* L3 parity interrupt is always unmasked. */ ++ dev_priv->gt_irq_mask = ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT; ++ gt_irqs |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; ++ } ++ ++ gt_irqs |= GT_RENDER_USER_INTERRUPT; ++ if (IS_GEN5(dev)) { ++ gt_irqs |= GT_RENDER_PIPECTL_NOTIFY_INTERRUPT | ++ ILK_BSD_USER_INTERRUPT; ++ } else { ++ gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT; ++ } ++ ++ I915_WRITE(GTIIR, I915_READ(GTIIR)); ++ I915_WRITE(GTIMR, dev_priv->gt_irq_mask); ++ I915_WRITE(GTIER, gt_irqs); ++ POSTING_READ(GTIER); ++ ++ if (INTEL_INFO(dev)->gen >= 6) { ++ pm_irqs |= GEN6_PM_RPS_EVENTS; ++ ++ if (HAS_VEBOX(dev)) ++ pm_irqs |= PM_VEBOX_USER_INTERRUPT; ++ ++ I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); ++ I915_WRITE(GEN6_PMIMR, 0xffffffff); ++ I915_WRITE(GEN6_PMIER, pm_irqs); ++ POSTING_READ(GEN6_PMIER); ++ } ++} ++ + static int ironlake_irq_postinstall(struct drm_device *dev) + { + unsigned long irqflags; +@@ -2252,7 +2292,6 @@ static int ironlake_irq_postinstall(struct drm_device *dev) + DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | + DE_AUX_CHANNEL_A | DE_PIPEB_FIFO_UNDERRUN | + DE_PIPEA_FIFO_UNDERRUN | DE_POISON; +- u32 gt_irqs; + + dev_priv->irq_mask = ~display_mask; + +@@ -2263,21 +2302,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) + DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT); + POSTING_READ(DEIER); + +- dev_priv->gt_irq_mask = ~0; +- +- I915_WRITE(GTIIR, I915_READ(GTIIR)); +- I915_WRITE(GTIMR, dev_priv->gt_irq_mask); +- +- gt_irqs = GT_RENDER_USER_INTERRUPT; +- +- if (IS_GEN6(dev)) +- gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT; +- else +- gt_irqs |= GT_RENDER_PIPECTL_NOTIFY_INTERRUPT | +- ILK_BSD_USER_INTERRUPT; +- +- I915_WRITE(GTIER, gt_irqs); +- POSTING_READ(GTIER); ++ gen5_gt_irq_postinstall(dev); + + ibx_irq_postinstall(dev); + +@@ -2306,8 +2331,6 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) + DE_PLANEA_FLIP_DONE_IVB | + DE_AUX_CHANNEL_A_IVB | + DE_ERR_INT_IVB; +- u32 pm_irqs = GEN6_PM_RPS_EVENTS; +- u32 gt_irqs; + + dev_priv->irq_mask = ~display_mask; + +@@ -2322,30 +2345,7 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) + DE_PIPEA_VBLANK_IVB); + POSTING_READ(DEIER); + +- dev_priv->gt_irq_mask = ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT; +- +- I915_WRITE(GTIIR, I915_READ(GTIIR)); +- I915_WRITE(GTIMR, dev_priv->gt_irq_mask); +- +- gt_irqs = GT_RENDER_USER_INTERRUPT | GT_BSD_USER_INTERRUPT | +- GT_BLT_USER_INTERRUPT | GT_RENDER_L3_PARITY_ERROR_INTERRUPT; +- I915_WRITE(GTIER, gt_irqs); +- POSTING_READ(GTIER); +- +- I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); +- if (HAS_VEBOX(dev)) +- pm_irqs |= PM_VEBOX_USER_INTERRUPT; +- +- /* Our enable/disable rps functions may touch these registers so +- * make sure to set a known state for only the non-RPS bits. +- * The RMW is extra paranoia since this should be called after being set +- * to a known state in preinstall. +- * */ +- I915_WRITE(GEN6_PMIMR, +- (I915_READ(GEN6_PMIMR) | ~GEN6_PM_RPS_EVENTS) & ~pm_irqs); +- I915_WRITE(GEN6_PMIER, +- (I915_READ(GEN6_PMIER) & GEN6_PM_RPS_EVENTS) | pm_irqs); +- POSTING_READ(GEN6_PMIER); ++ gen5_gt_irq_postinstall(dev); + + ibx_irq_postinstall(dev); + +@@ -2355,7 +2355,6 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) + static int valleyview_irq_postinstall(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +- u32 gt_irqs; + u32 enable_mask; + u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV; + unsigned long irqflags; +@@ -2395,13 +2394,7 @@ static int valleyview_irq_postinstall(struct drm_device *dev) + I915_WRITE(VLV_IIR, 0xffffffff); + I915_WRITE(VLV_IIR, 0xffffffff); + +- I915_WRITE(GTIIR, I915_READ(GTIIR)); +- I915_WRITE(GTIMR, dev_priv->gt_irq_mask); +- +- gt_irqs = GT_RENDER_USER_INTERRUPT | GT_BSD_USER_INTERRUPT | +- GT_BLT_USER_INTERRUPT; +- I915_WRITE(GTIER, gt_irqs); +- POSTING_READ(GTIER); ++ gen5_gt_irq_postinstall(dev); + + /* ack & enable invalid PTE error interrupts */ + #if 0 /* FIXME: add support to irq handler for checking these bits */ +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 886da760df06..20c7c77e2b5e 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3319,8 +3319,6 @@ static void gen6_enable_rps(struct drm_device *dev) + + gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8); + +- /* requires MSI enabled */ +- I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) | GEN6_PM_RPS_EVENTS); + spin_lock_irq(&dev_priv->irq_lock); + /* FIXME: Our interrupt enabling sequence is bonghits. + * dev_priv->rps.pm_iir really should be 0 here. */ +@@ -3599,8 +3597,6 @@ static void valleyview_enable_rps(struct drm_device *dev) + + valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay); + +- /* requires MSI enabled */ +- I915_WRITE(GEN6_PMIER, GEN6_PM_RPS_EVENTS); + spin_lock_irq(&dev_priv->irq_lock); + WARN_ON(dev_priv->rps.pm_iir != 0); + I915_WRITE(GEN6_PMIMR, 0); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0466-drm-i915-extract-rps-interrupt-enable-disable-helper.patch b/patches.baytrail/0466-drm-i915-extract-rps-interrupt-enable-disable-helper.patch new file mode 100644 index 000000000000..237093a14316 --- /dev/null +++ b/patches.baytrail/0466-drm-i915-extract-rps-interrupt-enable-disable-helper.patch @@ -0,0 +1,158 @@ +From 8d69e66e6e90841bf12223765e74531f45195407 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 12 Jul 2013 22:43:27 +0200 +Subject: drm/i915: extract rps interrupt enable/disable helpers + +The VECS enabling required some changes to how rps interrupts are +enabled/disabled since VECS interrupts are handling with the PM +interrupt registers. + +But now that the pre/postinstall sequences is identical for all +platforms with rps support (snb, ivb, hsw, vlv) we can also use the +exact same sequence to actually enable the rps interrupts. Strictly +speaking using spinlocks is overkill on snb/ivb & vlv since they have +no VECS ring, but imo that's more than made up by the common code. + +Hence this just unifies the vlv code with the snb-hsw code which +matched exactly before the VECS enabling. See + +commit eda63ffb906c2fb3b609a0e87aeb63c0f25b9e6b +Author: Ben Widawsky +Date: Tue May 28 19:22:26 2013 -0700 + + drm/i915: Add PM regs to pre/post install + +and + +commit 4848405cced3b46f4ec7d404b8ed5873171ae10a +Author: Ben Widawsky +Date: Tue May 28 19:22:27 2013 -0700 + + drm/i915: make PM interrupt writes non-destructive + +for why the gen6 code (shared between snb, ivb and hsw) needed to be +changed originally. + +v3: Improve the commit message to more clearly spell out why we want +to unify the code and what exactly changes. + +Cc: Paulo Zanoni +Cc: Ben Widawsky +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 44fc7d5cf30723563558715f0794c8389a5c15ba) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 59 ++++++++++++++++++++--------------------- + 1 file changed, 29 insertions(+), 30 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 20c7c77e2b5e..f3ae27291701 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3121,13 +3121,10 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) + trace_intel_gpu_freq_change(vlv_gpu_freq(dev_priv->mem_freq, val)); + } + +- +-static void gen6_disable_rps(struct drm_device *dev) ++static void gen6_disable_rps_interrupts(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + +- I915_WRITE(GEN6_RC_CONTROL, 0); +- I915_WRITE(GEN6_RPNSWREQ, 1 << 31); + I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); + I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) & ~GEN6_PM_RPS_EVENTS); + /* Complete PM interrupt masking here doesn't race with the rps work +@@ -3142,23 +3139,23 @@ static void gen6_disable_rps(struct drm_device *dev) + I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); + } + +-static void valleyview_disable_rps(struct drm_device *dev) ++static void gen6_disable_rps(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + + I915_WRITE(GEN6_RC_CONTROL, 0); +- I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); +- I915_WRITE(GEN6_PMIER, 0); +- /* Complete PM interrupt masking here doesn't race with the rps work +- * item again unmasking PM interrupts because that is using a different +- * register (PMIMR) to mask PM interrupts. The only risk is in leaving +- * stale bits in PMIIR and PMIMR which gen6_enable_rps will clean up. */ ++ I915_WRITE(GEN6_RPNSWREQ, 1 << 31); + +- spin_lock_irq(&dev_priv->irq_lock); +- dev_priv->rps.pm_iir = 0; +- spin_unlock_irq(&dev_priv->irq_lock); ++ gen6_disable_rps_interrupts(dev); ++} ++ ++static void valleyview_disable_rps(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ I915_WRITE(GEN6_RC_CONTROL, 0); + +- I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); ++ gen6_disable_rps_interrupts(dev); + + if (dev_priv->vlv_pctx) { + drm_gem_object_unreference(&dev_priv->vlv_pctx->base); +@@ -3191,6 +3188,21 @@ int intel_enable_rc6(const struct drm_device *dev) + return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE); + } + ++static void gen6_enable_rps_interrupts(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ spin_lock_irq(&dev_priv->irq_lock); ++ /* FIXME: Our interrupt enabling sequence is bonghits. ++ * dev_priv->rps.pm_iir really should be 0 here. */ ++ dev_priv->rps.pm_iir = 0; ++ I915_WRITE(GEN6_PMIMR, I915_READ(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS); ++ I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); ++ spin_unlock_irq(&dev_priv->irq_lock); ++ /* unmask all PM interrupts */ ++ I915_WRITE(GEN6_PMINTRMSK, 0); ++} ++ + static void gen6_enable_rps(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -3319,15 +3331,7 @@ static void gen6_enable_rps(struct drm_device *dev) + + gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8); + +- spin_lock_irq(&dev_priv->irq_lock); +- /* FIXME: Our interrupt enabling sequence is bonghits. +- * dev_priv->rps.pm_iir really should be 0 here. */ +- dev_priv->rps.pm_iir = 0; +- I915_WRITE(GEN6_PMIMR, I915_READ(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS); +- I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); +- spin_unlock_irq(&dev_priv->irq_lock); +- /* unmask all PM interrupts */ +- I915_WRITE(GEN6_PMINTRMSK, 0); ++ gen6_enable_rps_interrupts(dev); + + rc6vids = 0; + ret = sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids); +@@ -3597,12 +3601,7 @@ static void valleyview_enable_rps(struct drm_device *dev) + + valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay); + +- spin_lock_irq(&dev_priv->irq_lock); +- WARN_ON(dev_priv->rps.pm_iir != 0); +- I915_WRITE(GEN6_PMIMR, 0); +- spin_unlock_irq(&dev_priv->irq_lock); +- /* enable all PM interrupts */ +- I915_WRITE(GEN6_PMINTRMSK, 0); ++ gen6_enable_rps_interrupts(dev); + + gen6_gt_force_wake_put(dev_priv); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0467-drm-i915-simplify-rps-interrupt-enabling-disabling-s.patch b/patches.baytrail/0467-drm-i915-simplify-rps-interrupt-enabling-disabling-s.patch new file mode 100644 index 000000000000..be0293be6979 --- /dev/null +++ b/patches.baytrail/0467-drm-i915-simplify-rps-interrupt-enabling-disabling-s.patch @@ -0,0 +1,55 @@ +From 89aad62e712a481d4d311b6846e2845638a88cfb Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 4 Jul 2013 23:35:34 +0200 +Subject: drm/i915: simplify rps interrupt enabling/disabling sequence + +At the moment we have the following interrupt enabling sequence: +1. irq preinstall hook +2. enabling the interrupt handler and calling irq postinstall hook +3. enable rps interrupts from the async work + +And the folliwing disable sequence: +1. disabling the interrupt handler and calling the uninstall hook +2. disabling the rps interrupt + +Since the postinstall hook now always sets up PMIIR, PMIER and PMIMR +to known-good states there no way for an interrupt to sneak in in the +enable sequence, so we can reinstate the WARN lost in + +commit eda63ffb906c2fb3b609a0e87aeb63c0f25b9e6b +Author: Ben Widawsky +Date: Tue May 28 19:22:26 2013 -0700 + + drm/i915: Add PM regs to pre/post install + +Note that there's some room for future cleanups since most of the +interrupt register clearing in the disable function is rather +redundant. But that's better done in follow-up patches, if at all. + +Cc: Ben Widawsky +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit a0b3335a2141aadb8f2398ade97fe574f2ddc875) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index f3ae27291701..19646d3aa052 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3193,9 +3193,7 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + + spin_lock_irq(&dev_priv->irq_lock); +- /* FIXME: Our interrupt enabling sequence is bonghits. +- * dev_priv->rps.pm_iir really should be 0 here. */ +- dev_priv->rps.pm_iir = 0; ++ WARN_ON(dev_priv->rps.pm_iir); + I915_WRITE(GEN6_PMIMR, I915_READ(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS); + I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); + spin_unlock_irq(&dev_priv->irq_lock); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0468-drm-i915-We-implement-WaFbcWaitForVBlankBeforeEnable.patch b/patches.baytrail/0468-drm-i915-We-implement-WaFbcWaitForVBlankBeforeEnable.patch new file mode 100644 index 000000000000..52f598287d08 --- /dev/null +++ b/patches.baytrail/0468-drm-i915-We-implement-WaFbcWaitForVBlankBeforeEnable.patch @@ -0,0 +1,33 @@ +From 77516eaf1c5aee58fef3981d8ac480401801a3f4 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Fri, 7 Jun 2013 17:41:07 +0100 +Subject: drm/i915: We implement WaFbcWaitForVBlankBeforeEnable for ilk and snb + +We also wait for that blank on other platforms but the w/a doesn't +apply there. Not an issue at all. + +Signed-off-by: Damien Lespiau +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 7457d61748f7939dea49849db442cb3df4c7c3fe) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 19646d3aa052..abd216d6cde3 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -404,6 +404,8 @@ static void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) + * following the termination of the page-flipping sequence + * and indeed performing the enable as a co-routine and not + * waiting synchronously upon the vblank. ++ * ++ * WaFbcWaitForVBlankBeforeEnable:ilk,snb + */ + schedule_delayed_work(&work->work, msecs_to_jiffies(50)); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0469-drm-i915-We-implement-WaFbcAsynchFlipDisableFbcQueue.patch b/patches.baytrail/0469-drm-i915-We-implement-WaFbcAsynchFlipDisableFbcQueue.patch new file mode 100644 index 000000000000..14d41d16303c --- /dev/null +++ b/patches.baytrail/0469-drm-i915-We-implement-WaFbcAsynchFlipDisableFbcQueue.patch @@ -0,0 +1,42 @@ +From 8d1ab59df9e8a19abc331c73180269222c8cf96c Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Fri, 14 Jun 2013 15:23:24 +0100 +Subject: drm/i915: We implement WaFbcAsynchFlipDisableFbcQueue on ilk and snb + +v2: Put the comment a bit closer to the actual write (Paulo Zanoni) + +Reviewed-by: Paulo Zanoni +Signed-off-by: Damien Lespiau +[danvet: Fix space before tab.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 4bb353343dcc2486a1deda87f4c069153dc353c3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index abd216d6cde3..cc5883215df4 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4453,6 +4453,7 @@ static void ironlake_init_clock_gating(struct drm_device *dev) + * The bit 7,8,9 of 0x42020. + */ + if (IS_IRONLAKE_M(dev)) { ++ /* WaFbcAsynchFlipDisableFbcQueue:ilk */ + I915_WRITE(ILK_DISPLAY_CHICKEN1, + I915_READ(ILK_DISPLAY_CHICKEN1) | + ILK_FBCQ_DIS); +@@ -4589,6 +4590,8 @@ static void gen6_init_clock_gating(struct drm_device *dev) + * The bit5 and bit7 of 0x42020 + * The bit14 of 0x70180 + * The bit14 of 0x71180 ++ * ++ * WaFbcAsynchFlipDisableFbcQueue:snb + */ + I915_WRITE(ILK_DISPLAY_CHICKEN1, + I915_READ(ILK_DISPLAY_CHICKEN1) | +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0470-drm-i915-We-implement-WaFbcDisableDpfcClockGating-on.patch b/patches.baytrail/0470-drm-i915-We-implement-WaFbcDisableDpfcClockGating-on.patch new file mode 100644 index 000000000000..e9b820a4b1cc --- /dev/null +++ b/patches.baytrail/0470-drm-i915-We-implement-WaFbcDisableDpfcClockGating-on.patch @@ -0,0 +1,33 @@ +From 253338ee832f1975a5802417448206c528043593 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Fri, 7 Jun 2013 17:41:09 +0100 +Subject: drm/i915: We implement WaFbcDisableDpfcClockGating on ilk + +Signed-off-by: Damien Lespiau +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit f1e8fa56fd650e0a23f64afdf59f3907d9a89615) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index cc5883215df4..7c7e0cd40295 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4416,7 +4416,10 @@ static void ironlake_init_clock_gating(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; + +- /* Required for FBC */ ++ /* ++ * Required for FBC ++ * WaFbcDisableDpfcClockGating:ilk ++ */ + dspclk_gate |= ILK_DPFCRUNIT_CLOCK_GATE_DISABLE | + ILK_DPFCUNIT_CLOCK_GATE_DISABLE | + ILK_DPFDUNIT_CLOCK_GATE_ENABLE; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0471-drm-i915-We-implement-WaMPhyProgramming-on-Haswell.patch b/patches.baytrail/0471-drm-i915-We-implement-WaMPhyProgramming-on-Haswell.patch new file mode 100644 index 000000000000..49ce96652182 --- /dev/null +++ b/patches.baytrail/0471-drm-i915-We-implement-WaMPhyProgramming-on-Haswell.patch @@ -0,0 +1,33 @@ +From 1c28bae6e1cf1449a6f8ef34999ea7c8963d979c Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Fri, 7 Jun 2013 17:41:10 +0100 +Subject: drm/i915: We implement WaMPhyProgramming on Haswell + +Signed-off-by: Damien Lespiau +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 19bc678a6066d4ecca938c50ac2f9e9ccfb0ddbe) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 5363ff059ec9..e11d7426328f 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5163,7 +5163,10 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) + BUG_ON(val != final); + } + +-/* Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O. */ ++/* ++ * Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O. ++ * WaMPhyProgramming:hsw ++ */ + static void lpt_init_pch_refclk(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0472-drm-i915-Don-t-try-to-calculate-RC6-residency-on-GEN.patch b/patches.baytrail/0472-drm-i915-Don-t-try-to-calculate-RC6-residency-on-GEN.patch new file mode 100644 index 000000000000..53661fa54727 --- /dev/null +++ b/patches.baytrail/0472-drm-i915-Don-t-try-to-calculate-RC6-residency-on-GEN.patch @@ -0,0 +1,35 @@ +From ddf5ba89918a5441e160c67591dad60752afa2c6 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Fri, 7 Jun 2013 17:41:14 +0100 +Subject: drm/i915: Don't try to calculate RC6 residency on GEN4 and before + +intel_enable_rc6() is used to check if we can compute the RC6 residency +in the sysfs code. Disable this for platforms older than Ironlake. + +Signed-off-by: Damien Lespiau +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit eb4926e4a6e3922398fd6880f07a84db95aa3741) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 7c7e0cd40295..948c171d7f73 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3167,6 +3167,10 @@ static void valleyview_disable_rps(struct drm_device *dev) + + int intel_enable_rc6(const struct drm_device *dev) + { ++ /* No RC6 before Ironlake */ ++ if (INTEL_INFO(dev)->gen < 5) ++ return 0; ++ + /* Respect the kernel parameter if it is set */ + if (i915_enable_rc6 >= 0) + return i915_enable_rc6; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0473-drm-i915-Fix-retrieval-of-hangcheck-stats.patch b/patches.baytrail/0473-drm-i915-Fix-retrieval-of-hangcheck-stats.patch new file mode 100644 index 000000000000..94b025d14c16 --- /dev/null +++ b/patches.baytrail/0473-drm-i915-Fix-retrieval-of-hangcheck-stats.patch @@ -0,0 +1,80 @@ +From 93fda4f8e7ba96edfcdd01a5cfc955a9a1c0b0e2 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 3 Jul 2013 17:22:06 +0300 +Subject: drm/i915: Fix retrieval of hangcheck stats + +The default context is always supported (as it contains the global +hangcheck stats) and the contexts for hangcheck are not limited +to any ring. + +References: https://bugs.freedesktop.org/show_bug.cgi?id=65845 +Signed-off-by: Chris Wilson +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 11fa3384042f5578e0f6179eef70cbcb2892be92) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 +- + drivers/gpu/drm/i915/i915_gem_context.c | 23 ++++++++--------------- + 2 files changed, 9 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 7adf2b45b185..dae1bf60d068 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1864,7 +1864,7 @@ static inline void i915_gem_context_unreference(struct i915_hw_context *ctx) + } + + struct i915_ctx_hang_stats * __must_check +-i915_gem_context_get_hang_stats(struct intel_ring_buffer *ring, ++i915_gem_context_get_hang_stats(struct drm_device *dev, + struct drm_file *file, + u32 id); + int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index 2074544682cf..2470206a4d07 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -304,31 +304,24 @@ static int context_idr_cleanup(int id, void *p, void *data) + } + + struct i915_ctx_hang_stats * +-i915_gem_context_get_hang_stats(struct intel_ring_buffer *ring, ++i915_gem_context_get_hang_stats(struct drm_device *dev, + struct drm_file *file, + u32 id) + { +- struct drm_i915_private *dev_priv = ring->dev->dev_private; ++ struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_file_private *file_priv = file->driver_priv; +- struct i915_hw_context *to; +- +- if (dev_priv->hw_contexts_disabled) +- return ERR_PTR(-ENOENT); +- +- if (ring->id != RCS) +- return ERR_PTR(-EINVAL); +- +- if (file == NULL) +- return ERR_PTR(-EINVAL); ++ struct i915_hw_context *ctx; + + if (id == DEFAULT_CONTEXT_ID) + return &file_priv->hang_stats; + +- to = i915_gem_context_get(file->driver_priv, id); +- if (to == NULL) ++ ctx = NULL; ++ if (!dev_priv->hw_contexts_disabled) ++ ctx = i915_gem_context_get(file->driver_priv, id); ++ if (ctx == NULL) + return ERR_PTR(-ENOENT); + +- return &to->hang_stats; ++ return &ctx->hang_stats; + } + + void i915_gem_context_close(struct drm_device *dev, struct drm_file *file) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0474-drm-i915-Replace-open-coding-of-DEFAULT_CONTEXT_ID.patch b/patches.baytrail/0474-drm-i915-Replace-open-coding-of-DEFAULT_CONTEXT_ID.patch new file mode 100644 index 000000000000..f7c95760cc3d --- /dev/null +++ b/patches.baytrail/0474-drm-i915-Replace-open-coding-of-DEFAULT_CONTEXT_ID.patch @@ -0,0 +1,52 @@ +From 4e3d6c24c1064ef08aceb1f8913c82a14aa7ac7e Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 3 Jul 2013 17:22:07 +0300 +Subject: drm/i915: Replace open-coding of DEFAULT_CONTEXT_ID + +The intent of the check is made more clear if we use the proper name for +0 here. + +Signed-off-by: Chris Wilson +Reviewed-by: Mika Kuoppala +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit e85209698649be30cb1389966f29107d63f16940) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 64eda4463b70..1b58694d7be7 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -873,7 +873,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + break; + case I915_EXEC_BSD: + ring = &dev_priv->ring[VCS]; +- if (ctx_id != 0) { ++ if (ctx_id != DEFAULT_CONTEXT_ID) { + DRM_DEBUG("Ring %s doesn't support contexts\n", + ring->name); + return -EPERM; +@@ -881,7 +881,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + break; + case I915_EXEC_BLT: + ring = &dev_priv->ring[BCS]; +- if (ctx_id != 0) { ++ if (ctx_id != DEFAULT_CONTEXT_ID) { + DRM_DEBUG("Ring %s doesn't support contexts\n", + ring->name); + return -EPERM; +@@ -889,7 +889,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + break; + case I915_EXEC_VEBOX: + ring = &dev_priv->ring[VECS]; +- if (ctx_id != 0) { ++ if (ctx_id != DEFAULT_CONTEXT_ID) { + DRM_DEBUG("Ring %s doesn't support contexts\n", + ring->name); + return -EPERM; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0475-drm-i915-introduce-i915_queue_hangcheck.patch b/patches.baytrail/0475-drm-i915-introduce-i915_queue_hangcheck.patch new file mode 100644 index 000000000000..60a40b40a26d --- /dev/null +++ b/patches.baytrail/0475-drm-i915-introduce-i915_queue_hangcheck.patch @@ -0,0 +1,95 @@ +From 984bf9a3ba2731044bbb1cdc0bd70caeb4172108 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Wed, 3 Jul 2013 17:22:08 +0300 +Subject: drm/i915: introduce i915_queue_hangcheck + +To run hangcheck in near future. + +Signed-off-by: Mika Kuoppala +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 10cd45b6e8ac1d1a99f6bdf0e0c80f2a1351f3f5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/i915_gem.c | 6 ++---- + drivers/gpu/drm/i915/i915_irq.c | 21 ++++++++++++--------- + 3 files changed, 15 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index dae1bf60d068..fc7b1105b47a 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1623,6 +1623,7 @@ extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); + extern void intel_console_resume(struct work_struct *work); + + /* i915_irq.c */ ++void i915_queue_hangcheck(struct drm_device *dev); + void i915_hangcheck_elapsed(unsigned long data); + void i915_handle_error(struct drm_device *dev, bool wedged); + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 791c238a6b01..e2370a2ef1ae 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2087,10 +2087,8 @@ int __i915_add_request(struct intel_ring_buffer *ring, + ring->outstanding_lazy_request = 0; + + if (!dev_priv->ums.mm_suspended) { +- if (i915_enable_hangcheck) { +- mod_timer(&dev_priv->gpu_error.hangcheck_timer, +- round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES)); +- } ++ i915_queue_hangcheck(ring->dev); ++ + if (was_empty) { + queue_delayed_work(dev_priv->wq, + &dev_priv->mm.retire_work, +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 70cd3053fac5..55086078cdc4 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -698,18 +698,13 @@ static void ironlake_rps_change_irq_handler(struct drm_device *dev) + static void notify_ring(struct drm_device *dev, + struct intel_ring_buffer *ring) + { +- struct drm_i915_private *dev_priv = dev->dev_private; +- + if (ring->obj == NULL) + return; + + trace_i915_gem_request_complete(ring, ring->get_seqno(ring, false)); + + wake_up_all(&ring->irq_queue); +- if (i915_enable_hangcheck) { +- mod_timer(&dev_priv->gpu_error.hangcheck_timer, +- round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES)); +- } ++ i915_queue_hangcheck(dev); + } + + static void gen6_pm_rps_work(struct work_struct *work) +@@ -2076,9 +2071,17 @@ void i915_hangcheck_elapsed(unsigned long data) + if (busy_count) + /* Reset timer case chip hangs without another request + * being added */ +- mod_timer(&dev_priv->gpu_error.hangcheck_timer, +- round_jiffies_up(jiffies + +- DRM_I915_HANGCHECK_JIFFIES)); ++ i915_queue_hangcheck(dev); ++} ++ ++void i915_queue_hangcheck(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ if (!i915_enable_hangcheck) ++ return; ++ ++ mod_timer(&dev_priv->gpu_error.hangcheck_timer, ++ round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES)); + } + + static void ibx_irq_preinstall(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0476-drm-i915-Move-gtt-and-ppgtt-under-address-space-umbr.patch b/patches.baytrail/0476-drm-i915-Move-gtt-and-ppgtt-under-address-space-umbr.patch new file mode 100644 index 000000000000..1b25d5f1c694 --- /dev/null +++ b/patches.baytrail/0476-drm-i915-Move-gtt-and-ppgtt-under-address-space-umbr.patch @@ -0,0 +1,638 @@ +From e08dbc07fcc5b2ba9439f5ecf34f3e19994383ac Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 16 Jul 2013 16:50:05 -0700 +Subject: drm/i915: Move gtt and ppgtt under address space umbrella + +The GTT and PPGTT can be thought of more generally as GPU address +spaces. Many of their actions (insert entries), state (LRU lists), and +many of their characteristics (size) can be shared. Do that. + +The change itself doesn't actually impact most of the VMA/VM rework +coming up, it just fits in with the grand scheme of abstracting the GPU +VM operations. GGTT will usually be a special case where we either know +an object must be in the GGTT (dislay engine, workarounds, etc.). + +The scratch page is left as part of the VM (even though it's currently +shared with the ppgtt code) because in the future when we have Full +PPGTT, I intend to create a separate scratch page for each. + +v2: Drop usage of i915_gtt_vm (Daniel) +Make cleanup also part of the parent class (Ben) +Modified commit msg +Rebased + +v3: Properly share scratch page (Imre) +Finish commit message (Daniel, Imre) + +Signed-off-by: Ben Widawsky +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 853ba5d2231619e1c7f7de1269e135174ec8e3cb) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 4 +- + drivers/gpu/drm/i915/i915_dma.c | 4 +- + drivers/gpu/drm/i915/i915_drv.h | 57 ++++++------- + drivers/gpu/drm/i915/i915_gem.c | 4 +- + drivers/gpu/drm/i915/i915_gem_gtt.c | 165 ++++++++++++++++++++---------------- + 5 files changed, 123 insertions(+), 111 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 8819f851e996..1c697c0ab7e5 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -276,8 +276,8 @@ static int i915_gem_object_info(struct seq_file *m, void *data) + count, size); + + seq_printf(m, "%zu [%lu] gtt total\n", +- dev_priv->gtt.total, +- dev_priv->gtt.mappable_end - dev_priv->gtt.start); ++ dev_priv->gtt.base.total, ++ dev_priv->gtt.mappable_end - dev_priv->gtt.base.start); + + seq_putc(m, '\n'); + list_for_each_entry_reverse(file, &dev->filelist, lhead) { +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index db56ee7f27d5..146890cacabe 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1675,7 +1675,7 @@ out_gem_unload: + out_mtrrfree: + arch_phys_wc_del(dev_priv->gtt.mtrr); + io_mapping_free(dev_priv->gtt.mappable); +- dev_priv->gtt.gtt_remove(dev); ++ dev_priv->gtt.base.cleanup(&dev_priv->gtt.base); + out_rmmap: + pci_iounmap(dev->pdev, dev_priv->regs); + put_bridge: +@@ -1770,7 +1770,7 @@ int i915_driver_unload(struct drm_device *dev) + destroy_workqueue(dev_priv->wq); + pm_qos_remove_request(&dev_priv->pm_qos); + +- dev_priv->gtt.gtt_remove(dev); ++ dev_priv->gtt.base.cleanup(&dev_priv->gtt.base); + + if (dev_priv->slab) + kmem_cache_destroy(dev_priv->slab); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index fc7b1105b47a..3ce73b4041ef 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -446,6 +446,29 @@ enum i915_cache_level { + + typedef uint32_t gen6_gtt_pte_t; + ++struct i915_address_space { ++ struct drm_device *dev; ++ unsigned long start; /* Start offset always 0 for dri2 */ ++ size_t total; /* size addr space maps (ex. 2GB for ggtt) */ ++ ++ struct { ++ dma_addr_t addr; ++ struct page *page; ++ } scratch; ++ ++ /* FIXME: Need a more generic return type */ ++ gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr, ++ enum i915_cache_level level); ++ void (*clear_range)(struct i915_address_space *vm, ++ unsigned int first_entry, ++ unsigned int num_entries); ++ void (*insert_entries)(struct i915_address_space *vm, ++ struct sg_table *st, ++ unsigned int first_entry, ++ enum i915_cache_level cache_level); ++ void (*cleanup)(struct i915_address_space *vm); ++}; ++ + /* The Graphics Translation Table is the way in which GEN hardware translates a + * Graphics Virtual Address into a Physical Address. In addition to the normal + * collateral associated with any va->pa translations GEN hardware also has a +@@ -454,8 +477,7 @@ typedef uint32_t gen6_gtt_pte_t; + * the spec. + */ + struct i915_gtt { +- unsigned long start; /* Start offset of used GTT */ +- size_t total; /* Total size GTT can map */ ++ struct i915_address_space base; + size_t stolen_size; /* Total size of stolen memory */ + + unsigned long mappable_end; /* End offset that we can CPU map */ +@@ -466,10 +488,6 @@ struct i915_gtt { + void __iomem *gsm; + + bool do_idle_maps; +- struct { +- dma_addr_t addr; +- struct page *page; +- } scratch; + + int mtrr; + +@@ -477,38 +495,17 @@ struct i915_gtt { + int (*gtt_probe)(struct drm_device *dev, size_t *gtt_total, + size_t *stolen, phys_addr_t *mappable_base, + unsigned long *mappable_end); +- void (*gtt_remove)(struct drm_device *dev); +- void (*gtt_clear_range)(struct drm_device *dev, +- unsigned int first_entry, +- unsigned int num_entries); +- void (*gtt_insert_entries)(struct drm_device *dev, +- struct sg_table *st, +- unsigned int pg_start, +- enum i915_cache_level cache_level); +- gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr, +- enum i915_cache_level level); + }; +-#define gtt_total_entries(gtt) ((gtt).total >> PAGE_SHIFT) ++#define gtt_total_entries(gtt) ((gtt).base.total >> PAGE_SHIFT) + + struct i915_hw_ppgtt { +- struct drm_device *dev; ++ struct i915_address_space base; + unsigned num_pd_entries; + struct page **pt_pages; + uint32_t pd_offset; + dma_addr_t *pt_dma_addr; + +- /* pte functions, mirroring the interface of the global gtt. */ +- void (*clear_range)(struct i915_hw_ppgtt *ppgtt, +- unsigned int first_entry, +- unsigned int num_entries); +- void (*insert_entries)(struct i915_hw_ppgtt *ppgtt, +- struct sg_table *st, +- unsigned int pg_start, +- enum i915_cache_level cache_level); +- gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr, +- enum i915_cache_level level); + int (*enable)(struct drm_device *dev); +- void (*cleanup)(struct i915_hw_ppgtt *ppgtt); + }; + + struct i915_ctx_hang_stats { +@@ -1125,7 +1122,7 @@ typedef struct drm_i915_private { + enum modeset_restore modeset_restore; + struct mutex modeset_restore_lock; + +- struct i915_gtt gtt; ++ struct i915_gtt gtt; /* VMA representing the global address space */ + + struct i915_gem_mm mm; + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index e2370a2ef1ae..cc336bc8d8fe 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -181,7 +181,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, + pinned += i915_gem_obj_ggtt_size(obj); + mutex_unlock(&dev->struct_mutex); + +- args->aper_size = dev_priv->gtt.total; ++ args->aper_size = dev_priv->gtt.base.total; + args->aper_available_size = args->aper_size - pinned; + + return 0; +@@ -3065,7 +3065,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + u32 size, fence_size, fence_alignment, unfenced_alignment; + bool mappable, fenceable; + size_t gtt_max = map_and_fenceable ? +- dev_priv->gtt.mappable_end : dev_priv->gtt.total; ++ dev_priv->gtt.mappable_end : dev_priv->gtt.base.total; + int ret; + + fence_size = i915_gem_get_gtt_size(dev, +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 422273328302..f982bf0de157 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -124,7 +124,7 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr, + + static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt) + { +- struct drm_i915_private *dev_priv = ppgtt->dev->dev_private; ++ struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private; + gen6_gtt_pte_t __iomem *pd_addr; + uint32_t pd_entry; + int i; +@@ -203,18 +203,18 @@ static int gen6_ppgtt_enable(struct drm_device *dev) + } + + /* PPGTT support for Sandybdrige/Gen6 and later */ +-static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, ++static void gen6_ppgtt_clear_range(struct i915_address_space *vm, + unsigned first_entry, + unsigned num_entries) + { +- struct drm_i915_private *dev_priv = ppgtt->dev->dev_private; ++ struct i915_hw_ppgtt *ppgtt = ++ container_of(vm, struct i915_hw_ppgtt, base); + gen6_gtt_pte_t *pt_vaddr, scratch_pte; + unsigned act_pt = first_entry / I915_PPGTT_PT_ENTRIES; + unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; + unsigned last_pte, i; + +- scratch_pte = ppgtt->pte_encode(dev_priv->gtt.scratch.addr, +- I915_CACHE_LLC); ++ scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC); + + while (num_entries) { + last_pte = first_pte + num_entries; +@@ -234,11 +234,13 @@ static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, + } + } + +-static void gen6_ppgtt_insert_entries(struct i915_hw_ppgtt *ppgtt, ++static void gen6_ppgtt_insert_entries(struct i915_address_space *vm, + struct sg_table *pages, + unsigned first_entry, + enum i915_cache_level cache_level) + { ++ struct i915_hw_ppgtt *ppgtt = ++ container_of(vm, struct i915_hw_ppgtt, base); + gen6_gtt_pte_t *pt_vaddr; + unsigned act_pt = first_entry / I915_PPGTT_PT_ENTRIES; + unsigned act_pte = first_entry % I915_PPGTT_PT_ENTRIES; +@@ -249,7 +251,7 @@ static void gen6_ppgtt_insert_entries(struct i915_hw_ppgtt *ppgtt, + dma_addr_t page_addr; + + page_addr = sg_page_iter_dma_address(&sg_iter); +- pt_vaddr[act_pte] = ppgtt->pte_encode(page_addr, cache_level); ++ pt_vaddr[act_pte] = vm->pte_encode(page_addr, cache_level); + if (++act_pte == I915_PPGTT_PT_ENTRIES) { + kunmap_atomic(pt_vaddr); + act_pt++; +@@ -261,13 +263,15 @@ static void gen6_ppgtt_insert_entries(struct i915_hw_ppgtt *ppgtt, + kunmap_atomic(pt_vaddr); + } + +-static void gen6_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt) ++static void gen6_ppgtt_cleanup(struct i915_address_space *vm) + { ++ struct i915_hw_ppgtt *ppgtt = ++ container_of(vm, struct i915_hw_ppgtt, base); + int i; + + if (ppgtt->pt_dma_addr) { + for (i = 0; i < ppgtt->num_pd_entries; i++) +- pci_unmap_page(ppgtt->dev->pdev, ++ pci_unmap_page(ppgtt->base.dev->pdev, + ppgtt->pt_dma_addr[i], + 4096, PCI_DMA_BIDIRECTIONAL); + } +@@ -281,7 +285,7 @@ static void gen6_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt) + + static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) + { +- struct drm_device *dev = ppgtt->dev; ++ struct drm_device *dev = ppgtt->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned first_pd_entry_in_global_pt; + int i; +@@ -293,17 +297,18 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) + first_pd_entry_in_global_pt = gtt_total_entries(dev_priv->gtt); + + if (IS_HASWELL(dev)) { +- ppgtt->pte_encode = hsw_pte_encode; ++ ppgtt->base.pte_encode = hsw_pte_encode; + } else if (IS_VALLEYVIEW(dev)) { +- ppgtt->pte_encode = byt_pte_encode; ++ ppgtt->base.pte_encode = byt_pte_encode; + } else { +- ppgtt->pte_encode = gen6_pte_encode; ++ ppgtt->base.pte_encode = gen6_pte_encode; + } + ppgtt->num_pd_entries = GEN6_PPGTT_PD_ENTRIES; + ppgtt->enable = gen6_ppgtt_enable; +- ppgtt->clear_range = gen6_ppgtt_clear_range; +- ppgtt->insert_entries = gen6_ppgtt_insert_entries; +- ppgtt->cleanup = gen6_ppgtt_cleanup; ++ ppgtt->base.clear_range = gen6_ppgtt_clear_range; ++ ppgtt->base.insert_entries = gen6_ppgtt_insert_entries; ++ ppgtt->base.cleanup = gen6_ppgtt_cleanup; ++ ppgtt->base.scratch = dev_priv->gtt.base.scratch; + ppgtt->pt_pages = kzalloc(sizeof(struct page *)*ppgtt->num_pd_entries, + GFP_KERNEL); + if (!ppgtt->pt_pages) +@@ -334,8 +339,8 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) + ppgtt->pt_dma_addr[i] = pt_addr; + } + +- ppgtt->clear_range(ppgtt, 0, +- ppgtt->num_pd_entries*I915_PPGTT_PT_ENTRIES); ++ ppgtt->base.clear_range(&ppgtt->base, 0, ++ ppgtt->num_pd_entries * I915_PPGTT_PT_ENTRIES); + + ppgtt->pd_offset = first_pd_entry_in_global_pt * sizeof(gen6_gtt_pte_t); + +@@ -368,7 +373,7 @@ static int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) + if (!ppgtt) + return -ENOMEM; + +- ppgtt->dev = dev; ++ ppgtt->base.dev = dev; + + if (INTEL_INFO(dev)->gen < 8) + ret = gen6_ppgtt_init(ppgtt); +@@ -391,7 +396,7 @@ void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev) + if (!ppgtt) + return; + +- ppgtt->cleanup(ppgtt); ++ ppgtt->base.cleanup(&ppgtt->base); + dev_priv->mm.aliasing_ppgtt = NULL; + } + +@@ -399,17 +404,17 @@ void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, + struct drm_i915_gem_object *obj, + enum i915_cache_level cache_level) + { +- ppgtt->insert_entries(ppgtt, obj->pages, +- i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT, +- cache_level); ++ ppgtt->base.insert_entries(&ppgtt->base, obj->pages, ++ i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT, ++ cache_level); + } + + void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, + struct drm_i915_gem_object *obj) + { +- ppgtt->clear_range(ppgtt, +- i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT, +- obj->base.size >> PAGE_SHIFT); ++ ppgtt->base.clear_range(&ppgtt->base, ++ i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT, ++ obj->base.size >> PAGE_SHIFT); + } + + extern int intel_iommu_gfx_mapped; +@@ -456,8 +461,9 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) + struct drm_i915_gem_object *obj; + + /* First fill our portion of the GTT with scratch pages */ +- dev_priv->gtt.gtt_clear_range(dev, dev_priv->gtt.start / PAGE_SIZE, +- dev_priv->gtt.total / PAGE_SIZE); ++ dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, ++ dev_priv->gtt.base.start / PAGE_SIZE, ++ dev_priv->gtt.base.total / PAGE_SIZE); + + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { + i915_gem_clflush_object(obj); +@@ -486,12 +492,12 @@ int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj) + * within the global GTT as well as accessible by the GPU through the GMADR + * mapped BAR (dev_priv->mm.gtt->gtt). + */ +-static void gen6_ggtt_insert_entries(struct drm_device *dev, ++static void gen6_ggtt_insert_entries(struct i915_address_space *vm, + struct sg_table *st, + unsigned int first_entry, + enum i915_cache_level level) + { +- struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = vm->dev->dev_private; + gen6_gtt_pte_t __iomem *gtt_entries = + (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry; + int i = 0; +@@ -500,8 +506,7 @@ static void gen6_ggtt_insert_entries(struct drm_device *dev, + + for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) { + addr = sg_page_iter_dma_address(&sg_iter); +- iowrite32(dev_priv->gtt.pte_encode(addr, level), +- >t_entries[i]); ++ iowrite32(vm->pte_encode(addr, level), >t_entries[i]); + i++; + } + +@@ -512,8 +517,8 @@ static void gen6_ggtt_insert_entries(struct drm_device *dev, + * hardware should work, we must keep this posting read for paranoia. + */ + if (i != 0) +- WARN_ON(readl(>t_entries[i-1]) +- != dev_priv->gtt.pte_encode(addr, level)); ++ WARN_ON(readl(>t_entries[i-1]) != ++ vm->pte_encode(addr, level)); + + /* This next bit makes the above posting read even more important. We + * want to flush the TLBs only after we're certain all the PTE updates +@@ -523,11 +528,11 @@ static void gen6_ggtt_insert_entries(struct drm_device *dev, + POSTING_READ(GFX_FLSH_CNTL_GEN6); + } + +-static void gen6_ggtt_clear_range(struct drm_device *dev, ++static void gen6_ggtt_clear_range(struct i915_address_space *vm, + unsigned int first_entry, + unsigned int num_entries) + { +- struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = vm->dev->dev_private; + gen6_gtt_pte_t scratch_pte, __iomem *gtt_base = + (gen6_gtt_pte_t __iomem *) dev_priv->gtt.gsm + first_entry; + const int max_entries = gtt_total_entries(dev_priv->gtt) - first_entry; +@@ -538,15 +543,14 @@ static void gen6_ggtt_clear_range(struct drm_device *dev, + first_entry, num_entries, max_entries)) + num_entries = max_entries; + +- scratch_pte = dev_priv->gtt.pte_encode(dev_priv->gtt.scratch.addr, +- I915_CACHE_LLC); ++ scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC); + for (i = 0; i < num_entries; i++) + iowrite32(scratch_pte, >t_base[i]); + readl(gtt_base); + } + + +-static void i915_ggtt_insert_entries(struct drm_device *dev, ++static void i915_ggtt_insert_entries(struct i915_address_space *vm, + struct sg_table *st, + unsigned int pg_start, + enum i915_cache_level cache_level) +@@ -558,7 +562,7 @@ static void i915_ggtt_insert_entries(struct drm_device *dev, + + } + +-static void i915_ggtt_clear_range(struct drm_device *dev, ++static void i915_ggtt_clear_range(struct i915_address_space *vm, + unsigned int first_entry, + unsigned int num_entries) + { +@@ -571,10 +575,11 @@ void i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj, + { + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; ++ const unsigned long entry = i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT; + +- dev_priv->gtt.gtt_insert_entries(dev, obj->pages, +- i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT, +- cache_level); ++ dev_priv->gtt.base.insert_entries(&dev_priv->gtt.base, obj->pages, ++ entry, ++ cache_level); + + obj->has_global_gtt_mapping = 1; + } +@@ -583,10 +588,11 @@ void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj) + { + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; ++ const unsigned long entry = i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT; + +- dev_priv->gtt.gtt_clear_range(obj->base.dev, +- i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT, +- obj->base.size >> PAGE_SHIFT); ++ dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, ++ entry, ++ obj->base.size >> PAGE_SHIFT); + + obj->has_global_gtt_mapping = 0; + } +@@ -663,20 +669,23 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + obj->has_global_gtt_mapping = 1; + } + +- dev_priv->gtt.start = start; +- dev_priv->gtt.total = end - start; ++ dev_priv->gtt.base.start = start; ++ dev_priv->gtt.base.total = end - start; + + /* Clear any non-preallocated blocks */ + drm_mm_for_each_hole(entry, &dev_priv->mm.gtt_space, + hole_start, hole_end) { ++ const unsigned long count = (hole_end - hole_start) / PAGE_SIZE; + DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", + hole_start, hole_end); +- dev_priv->gtt.gtt_clear_range(dev, hole_start / PAGE_SIZE, +- (hole_end-hole_start) / PAGE_SIZE); ++ dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, ++ hole_start / PAGE_SIZE, ++ count); + } + + /* And finally clear the reserved guard page */ +- dev_priv->gtt.gtt_clear_range(dev, end / PAGE_SIZE - 1, 1); ++ dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, ++ end / PAGE_SIZE - 1, 1); + } + + static bool +@@ -699,7 +708,7 @@ void i915_gem_init_global_gtt(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long gtt_size, mappable_size; + +- gtt_size = dev_priv->gtt.total; ++ gtt_size = dev_priv->gtt.base.total; + mappable_size = dev_priv->gtt.mappable_end; + + if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) { +@@ -744,8 +753,8 @@ static int setup_scratch_page(struct drm_device *dev) + #else + dma_addr = page_to_phys(page); + #endif +- dev_priv->gtt.scratch.page = page; +- dev_priv->gtt.scratch.addr = dma_addr; ++ dev_priv->gtt.base.scratch.page = page; ++ dev_priv->gtt.base.scratch.addr = dma_addr; + + return 0; + } +@@ -753,11 +762,13 @@ static int setup_scratch_page(struct drm_device *dev) + static void teardown_scratch_page(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- set_pages_wb(dev_priv->gtt.scratch.page, 1); +- pci_unmap_page(dev->pdev, dev_priv->gtt.scratch.addr, ++ struct page *page = dev_priv->gtt.base.scratch.page; ++ ++ set_pages_wb(page, 1); ++ pci_unmap_page(dev->pdev, dev_priv->gtt.base.scratch.addr, + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); +- put_page(dev_priv->gtt.scratch.page); +- __free_page(dev_priv->gtt.scratch.page); ++ put_page(page); ++ __free_page(page); + } + + static inline unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl) +@@ -820,17 +831,18 @@ static int gen6_gmch_probe(struct drm_device *dev, + if (ret) + DRM_ERROR("Scratch setup failed\n"); + +- dev_priv->gtt.gtt_clear_range = gen6_ggtt_clear_range; +- dev_priv->gtt.gtt_insert_entries = gen6_ggtt_insert_entries; ++ dev_priv->gtt.base.clear_range = gen6_ggtt_clear_range; ++ dev_priv->gtt.base.insert_entries = gen6_ggtt_insert_entries; + + return ret; + } + +-static void gen6_gmch_remove(struct drm_device *dev) ++static void gen6_gmch_remove(struct i915_address_space *vm) + { +- struct drm_i915_private *dev_priv = dev->dev_private; +- iounmap(dev_priv->gtt.gsm); +- teardown_scratch_page(dev_priv->dev); ++ ++ struct i915_gtt *gtt = container_of(vm, struct i915_gtt, base); ++ iounmap(gtt->gsm); ++ teardown_scratch_page(vm->dev); + } + + static int i915_gmch_probe(struct drm_device *dev, +@@ -851,13 +863,13 @@ static int i915_gmch_probe(struct drm_device *dev, + intel_gtt_get(gtt_total, stolen, mappable_base, mappable_end); + + dev_priv->gtt.do_idle_maps = needs_idle_maps(dev_priv->dev); +- dev_priv->gtt.gtt_clear_range = i915_ggtt_clear_range; +- dev_priv->gtt.gtt_insert_entries = i915_ggtt_insert_entries; ++ dev_priv->gtt.base.clear_range = i915_ggtt_clear_range; ++ dev_priv->gtt.base.insert_entries = i915_ggtt_insert_entries; + + return 0; + } + +-static void i915_gmch_remove(struct drm_device *dev) ++static void i915_gmch_remove(struct i915_address_space *vm) + { + intel_gmch_remove(); + } +@@ -870,27 +882,30 @@ int i915_gem_gtt_init(struct drm_device *dev) + + if (INTEL_INFO(dev)->gen <= 5) { + gtt->gtt_probe = i915_gmch_probe; +- gtt->gtt_remove = i915_gmch_remove; ++ gtt->base.cleanup = i915_gmch_remove; + } else { + gtt->gtt_probe = gen6_gmch_probe; +- gtt->gtt_remove = gen6_gmch_remove; ++ gtt->base.cleanup = gen6_gmch_remove; + if (IS_HASWELL(dev) && dev_priv->ellc_size) +- gtt->pte_encode = iris_pte_encode; ++ gtt->base.pte_encode = iris_pte_encode; + else if (IS_HASWELL(dev)) +- gtt->pte_encode = hsw_pte_encode; ++ gtt->base.pte_encode = hsw_pte_encode; + else if (IS_VALLEYVIEW(dev)) +- gtt->pte_encode = byt_pte_encode; ++ gtt->base.pte_encode = byt_pte_encode; + else +- gtt->pte_encode = gen6_pte_encode; ++ gtt->base.pte_encode = gen6_pte_encode; + } + +- ret = gtt->gtt_probe(dev, >t->total, >t->stolen_size, ++ ret = gtt->gtt_probe(dev, >t->base.total, >t->stolen_size, + >t->mappable_base, >t->mappable_end); + if (ret) + return ret; + ++ gtt->base.dev = dev; ++ + /* GMADR is the PCI mmio aperture into the global GTT. */ +- DRM_INFO("Memory usable by graphics device = %zdM\n", gtt->total >> 20); ++ DRM_INFO("Memory usable by graphics device = %zdM\n", ++ gtt->base.total >> 20); + DRM_DEBUG_DRIVER("GMADR size = %ldM\n", gtt->mappable_end >> 20); + DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", gtt->stolen_size >> 20); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0477-drm-i915-Put-the-mm-in-the-parent-address-space.patch b/patches.baytrail/0477-drm-i915-Put-the-mm-in-the-parent-address-space.patch new file mode 100644 index 000000000000..75aef1ffdf00 --- /dev/null +++ b/patches.baytrail/0477-drm-i915-Put-the-mm-in-the-parent-address-space.patch @@ -0,0 +1,190 @@ +From f86250e11b7c42d330a84ca7410b435537841a07 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 16 Jul 2013 16:50:06 -0700 +Subject: drm/i915: Put the mm in the parent address space + +Every address space should support object allocation. It therefore makes +sense to have the allocator be part of the "superclass" which GGTT and +PPGTT will derive. + +Since our maximum address space size is only 2GB we're not yet able to +avoid doing allocation/eviction; but we'd hope one day this becomes +almost irrelvant. + +v2: Rebased + +Signed-off-by: Ben Widawsky +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 93bd8649dba3155d1a0ba2a902d9c49f1c75a1da) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 4 ++-- + drivers/gpu/drm/i915/i915_drv.h | 3 +-- + drivers/gpu/drm/i915/i915_gem.c | 2 +- + drivers/gpu/drm/i915/i915_gem_evict.c | 10 +++++----- + drivers/gpu/drm/i915/i915_gem_gtt.c | 17 +++++++++++------ + drivers/gpu/drm/i915/i915_gem_stolen.c | 4 ++-- + 6 files changed, 22 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 146890cacabe..c6d3105516ca 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1358,7 +1358,7 @@ cleanup_gem: + i915_gem_context_fini(dev); + mutex_unlock(&dev->struct_mutex); + i915_gem_cleanup_aliasing_ppgtt(dev); +- drm_mm_takedown(&dev_priv->mm.gtt_space); ++ drm_mm_takedown(&dev_priv->gtt.base.mm); + cleanup_irq: + drm_irq_uninstall(dev); + cleanup_gem_stolen: +@@ -1760,7 +1760,7 @@ int i915_driver_unload(struct drm_device *dev) + i915_free_hws(dev); + } + +- drm_mm_takedown(&dev_priv->mm.gtt_space); ++ drm_mm_takedown(&dev_priv->gtt.base.mm); + if (dev_priv->regs != NULL) + pci_iounmap(dev->pdev, dev_priv->regs); + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 3ce73b4041ef..a6497f520578 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -447,6 +447,7 @@ enum i915_cache_level { + typedef uint32_t gen6_gtt_pte_t; + + struct i915_address_space { ++ struct drm_mm mm; + struct drm_device *dev; + unsigned long start; /* Start offset always 0 for dri2 */ + size_t total; /* size addr space maps (ex. 2GB for ggtt) */ +@@ -832,8 +833,6 @@ struct intel_l3_parity { + struct i915_gem_mm { + /** Memory allocator for GTT stolen memory */ + struct drm_mm stolen; +- /** Memory allocator for GTT */ +- struct drm_mm gtt_space; + /** List of all objects in gtt_space. Used to restore gtt + * mappings on resume */ + struct list_head bound_list; +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index cc336bc8d8fe..b99c73b82ce4 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3107,7 +3107,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + i915_gem_object_pin_pages(obj); + + search_free: +- ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space, ++ ret = drm_mm_insert_node_in_range_generic(&dev_priv->gtt.base.mm, + &obj->gtt_space, + size, alignment, + obj->cache_level, 0, gtt_max); +diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c +index 5f8afc48bb7e..f1c9ab096b00 100644 +--- a/drivers/gpu/drm/i915/i915_gem_evict.c ++++ b/drivers/gpu/drm/i915/i915_gem_evict.c +@@ -78,12 +78,12 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, + + INIT_LIST_HEAD(&unwind_list); + if (mappable) +- drm_mm_init_scan_with_range(&dev_priv->mm.gtt_space, +- min_size, alignment, cache_level, +- 0, dev_priv->gtt.mappable_end); ++ drm_mm_init_scan_with_range(&dev_priv->gtt.base.mm, min_size, ++ alignment, cache_level, 0, ++ dev_priv->gtt.mappable_end); + else +- drm_mm_init_scan(&dev_priv->mm.gtt_space, +- min_size, alignment, cache_level); ++ drm_mm_init_scan(&dev_priv->gtt.base.mm, min_size, alignment, ++ cache_level); + + /* First see if there is a large enough contiguous idle region... */ + list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) { +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index f982bf0de157..999ecfecb32e 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -269,6 +269,8 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm) + container_of(vm, struct i915_hw_ppgtt, base); + int i; + ++ drm_mm_takedown(&ppgtt->base.mm); ++ + if (ppgtt->pt_dma_addr) { + for (i = 0; i < ppgtt->num_pd_entries; i++) + pci_unmap_page(ppgtt->base.dev->pdev, +@@ -382,8 +384,11 @@ static int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) + + if (ret) + kfree(ppgtt); +- else ++ else { + dev_priv->mm.aliasing_ppgtt = ppgtt; ++ drm_mm_init(&ppgtt->base.mm, ppgtt->base.start, ++ ppgtt->base.total); ++ } + + return ret; + } +@@ -651,9 +656,9 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + BUG_ON(mappable_end > end); + + /* Subtract the guard page ... */ +- drm_mm_init(&dev_priv->mm.gtt_space, start, end - start - PAGE_SIZE); ++ drm_mm_init(&dev_priv->gtt.base.mm, start, end - start - PAGE_SIZE); + if (!HAS_LLC(dev)) +- dev_priv->mm.gtt_space.color_adjust = i915_gtt_color_adjust; ++ dev_priv->gtt.base.mm.color_adjust = i915_gtt_color_adjust; + + /* Mark any preallocated objects as occupied */ + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { +@@ -662,7 +667,7 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + i915_gem_obj_ggtt_offset(obj), obj->base.size); + + WARN_ON(i915_gem_obj_ggtt_bound(obj)); +- ret = drm_mm_reserve_node(&dev_priv->mm.gtt_space, ++ ret = drm_mm_reserve_node(&dev_priv->gtt.base.mm, + &obj->gtt_space); + if (ret) + DRM_DEBUG_KMS("Reservation failed\n"); +@@ -673,7 +678,7 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + dev_priv->gtt.base.total = end - start; + + /* Clear any non-preallocated blocks */ +- drm_mm_for_each_hole(entry, &dev_priv->mm.gtt_space, ++ drm_mm_for_each_hole(entry, &dev_priv->gtt.base.mm, + hole_start, hole_end) { + const unsigned long count = (hole_end - hole_start) / PAGE_SIZE; + DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", +@@ -727,7 +732,7 @@ void i915_gem_init_global_gtt(struct drm_device *dev) + return; + + DRM_ERROR("Aliased PPGTT setup failed %d\n", ret); +- drm_mm_takedown(&dev_priv->mm.gtt_space); ++ drm_mm_takedown(&dev_priv->gtt.base.mm); + gtt_size += GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE; + } + i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size); +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 5c1a535d5072..ede8c41399d9 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -399,8 +399,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + */ + obj->gtt_space.start = gtt_offset; + obj->gtt_space.size = size; +- if (drm_mm_initialized(&dev_priv->mm.gtt_space)) { +- ret = drm_mm_reserve_node(&dev_priv->mm.gtt_space, ++ if (drm_mm_initialized(&dev_priv->gtt.base.mm)) { ++ ret = drm_mm_reserve_node(&dev_priv->gtt.base.mm, + &obj->gtt_space); + if (ret) { + DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0478-drm-i915-Create-a-global-list-of-vms.patch b/patches.baytrail/0478-drm-i915-Create-a-global-list-of-vms.patch new file mode 100644 index 000000000000..c8967502dc35 --- /dev/null +++ b/patches.baytrail/0478-drm-i915-Create-a-global-list-of-vms.patch @@ -0,0 +1,71 @@ +From 348a43de739dadc5abbe04ba13b5ff4573206e24 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 16 Jul 2013 16:50:07 -0700 +Subject: drm/i915: Create a global list of vms + +After we plumb our code to support multiple address spaces (VMs), there +are a few situations where we want to be able to traverse the list of +all address spaces in the system. Cases like eviction, or error state +collection are obvious example. + +v2: Delete the global link instead of the list head. While this in and +of itself shouldn't be really be a problem, doing this allows us to WARN +on an non-empty list, which is a problem. (Daniel) + +Signed-off-by: Ben Widawsky +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit a7bbbd63e79a89b3e7b77eb734f2773ad69a2a43) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 6 ++++++ + drivers/gpu/drm/i915/i915_drv.h | 2 ++ + 2 files changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index c6d3105516ca..3bbf8ef0f984 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1500,6 +1500,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + + i915_dump_device_info(dev_priv); + ++ INIT_LIST_HEAD(&dev_priv->vm_list); ++ INIT_LIST_HEAD(&dev_priv->gtt.base.global_link); ++ list_add(&dev_priv->gtt.base.global_link, &dev_priv->vm_list); ++ + if (i915_get_bridge_dev(dev)) { + ret = -EIO; + goto free_priv; +@@ -1760,6 +1764,8 @@ int i915_driver_unload(struct drm_device *dev) + i915_free_hws(dev); + } + ++ list_del(&dev_priv->gtt.base.global_link); ++ WARN_ON(!list_empty(&dev_priv->vm_list)); + drm_mm_takedown(&dev_priv->gtt.base.mm); + if (dev_priv->regs != NULL) + pci_iounmap(dev->pdev, dev_priv->regs); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index a6497f520578..bcfcc1086d5b 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -449,6 +449,7 @@ typedef uint32_t gen6_gtt_pte_t; + struct i915_address_space { + struct drm_mm mm; + struct drm_device *dev; ++ struct list_head global_link; + unsigned long start; /* Start offset always 0 for dri2 */ + size_t total; /* size addr space maps (ex. 2GB for ggtt) */ + +@@ -1121,6 +1122,7 @@ typedef struct drm_i915_private { + enum modeset_restore modeset_restore; + struct mutex modeset_restore_lock; + ++ struct list_head vm_list; /* Global list of all address spaces */ + struct i915_gtt gtt; /* VMA representing the global address space */ + + struct i915_gem_mm mm; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0479-drm-i915-Move-active-inactive-lists-to-new-mm.patch b/patches.baytrail/0479-drm-i915-Move-active-inactive-lists-to-new-mm.patch new file mode 100644 index 000000000000..2e794304388d --- /dev/null +++ b/patches.baytrail/0479-drm-i915-Move-active-inactive-lists-to-new-mm.patch @@ -0,0 +1,462 @@ +From 95829069a5f93790175d1cd4ef53bcd62dd145aa Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 16 Jul 2013 16:50:08 -0700 +Subject: drm/i915: Move active/inactive lists to new mm + +Shamelessly manipulated out of Daniel :-) +"When moving the lists around explain that the active/inactive stuff is +used by eviction when we run out of address space, so needs to be +per-vma and per-address space. Bound/unbound otoh is used by the +shrinker which only cares about the amount of memory used and not one +bit about in which address space this memory is all used in. Of course +to actual kick out an object we need to unbind it from every address +space, but for that we have the per-object list of vmas." + +v2: Leave the bound list as a global one. (Chris, indirectly) + +v3: Rebased with no i915_gtt_vm. In most places I added a new *vm local, +since it will eventually be replaces by a vm argument. +Put comment back inline, since it no longer makes sense to do otherwise. + +v4: Rebased on hangcheck/error state movement + +Signed-off-by: Ben Widawsky +Reviewed-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 5cef07e1628300aeda9ac9dae95a2b406175b3ff) +Signed-off-by: James Ausmus + +Conflicts: + drivers/gpu/drm/i915/i915_gem.c + (context changes) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 16 +++++++----- + drivers/gpu/drm/i915/i915_drv.h | 46 +++++++++++++++++----------------- + drivers/gpu/drm/i915/i915_gem.c | 33 ++++++++++++------------ + drivers/gpu/drm/i915/i915_gem_debug.c | 2 +- + drivers/gpu/drm/i915/i915_gem_evict.c | 18 ++++++------- + drivers/gpu/drm/i915/i915_gem_stolen.c | 3 ++- + drivers/gpu/drm/i915/i915_gpu_error.c | 8 +++--- + 7 files changed, 67 insertions(+), 59 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 1c697c0ab7e5..a9246e9c5f9d 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -135,7 +135,8 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) + uintptr_t list = (uintptr_t) node->info_ent->data; + struct list_head *head; + struct drm_device *dev = node->minor->dev; +- drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct i915_address_space *vm = &dev_priv->gtt.base; + struct drm_i915_gem_object *obj; + size_t total_obj_size, total_gtt_size; + int count, ret; +@@ -147,11 +148,11 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) + switch (list) { + case ACTIVE_LIST: + seq_puts(m, "Active:\n"); +- head = &dev_priv->mm.active_list; ++ head = &vm->active_list; + break; + case INACTIVE_LIST: + seq_puts(m, "Inactive:\n"); +- head = &dev_priv->mm.inactive_list; ++ head = &vm->inactive_list; + break; + default: + mutex_unlock(&dev->struct_mutex); +@@ -219,6 +220,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data) + u32 count, mappable_count, purgeable_count; + size_t size, mappable_size, purgeable_size; + struct drm_i915_gem_object *obj; ++ struct i915_address_space *vm = &dev_priv->gtt.base; + struct drm_file *file; + int ret; + +@@ -236,12 +238,12 @@ static int i915_gem_object_info(struct seq_file *m, void *data) + count, mappable_count, size, mappable_size); + + size = count = mappable_size = mappable_count = 0; +- count_objects(&dev_priv->mm.active_list, mm_list); ++ count_objects(&vm->active_list, mm_list); + seq_printf(m, " %u [%u] active objects, %zu [%zu] bytes\n", + count, mappable_count, size, mappable_size); + + size = count = mappable_size = mappable_count = 0; +- count_objects(&dev_priv->mm.inactive_list, mm_list); ++ count_objects(&vm->inactive_list, mm_list); + seq_printf(m, " %u [%u] inactive objects, %zu [%zu] bytes\n", + count, mappable_count, size, mappable_size); + +@@ -1625,6 +1627,7 @@ i915_drop_caches_set(void *data, u64 val) + struct drm_device *dev = data; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj, *next; ++ struct i915_address_space *vm = &dev_priv->gtt.base; + int ret; + + DRM_DEBUG_DRIVER("Dropping caches: 0x%08llx\n", val); +@@ -1645,7 +1648,8 @@ i915_drop_caches_set(void *data, u64 val) + i915_gem_retire_requests(dev); + + if (val & DROP_BOUND) { +- list_for_each_entry_safe(obj, next, &dev_priv->mm.inactive_list, mm_list) ++ list_for_each_entry_safe(obj, next, &vm->inactive_list, ++ mm_list) + if (obj->pin_count == 0) { + ret = i915_gem_object_unbind(obj); + if (ret) +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index bcfcc1086d5b..0bd41e4b9f08 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -458,6 +458,29 @@ struct i915_address_space { + struct page *page; + } scratch; + ++ /** ++ * List of objects currently involved in rendering. ++ * ++ * Includes buffers having the contents of their GPU caches ++ * flushed, not necessarily primitives. last_rendering_seqno ++ * represents when the rendering involved will be completed. ++ * ++ * A reference is held on the buffer while on this list. ++ */ ++ struct list_head active_list; ++ ++ /** ++ * LRU list of objects which are not in the ringbuffer and ++ * are ready to unbind, but are still in the GTT. ++ * ++ * last_rendering_seqno is 0 while an object is in this list. ++ * ++ * A reference is not held on the buffer while on this list, ++ * as merely being GTT-bound shouldn't prevent its being ++ * freed, and we'll pull it off the list in the free path. ++ */ ++ struct list_head inactive_list; ++ + /* FIXME: Need a more generic return type */ + gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr, + enum i915_cache_level level); +@@ -853,29 +876,6 @@ struct i915_gem_mm { + struct shrinker inactive_shrinker; + bool shrinker_no_lock_stealing; + +- /** +- * List of objects currently involved in rendering. +- * +- * Includes buffers having the contents of their GPU caches +- * flushed, not necessarily primitives. last_rendering_seqno +- * represents when the rendering involved will be completed. +- * +- * A reference is held on the buffer while on this list. +- */ +- struct list_head active_list; +- +- /** +- * LRU list of objects which are not in the ringbuffer and +- * are ready to unbind, but are still in the GTT. +- * +- * last_rendering_seqno is 0 while an object is in this list. +- * +- * A reference is not held on the buffer while on this list, +- * as merely being GTT-bound shouldn't prevent its being +- * freed, and we'll pull it off the list in the free path. +- */ +- struct list_head inactive_list; +- + /** LRU list of objects with fence regs on them. */ + struct list_head fence_list; + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index b99c73b82ce4..0d749cb9d01a 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -1692,6 +1692,7 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, + bool purgeable_only) + { + struct drm_i915_gem_object *obj, *next; ++ struct i915_address_space *vm = &dev_priv->gtt.base; + long count = 0; + + list_for_each_entry_safe(obj, next, +@@ -1705,9 +1706,7 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, + } + } + +- list_for_each_entry_safe(obj, next, +- &dev_priv->mm.inactive_list, +- mm_list) { ++ list_for_each_entry_safe(obj, next, &vm->inactive_list, mm_list) { + if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) && + i915_gem_object_unbind(obj) == 0 && + i915_gem_object_put_pages(obj) == 0) { +@@ -1878,6 +1877,7 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, + { + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; ++ struct i915_address_space *vm = &dev_priv->gtt.base; + u32 seqno = intel_ring_get_seqno(ring); + + BUG_ON(ring == NULL); +@@ -1894,7 +1894,7 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, + } + + /* Move from whatever list we were on to the tail of execution. */ +- list_move_tail(&obj->mm_list, &dev_priv->mm.active_list); ++ list_move_tail(&obj->mm_list, &vm->active_list); + list_move_tail(&obj->ring_list, &ring->active_list); + + obj->last_read_seqno = seqno; +@@ -1918,11 +1918,12 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) + { + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; ++ struct i915_address_space *vm = &dev_priv->gtt.base; + + BUG_ON(obj->base.write_domain & ~I915_GEM_GPU_DOMAINS); + BUG_ON(!obj->active); + +- list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); ++ list_move_tail(&obj->mm_list, &vm->inactive_list); + + list_del_init(&obj->ring_list); + obj->ring = NULL; +@@ -2274,6 +2275,7 @@ void i915_gem_restore_fences(struct drm_device *dev) + void i915_gem_reset(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; ++ struct i915_address_space *vm = &dev_priv->gtt.base; + struct drm_i915_gem_object *obj; + struct intel_ring_buffer *ring; + int i; +@@ -2284,12 +2286,8 @@ void i915_gem_reset(struct drm_device *dev) + /* Move everything out of the GPU domains to ensure we do any + * necessary invalidation upon reuse. + */ +- list_for_each_entry(obj, +- &dev_priv->mm.inactive_list, +- mm_list) +- { ++ list_for_each_entry(obj, &vm->inactive_list, mm_list) + obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; +- } + + i915_gem_restore_fences(dev); + } +@@ -3062,6 +3060,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + { + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; ++ struct i915_address_space *vm = &dev_priv->gtt.base; + u32 size, fence_size, fence_alignment, unfenced_alignment; + bool mappable, fenceable; + size_t gtt_max = map_and_fenceable ? +@@ -3137,7 +3136,7 @@ search_free: + } + + list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); +- list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); ++ list_add_tail(&obj->mm_list, &vm->inactive_list); + + fenceable = + i915_gem_obj_ggtt_size(obj) == fence_size && +@@ -3285,7 +3284,8 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) + + /* And bump the LRU for this access */ + if (i915_gem_object_is_inactive(obj)) +- list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); ++ list_move_tail(&obj->mm_list, ++ &dev_priv->gtt.base.inactive_list); + + return 0; + } +@@ -4226,7 +4226,7 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, + return ret; + } + +- BUG_ON(!list_empty(&dev_priv->mm.active_list)); ++ BUG_ON(!list_empty(&dev_priv->gtt.base.active_list)); + mutex_unlock(&dev->struct_mutex); + + ret = drm_irq_install(dev); +@@ -4304,8 +4304,8 @@ i915_gem_load(struct drm_device *dev) + SLAB_HWCACHE_ALIGN, + NULL); + +- INIT_LIST_HEAD(&dev_priv->mm.active_list); +- INIT_LIST_HEAD(&dev_priv->mm.inactive_list); ++ INIT_LIST_HEAD(&dev_priv->gtt.base.active_list); ++ INIT_LIST_HEAD(&dev_priv->gtt.base.inactive_list); + INIT_LIST_HEAD(&dev_priv->mm.unbound_list); + INIT_LIST_HEAD(&dev_priv->mm.bound_list); + INIT_LIST_HEAD(&dev_priv->mm.fence_list); +@@ -4576,6 +4576,7 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) + struct drm_i915_private, + mm.inactive_shrinker); + struct drm_device *dev = dev_priv->dev; ++ struct i915_address_space *vm = &dev_priv->gtt.base; + struct drm_i915_gem_object *obj; + int nr_to_scan = sc->nr_to_scan; + bool unlock = true; +@@ -4604,7 +4605,7 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) + list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) + if (obj->pages_pin_count == 0) + cnt += obj->base.size >> PAGE_SHIFT; +- list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) ++ list_for_each_entry(obj, &vm->inactive_list, global_list) + if (obj->pin_count == 0 && obj->pages_pin_count == 0) + cnt += obj->base.size >> PAGE_SHIFT; + +diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c +index 582e6a5f3dac..bf945a39fbb1 100644 +--- a/drivers/gpu/drm/i915/i915_gem_debug.c ++++ b/drivers/gpu/drm/i915/i915_gem_debug.c +@@ -97,7 +97,7 @@ i915_verify_lists(struct drm_device *dev) + } + } + +- list_for_each_entry(obj, &dev_priv->mm.inactive_list, list) { ++ list_for_each_entry(obj, &i915_gtt_vm->inactive_list, list) { + if (obj->base.dev != dev || + !atomic_read(&obj->base.refcount.refcount)) { + DRM_ERROR("freed inactive %p\n", obj); +diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c +index f1c9ab096b00..43b82350d8dc 100644 +--- a/drivers/gpu/drm/i915/i915_gem_evict.c ++++ b/drivers/gpu/drm/i915/i915_gem_evict.c +@@ -47,6 +47,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, + bool mappable, bool nonblocking) + { + drm_i915_private_t *dev_priv = dev->dev_private; ++ struct i915_address_space *vm = &dev_priv->gtt.base; + struct list_head eviction_list, unwind_list; + struct drm_i915_gem_object *obj; + int ret = 0; +@@ -78,15 +79,14 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, + + INIT_LIST_HEAD(&unwind_list); + if (mappable) +- drm_mm_init_scan_with_range(&dev_priv->gtt.base.mm, min_size, ++ drm_mm_init_scan_with_range(&vm->mm, min_size, + alignment, cache_level, 0, + dev_priv->gtt.mappable_end); + else +- drm_mm_init_scan(&dev_priv->gtt.base.mm, min_size, alignment, +- cache_level); ++ drm_mm_init_scan(&vm->mm, min_size, alignment, cache_level); + + /* First see if there is a large enough contiguous idle region... */ +- list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) { ++ list_for_each_entry(obj, &vm->inactive_list, mm_list) { + if (mark_free(obj, &unwind_list)) + goto found; + } +@@ -95,7 +95,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, + goto none; + + /* Now merge in the soon-to-be-expired objects... */ +- list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { ++ list_for_each_entry(obj, &vm->active_list, mm_list) { + if (mark_free(obj, &unwind_list)) + goto found; + } +@@ -154,12 +154,13 @@ int + i915_gem_evict_everything(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; ++ struct i915_address_space *vm = &dev_priv->gtt.base; + struct drm_i915_gem_object *obj, *next; + bool lists_empty; + int ret; + +- lists_empty = (list_empty(&dev_priv->mm.inactive_list) && +- list_empty(&dev_priv->mm.active_list)); ++ lists_empty = (list_empty(&vm->inactive_list) && ++ list_empty(&vm->active_list)); + if (lists_empty) + return -ENOSPC; + +@@ -176,8 +177,7 @@ i915_gem_evict_everything(struct drm_device *dev) + i915_gem_retire_requests(dev); + + /* Having flushed everything, unbind() should never raise an error */ +- list_for_each_entry_safe(obj, next, +- &dev_priv->mm.inactive_list, mm_list) ++ list_for_each_entry_safe(obj, next, &vm->inactive_list, mm_list) + if (obj->pin_count == 0) + WARN_ON(i915_gem_object_unbind(obj)); + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index ede8c41399d9..46a971560b01 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -351,6 +351,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + u32 size) + { + struct drm_i915_private *dev_priv = dev->dev_private; ++ struct i915_address_space *vm = &dev_priv->gtt.base; + struct drm_i915_gem_object *obj; + struct drm_mm_node *stolen; + int ret; +@@ -411,7 +412,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + obj->has_global_gtt_mapping = 1; + + list_add_tail(&obj->global_list, &dev_priv->mm.bound_list); +- list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); ++ list_add_tail(&obj->mm_list, &vm->inactive_list); + + return obj; + +diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c +index 58386cebb865..d970d84da65f 100644 +--- a/drivers/gpu/drm/i915/i915_gpu_error.c ++++ b/drivers/gpu/drm/i915/i915_gpu_error.c +@@ -622,6 +622,7 @@ static struct drm_i915_error_object * + i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, + struct intel_ring_buffer *ring) + { ++ struct i915_address_space *vm = &dev_priv->gtt.base; + struct drm_i915_gem_object *obj; + u32 seqno; + +@@ -641,7 +642,7 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, + } + + seqno = ring->get_seqno(ring, false); +- list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { ++ list_for_each_entry(obj, &vm->active_list, mm_list) { + if (obj->ring != ring) + continue; + +@@ -773,11 +774,12 @@ static void i915_gem_record_rings(struct drm_device *dev, + static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv, + struct drm_i915_error_state *error) + { ++ struct i915_address_space *vm = &dev_priv->gtt.base; + struct drm_i915_gem_object *obj; + int i; + + i = 0; +- list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) ++ list_for_each_entry(obj, &vm->active_list, mm_list) + i++; + error->active_bo_count = i; + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) +@@ -797,7 +799,7 @@ static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv, + error->active_bo_count = + capture_active_bo(error->active_bo, + error->active_bo_count, +- &dev_priv->mm.active_list); ++ &vm->active_list); + + if (error->pinned_bo) + error->pinned_bo_count = +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0480-drm-i915-Free-stolen-node-on-failed-preallocation.patch b/patches.baytrail/0480-drm-i915-Free-stolen-node-on-failed-preallocation.patch new file mode 100644 index 000000000000..f00775967302 --- /dev/null +++ b/patches.baytrail/0480-drm-i915-Free-stolen-node-on-failed-preallocation.patch @@ -0,0 +1,42 @@ +From d6abeb0a8a79c011114af53bf02f60845e8a9907 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 17 Jul 2013 12:19:02 -0700 +Subject: drm/i915: Free stolen node on failed preallocation + +The odds of this happening are *extremely* unlikely. + +Reported-by: Imre Deak +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit f7f181843e6c24644b4b71b8631a5ea87de05158) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_stolen.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 46a971560b01..a893834ab010 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -405,7 +405,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + &obj->gtt_space); + if (ret) { + DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); +- goto unref_out; ++ goto err_out; + } + } + +@@ -416,7 +416,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + + return obj; + +-unref_out: ++err_out: ++ drm_mm_put_block(stolen); + drm_gem_object_unreference(&obj->base); + return NULL; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0481-drm-i915-Create-VMAs.patch b/patches.baytrail/0481-drm-i915-Create-VMAs.patch new file mode 100644 index 000000000000..30e3da3ee971 --- /dev/null +++ b/patches.baytrail/0481-drm-i915-Create-VMAs.patch @@ -0,0 +1,428 @@ +From ccf33cf038a407ddfe8b2037e1640479865847f4 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 17 Jul 2013 12:19:03 -0700 +Subject: drm/i915: Create VMAs + +Formerly: "drm/i915: Create VMAs (part 1)" + +In a previous patch, the notion of a VM was introduced. A VMA describes +an area of part of the VM address space. A VMA is similar to the concept +in the linux mm. However, instead of representing regular memory, a VMA +is backed by a GEM BO. There may be many VMAs for a given object, one +for each VM the object is to be used in. This may occur through flink, +dma-buf, or a number of other transient states. + +Currently the code depends on only 1 VMA per object, for the global GTT +(and aliasing PPGTT). The following patches will address this and make +the rest of the infrastructure more suited + +v2: s/i915_obj/i915_gem_obj (Chris) + +v3: Only move an object to the now global unbound list if there are no +more VMAs for the object which are bound into a VM (ie. the list is +empty). + +v4: killed obj->gtt_space +some reworks due to rebase + +v5: Free vma on error path (Imre) + +v6: Another missed vma free in i915_gem_object_bind_to_gtt error path +(Imre) +Fixed vma freeing in stolen preallocation (Imre) + +Signed-off-by: Ben Widawsky +Reviewed-by: Imre Deak +[danvet: Squash in fixup from Ben to not deref a non-existing vma in +set_cache_level, reported by Chris.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 2f63315692b1d3c055972ad33fc7168ae908b97b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 48 +++++++++++++++++----- + drivers/gpu/drm/i915/i915_gem.c | 74 +++++++++++++++++++++++++++------- + drivers/gpu/drm/i915/i915_gem_evict.c | 12 ++++-- + drivers/gpu/drm/i915/i915_gem_gtt.c | 5 ++- + drivers/gpu/drm/i915/i915_gem_stolen.c | 15 +++++-- + 5 files changed, 120 insertions(+), 34 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 0bd41e4b9f08..d972025bff14 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -533,6 +533,17 @@ struct i915_hw_ppgtt { + int (*enable)(struct drm_device *dev); + }; + ++/* To make things as simple as possible (ie. no refcounting), a VMA's lifetime ++ * will always be <= an objects lifetime. So object refcounting should cover us. ++ */ ++struct i915_vma { ++ struct drm_mm_node node; ++ struct drm_i915_gem_object *obj; ++ struct i915_address_space *vm; ++ ++ struct list_head vma_link; /* Link in the object's VMA list */ ++}; ++ + struct i915_ctx_hang_stats { + /* This context had batch pending when hang was declared */ + unsigned batch_pending; +@@ -1230,8 +1241,9 @@ struct drm_i915_gem_object { + + const struct drm_i915_gem_object_ops *ops; + +- /** Current space allocated to this object in the GTT, if any. */ +- struct drm_mm_node gtt_space; ++ /** List of VMAs backed by this object */ ++ struct list_head vma_list; ++ + /** Stolen memory for this object, instead of being backed by shmem. */ + struct drm_mm_node *stolen; + struct list_head global_list; +@@ -1357,18 +1369,32 @@ struct drm_i915_gem_object { + + #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) + +-/* Offset of the first PTE pointing to this object */ +-static inline unsigned long +-i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o) ++/* This is a temporary define to help transition us to real VMAs. If you see ++ * this, you're either reviewing code, or bisecting it. */ ++static inline struct i915_vma * ++__i915_gem_obj_to_vma(struct drm_i915_gem_object *obj) + { +- return o->gtt_space.start; ++ if (list_empty(&obj->vma_list)) ++ return NULL; ++ return list_first_entry(&obj->vma_list, struct i915_vma, vma_link); + } + + /* Whether or not this object is currently mapped by the translation tables */ + static inline bool + i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *o) + { +- return drm_mm_node_allocated(&o->gtt_space); ++ struct i915_vma *vma = __i915_gem_obj_to_vma(o); ++ if (vma == NULL) ++ return false; ++ return drm_mm_node_allocated(&vma->node); ++} ++ ++/* Offset of the first PTE pointing to this object */ ++static inline unsigned long ++i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o) ++{ ++ BUG_ON(list_empty(&o->vma_list)); ++ return __i915_gem_obj_to_vma(o)->node.start; + } + + /* The size used in the translation tables may be larger than the actual size of +@@ -1378,14 +1404,15 @@ i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *o) + static inline unsigned long + i915_gem_obj_ggtt_size(struct drm_i915_gem_object *o) + { +- return o->gtt_space.size; ++ BUG_ON(list_empty(&o->vma_list)); ++ return __i915_gem_obj_to_vma(o)->node.size; + } + + static inline void + i915_gem_obj_ggtt_set_color(struct drm_i915_gem_object *o, + enum i915_cache_level color) + { +- o->gtt_space.color = color; ++ __i915_gem_obj_to_vma(o)->node.color = color; + } + + /** +@@ -1693,6 +1720,9 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, + struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, + size_t size); + void i915_gem_free_object(struct drm_gem_object *obj); ++struct i915_vma *i915_gem_vma_create(struct drm_i915_gem_object *obj, ++ struct i915_address_space *vm); ++void i915_gem_vma_destroy(struct i915_vma *vma); + + int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, + uint32_t alignment, +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 0d749cb9d01a..3200a201bcba 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2590,6 +2590,7 @@ int + i915_gem_object_unbind(struct drm_i915_gem_object *obj) + { + drm_i915_private_t *dev_priv = obj->base.dev->dev_private; ++ struct i915_vma *vma; + int ret; + + if (!i915_gem_obj_ggtt_bound(obj)) +@@ -2627,11 +2628,20 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) + i915_gem_object_unpin_pages(obj); + + list_del(&obj->mm_list); +- list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list); + /* Avoid an unnecessary call to unbind on rebind. */ + obj->map_and_fenceable = true; + +- drm_mm_remove_node(&obj->gtt_space); ++ vma = __i915_gem_obj_to_vma(obj); ++ list_del(&vma->vma_link); ++ drm_mm_remove_node(&vma->node); ++ i915_gem_vma_destroy(vma); ++ ++ /* Since the unbound list is global, only move to that list if ++ * no more VMAs exist. ++ * NB: Until we have real VMAs there will only ever be one */ ++ WARN_ON(!list_empty(&obj->vma_list)); ++ if (list_empty(&obj->vma_list)) ++ list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list); + + return 0; + } +@@ -3065,8 +3075,12 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + bool mappable, fenceable; + size_t gtt_max = map_and_fenceable ? + dev_priv->gtt.mappable_end : dev_priv->gtt.base.total; ++ struct i915_vma *vma; + int ret; + ++ if (WARN_ON(!list_empty(&obj->vma_list))) ++ return -EBUSY; ++ + fence_size = i915_gem_get_gtt_size(dev, + obj->base.size, + obj->tiling_mode); +@@ -3105,9 +3119,15 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + + i915_gem_object_pin_pages(obj); + ++ vma = i915_gem_vma_create(obj, &dev_priv->gtt.base); ++ if (vma == NULL) { ++ i915_gem_object_unpin_pages(obj); ++ return -ENOMEM; ++ } ++ + search_free: + ret = drm_mm_insert_node_in_range_generic(&dev_priv->gtt.base.mm, +- &obj->gtt_space, ++ &vma->node, + size, alignment, + obj->cache_level, 0, gtt_max); + if (ret) { +@@ -3118,25 +3138,21 @@ search_free: + if (ret == 0) + goto search_free; + +- i915_gem_object_unpin_pages(obj); +- return ret; ++ goto err_out; + } +- if (WARN_ON(!i915_gem_valid_gtt_space(dev, &obj->gtt_space, ++ if (WARN_ON(!i915_gem_valid_gtt_space(dev, &vma->node, + obj->cache_level))) { +- i915_gem_object_unpin_pages(obj); +- drm_mm_remove_node(&obj->gtt_space); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_out; + } + + ret = i915_gem_gtt_prepare_object(obj); +- if (ret) { +- i915_gem_object_unpin_pages(obj); +- drm_mm_remove_node(&obj->gtt_space); +- return ret; +- } ++ if (ret) ++ goto err_out; + + list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); + list_add_tail(&obj->mm_list, &vm->inactive_list); ++ list_add(&vma->vma_link, &obj->vma_list); + + fenceable = + i915_gem_obj_ggtt_size(obj) == fence_size && +@@ -3150,6 +3166,12 @@ search_free: + trace_i915_gem_object_bind(obj, map_and_fenceable); + i915_gem_verify_gtt(dev); + return 0; ++ ++err_out: ++ i915_gem_vma_destroy(vma); ++ i915_gem_object_unpin_pages(obj); ++ drm_mm_remove_node(&vma->node); ++ return ret; + } + + void +@@ -3295,6 +3317,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + { + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; ++ struct i915_vma *vma = __i915_gem_obj_to_vma(obj); + int ret; + + if (obj->cache_level == cache_level) +@@ -3305,7 +3328,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + return -EBUSY; + } + +- if (!i915_gem_valid_gtt_space(dev, &obj->gtt_space, cache_level)) { ++ if (vma && !i915_gem_valid_gtt_space(dev, &vma->node, cache_level)) { + ret = i915_gem_object_unbind(obj); + if (ret) + return ret; +@@ -3850,6 +3873,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, + INIT_LIST_HEAD(&obj->global_list); + INIT_LIST_HEAD(&obj->ring_list); + INIT_LIST_HEAD(&obj->exec_list); ++ INIT_LIST_HEAD(&obj->vma_list); + + obj->ops = ops; + +@@ -3970,6 +3994,26 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) + i915_gem_object_free(obj); + } + ++struct i915_vma *i915_gem_vma_create(struct drm_i915_gem_object *obj, ++ struct i915_address_space *vm) ++{ ++ struct i915_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL); ++ if (vma == NULL) ++ return ERR_PTR(-ENOMEM); ++ ++ INIT_LIST_HEAD(&vma->vma_link); ++ vma->vm = vm; ++ vma->obj = obj; ++ ++ return vma; ++} ++ ++void i915_gem_vma_destroy(struct i915_vma *vma) ++{ ++ WARN_ON(vma->node.allocated); ++ kfree(vma); ++} ++ + int + i915_gem_idle(struct drm_device *dev) + { +diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c +index 43b82350d8dc..df61f338dea1 100644 +--- a/drivers/gpu/drm/i915/i915_gem_evict.c ++++ b/drivers/gpu/drm/i915/i915_gem_evict.c +@@ -34,11 +34,13 @@ + static bool + mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind) + { ++ struct i915_vma *vma = __i915_gem_obj_to_vma(obj); ++ + if (obj->pin_count) + return false; + + list_add(&obj->exec_list, unwind); +- return drm_mm_scan_add_block(&obj->gtt_space); ++ return drm_mm_scan_add_block(&vma->node); + } + + int +@@ -49,6 +51,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, + drm_i915_private_t *dev_priv = dev->dev_private; + struct i915_address_space *vm = &dev_priv->gtt.base; + struct list_head eviction_list, unwind_list; ++ struct i915_vma *vma; + struct drm_i915_gem_object *obj; + int ret = 0; + +@@ -106,8 +109,8 @@ none: + obj = list_first_entry(&unwind_list, + struct drm_i915_gem_object, + exec_list); +- +- ret = drm_mm_scan_remove_block(&obj->gtt_space); ++ vma = __i915_gem_obj_to_vma(obj); ++ ret = drm_mm_scan_remove_block(&vma->node); + BUG_ON(ret); + + list_del_init(&obj->exec_list); +@@ -127,7 +130,8 @@ found: + obj = list_first_entry(&unwind_list, + struct drm_i915_gem_object, + exec_list); +- if (drm_mm_scan_remove_block(&obj->gtt_space)) { ++ vma = __i915_gem_obj_to_vma(obj); ++ if (drm_mm_scan_remove_block(&vma->node)) { + list_move(&obj->exec_list, &eviction_list); + drm_gem_object_reference(&obj->base); + continue; +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 999ecfecb32e..3b639a94dddf 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -662,16 +662,17 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + + /* Mark any preallocated objects as occupied */ + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { ++ struct i915_vma *vma = __i915_gem_obj_to_vma(obj); + int ret; + DRM_DEBUG_KMS("reserving preallocated space: %lx + %zx\n", + i915_gem_obj_ggtt_offset(obj), obj->base.size); + + WARN_ON(i915_gem_obj_ggtt_bound(obj)); +- ret = drm_mm_reserve_node(&dev_priv->gtt.base.mm, +- &obj->gtt_space); ++ ret = drm_mm_reserve_node(&dev_priv->gtt.base.mm, &vma->node); + if (ret) + DRM_DEBUG_KMS("Reservation failed\n"); + obj->has_global_gtt_mapping = 1; ++ list_add(&vma->vma_link, &obj->vma_list); + } + + dev_priv->gtt.base.start = start; +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index a893834ab010..f52613605fe1 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -354,6 +354,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + struct i915_address_space *vm = &dev_priv->gtt.base; + struct drm_i915_gem_object *obj; + struct drm_mm_node *stolen; ++ struct i915_vma *vma; + int ret; + + if (!drm_mm_initialized(&dev_priv->mm.stolen)) +@@ -393,18 +394,24 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + if (gtt_offset == I915_GTT_OFFSET_NONE) + return obj; + ++ vma = i915_gem_vma_create(obj, &dev_priv->gtt.base); ++ if (!vma) { ++ ret = -ENOMEM; ++ goto err_out; ++ } ++ + /* To simplify the initialisation sequence between KMS and GTT, + * we allow construction of the stolen object prior to + * setting up the GTT space. The actual reservation will occur + * later. + */ +- obj->gtt_space.start = gtt_offset; +- obj->gtt_space.size = size; ++ vma->node.start = gtt_offset; ++ vma->node.size = size; + if (drm_mm_initialized(&dev_priv->gtt.base.mm)) { +- ret = drm_mm_reserve_node(&dev_priv->gtt.base.mm, +- &obj->gtt_space); ++ ret = drm_mm_reserve_node(&dev_priv->gtt.base.mm, &vma->node); + if (ret) { + DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); ++ i915_gem_vma_destroy(vma); + goto err_out; + } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0482-drm-Added-SDP-and-VSC-structures-for-handling-PSR-fo.patch b/patches.baytrail/0482-drm-Added-SDP-and-VSC-structures-for-handling-PSR-fo.patch new file mode 100644 index 000000000000..09d8516eaf68 --- /dev/null +++ b/patches.baytrail/0482-drm-Added-SDP-and-VSC-structures-for-handling-PSR-fo.patch @@ -0,0 +1,83 @@ +From dcd463f5f27da560f0b00453d033d99fd0f1a63d Mon Sep 17 00:00:00 2001 +From: Shobhit Kumar +Date: Thu, 11 Jul 2013 18:44:55 -0300 +Subject: drm: Added SDP and VSC structures for handling PSR for eDP + +SDP header and SDP VSC header as per eDP 1.3 spec, section 3.5, +chapter "PSR Secondary Data Package Support". + +v2: Modified and corrected the structures to be more in line for +kernel coding guidelines and rebased the code on Paulo's DP patchset +v3: removing unecessary identation at DP_RECEIVER_CAP_SIZE +v4: moving them to include/drm/drm_dp_helper.h and also already + icluding EDP_PSR_RECEIVER_CAP_SIZE to add everything needed + for PSR at once at drm_dp_helper.h +v5: Fix SDP VSC header and identation by (Paulo Zanoni) and + remove i915 from title (Daniel Vetter) +v6: Fix spec version and move comments from code to commit message + since numbers might change in the future (by Paulo Zanoni). + +CC: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Sateesh Kavuri +Signed-off-by: Shobhit Kumar +Signed-off-by: Rodrigo Vivi +Acked-by: Dave Airlie +Signed-off-by: Daniel Vetter +(cherry picked from commit 52604b1ffabac61eb07cce711f18e18ac74fbeae) +Signed-off-by: Darren Hart +--- + include/drm/drm_dp_helper.h | 31 ++++++++++++++++++++++++++++++- + 1 file changed, 30 insertions(+), 1 deletion(-) + +diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h +index e8e1417af3d9..ae8dbfb1207c 100644 +--- a/include/drm/drm_dp_helper.h ++++ b/include/drm/drm_dp_helper.h +@@ -342,13 +342,42 @@ u8 drm_dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE], + u8 drm_dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE], + int lane); + +-#define DP_RECEIVER_CAP_SIZE 0xf ++#define DP_RECEIVER_CAP_SIZE 0xf ++#define EDP_PSR_RECEIVER_CAP_SIZE 2 ++ + void drm_dp_link_train_clock_recovery_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]); + void drm_dp_link_train_channel_eq_delay(u8 dpcd[DP_RECEIVER_CAP_SIZE]); + + u8 drm_dp_link_rate_to_bw_code(int link_rate); + int drm_dp_bw_code_to_link_rate(u8 link_bw); + ++struct edp_sdp_header { ++ u8 HB0; /* Secondary Data Packet ID */ ++ u8 HB1; /* Secondary Data Packet Type */ ++ u8 HB2; /* 7:5 reserved, 4:0 revision number */ ++ u8 HB3; /* 7:5 reserved, 4:0 number of valid data bytes */ ++} __packed; ++ ++#define EDP_SDP_HEADER_REVISION_MASK 0x1F ++#define EDP_SDP_HEADER_VALID_PAYLOAD_BYTES 0x1F ++ ++struct edp_vsc_psr { ++ struct edp_sdp_header sdp_header; ++ u8 DB0; /* Stereo Interface */ ++ u8 DB1; /* 0 - PSR State; 1 - Update RFB; 2 - CRC Valid */ ++ u8 DB2; /* CRC value bits 7:0 of the R or Cr component */ ++ u8 DB3; /* CRC value bits 15:8 of the R or Cr component */ ++ u8 DB4; /* CRC value bits 7:0 of the G or Y component */ ++ u8 DB5; /* CRC value bits 15:8 of the G or Y component */ ++ u8 DB6; /* CRC value bits 7:0 of the B or Cb component */ ++ u8 DB7; /* CRC value bits 15:8 of the B or Cb component */ ++ u8 DB8_31[24]; /* Reserved */ ++} __packed; ++ ++#define EDP_VSC_PSR_STATE_ACTIVE (1<<0) ++#define EDP_VSC_PSR_UPDATE_RFB (1<<1) ++#define EDP_VSC_PSR_CRC_VALUES_VALID (1<<2) ++ + static inline int + drm_dp_max_link_rate(u8 dpcd[DP_RECEIVER_CAP_SIZE]) + { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0483-drm-i915-Read-the-EDP-DPCD-and-PSR-Capability.patch b/patches.baytrail/0483-drm-i915-Read-the-EDP-DPCD-and-PSR-Capability.patch new file mode 100644 index 000000000000..c662f1bd3578 --- /dev/null +++ b/patches.baytrail/0483-drm-i915-Read-the-EDP-DPCD-and-PSR-Capability.patch @@ -0,0 +1,67 @@ +From dae792591097723957e5b0824f38c7803052876b Mon Sep 17 00:00:00 2001 +From: Shobhit Kumar +Date: Thu, 11 Jul 2013 18:44:56 -0300 +Subject: drm/i915: Read the EDP DPCD and PSR Capability + +v2: reuse of just created is_edp_psr and put it at right place. +v3: move is_edp_psr above intel_edp_disable +v4: remove parentheses. Noticed by Paulo. + +Reviewed-by: Paulo Zanoni +Reviewed-by: Jani Nikula +Signed-off-by: Shobhit Kumar +Signed-off-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 2293bb5c0383f522ac659946ccfadb0e6d2f03c5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 13 +++++++++++++ + drivers/gpu/drm/i915/intel_drv.h | 1 + + 2 files changed, 14 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 9d90d4350ebf..71c7e9ef8152 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1380,6 +1380,12 @@ static void intel_dp_get_config(struct intel_encoder *encoder, + } + } + ++static bool is_edp_psr(struct intel_dp *intel_dp) ++{ ++ return is_edp(intel_dp) && ++ intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED; ++} ++ + static void intel_disable_dp(struct intel_encoder *encoder) + { + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); +@@ -2293,6 +2299,13 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) + if (intel_dp->dpcd[DP_DPCD_REV] == 0) + return false; /* DPCD not present */ + ++ /* Check if the panel supports PSR */ ++ memset(intel_dp->psr_dpcd, 0, sizeof(intel_dp->psr_dpcd)); ++ intel_dp_aux_native_read_retry(intel_dp, DP_PSR_SUPPORT, ++ intel_dp->psr_dpcd, ++ sizeof(intel_dp->psr_dpcd)); ++ if (is_edp_psr(intel_dp)) ++ DRM_DEBUG_KMS("Detected EDP PSR Panel.\n"); + if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & + DP_DWN_STRM_PORT_PRESENT)) + return true; /* native DP sink */ +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 02fee4364e8a..fdb71b445bf9 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -487,6 +487,7 @@ struct intel_dp { + uint8_t link_bw; + uint8_t lane_count; + uint8_t dpcd[DP_RECEIVER_CAP_SIZE]; ++ uint8_t psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE]; + uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS]; + struct i2c_adapter adapter; + struct i2c_algo_dp_aux_data algo; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0484-drm-i915-split-aux_clock_divider-logic-in-a-separate.patch b/patches.baytrail/0484-drm-i915-split-aux_clock_divider-logic-in-a-separate.patch new file mode 100644 index 000000000000..6243cbe1ab8b --- /dev/null +++ b/patches.baytrail/0484-drm-i915-split-aux_clock_divider-logic-in-a-separate.patch @@ -0,0 +1,112 @@ +From 97dece8e9c9b71933535a703d3f2df0da89363e6 Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Thu, 11 Jul 2013 18:44:57 -0300 +Subject: drm/i915: split aux_clock_divider logic in a separated function for + reuse. + +Prep patch for reuse aux_clock_divider with EDP_PSR_AUX_CTL setup. + +Reviewed-by: Paulo Zanoni +Signed-off-by: Rodrigo Vivi +Reviewed-by: Shobhit Kumar +Signed-off-by: Daniel Vetter +(cherry picked from commit b84a1cf8950ed075c4ab2630514d4caaae504176) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 58 +++++++++++++++++++++++------------------ + 1 file changed, 33 insertions(+), 25 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 71c7e9ef8152..be6b47140e09 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -276,29 +276,12 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) + return status; + } + +-static int +-intel_dp_aux_ch(struct intel_dp *intel_dp, +- uint8_t *send, int send_bytes, +- uint8_t *recv, int recv_size) ++static uint32_t get_aux_clock_divider(struct intel_dp *intel_dp) + { + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- uint32_t ch_ctl = intel_dp->aux_ch_ctl_reg; +- uint32_t ch_data = ch_ctl + 4; +- int i, ret, recv_bytes; +- uint32_t status; +- uint32_t aux_clock_divider; +- int try, precharge; +- bool has_aux_irq = INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev); + +- /* dp aux is extremely sensitive to irq latency, hence request the +- * lowest possible wakeup latency and so prevent the cpu from going into +- * deep sleep states. +- */ +- pm_qos_update_request(&dev_priv->pm_qos, 0); +- +- intel_dp_check_edp(intel_dp); + /* The clock divider is based off the hrawclk, + * and would like to run at 2MHz. So, take the + * hrawclk value and divide by 2 and use that +@@ -307,23 +290,48 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, + * clock divider. + */ + if (IS_VALLEYVIEW(dev)) { +- aux_clock_divider = 100; ++ return 100; + } else if (intel_dig_port->port == PORT_A) { + if (HAS_DDI(dev)) +- aux_clock_divider = DIV_ROUND_CLOSEST( ++ return DIV_ROUND_CLOSEST( + intel_ddi_get_cdclk_freq(dev_priv), 2000); + else if (IS_GEN6(dev) || IS_GEN7(dev)) +- aux_clock_divider = 200; /* SNB & IVB eDP input clock at 400Mhz */ ++ return 200; /* SNB & IVB eDP input clock at 400Mhz */ + else +- aux_clock_divider = 225; /* eDP input clock at 450Mhz */ ++ return 225; /* eDP input clock at 450Mhz */ + } else if (dev_priv->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { + /* Workaround for non-ULT HSW */ +- aux_clock_divider = 74; ++ return 74; + } else if (HAS_PCH_SPLIT(dev)) { +- aux_clock_divider = DIV_ROUND_UP(intel_pch_rawclk(dev), 2); ++ return DIV_ROUND_UP(intel_pch_rawclk(dev), 2); + } else { +- aux_clock_divider = intel_hrawclk(dev) / 2; ++ return intel_hrawclk(dev) / 2; + } ++} ++ ++static int ++intel_dp_aux_ch(struct intel_dp *intel_dp, ++ uint8_t *send, int send_bytes, ++ uint8_t *recv, int recv_size) ++{ ++ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); ++ struct drm_device *dev = intel_dig_port->base.base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ uint32_t ch_ctl = intel_dp->aux_ch_ctl_reg; ++ uint32_t ch_data = ch_ctl + 4; ++ int i, ret, recv_bytes; ++ uint32_t status; ++ uint32_t aux_clock_divider = get_aux_clock_divider(intel_dp); ++ int try, precharge; ++ bool has_aux_irq = INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev); ++ ++ /* dp aux is extremely sensitive to irq latency, hence request the ++ * lowest possible wakeup latency and so prevent the cpu from going into ++ * deep sleep states. ++ */ ++ pm_qos_update_request(&dev_priv->pm_qos, 0); ++ ++ intel_dp_check_edp(intel_dp); + + if (IS_GEN6(dev)) + precharge = 3; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0485-drm-i915-Enable-Disable-PSR.patch b/patches.baytrail/0485-drm-i915-Enable-Disable-PSR.patch new file mode 100644 index 000000000000..fd2b56012c68 --- /dev/null +++ b/patches.baytrail/0485-drm-i915-Enable-Disable-PSR.patch @@ -0,0 +1,298 @@ +From 339b1baee30650c3ac63c2790c78960ba12bbfdc Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Thu, 11 Jul 2013 18:44:58 -0300 +Subject: drm/i915: Enable/Disable PSR + +Adding Enable and Disable PSR functionalities. This includes setting the +PSR configuration over AUX, sending SDP VSC DIP over the eDP PIPE config, +enabling PSR in the sink via DPCD register and finally enabling PSR on +the host. + +This patch is based on initial PSR code by Sateesh Kavuri and Kumar Shobhit +but in a different implementation. + +v2: * moved functions around and changed its names. + * removed VSC DIP unset from disable. + * remove FBC wa. + * don't mask LSPS anymore. + * incorporate new crtc usage after a rebase. +v3: Make a clear separation between Sink (Panel) and Source (HW) enabling. +v4: Fix identation and other style issues raised by checkpatch (by Paulo). +v5: Changes according to Paulo's review: + static on write_vsc; + avoid using dp_to_dev when already calling dp_to_dig_port; + remove unecessary TP default time setting; + remove unecessary interrupts disabling; + remove unecessary wait_for_vblank when disabling psr; +v6: remove unecessary wait_for_vblank when writing vsc; +v7: adding setup once function to avoid unnecessarily write to vsc + and set debug_ctl every time we enable or disable psr. + +Cc: Paulo Zanoni +Credits-by: Sateesh Kavuri +Credits-by: Shobhit Kumar +Signed-off-by: Rodrigo Vivi +Reviewed-by: Paulo Zanoni +Reviewed-by: Shobhit Kumar +[danvet: Apply Paulo's suggestion for unconditionally clearing the +control register when writing the DIP.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 2b28bb1b6440fadececc4cf8f29c55d510c6db09) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 42 +++++++++++ + drivers/gpu/drm/i915/intel_dp.c | 149 +++++++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/i915/intel_drv.h | 4 ++ + 3 files changed, 195 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 9fb32dfbfeb9..780a5dc9c131 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -1781,6 +1781,47 @@ + #define BCLRPAT(pipe) _PIPE(pipe, _BCLRPAT_A, _BCLRPAT_B) + #define VSYNCSHIFT(trans) _TRANSCODER(trans, _VSYNCSHIFT_A, _VSYNCSHIFT_B) + ++/* HSW eDP PSR registers */ ++#define EDP_PSR_CTL 0x64800 ++#define EDP_PSR_ENABLE (1<<31) ++#define EDP_PSR_LINK_DISABLE (0<<27) ++#define EDP_PSR_LINK_STANDBY (1<<27) ++#define EDP_PSR_MIN_LINK_ENTRY_TIME_MASK (3<<25) ++#define EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES (0<<25) ++#define EDP_PSR_MIN_LINK_ENTRY_TIME_4_LINES (1<<25) ++#define EDP_PSR_MIN_LINK_ENTRY_TIME_2_LINES (2<<25) ++#define EDP_PSR_MIN_LINK_ENTRY_TIME_0_LINES (3<<25) ++#define EDP_PSR_MAX_SLEEP_TIME_SHIFT 20 ++#define EDP_PSR_SKIP_AUX_EXIT (1<<12) ++#define EDP_PSR_TP1_TP2_SEL (0<<11) ++#define EDP_PSR_TP1_TP3_SEL (1<<11) ++#define EDP_PSR_TP2_TP3_TIME_500us (0<<8) ++#define EDP_PSR_TP2_TP3_TIME_100us (1<<8) ++#define EDP_PSR_TP2_TP3_TIME_2500us (2<<8) ++#define EDP_PSR_TP2_TP3_TIME_0us (3<<8) ++#define EDP_PSR_TP1_TIME_500us (0<<4) ++#define EDP_PSR_TP1_TIME_100us (1<<4) ++#define EDP_PSR_TP1_TIME_2500us (2<<4) ++#define EDP_PSR_TP1_TIME_0us (3<<4) ++#define EDP_PSR_IDLE_FRAME_SHIFT 0 ++ ++#define EDP_PSR_AUX_CTL 0x64810 ++#define EDP_PSR_AUX_DATA1 0x64814 ++#define EDP_PSR_DPCD_COMMAND 0x80060000 ++#define EDP_PSR_AUX_DATA2 0x64818 ++#define EDP_PSR_DPCD_NORMAL_OPERATION (1<<24) ++#define EDP_PSR_AUX_DATA3 0x6481c ++#define EDP_PSR_AUX_DATA4 0x64820 ++#define EDP_PSR_AUX_DATA5 0x64824 ++ ++#define EDP_PSR_STATUS_CTL 0x64840 ++#define EDP_PSR_STATUS_STATE_MASK (7<<29) ++ ++#define EDP_PSR_DEBUG_CTL 0x64860 ++#define EDP_PSR_DEBUG_MASK_LPSP (1<<27) ++#define EDP_PSR_DEBUG_MASK_MEMUP (1<<26) ++#define EDP_PSR_DEBUG_MASK_HPD (1<<25) ++ + /* VGA port control */ + #define ADPA 0x61100 + #define PCH_ADPA 0xe1100 +@@ -2056,6 +2097,7 @@ + * (Haswell and newer) to see which VIDEO_DIP_DATA byte corresponds to each byte + * of the infoframe structure specified by CEA-861. */ + #define VIDEO_DIP_DATA_SIZE 32 ++#define VIDEO_DIP_VSC_DATA_SIZE 36 + #define VIDEO_DIP_CTL 0x61170 + /* Pre HSW: */ + #define VIDEO_DIP_ENABLE (1 << 31) +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index be6b47140e09..6f2e558b475c 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1394,6 +1394,153 @@ static bool is_edp_psr(struct intel_dp *intel_dp) + intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED; + } + ++static bool intel_edp_is_psr_enabled(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (!IS_HASWELL(dev)) ++ return false; ++ ++ return I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE; ++} ++ ++static void intel_edp_psr_write_vsc(struct intel_dp *intel_dp, ++ struct edp_vsc_psr *vsc_psr) ++{ ++ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); ++ struct drm_device *dev = dig_port->base.base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); ++ u32 ctl_reg = HSW_TVIDEO_DIP_CTL(crtc->config.cpu_transcoder); ++ u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(crtc->config.cpu_transcoder); ++ uint32_t *data = (uint32_t *) vsc_psr; ++ unsigned int i; ++ ++ /* As per BSPec (Pipe Video Data Island Packet), we need to disable ++ the video DIP being updated before program video DIP data buffer ++ registers for DIP being updated. */ ++ I915_WRITE(ctl_reg, 0); ++ POSTING_READ(ctl_reg); ++ ++ for (i = 0; i < VIDEO_DIP_VSC_DATA_SIZE; i += 4) { ++ if (i < sizeof(struct edp_vsc_psr)) ++ I915_WRITE(data_reg + i, *data++); ++ else ++ I915_WRITE(data_reg + i, 0); ++ } ++ ++ I915_WRITE(ctl_reg, VIDEO_DIP_ENABLE_VSC_HSW); ++ POSTING_READ(ctl_reg); ++} ++ ++static void intel_edp_psr_setup(struct intel_dp *intel_dp) ++{ ++ struct drm_device *dev = intel_dp_to_dev(intel_dp); ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct edp_vsc_psr psr_vsc; ++ ++ if (intel_dp->psr_setup_done) ++ return; ++ ++ /* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */ ++ memset(&psr_vsc, 0, sizeof(psr_vsc)); ++ psr_vsc.sdp_header.HB0 = 0; ++ psr_vsc.sdp_header.HB1 = 0x7; ++ psr_vsc.sdp_header.HB2 = 0x2; ++ psr_vsc.sdp_header.HB3 = 0x8; ++ intel_edp_psr_write_vsc(intel_dp, &psr_vsc); ++ ++ /* Avoid continuous PSR exit by masking memup and hpd */ ++ I915_WRITE(EDP_PSR_DEBUG_CTL, EDP_PSR_DEBUG_MASK_MEMUP | ++ EDP_PSR_DEBUG_MASK_HPD); ++ ++ intel_dp->psr_setup_done = true; ++} ++ ++static void intel_edp_psr_enable_sink(struct intel_dp *intel_dp) ++{ ++ struct drm_device *dev = intel_dp_to_dev(intel_dp); ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ uint32_t aux_clock_divider = get_aux_clock_divider(intel_dp); ++ int precharge = 0x3; ++ int msg_size = 5; /* Header(4) + Message(1) */ ++ ++ /* Enable PSR in sink */ ++ if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) ++ intel_dp_aux_native_write_1(intel_dp, DP_PSR_EN_CFG, ++ DP_PSR_ENABLE & ++ ~DP_PSR_MAIN_LINK_ACTIVE); ++ else ++ intel_dp_aux_native_write_1(intel_dp, DP_PSR_EN_CFG, ++ DP_PSR_ENABLE | ++ DP_PSR_MAIN_LINK_ACTIVE); ++ ++ /* Setup AUX registers */ ++ I915_WRITE(EDP_PSR_AUX_DATA1, EDP_PSR_DPCD_COMMAND); ++ I915_WRITE(EDP_PSR_AUX_DATA2, EDP_PSR_DPCD_NORMAL_OPERATION); ++ I915_WRITE(EDP_PSR_AUX_CTL, ++ DP_AUX_CH_CTL_TIME_OUT_400us | ++ (msg_size << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | ++ (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | ++ (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT)); ++} ++ ++static void intel_edp_psr_enable_source(struct intel_dp *intel_dp) ++{ ++ struct drm_device *dev = intel_dp_to_dev(intel_dp); ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ uint32_t max_sleep_time = 0x1f; ++ uint32_t idle_frames = 1; ++ uint32_t val = 0x0; ++ ++ if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) { ++ val |= EDP_PSR_LINK_STANDBY; ++ val |= EDP_PSR_TP2_TP3_TIME_0us; ++ val |= EDP_PSR_TP1_TIME_0us; ++ val |= EDP_PSR_SKIP_AUX_EXIT; ++ } else ++ val |= EDP_PSR_LINK_DISABLE; ++ ++ I915_WRITE(EDP_PSR_CTL, val | ++ EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES | ++ max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | ++ idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | ++ EDP_PSR_ENABLE); ++} ++ ++void intel_edp_psr_enable(struct intel_dp *intel_dp) ++{ ++ struct drm_device *dev = intel_dp_to_dev(intel_dp); ++ ++ if (!is_edp_psr(intel_dp) || intel_edp_is_psr_enabled(dev)) ++ return; ++ ++ /* Setup PSR once */ ++ intel_edp_psr_setup(intel_dp); ++ ++ /* Enable PSR on the panel */ ++ intel_edp_psr_enable_sink(intel_dp); ++ ++ /* Enable PSR on the host */ ++ intel_edp_psr_enable_source(intel_dp); ++} ++ ++void intel_edp_psr_disable(struct intel_dp *intel_dp) ++{ ++ struct drm_device *dev = intel_dp_to_dev(intel_dp); ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (!intel_edp_is_psr_enabled(dev)) ++ return; ++ ++ I915_WRITE(EDP_PSR_CTL, I915_READ(EDP_PSR_CTL) & ~EDP_PSR_ENABLE); ++ ++ /* Wait till PSR is idle */ ++ if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) & ++ EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10)) ++ DRM_ERROR("Timed out waiting for PSR Idle State\n"); ++} ++ + static void intel_disable_dp(struct intel_encoder *encoder) + { + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); +@@ -3205,6 +3352,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + WARN(error, "intel_dp_i2c_init failed with error %d for port %c\n", + error, port_name(port)); + ++ intel_dp->psr_setup_done = false; ++ + if (!intel_edp_init_connector(intel_dp, intel_connector)) { + i2c_del_adapter(&intel_dp->adapter); + if (is_edp(intel_dp)) { +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index fdb71b445bf9..9b0ac47a565e 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -499,6 +499,7 @@ struct intel_dp { + int backlight_off_delay; + struct delayed_work panel_vdd_work; + bool want_panel_vdd; ++ bool psr_setup_done; + struct intel_connector *attached_connector; + }; + +@@ -834,4 +835,7 @@ extern bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, + enum transcoder pch_transcoder, + bool enable); + ++extern void intel_edp_psr_enable(struct intel_dp *intel_dp); ++extern void intel_edp_psr_disable(struct intel_dp *intel_dp); ++ + #endif /* __INTEL_DRV_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0486-drm-i915-Added-debugfs-support-for-PSR-Status.patch b/patches.baytrail/0486-drm-i915-Added-debugfs-support-for-PSR-Status.patch new file mode 100644 index 000000000000..49268668cea3 --- /dev/null +++ b/patches.baytrail/0486-drm-i915-Added-debugfs-support-for-PSR-Status.patch @@ -0,0 +1,178 @@ +From 23d01f158b1023d3b2430328fc5088989d5a22ea Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Thu, 11 Jul 2013 18:44:59 -0300 +Subject: drm/i915: Added debugfs support for PSR Status + +Adding support for PSR Status, PSR entry counter and performance counters. +Heavily based on initial work from Shobhit. + +v2: Fix PSR Status Link bits by Paulo Zanoni. +v3: Prefer seq_puts to seq_printf by Paulo Zanoni. +v4: Fix identation by Paulo Zanoni. +v5: Return earlier if it isn't Haswell in order to avoid reading non-existing + registers - by Paulo Zanoni. + +CC: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Credits-by: Shobhit Kumar +Signed-off-by: Rodrigo Vivi +Reviewed-by: Shobhit Kumar +Signed-off-by: Daniel Vetter +(cherry picked from commit e91fd8c6dec2ffa903b4f695fce4b9d7248ed2d5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 95 +++++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/i915/i915_reg.h | 24 ++++++++++ + 2 files changed, 119 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index a9246e9c5f9d..65619e6fde86 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1545,6 +1545,100 @@ static int i915_llc(struct seq_file *m, void *data) + return 0; + } + ++static int i915_edp_psr_status(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ u32 psrctl, psrstat, psrperf; ++ ++ if (!IS_HASWELL(dev)) { ++ seq_puts(m, "PSR not supported on this platform\n"); ++ return 0; ++ } ++ ++ psrctl = I915_READ(EDP_PSR_CTL); ++ seq_printf(m, "PSR Enabled: %s\n", ++ yesno(psrctl & EDP_PSR_ENABLE)); ++ ++ psrstat = I915_READ(EDP_PSR_STATUS_CTL); ++ ++ seq_puts(m, "PSR Current State: "); ++ switch (psrstat & EDP_PSR_STATUS_STATE_MASK) { ++ case EDP_PSR_STATUS_STATE_IDLE: ++ seq_puts(m, "Reset state\n"); ++ break; ++ case EDP_PSR_STATUS_STATE_SRDONACK: ++ seq_puts(m, "Wait for TG/Stream to send on frame of data after SRD conditions are met\n"); ++ break; ++ case EDP_PSR_STATUS_STATE_SRDENT: ++ seq_puts(m, "SRD entry\n"); ++ break; ++ case EDP_PSR_STATUS_STATE_BUFOFF: ++ seq_puts(m, "Wait for buffer turn off\n"); ++ break; ++ case EDP_PSR_STATUS_STATE_BUFON: ++ seq_puts(m, "Wait for buffer turn on\n"); ++ break; ++ case EDP_PSR_STATUS_STATE_AUXACK: ++ seq_puts(m, "Wait for AUX to acknowledge on SRD exit\n"); ++ break; ++ case EDP_PSR_STATUS_STATE_SRDOFFACK: ++ seq_puts(m, "Wait for TG/Stream to acknowledge the SRD VDM exit\n"); ++ break; ++ default: ++ seq_puts(m, "Unknown\n"); ++ break; ++ } ++ ++ seq_puts(m, "Link Status: "); ++ switch (psrstat & EDP_PSR_STATUS_LINK_MASK) { ++ case EDP_PSR_STATUS_LINK_FULL_OFF: ++ seq_puts(m, "Link is fully off\n"); ++ break; ++ case EDP_PSR_STATUS_LINK_FULL_ON: ++ seq_puts(m, "Link is fully on\n"); ++ break; ++ case EDP_PSR_STATUS_LINK_STANDBY: ++ seq_puts(m, "Link is in standby\n"); ++ break; ++ default: ++ seq_puts(m, "Unknown\n"); ++ break; ++ } ++ ++ seq_printf(m, "PSR Entry Count: %u\n", ++ psrstat >> EDP_PSR_STATUS_COUNT_SHIFT & ++ EDP_PSR_STATUS_COUNT_MASK); ++ ++ seq_printf(m, "Max Sleep Timer Counter: %u\n", ++ psrstat >> EDP_PSR_STATUS_MAX_SLEEP_TIMER_SHIFT & ++ EDP_PSR_STATUS_MAX_SLEEP_TIMER_MASK); ++ ++ seq_printf(m, "Had AUX error: %s\n", ++ yesno(psrstat & EDP_PSR_STATUS_AUX_ERROR)); ++ ++ seq_printf(m, "Sending AUX: %s\n", ++ yesno(psrstat & EDP_PSR_STATUS_AUX_SENDING)); ++ ++ seq_printf(m, "Sending Idle: %s\n", ++ yesno(psrstat & EDP_PSR_STATUS_SENDING_IDLE)); ++ ++ seq_printf(m, "Sending TP2 TP3: %s\n", ++ yesno(psrstat & EDP_PSR_STATUS_SENDING_TP2_TP3)); ++ ++ seq_printf(m, "Sending TP1: %s\n", ++ yesno(psrstat & EDP_PSR_STATUS_SENDING_TP1)); ++ ++ seq_printf(m, "Idle Count: %u\n", ++ psrstat & EDP_PSR_STATUS_IDLE_MASK); ++ ++ psrperf = (I915_READ(EDP_PSR_PERF_CNT)) & EDP_PSR_PERF_CNT_MASK; ++ seq_printf(m, "Performance Counter: %u\n", psrperf); ++ ++ return 0; ++} ++ + static int + i915_wedged_get(void *data, u64 *val) + { +@@ -1977,6 +2071,7 @@ static struct drm_info_list i915_debugfs_list[] = { + {"i915_ppgtt_info", i915_ppgtt_info, 0}, + {"i915_dpio", i915_dpio_info, 0}, + {"i915_llc", i915_llc, 0}, ++ {"i915_edp_psr_status", i915_edp_psr_status, 0}, + }; + #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 780a5dc9c131..918597035b62 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -1816,6 +1816,30 @@ + + #define EDP_PSR_STATUS_CTL 0x64840 + #define EDP_PSR_STATUS_STATE_MASK (7<<29) ++#define EDP_PSR_STATUS_STATE_IDLE (0<<29) ++#define EDP_PSR_STATUS_STATE_SRDONACK (1<<29) ++#define EDP_PSR_STATUS_STATE_SRDENT (2<<29) ++#define EDP_PSR_STATUS_STATE_BUFOFF (3<<29) ++#define EDP_PSR_STATUS_STATE_BUFON (4<<29) ++#define EDP_PSR_STATUS_STATE_AUXACK (5<<29) ++#define EDP_PSR_STATUS_STATE_SRDOFFACK (6<<29) ++#define EDP_PSR_STATUS_LINK_MASK (3<<26) ++#define EDP_PSR_STATUS_LINK_FULL_OFF (0<<26) ++#define EDP_PSR_STATUS_LINK_FULL_ON (1<<26) ++#define EDP_PSR_STATUS_LINK_STANDBY (2<<26) ++#define EDP_PSR_STATUS_MAX_SLEEP_TIMER_SHIFT 20 ++#define EDP_PSR_STATUS_MAX_SLEEP_TIMER_MASK 0x1f ++#define EDP_PSR_STATUS_COUNT_SHIFT 16 ++#define EDP_PSR_STATUS_COUNT_MASK 0xf ++#define EDP_PSR_STATUS_AUX_ERROR (1<<15) ++#define EDP_PSR_STATUS_AUX_SENDING (1<<12) ++#define EDP_PSR_STATUS_SENDING_IDLE (1<<9) ++#define EDP_PSR_STATUS_SENDING_TP2_TP3 (1<<8) ++#define EDP_PSR_STATUS_SENDING_TP1 (1<<4) ++#define EDP_PSR_STATUS_IDLE_MASK 0xf ++ ++#define EDP_PSR_PERF_CNT 0x64844 ++#define EDP_PSR_PERF_CNT_MASK 0xffffff + + #define EDP_PSR_DEBUG_CTL 0x64860 + #define EDP_PSR_DEBUG_MASK_LPSP (1<<27) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0487-drm-i915-Match-all-PSR-mode-entry-conditions-before-.patch b/patches.baytrail/0487-drm-i915-Match-all-PSR-mode-entry-conditions-before-.patch new file mode 100644 index 000000000000..ad1644525fb3 --- /dev/null +++ b/patches.baytrail/0487-drm-i915-Match-all-PSR-mode-entry-conditions-before-.patch @@ -0,0 +1,225 @@ +From 73746c30cf601a60c7ccfbb261bbbc145ee31881 Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Thu, 11 Jul 2013 18:45:00 -0300 +Subject: drm/i915: Match all PSR mode entry conditions before enabling it. + +v2: Prefer seq_puts to seq_printf by Paulo Zanoni. +v3: small changes like avoiding calling dp_to_dig_port twice as noticed by + Paulo Zanoni. +v4: Avoiding reading non-existent registers - noticed by Paulo + on first psr debugfs patch. +v5: Accepting more suggestions from Paulo: + * check sw interlace flag instead of i915_read + * introduce PSR_S3D_ENABLED to avoid forgeting it whenever added. + +Cc: Paulo Zanoni +Signed-off-by: Rodrigo Vivi +Reviewed-by: Paulo Zanoni +Reviewed-by: Shobhit Kumar +[danvet: Fix up debugfs output (spotted by Paulo) and rip out the +power well check since we really can't do that in a race-free manner, +so it's bogus.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 3f51e4713fc57ab0fc225c3f0e67578a53c24a11) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 42 ++++++++++++++++++++--- + drivers/gpu/drm/i915/i915_drv.h | 13 +++++++ + drivers/gpu/drm/i915/i915_reg.h | 7 ++++ + drivers/gpu/drm/i915/intel_dp.c | 67 ++++++++++++++++++++++++++++++++++++- + 4 files changed, 123 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 65619e6fde86..973f2727d703 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1550,17 +1550,49 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) + struct drm_info_node *node = m->private; + struct drm_device *dev = node->minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- u32 psrctl, psrstat, psrperf; ++ u32 psrstat, psrperf; + + if (!IS_HASWELL(dev)) { + seq_puts(m, "PSR not supported on this platform\n"); ++ } else if (IS_HASWELL(dev) && I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE) { ++ seq_puts(m, "PSR enabled\n"); ++ } else { ++ seq_puts(m, "PSR disabled: "); ++ switch (dev_priv->no_psr_reason) { ++ case PSR_NO_SOURCE: ++ seq_puts(m, "not supported on this platform"); ++ break; ++ case PSR_NO_SINK: ++ seq_puts(m, "not supported by panel"); ++ break; ++ case PSR_CRTC_NOT_ACTIVE: ++ seq_puts(m, "crtc not active"); ++ break; ++ case PSR_PWR_WELL_ENABLED: ++ seq_puts(m, "power well enabled"); ++ break; ++ case PSR_NOT_TILED: ++ seq_puts(m, "not tiled"); ++ break; ++ case PSR_SPRITE_ENABLED: ++ seq_puts(m, "sprite enabled"); ++ break; ++ case PSR_S3D_ENABLED: ++ seq_puts(m, "stereo 3d enabled"); ++ break; ++ case PSR_INTERLACED_ENABLED: ++ seq_puts(m, "interlaced enabled"); ++ break; ++ case PSR_HSW_NOT_DDIA: ++ seq_puts(m, "HSW ties PSR to DDI A (eDP)"); ++ break; ++ default: ++ seq_puts(m, "unknown reason"); ++ } ++ seq_puts(m, "\n"); + return 0; + } + +- psrctl = I915_READ(EDP_PSR_CTL); +- seq_printf(m, "PSR Enabled: %s\n", +- yesno(psrctl & EDP_PSR_ENABLE)); +- + psrstat = I915_READ(EDP_PSR_STATUS_CTL); + + seq_puts(m, "PSR Current State: "); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index d972025bff14..6d8dc7475536 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -593,6 +593,17 @@ struct i915_fbc { + } no_fbc_reason; + }; + ++enum no_psr_reason { ++ PSR_NO_SOURCE, /* Not supported on platform */ ++ PSR_NO_SINK, /* Not supported by panel */ ++ PSR_CRTC_NOT_ACTIVE, ++ PSR_PWR_WELL_ENABLED, ++ PSR_NOT_TILED, ++ PSR_SPRITE_ENABLED, ++ PSR_S3D_ENABLED, ++ PSR_INTERLACED_ENABLED, ++ PSR_HSW_NOT_DDIA, ++}; + + enum intel_pch { + PCH_NONE = 0, /* No PCH present */ +@@ -1174,6 +1185,8 @@ typedef struct drm_i915_private { + /* Haswell power well */ + struct i915_power_well power_well; + ++ enum no_psr_reason no_psr_reason; ++ + struct i915_gpu_error gpu_error; + + struct drm_i915_gem_object *vlv_pctx; +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 918597035b62..6f2df01d8562 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -4158,6 +4158,13 @@ + #define HSW_TVIDEO_DIP_VSC_DATA(trans) \ + _TRANSCODER(trans, HSW_VIDEO_DIP_VSC_DATA_A, HSW_VIDEO_DIP_VSC_DATA_B) + ++#define HSW_STEREO_3D_CTL_A 0x70020 ++#define S3D_ENABLE (1<<31) ++#define HSW_STEREO_3D_CTL_B 0x71020 ++ ++#define HSW_STEREO_3D_CTL(trans) \ ++ _TRANSCODER(trans, HSW_STEREO_3D_CTL_A, HSW_STEREO_3D_CTL_A) ++ + #define _PCH_TRANS_HTOTAL_B 0xe1000 + #define _PCH_TRANS_HBLANK_B 0xe1004 + #define _PCH_TRANS_HSYNC_B 0xe1008 +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 6f2e558b475c..070dc55c10d4 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1508,11 +1508,76 @@ static void intel_edp_psr_enable_source(struct intel_dp *intel_dp) + EDP_PSR_ENABLE); + } + ++static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp) ++{ ++ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); ++ struct drm_device *dev = dig_port->base.base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_crtc *crtc = dig_port->base.base.crtc; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ struct drm_i915_gem_object *obj = to_intel_framebuffer(crtc->fb)->obj; ++ struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; ++ ++ if (!IS_HASWELL(dev)) { ++ DRM_DEBUG_KMS("PSR not supported on this platform\n"); ++ dev_priv->no_psr_reason = PSR_NO_SOURCE; ++ return false; ++ } ++ ++ if ((intel_encoder->type != INTEL_OUTPUT_EDP) || ++ (dig_port->port != PORT_A)) { ++ DRM_DEBUG_KMS("HSW ties PSR to DDI A (eDP)\n"); ++ dev_priv->no_psr_reason = PSR_HSW_NOT_DDIA; ++ return false; ++ } ++ ++ if (!is_edp_psr(intel_dp)) { ++ DRM_DEBUG_KMS("PSR not supported by this panel\n"); ++ dev_priv->no_psr_reason = PSR_NO_SINK; ++ return false; ++ } ++ ++ if (!intel_crtc->active || !crtc->fb || !crtc->mode.clock) { ++ DRM_DEBUG_KMS("crtc not active for PSR\n"); ++ dev_priv->no_psr_reason = PSR_CRTC_NOT_ACTIVE; ++ return false; ++ } ++ ++ if (obj->tiling_mode != I915_TILING_X || ++ obj->fence_reg == I915_FENCE_REG_NONE) { ++ DRM_DEBUG_KMS("PSR condition failed: fb not tiled or fenced\n"); ++ dev_priv->no_psr_reason = PSR_NOT_TILED; ++ return false; ++ } ++ ++ if (I915_READ(SPRCTL(intel_crtc->pipe)) & SPRITE_ENABLE) { ++ DRM_DEBUG_KMS("PSR condition failed: Sprite is Enabled\n"); ++ dev_priv->no_psr_reason = PSR_SPRITE_ENABLED; ++ return false; ++ } ++ ++ if (I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config.cpu_transcoder)) & ++ S3D_ENABLE) { ++ DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n"); ++ dev_priv->no_psr_reason = PSR_S3D_ENABLED; ++ return false; ++ } ++ ++ if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) { ++ DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n"); ++ dev_priv->no_psr_reason = PSR_INTERLACED_ENABLED; ++ return false; ++ } ++ ++ return true; ++} ++ + void intel_edp_psr_enable(struct intel_dp *intel_dp) + { + struct drm_device *dev = intel_dp_to_dev(intel_dp); + +- if (!is_edp_psr(intel_dp) || intel_edp_is_psr_enabled(dev)) ++ if (!intel_edp_psr_match_conditions(intel_dp) || ++ intel_edp_is_psr_enabled(dev)) + return; + + /* Setup PSR once */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0488-drm-intel-add-enable_psr-module-option-and-disable-p.patch b/patches.baytrail/0488-drm-intel-add-enable_psr-module-option-and-disable-p.patch new file mode 100644 index 000000000000..b7cebd2ee7f4 --- /dev/null +++ b/patches.baytrail/0488-drm-intel-add-enable_psr-module-option-and-disable-p.patch @@ -0,0 +1,90 @@ +From 82f4d4d6fdc5f059029c045fc9ddf784eeaec035 Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Thu, 11 Jul 2013 18:45:02 -0300 +Subject: drm/intel: add enable_psr module option and disable psr by default + +v2: prefer seq_puts to seq_printf detected by Paulo Zanoni. +v3: PSR is disabled by default. Without userspace ready it + will cause regression for kde and xdm users + +Signed-off-by: Rodrigo Vivi +Reviewed-by: Shobhit Kumar +Signed-off-by: Daniel Vetter +(cherry picked from commit 105b7c11f036f734988990541674a93e54cf4ec1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 3 +++ + drivers/gpu/drm/i915/i915_drv.c | 4 ++++ + drivers/gpu/drm/i915/i915_drv.h | 2 ++ + drivers/gpu/drm/i915/intel_dp.c | 6 ++++++ + 4 files changed, 15 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 973f2727d703..9d871c7eeaee 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1565,6 +1565,9 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) + case PSR_NO_SINK: + seq_puts(m, "not supported by panel"); + break; ++ case PSR_MODULE_PARAM: ++ seq_puts(m, "disabled by flag"); ++ break; + case PSR_CRTC_NOT_ACTIVE: + seq_puts(m, "crtc not active"); + break; +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 370f2da5d9c0..dd6324901d57 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -118,6 +118,10 @@ module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0600); + MODULE_PARM_DESC(i915_enable_ppgtt, + "Enable PPGTT (default: true)"); + ++int i915_enable_psr __read_mostly = 0; ++module_param_named(enable_psr, i915_enable_psr, int, 0600); ++MODULE_PARM_DESC(enable_psr, "Enable PSR (default: false)"); ++ + unsigned int i915_preliminary_hw_support __read_mostly = 0; + module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600); + MODULE_PARM_DESC(preliminary_hw_support, +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 6d8dc7475536..31441f8561e5 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -596,6 +596,7 @@ struct i915_fbc { + enum no_psr_reason { + PSR_NO_SOURCE, /* Not supported on platform */ + PSR_NO_SINK, /* Not supported by panel */ ++ PSR_MODULE_PARAM, + PSR_CRTC_NOT_ACTIVE, + PSR_PWR_WELL_ENABLED, + PSR_NOT_TILED, +@@ -1622,6 +1623,7 @@ extern int i915_enable_rc6 __read_mostly; + extern int i915_enable_fbc __read_mostly; + extern bool i915_enable_hangcheck __read_mostly; + extern int i915_enable_ppgtt __read_mostly; ++extern int i915_enable_psr __read_mostly; + extern unsigned int i915_preliminary_hw_support __read_mostly; + extern int i915_disable_power_well __read_mostly; + extern int i915_enable_ips __read_mostly; +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 070dc55c10d4..74e81383eddb 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1537,6 +1537,12 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp) + return false; + } + ++ if (!i915_enable_psr) { ++ DRM_DEBUG_KMS("PSR disable by flag\n"); ++ dev_priv->no_psr_reason = PSR_MODULE_PARAM; ++ return false; ++ } ++ + if (!intel_crtc->active || !crtc->fb || !crtc->mode.clock) { + DRM_DEBUG_KMS("crtc not active for PSR\n"); + dev_priv->no_psr_reason = PSR_CRTC_NOT_ACTIVE; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0489-drm-i915-add-update-function-to-disable-enable-back-.patch b/patches.baytrail/0489-drm-i915-add-update-function-to-disable-enable-back-.patch new file mode 100644 index 000000000000..4bf6367a5f2e --- /dev/null +++ b/patches.baytrail/0489-drm-i915-add-update-function-to-disable-enable-back-.patch @@ -0,0 +1,94 @@ +From 3e3fc7cebc1c398779837011c75b18b230239154 Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Thu, 11 Jul 2013 18:45:01 -0300 +Subject: drm/i915: add update function to disable/enable-back PSR + +Required function to disable PSR when going to console mode. +But also can be used whenever PSR mode entry conditions changed. + +v2: Add it before PSR Hook. Update function not really been called yet. +v3: Fix coding style detected by checkpatch by Paulo Zanoni. +v4: do_enable must be static as Paulo noticed. + +Cc: Paulo Zanoni +Signed-off-by: Rodrigo Vivi +Reviewed-by: Paulo Zanoni +Reviewed-by: Shobhit Kumar +Signed-off-by: Daniel Vetter +(cherry picked from commit 3d739d92d9cbce6cdaf101fe78870f97fcbf5349) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 31 ++++++++++++++++++++++++++++++- + drivers/gpu/drm/i915/intel_drv.h | 1 + + 2 files changed, 31 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 74e81383eddb..55f3c970a766 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1578,7 +1578,7 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp) + return true; + } + +-void intel_edp_psr_enable(struct intel_dp *intel_dp) ++static void intel_edp_psr_do_enable(struct intel_dp *intel_dp) + { + struct drm_device *dev = intel_dp_to_dev(intel_dp); + +@@ -1596,6 +1596,15 @@ void intel_edp_psr_enable(struct intel_dp *intel_dp) + intel_edp_psr_enable_source(intel_dp); + } + ++void intel_edp_psr_enable(struct intel_dp *intel_dp) ++{ ++ struct drm_device *dev = intel_dp_to_dev(intel_dp); ++ ++ if (intel_edp_psr_match_conditions(intel_dp) && ++ !intel_edp_is_psr_enabled(dev)) ++ intel_edp_psr_do_enable(intel_dp); ++} ++ + void intel_edp_psr_disable(struct intel_dp *intel_dp) + { + struct drm_device *dev = intel_dp_to_dev(intel_dp); +@@ -1612,6 +1621,26 @@ void intel_edp_psr_disable(struct intel_dp *intel_dp) + DRM_ERROR("Timed out waiting for PSR Idle State\n"); + } + ++void intel_edp_psr_update(struct drm_device *dev) ++{ ++ struct intel_encoder *encoder; ++ struct intel_dp *intel_dp = NULL; ++ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) ++ if (encoder->type == INTEL_OUTPUT_EDP) { ++ intel_dp = enc_to_intel_dp(&encoder->base); ++ ++ if (!is_edp_psr(intel_dp)) ++ return; ++ ++ if (!intel_edp_psr_match_conditions(intel_dp)) ++ intel_edp_psr_disable(intel_dp); ++ else ++ if (!intel_edp_is_psr_enabled(dev)) ++ intel_edp_psr_do_enable(intel_dp); ++ } ++} ++ + static void intel_disable_dp(struct intel_encoder *encoder) + { + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 9b0ac47a565e..31087ff6d871 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -837,5 +837,6 @@ extern bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, + + extern void intel_edp_psr_enable(struct intel_dp *intel_dp); + extern void intel_edp_psr_disable(struct intel_dp *intel_dp); ++extern void intel_edp_psr_update(struct drm_device *dev); + + #endif /* __INTEL_DRV_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0490-drm-i915-Hook-PSR-functionality.patch b/patches.baytrail/0490-drm-i915-Hook-PSR-functionality.patch new file mode 100644 index 000000000000..57d69199d8cf --- /dev/null +++ b/patches.baytrail/0490-drm-i915-Hook-PSR-functionality.patch @@ -0,0 +1,63 @@ +From 82161b2209ac8fc97b473c77442defeef84b3400 Mon Sep 17 00:00:00 2001 +From: Rodrigo Vivi +Date: Thu, 11 Jul 2013 18:45:05 -0300 +Subject: drm/i915: Hook PSR functionality + +PSR must be enabled after transcoder and port are running. +And it is only available for HSW. + +v2: move enable/disable to intel_ddi +v3: The spec suggests PSR should be disabled even before backlight (by pzanoni) +v4: also disabling and enabling whenever panel is disabled/enabled. +v5: make it last patch to avoid breaking whenever bisecting. So calling for + update and force exit came to this patch along with enable/disable calls. +v6: Remove unused and unecessary psr_enable/disable calls, as notice by Paulo. + +CC: Paulo Zanoni +Signed-off-by: Rodrigo Vivi +[danvet: Drop the psr exit code in the busy ioctl since I didn't merge +that part of the infrastructure yet - it needs more thought.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 4906557eb37b7fef84fad4304acef6dedf919880) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 2 ++ + drivers/gpu/drm/i915/intel_display.c | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index b042ee5c4070..931b4bb1f9dc 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -1118,6 +1118,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) + intel_dp_stop_link_train(intel_dp); + + ironlake_edp_backlight_on(intel_dp); ++ intel_edp_psr_enable(intel_dp); + } + + if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) { +@@ -1148,6 +1149,7 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) + if (type == INTEL_OUTPUT_EDP) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + ++ intel_edp_psr_disable(intel_dp); + ironlake_edp_backlight_off(intel_dp); + } + } +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index e11d7426328f..55fcab85b7db 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2274,6 +2274,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, + } + + intel_update_fbc(dev); ++ intel_edp_psr_update(dev); + mutex_unlock(&dev->struct_mutex); + + intel_crtc_update_sarea_pos(crtc, x, y); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0491-drm-i915-restore-debug-message-lost-in-merge-resolut.patch b/patches.baytrail/0491-drm-i915-restore-debug-message-lost-in-merge-resolut.patch new file mode 100644 index 000000000000..00a808acc0d8 --- /dev/null +++ b/patches.baytrail/0491-drm-i915-restore-debug-message-lost-in-merge-resolut.patch @@ -0,0 +1,36 @@ +From 20f582a1a0d9696587528f41fcb1822e81d11b54 Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Thu, 18 Jul 2013 17:44:13 +0300 +Subject: drm/i915: restore debug message lost in merge resolution + +Restore debug message lost in merge commit e1b73cba13. Also clarify it +that we are only clamping bpp not overwriting it. + +Signed-off-by: Imre Deak +Signed-off-by: Daniel Vetter +(cherry picked from commit 7984211ee8e1fa03cd4bc9ef3d347f94f8a2c8a8) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 55f3c970a766..db9cb317f5ce 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -729,8 +729,11 @@ intel_dp_compute_config(struct intel_encoder *encoder, + /* Walk through all bpp values. Luckily they're all nicely spaced with 2 + * bpc in between. */ + bpp = pipe_config->pipe_bpp; +- if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp) ++ if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp) { ++ DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n", ++ dev_priv->vbt.edp_bpp); + bpp = min_t(int, bpp, dev_priv->vbt.edp_bpp); ++ } + + for (; bpp >= 6*3; bpp -= 2*3) { + mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0492-drm-i915-remove-SDV-support-from-lpt_pch_init_refclk.patch b/patches.baytrail/0492-drm-i915-remove-SDV-support-from-lpt_pch_init_refclk.patch new file mode 100644 index 000000000000..02722235805a --- /dev/null +++ b/patches.baytrail/0492-drm-i915-remove-SDV-support-from-lpt_pch_init_refclk.patch @@ -0,0 +1,186 @@ +From 3fb9e9cdf36d39a8009dd1b6b09d61267d2e0f48 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 12 Jul 2013 14:19:36 -0300 +Subject: drm/i915: remove SDV support from lpt_pch_init_refclk + +The machines that fall in the "is_sdv" case are some very early +pre-production steppings. This patch may break VGA output after +suspend/resume on these machines. + +Even the documentation for the is_sdv cases was removed from BSpec. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 0ff066a9e4a29481226a6d46eab6bd9499aeaddb) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 104 ++++++++++++----------------------- + 1 file changed, 34 insertions(+), 70 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 55fcab85b7db..891594cf7a35 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5174,7 +5174,6 @@ static void lpt_init_pch_refclk(struct drm_device *dev) + struct drm_mode_config *mode_config = &dev->mode_config; + struct intel_encoder *encoder; + bool has_vga = false; +- bool is_sdv = false; + u32 tmp; + + list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { +@@ -5190,10 +5189,6 @@ static void lpt_init_pch_refclk(struct drm_device *dev) + + mutex_lock(&dev_priv->dpio_lock); + +- /* XXX: Rip out SDV support once Haswell ships for real. */ +- if (IS_HASWELL(dev) && (dev->pci_device & 0xFF00) == 0x0C00) +- is_sdv = true; +- + tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); + tmp &= ~SBI_SSCCTL_DISABLE; + tmp |= SBI_SSCCTL_PATHALT; +@@ -5205,36 +5200,27 @@ static void lpt_init_pch_refclk(struct drm_device *dev) + tmp &= ~SBI_SSCCTL_PATHALT; + intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); + +- if (!is_sdv) { +- tmp = I915_READ(SOUTH_CHICKEN2); +- tmp |= FDI_MPHY_IOSFSB_RESET_CTL; +- I915_WRITE(SOUTH_CHICKEN2, tmp); ++ tmp = I915_READ(SOUTH_CHICKEN2); ++ tmp |= FDI_MPHY_IOSFSB_RESET_CTL; ++ I915_WRITE(SOUTH_CHICKEN2, tmp); + +- if (wait_for_atomic_us(I915_READ(SOUTH_CHICKEN2) & +- FDI_MPHY_IOSFSB_RESET_STATUS, 100)) +- DRM_ERROR("FDI mPHY reset assert timeout\n"); ++ if (wait_for_atomic_us(I915_READ(SOUTH_CHICKEN2) & ++ FDI_MPHY_IOSFSB_RESET_STATUS, 100)) ++ DRM_ERROR("FDI mPHY reset assert timeout\n"); + +- tmp = I915_READ(SOUTH_CHICKEN2); +- tmp &= ~FDI_MPHY_IOSFSB_RESET_CTL; +- I915_WRITE(SOUTH_CHICKEN2, tmp); ++ tmp = I915_READ(SOUTH_CHICKEN2); ++ tmp &= ~FDI_MPHY_IOSFSB_RESET_CTL; ++ I915_WRITE(SOUTH_CHICKEN2, tmp); + +- if (wait_for_atomic_us((I915_READ(SOUTH_CHICKEN2) & +- FDI_MPHY_IOSFSB_RESET_STATUS) == 0, +- 100)) +- DRM_ERROR("FDI mPHY reset de-assert timeout\n"); +- } ++ if (wait_for_atomic_us((I915_READ(SOUTH_CHICKEN2) & ++ FDI_MPHY_IOSFSB_RESET_STATUS) == 0, 100)) ++ DRM_ERROR("FDI mPHY reset de-assert timeout\n"); + + tmp = intel_sbi_read(dev_priv, 0x8008, SBI_MPHY); + tmp &= ~(0xFF << 24); + tmp |= (0x12 << 24); + intel_sbi_write(dev_priv, 0x8008, tmp, SBI_MPHY); + +- if (is_sdv) { +- tmp = intel_sbi_read(dev_priv, 0x800C, SBI_MPHY); +- tmp |= 0x7FFF; +- intel_sbi_write(dev_priv, 0x800C, tmp, SBI_MPHY); +- } +- + tmp = intel_sbi_read(dev_priv, 0x2008, SBI_MPHY); + tmp |= (1 << 11); + intel_sbi_write(dev_priv, 0x2008, tmp, SBI_MPHY); +@@ -5243,24 +5229,6 @@ static void lpt_init_pch_refclk(struct drm_device *dev) + tmp |= (1 << 11); + intel_sbi_write(dev_priv, 0x2108, tmp, SBI_MPHY); + +- if (is_sdv) { +- tmp = intel_sbi_read(dev_priv, 0x2038, SBI_MPHY); +- tmp |= (0x3F << 24) | (0xF << 20) | (0xF << 16); +- intel_sbi_write(dev_priv, 0x2038, tmp, SBI_MPHY); +- +- tmp = intel_sbi_read(dev_priv, 0x2138, SBI_MPHY); +- tmp |= (0x3F << 24) | (0xF << 20) | (0xF << 16); +- intel_sbi_write(dev_priv, 0x2138, tmp, SBI_MPHY); +- +- tmp = intel_sbi_read(dev_priv, 0x203C, SBI_MPHY); +- tmp |= (0x3F << 8); +- intel_sbi_write(dev_priv, 0x203C, tmp, SBI_MPHY); +- +- tmp = intel_sbi_read(dev_priv, 0x213C, SBI_MPHY); +- tmp |= (0x3F << 8); +- intel_sbi_write(dev_priv, 0x213C, tmp, SBI_MPHY); +- } +- + tmp = intel_sbi_read(dev_priv, 0x206C, SBI_MPHY); + tmp |= (1 << 24) | (1 << 21) | (1 << 18); + intel_sbi_write(dev_priv, 0x206C, tmp, SBI_MPHY); +@@ -5269,17 +5237,15 @@ static void lpt_init_pch_refclk(struct drm_device *dev) + tmp |= (1 << 24) | (1 << 21) | (1 << 18); + intel_sbi_write(dev_priv, 0x216C, tmp, SBI_MPHY); + +- if (!is_sdv) { +- tmp = intel_sbi_read(dev_priv, 0x2080, SBI_MPHY); +- tmp &= ~(7 << 13); +- tmp |= (5 << 13); +- intel_sbi_write(dev_priv, 0x2080, tmp, SBI_MPHY); ++ tmp = intel_sbi_read(dev_priv, 0x2080, SBI_MPHY); ++ tmp &= ~(7 << 13); ++ tmp |= (5 << 13); ++ intel_sbi_write(dev_priv, 0x2080, tmp, SBI_MPHY); + +- tmp = intel_sbi_read(dev_priv, 0x2180, SBI_MPHY); +- tmp &= ~(7 << 13); +- tmp |= (5 << 13); +- intel_sbi_write(dev_priv, 0x2180, tmp, SBI_MPHY); +- } ++ tmp = intel_sbi_read(dev_priv, 0x2180, SBI_MPHY); ++ tmp &= ~(7 << 13); ++ tmp |= (5 << 13); ++ intel_sbi_write(dev_priv, 0x2180, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x208C, SBI_MPHY); + tmp &= ~0xFF; +@@ -5301,25 +5267,23 @@ static void lpt_init_pch_refclk(struct drm_device *dev) + tmp |= (0x1C << 16); + intel_sbi_write(dev_priv, 0x2198, tmp, SBI_MPHY); + +- if (!is_sdv) { +- tmp = intel_sbi_read(dev_priv, 0x20C4, SBI_MPHY); +- tmp |= (1 << 27); +- intel_sbi_write(dev_priv, 0x20C4, tmp, SBI_MPHY); ++ tmp = intel_sbi_read(dev_priv, 0x20C4, SBI_MPHY); ++ tmp |= (1 << 27); ++ intel_sbi_write(dev_priv, 0x20C4, tmp, SBI_MPHY); + +- tmp = intel_sbi_read(dev_priv, 0x21C4, SBI_MPHY); +- tmp |= (1 << 27); +- intel_sbi_write(dev_priv, 0x21C4, tmp, SBI_MPHY); ++ tmp = intel_sbi_read(dev_priv, 0x21C4, SBI_MPHY); ++ tmp |= (1 << 27); ++ intel_sbi_write(dev_priv, 0x21C4, tmp, SBI_MPHY); + +- tmp = intel_sbi_read(dev_priv, 0x20EC, SBI_MPHY); +- tmp &= ~(0xF << 28); +- tmp |= (4 << 28); +- intel_sbi_write(dev_priv, 0x20EC, tmp, SBI_MPHY); ++ tmp = intel_sbi_read(dev_priv, 0x20EC, SBI_MPHY); ++ tmp &= ~(0xF << 28); ++ tmp |= (4 << 28); ++ intel_sbi_write(dev_priv, 0x20EC, tmp, SBI_MPHY); + +- tmp = intel_sbi_read(dev_priv, 0x21EC, SBI_MPHY); +- tmp &= ~(0xF << 28); +- tmp |= (4 << 28); +- intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY); +- } ++ tmp = intel_sbi_read(dev_priv, 0x21EC, SBI_MPHY); ++ tmp &= ~(0xF << 28); ++ tmp |= (4 << 28); ++ intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY); + + /* ULT uses SBI_GEN0, but ULT doesn't have VGA, so we don't care. */ + tmp = intel_sbi_read(dev_priv, SBI_DBUFF0, SBI_ICLK); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0493-drm-i915-extract-FDI-mPHY-functions-from-lpt_init_pc.patch b/patches.baytrail/0493-drm-i915-extract-FDI-mPHY-functions-from-lpt_init_pc.patch new file mode 100644 index 000000000000..5ce093b7be8a --- /dev/null +++ b/patches.baytrail/0493-drm-i915-extract-FDI-mPHY-functions-from-lpt_init_pc.patch @@ -0,0 +1,130 @@ +From 5ac7aac76266a0da596a2b41b8d718af5ccf08aa Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 18 Jul 2013 18:51:11 -0300 +Subject: drm/i915: extract FDI mPHY functions from lpt_init_pch_refclk + +Because lpt_init_pch_refclk implements the "Sequence to enable +CLKOUT_DP for FDI usage and configure PCH FDI I/O", which is very +similar to "Sequence to enable CLKOUT_DP" and "Sequence to enable +CLKOUT_DP without spread". With the extracted functions we can more +easily implement the two missing sequences. + +v2: Rebase (WaMPhyProgramming:hsw comment). + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit f31f2d55eb77190e66cb13e5dd2beca7a91f8dd0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 79 ++++++++++++++++++++---------------- + 1 file changed, 45 insertions(+), 34 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 891594cf7a35..3129a58f32c8 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5164,41 +5164,9 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) + BUG_ON(val != final); + } + +-/* +- * Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O. +- * WaMPhyProgramming:hsw +- */ +-static void lpt_init_pch_refclk(struct drm_device *dev) ++static void lpt_reset_fdi_mphy(struct drm_i915_private *dev_priv) + { +- struct drm_i915_private *dev_priv = dev->dev_private; +- struct drm_mode_config *mode_config = &dev->mode_config; +- struct intel_encoder *encoder; +- bool has_vga = false; +- u32 tmp; +- +- list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { +- switch (encoder->type) { +- case INTEL_OUTPUT_ANALOG: +- has_vga = true; +- break; +- } +- } +- +- if (!has_vga) +- return; +- +- mutex_lock(&dev_priv->dpio_lock); +- +- tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); +- tmp &= ~SBI_SSCCTL_DISABLE; +- tmp |= SBI_SSCCTL_PATHALT; +- intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); +- +- udelay(24); +- +- tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); +- tmp &= ~SBI_SSCCTL_PATHALT; +- intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); ++ uint32_t tmp; + + tmp = I915_READ(SOUTH_CHICKEN2); + tmp |= FDI_MPHY_IOSFSB_RESET_CTL; +@@ -5215,6 +5183,12 @@ static void lpt_init_pch_refclk(struct drm_device *dev) + if (wait_for_atomic_us((I915_READ(SOUTH_CHICKEN2) & + FDI_MPHY_IOSFSB_RESET_STATUS) == 0, 100)) + DRM_ERROR("FDI mPHY reset de-assert timeout\n"); ++} ++ ++/* WaMPhyProgramming:hsw */ ++static void lpt_program_fdi_mphy(struct drm_i915_private *dev_priv) ++{ ++ uint32_t tmp; + + tmp = intel_sbi_read(dev_priv, 0x8008, SBI_MPHY); + tmp &= ~(0xFF << 24); +@@ -5284,6 +5258,43 @@ static void lpt_init_pch_refclk(struct drm_device *dev) + tmp &= ~(0xF << 28); + tmp |= (4 << 28); + intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY); ++} ++ ++/* Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O. */ ++static void lpt_init_pch_refclk(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_mode_config *mode_config = &dev->mode_config; ++ struct intel_encoder *encoder; ++ bool has_vga = false; ++ u32 tmp; ++ ++ list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { ++ switch (encoder->type) { ++ case INTEL_OUTPUT_ANALOG: ++ has_vga = true; ++ break; ++ } ++ } ++ ++ if (!has_vga) ++ return; ++ ++ mutex_lock(&dev_priv->dpio_lock); ++ ++ tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); ++ tmp &= ~SBI_SSCCTL_DISABLE; ++ tmp |= SBI_SSCCTL_PATHALT; ++ intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); ++ ++ udelay(24); ++ ++ tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); ++ tmp &= ~SBI_SSCCTL_PATHALT; ++ intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); ++ ++ lpt_reset_fdi_mphy(dev_priv); ++ lpt_program_fdi_mphy(dev_priv); + + /* ULT uses SBI_GEN0, but ULT doesn't have VGA, so we don't care. */ + tmp = intel_sbi_read(dev_priv, SBI_DBUFF0, SBI_ICLK); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0494-drm-i915-extract-lpt_enable_clkout_dp-from-lpt_init_.patch b/patches.baytrail/0494-drm-i915-extract-lpt_enable_clkout_dp-from-lpt_init_.patch new file mode 100644 index 000000000000..9e47d9da4880 --- /dev/null +++ b/patches.baytrail/0494-drm-i915-extract-lpt_enable_clkout_dp-from-lpt_init_.patch @@ -0,0 +1,79 @@ +From 696201aba17ac3c191f106dd213b75e6f127bb88 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 12 Jul 2013 14:19:38 -0300 +Subject: drm/i915: extract lpt_enable_clkout_dp from lpt_init_pch_refclk + +The next step is to modify lpt_enable_clkout_dp to enable support for +"Sequence to enable CLKOUT_DP" and "Sequence to enable CLKOUT_DP +without spread". + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit bf8fa3d383aa9eb0003419e40ad0f3667c810154) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 38 +++++++++++++++++++++--------------- + 1 file changed, 22 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 3129a58f32c8..bf450d725fc3 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5261,24 +5261,10 @@ static void lpt_program_fdi_mphy(struct drm_i915_private *dev_priv) + } + + /* Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O. */ +-static void lpt_init_pch_refclk(struct drm_device *dev) ++static void lpt_enable_clkout_dp(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- struct drm_mode_config *mode_config = &dev->mode_config; +- struct intel_encoder *encoder; +- bool has_vga = false; +- u32 tmp; +- +- list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { +- switch (encoder->type) { +- case INTEL_OUTPUT_ANALOG: +- has_vga = true; +- break; +- } +- } +- +- if (!has_vga) +- return; ++ uint32_t tmp; + + mutex_lock(&dev_priv->dpio_lock); + +@@ -5304,6 +5290,26 @@ static void lpt_init_pch_refclk(struct drm_device *dev) + mutex_unlock(&dev_priv->dpio_lock); + } + ++static void lpt_init_pch_refclk(struct drm_device *dev) ++{ ++ struct drm_mode_config *mode_config = &dev->mode_config; ++ struct intel_encoder *encoder; ++ bool has_vga = false; ++ ++ list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { ++ switch (encoder->type) { ++ case INTEL_OUTPUT_ANALOG: ++ has_vga = true; ++ break; ++ } ++ } ++ ++ if (!has_vga) ++ return; ++ ++ lpt_enable_clkout_dp(dev); ++} ++ + /* + * Initialize reference clocks when the driver loads + */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0495-drm-i915-checking-for-NULL-instead-of-IS_ERR.patch b/patches.baytrail/0495-drm-i915-checking-for-NULL-instead-of-IS_ERR.patch new file mode 100644 index 000000000000..4cdc47c6bc8c --- /dev/null +++ b/patches.baytrail/0495-drm-i915-checking-for-NULL-instead-of-IS_ERR.patch @@ -0,0 +1,51 @@ +From fa20686f5067a32dc89268886469fcc5213a3066 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 19 Jul 2013 08:45:46 +0300 +Subject: drm/i915: checking for NULL instead of IS_ERR() + +i915_gem_vma_create() returns and ERR_PTR() or a valid pointer, it never +returns NULL. + +Signed-off-by: Dan Carpenter +Signed-off-by: Daniel Vetter +(cherry picked from commit db473b36d4a2eb02c65aefca11578698b3699fe0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 4 ++-- + drivers/gpu/drm/i915/i915_gem_stolen.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 3200a201bcba..5a0f78dfd0bf 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3120,9 +3120,9 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + i915_gem_object_pin_pages(obj); + + vma = i915_gem_vma_create(obj, &dev_priv->gtt.base); +- if (vma == NULL) { ++ if (IS_ERR(vma)) { + i915_gem_object_unpin_pages(obj); +- return -ENOMEM; ++ return PTR_ERR(vma); + } + + search_free: +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index f52613605fe1..27ffb4c865fa 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -395,8 +395,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + return obj; + + vma = i915_gem_vma_create(obj, &dev_priv->gtt.base); +- if (!vma) { +- ret = -ENOMEM; ++ if (IS_ERR(vma)) { ++ ret = PTR_ERR(vma); + goto err_out; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0496-drm-i915-use-after-free-on-error-path.patch b/patches.baytrail/0496-drm-i915-use-after-free-on-error-path.patch new file mode 100644 index 000000000000..10a544a680ee --- /dev/null +++ b/patches.baytrail/0496-drm-i915-use-after-free-on-error-path.patch @@ -0,0 +1,34 @@ +From d04b7be170996f83bcf5087b834b23bd8e1b9b9c Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 19 Jul 2013 08:46:27 +0300 +Subject: drm/i915: use after free on error path + +i915_gem_vma_destroy() frees its argument so we have to move the +drm_mm_remove_node() call up a few lines. + +Signed-off-by: Dan Carpenter +Signed-off-by: Daniel Vetter +(cherry picked from commit 6286ef9b56bfc5d4f3f06ef5488e41da4480dc85) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 5a0f78dfd0bf..c2e226edd999 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3168,9 +3168,9 @@ search_free: + return 0; + + err_out: ++ drm_mm_remove_node(&vma->node); + i915_gem_vma_destroy(vma); + i915_gem_object_unpin_pages(obj); +- drm_mm_remove_node(&vma->node); + return ret; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0497-drm-i915-add-prefault_disable-module-option.patch b/patches.baytrail/0497-drm-i915-add-prefault_disable-module-option.patch new file mode 100644 index 000000000000..32419945f46a --- /dev/null +++ b/patches.baytrail/0497-drm-i915-add-prefault_disable-module-option.patch @@ -0,0 +1,101 @@ +From 642da32b66bcfd5caa1dcc26bb01817c4e30d050 Mon Sep 17 00:00:00 2001 +From: Xiong Zhang +Date: Fri, 19 Jul 2013 13:51:24 +0800 +Subject: drm/i915: add prefault_disable module option + +prefault is stll enabled by default which prevent most of pwrite/pread/reloc +from running slow path, in order to verify these slow pathes, prefault need +to be disabled. + +Signed-off-by: Xiong Zhang +[danvet: Make checkpatch happy and bikeshed the module option help +text a bit.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 0b74b508f78cea96d0d1b47e72cc0ec7959cdc68) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 5 +++++ + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/i915_gem.c | 12 +++++++----- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 6 ++++-- + 4 files changed, 17 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index dd6324901d57..5849b0a91b4e 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -141,6 +141,11 @@ module_param_named(fastboot, i915_fastboot, bool, 0600); + MODULE_PARM_DESC(fastboot, "Try to skip unnecessary mode sets at boot time " + "(default: false)"); + ++bool i915_prefault_disable __read_mostly; ++module_param_named(prefault_disable, i915_prefault_disable, bool, 0600); ++MODULE_PARM_DESC(prefault_disable, ++ "Disable page prefaulting for pread/pwrite/reloc (default:false). For developers only."); ++ + static struct drm_driver driver; + extern int intel_agp_enabled; + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 31441f8561e5..452b2ae84c4e 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1628,6 +1628,7 @@ extern unsigned int i915_preliminary_hw_support __read_mostly; + extern int i915_disable_power_well __read_mostly; + extern int i915_enable_ips __read_mostly; + extern bool i915_fastboot __read_mostly; ++extern bool i915_prefault_disable __read_mostly; + + extern int i915_suspend(struct drm_device *dev, pm_message_t state); + extern int i915_resume(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index c2e226edd999..37641c014e7a 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -465,7 +465,7 @@ i915_gem_shmem_pread(struct drm_device *dev, + + mutex_unlock(&dev->struct_mutex); + +- if (!prefaulted) { ++ if (likely(!i915_prefault_disable) && !prefaulted) { + ret = fault_in_multipages_writeable(user_data, remain); + /* Userspace is tricking us, but we've already clobbered + * its pages with the prefault and promised to write the +@@ -860,10 +860,12 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, + args->size)) + return -EFAULT; + +- ret = fault_in_multipages_readable(to_user_ptr(args->data_ptr), +- args->size); +- if (ret) +- return -EFAULT; ++ if (likely(!i915_prefault_disable)) { ++ ret = fault_in_multipages_readable(to_user_ptr(args->data_ptr), ++ args->size); ++ if (ret) ++ return -EFAULT; ++ } + + ret = i915_mutex_lock_interruptible(dev); + if (ret) +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 1b58694d7be7..1734825bef34 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -759,8 +759,10 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, + if (!access_ok(VERIFY_WRITE, ptr, length)) + return -EFAULT; + +- if (fault_in_multipages_readable(ptr, length)) +- return -EFAULT; ++ if (likely(!i915_prefault_disable)) { ++ if (fault_in_multipages_readable(ptr, length)) ++ return -EFAULT; ++ } + } + + return 0; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0498-drm-i915-kill-ivybridge_irq_preinstall.patch b/patches.baytrail/0498-drm-i915-kill-ivybridge_irq_preinstall.patch new file mode 100644 index 000000000000..17bb569f8c52 --- /dev/null +++ b/patches.baytrail/0498-drm-i915-kill-ivybridge_irq_preinstall.patch @@ -0,0 +1,59 @@ +From 0cbf79b7218bbd8fc1ae9dc50cd1164ab175831b Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 12 Jul 2013 16:35:09 -0300 +Subject: drm/i915: kill ivybridge_irq_preinstall + +After Daniel's latest changes it's now equal to +ironlake_irq_preinstall. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 31694658fa5bc604a2df2cbaf72d4cfc52e9db48) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 21 +-------------------- + 1 file changed, 1 insertion(+), 20 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 55086078cdc4..3a37041c845c 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2139,25 +2139,6 @@ static void ironlake_irq_preinstall(struct drm_device *dev) + ibx_irq_preinstall(dev); + } + +-static void ivybridge_irq_preinstall(struct drm_device *dev) +-{ +- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +- +- atomic_set(&dev_priv->irq_received, 0); +- +- I915_WRITE(HWSTAM, 0xeffe); +- +- /* XXX hotplug from PCH */ +- +- I915_WRITE(DEIMR, 0xffffffff); +- I915_WRITE(DEIER, 0x0); +- POSTING_READ(DEIER); +- +- gen5_gt_irq_preinstall(dev); +- +- ibx_irq_preinstall(dev); +-} +- + static void valleyview_irq_preinstall(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +@@ -3166,7 +3147,7 @@ void intel_irq_init(struct drm_device *dev) + } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { + /* Share uninstall handlers with ILK/SNB */ + dev->driver->irq_handler = ivybridge_irq_handler; +- dev->driver->irq_preinstall = ivybridge_irq_preinstall; ++ dev->driver->irq_preinstall = ironlake_irq_preinstall; + dev->driver->irq_postinstall = ivybridge_irq_postinstall; + dev->driver->irq_uninstall = ironlake_irq_uninstall; + dev->driver->enable_vblank = ivybridge_enable_vblank; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0499-drm-i915-extract-ilk_display_irq_handler.patch b/patches.baytrail/0499-drm-i915-extract-ilk_display_irq_handler.patch new file mode 100644 index 000000000000..a59f7f29f138 --- /dev/null +++ b/patches.baytrail/0499-drm-i915-extract-ilk_display_irq_handler.patch @@ -0,0 +1,141 @@ +From 7cf0072b0de580f5ef2f3c40cc400d29cf8c9572 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 12 Jul 2013 16:35:10 -0300 +Subject: drm/i915: extract ilk_display_irq_handler + +It's the code that deals with de_iir. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit c008bc6eda951dd091115374930de97de48a8b67) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 104 +++++++++++++++++++++------------------- + 1 file changed, 56 insertions(+), 48 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 3a37041c845c..587a51af1e66 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1197,6 +1197,60 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) + cpt_serr_int_handler(dev); + } + ++static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (de_iir & DE_AUX_CHANNEL_A) ++ dp_aux_irq_handler(dev); ++ ++ if (de_iir & DE_GSE) ++ intel_opregion_asle_intr(dev); ++ ++ if (de_iir & DE_PIPEA_VBLANK) ++ drm_handle_vblank(dev, 0); ++ ++ if (de_iir & DE_PIPEB_VBLANK) ++ drm_handle_vblank(dev, 1); ++ ++ if (de_iir & DE_POISON) ++ DRM_ERROR("Poison interrupt\n"); ++ ++ if (de_iir & DE_PIPEA_FIFO_UNDERRUN) ++ if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_A, false)) ++ DRM_DEBUG_DRIVER("Pipe A FIFO underrun\n"); ++ ++ if (de_iir & DE_PIPEB_FIFO_UNDERRUN) ++ if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_B, false)) ++ DRM_DEBUG_DRIVER("Pipe B FIFO underrun\n"); ++ ++ if (de_iir & DE_PLANEA_FLIP_DONE) { ++ intel_prepare_page_flip(dev, 0); ++ intel_finish_page_flip_plane(dev, 0); ++ } ++ ++ if (de_iir & DE_PLANEB_FLIP_DONE) { ++ intel_prepare_page_flip(dev, 1); ++ intel_finish_page_flip_plane(dev, 1); ++ } ++ ++ /* check event from PCH */ ++ if (de_iir & DE_PCH_EVENT) { ++ u32 pch_iir = I915_READ(SDEIIR); ++ ++ if (HAS_PCH_CPT(dev)) ++ cpt_irq_handler(dev, pch_iir); ++ else ++ ibx_irq_handler(dev, pch_iir); ++ ++ /* should clear PCH hotplug event before clear CPU irq */ ++ I915_WRITE(SDEIIR, pch_iir); ++ } ++ ++ if (IS_GEN5(dev) && de_iir & DE_PCU_EVENT) ++ ironlake_rps_change_irq_handler(dev); ++} ++ + static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + { + struct drm_device *dev = (struct drm_device *) arg; +@@ -1355,54 +1409,8 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + else + snb_gt_irq_handler(dev, dev_priv, gt_iir); + +- if (de_iir & DE_AUX_CHANNEL_A) +- dp_aux_irq_handler(dev); +- +- if (de_iir & DE_GSE) +- intel_opregion_asle_intr(dev); +- +- if (de_iir & DE_PIPEA_VBLANK) +- drm_handle_vblank(dev, 0); +- +- if (de_iir & DE_PIPEB_VBLANK) +- drm_handle_vblank(dev, 1); +- +- if (de_iir & DE_POISON) +- DRM_ERROR("Poison interrupt\n"); +- +- if (de_iir & DE_PIPEA_FIFO_UNDERRUN) +- if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_A, false)) +- DRM_DEBUG_DRIVER("Pipe A FIFO underrun\n"); +- +- if (de_iir & DE_PIPEB_FIFO_UNDERRUN) +- if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_B, false)) +- DRM_DEBUG_DRIVER("Pipe B FIFO underrun\n"); +- +- if (de_iir & DE_PLANEA_FLIP_DONE) { +- intel_prepare_page_flip(dev, 0); +- intel_finish_page_flip_plane(dev, 0); +- } +- +- if (de_iir & DE_PLANEB_FLIP_DONE) { +- intel_prepare_page_flip(dev, 1); +- intel_finish_page_flip_plane(dev, 1); +- } +- +- /* check event from PCH */ +- if (de_iir & DE_PCH_EVENT) { +- u32 pch_iir = I915_READ(SDEIIR); +- +- if (HAS_PCH_CPT(dev)) +- cpt_irq_handler(dev, pch_iir); +- else +- ibx_irq_handler(dev, pch_iir); +- +- /* should clear PCH hotplug event before clear CPU irq */ +- I915_WRITE(SDEIIR, pch_iir); +- } +- +- if (IS_GEN5(dev) && de_iir & DE_PCU_EVENT) +- ironlake_rps_change_irq_handler(dev); ++ if (de_iir) ++ ilk_display_irq_handler(dev, de_iir); + + if (IS_GEN6(dev) && pm_iir & GEN6_PM_RPS_EVENTS) + gen6_rps_irq_handler(dev_priv, pm_iir); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0500-drm-i915-extract-ivb_display_irq_handler.patch b/patches.baytrail/0500-drm-i915-extract-ivb_display_irq_handler.patch new file mode 100644 index 000000000000..b2a25fe785c9 --- /dev/null +++ b/patches.baytrail/0500-drm-i915-extract-ivb_display_irq_handler.patch @@ -0,0 +1,106 @@ +From 9dfc86c8bbeadd616b86e983fe2862eeaf060c4d Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 12 Jul 2013 16:35:11 -0300 +Subject: drm/i915: extract ivb_display_irq_handler + +Just like we did with ilk_display_irq_handler. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 9719fb9852e4301d5b8d74feec141d3c3e60fae0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 63 +++++++++++++++++++++++------------------ + 1 file changed, 35 insertions(+), 28 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 587a51af1e66..287078707881 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1251,13 +1251,46 @@ static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir) + ironlake_rps_change_irq_handler(dev); + } + ++static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int i; ++ ++ if (de_iir & DE_ERR_INT_IVB) ++ ivb_err_int_handler(dev); ++ ++ if (de_iir & DE_AUX_CHANNEL_A_IVB) ++ dp_aux_irq_handler(dev); ++ ++ if (de_iir & DE_GSE_IVB) ++ intel_opregion_asle_intr(dev); ++ ++ for (i = 0; i < 3; i++) { ++ if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i))) ++ drm_handle_vblank(dev, i); ++ if (de_iir & (DE_PLANEA_FLIP_DONE_IVB << (5 * i))) { ++ intel_prepare_page_flip(dev, i); ++ intel_finish_page_flip_plane(dev, i); ++ } ++ } ++ ++ /* check event from PCH */ ++ if (!HAS_PCH_NOP(dev) && (de_iir & DE_PCH_EVENT_IVB)) { ++ u32 pch_iir = I915_READ(SDEIIR); ++ ++ cpt_irq_handler(dev, pch_iir); ++ ++ /* clear PCH hotplug event before clear CPU irq */ ++ I915_WRITE(SDEIIR, pch_iir); ++ } ++} ++ + static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + { + struct drm_device *dev = (struct drm_device *) arg; + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier = 0; + irqreturn_t ret = IRQ_NONE; +- int i; + + atomic_inc(&dev_priv->irq_received); + +@@ -1302,33 +1335,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + + de_iir = I915_READ(DEIIR); + if (de_iir) { +- if (de_iir & DE_ERR_INT_IVB) +- ivb_err_int_handler(dev); +- +- if (de_iir & DE_AUX_CHANNEL_A_IVB) +- dp_aux_irq_handler(dev); +- +- if (de_iir & DE_GSE_IVB) +- intel_opregion_asle_intr(dev); +- +- for (i = 0; i < 3; i++) { +- if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i))) +- drm_handle_vblank(dev, i); +- if (de_iir & (DE_PLANEA_FLIP_DONE_IVB << (5 * i))) { +- intel_prepare_page_flip(dev, i); +- intel_finish_page_flip_plane(dev, i); +- } +- } +- +- /* check event from PCH */ +- if (!HAS_PCH_NOP(dev) && (de_iir & DE_PCH_EVENT_IVB)) { +- u32 pch_iir = I915_READ(SDEIIR); +- +- cpt_irq_handler(dev, pch_iir); +- +- /* clear PCH hotplug event before clear CPU irq */ +- I915_WRITE(SDEIIR, pch_iir); +- } ++ ivb_display_irq_handler(dev, de_iir); + + I915_WRITE(DEIIR, de_iir); + ret = IRQ_HANDLED; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0501-drm-i915-don-t-read-or-write-GEN6_PMIIR-on-Gen-5.patch b/patches.baytrail/0501-drm-i915-don-t-read-or-write-GEN6_PMIIR-on-Gen-5.patch new file mode 100644 index 000000000000..d34e9f3e46af --- /dev/null +++ b/patches.baytrail/0501-drm-i915-don-t-read-or-write-GEN6_PMIIR-on-Gen-5.patch @@ -0,0 +1,63 @@ +From 7f322440b870dd7e69955e4d66b4709fa51c878d Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 12 Jul 2013 19:52:36 -0300 +Subject: drm/i915: don't read or write GEN6_PMIIR on Gen 5 + +The register doesn't exist on Gen 5. + +v2: Simplify checks since pm_iir is always 0 on Gen 5 (Chris) + +Signed-off-by: Paulo Zanoni +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 221ab43e8abe1e395d4bdd475ee3d4c2548f04ca) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 287078707881..ed4459e46e10 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1384,7 +1384,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + struct drm_device *dev = (struct drm_device *) arg; + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + int ret = IRQ_NONE; +- u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier; ++ u32 de_iir, gt_iir, de_ier, pm_iir = 0, sde_ier; + + atomic_inc(&dev_priv->irq_received); + +@@ -1404,9 +1404,10 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + + de_iir = I915_READ(DEIIR); + gt_iir = I915_READ(GTIIR); +- pm_iir = I915_READ(GEN6_PMIIR); ++ if (IS_GEN6(dev)) ++ pm_iir = I915_READ(GEN6_PMIIR); + +- if (de_iir == 0 && gt_iir == 0 && (!IS_GEN6(dev) || pm_iir == 0)) ++ if (de_iir == 0 && gt_iir == 0 && pm_iir == 0) + goto done; + + ret = IRQ_HANDLED; +@@ -1419,12 +1420,13 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + if (de_iir) + ilk_display_irq_handler(dev, de_iir); + +- if (IS_GEN6(dev) && pm_iir & GEN6_PM_RPS_EVENTS) ++ if (pm_iir & GEN6_PM_RPS_EVENTS) + gen6_rps_irq_handler(dev_priv, pm_iir); + + I915_WRITE(GTIIR, gt_iir); + I915_WRITE(DEIIR, de_iir); +- I915_WRITE(GEN6_PMIIR, pm_iir); ++ if (pm_iir) ++ I915_WRITE(GEN6_PMIIR, pm_iir); + + done: + I915_WRITE(DEIER, de_ier); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0502-drm-i915-reorganize-ironlake_irq_handler.patch b/patches.baytrail/0502-drm-i915-reorganize-ironlake_irq_handler.patch new file mode 100644 index 000000000000..7b64089e5f8b --- /dev/null +++ b/patches.baytrail/0502-drm-i915-reorganize-ironlake_irq_handler.patch @@ -0,0 +1,97 @@ +From 3fdaeda4bd25298e58e0d7692e76e6afa0654dbc Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 12 Jul 2013 19:54:41 -0300 +Subject: drm/i915: reorganize ironlake_irq_handler + +The ironlake_irq_handler and ivybridge_irq_handler functions do +basically the same thing, but they have different implementation +styles. With this patch we reorganize ironlake_irq_handler in a way +that makes it look very similar to ivybridge_irq_handler. + +One of the advantages of this new function style is that we don't +write 0 to the IIR registers anymore. + +v2: - Rebase due to changes on previous patches + - Move pm_iir to a tighter scope (Chris) + +Signed-off-by: Paulo Zanoni +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 27b9188e14f5f1033ed36ea84035898fe21e4f46) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 46 ++++++++++++++++++++--------------------- + 1 file changed, 23 insertions(+), 23 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index ed4459e46e10..703fe8343507 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1384,7 +1384,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + struct drm_device *dev = (struct drm_device *) arg; + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + int ret = IRQ_NONE; +- u32 de_iir, gt_iir, de_ier, pm_iir = 0, sde_ier; ++ u32 de_iir, gt_iir, de_ier, sde_ier; + + atomic_inc(&dev_priv->irq_received); + +@@ -1402,33 +1402,33 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + I915_WRITE(SDEIER, 0); + POSTING_READ(SDEIER); + +- de_iir = I915_READ(DEIIR); + gt_iir = I915_READ(GTIIR); +- if (IS_GEN6(dev)) +- pm_iir = I915_READ(GEN6_PMIIR); +- +- if (de_iir == 0 && gt_iir == 0 && pm_iir == 0) +- goto done; +- +- ret = IRQ_HANDLED; +- +- if (IS_GEN5(dev)) +- ilk_gt_irq_handler(dev, dev_priv, gt_iir); +- else +- snb_gt_irq_handler(dev, dev_priv, gt_iir); ++ if (gt_iir) { ++ if (IS_GEN5(dev)) ++ ilk_gt_irq_handler(dev, dev_priv, gt_iir); ++ else ++ snb_gt_irq_handler(dev, dev_priv, gt_iir); ++ I915_WRITE(GTIIR, gt_iir); ++ ret = IRQ_HANDLED; ++ } + +- if (de_iir) ++ de_iir = I915_READ(DEIIR); ++ if (de_iir) { + ilk_display_irq_handler(dev, de_iir); ++ I915_WRITE(DEIIR, de_iir); ++ ret = IRQ_HANDLED; ++ } + +- if (pm_iir & GEN6_PM_RPS_EVENTS) +- gen6_rps_irq_handler(dev_priv, pm_iir); +- +- I915_WRITE(GTIIR, gt_iir); +- I915_WRITE(DEIIR, de_iir); +- if (pm_iir) +- I915_WRITE(GEN6_PMIIR, pm_iir); ++ if (IS_GEN6(dev)) { ++ u32 pm_iir = I915_READ(GEN6_PMIIR); ++ if (pm_iir) { ++ if (pm_iir & GEN6_PM_RPS_EVENTS) ++ gen6_rps_irq_handler(dev_priv, pm_iir); ++ I915_WRITE(GEN6_PMIIR, pm_iir); ++ ret = IRQ_HANDLED; ++ } ++ } + +-done: + I915_WRITE(DEIER, de_ier); + POSTING_READ(DEIER); + I915_WRITE(SDEIER, sde_ier); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0503-drm-i915-POSTING_READ-DEIER-on-ivybridge_irq_handler.patch b/patches.baytrail/0503-drm-i915-POSTING_READ-DEIER-on-ivybridge_irq_handler.patch new file mode 100644 index 000000000000..fa9e719579c7 --- /dev/null +++ b/patches.baytrail/0503-drm-i915-POSTING_READ-DEIER-on-ivybridge_irq_handler.patch @@ -0,0 +1,33 @@ +From 82027f5e48e9c5c5cc300c0f9b8a40d9e649a9e3 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 12 Jul 2013 16:35:14 -0300 +Subject: drm/i915: POSTING_READ(DEIER) on ivybridge_irq_handler + +We have this POSTING_READ inside ironlake_irq_handler. I suppose we +also want it on IVB because we want to stop the IRQ handler as soon as +possible at this point. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 23a78516081c49398b6bf08d7a40e954048426bf) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 703fe8343507..d4b2682641ed 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1305,6 +1305,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + /* disable master interrupt before clearing iir */ + de_ier = I915_READ(DEIER); + I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); ++ POSTING_READ(DEIER); + + /* Disable south interrupts. We'll only write to SDEIIR once, so further + * interrupts will will be stored on its back queue, and then we'll be +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0504-drm-i915-add-ILK-SNB-support-to-ivybridge_irq_handle.patch b/patches.baytrail/0504-drm-i915-add-ILK-SNB-support-to-ivybridge_irq_handle.patch new file mode 100644 index 000000000000..c7a0e9ee7762 --- /dev/null +++ b/patches.baytrail/0504-drm-i915-add-ILK-SNB-support-to-ivybridge_irq_handle.patch @@ -0,0 +1,197 @@ +From 80e2d2b31df39c8fc8302f21f00dd46aafd44131 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 12 Jul 2013 19:56:30 -0300 +Subject: drm/i915: add ILK/SNB support to ivybridge_irq_handler + +And then rename it to ironlake_irq_handler. Also move +ilk_gt_irq_handler up to avoid forward declarations. + +In the previous patches I did small modifications to both +ironlake_irq_handler an ivybridge_irq_handler so they became very +similar functions. Now it should be very easy to verify that all we +need to add ILK/SNB support is to call ilk_gt_irq_handler, call +ilk_display_irq_handler and avoid reading pm_iir on gen 5. + +v2: - Rebase due to changes on the previous patches + - Move pm_iir to a tighter scope (Chris) + - Change some Gen checks for readability + +Signed-off-by: Paulo Zanoni +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit f1af8fc10cdb75da7f07f765e9af86dec064f2a8) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 115 +++++++++++----------------------------- + 1 file changed, 32 insertions(+), 83 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index d4b2682641ed..a2bcfa2908ab 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -844,6 +844,17 @@ static void ivybridge_parity_error_irq_handler(struct drm_device *dev) + queue_work(dev_priv->wq, &dev_priv->l3_parity.error_work); + } + ++static void ilk_gt_irq_handler(struct drm_device *dev, ++ struct drm_i915_private *dev_priv, ++ u32 gt_iir) ++{ ++ if (gt_iir & ++ (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT)) ++ notify_ring(dev, &dev_priv->ring[RCS]); ++ if (gt_iir & ILK_BSD_USER_INTERRUPT) ++ notify_ring(dev, &dev_priv->ring[VCS]); ++} ++ + static void snb_gt_irq_handler(struct drm_device *dev, + struct drm_i915_private *dev_priv, + u32 gt_iir) +@@ -1285,11 +1296,11 @@ static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir) + } + } + +-static irqreturn_t ivybridge_irq_handler(int irq, void *arg) ++static irqreturn_t ironlake_irq_handler(int irq, void *arg) + { + struct drm_device *dev = (struct drm_device *) arg; + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +- u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier = 0; ++ u32 de_iir, gt_iir, de_ier, sde_ier = 0; + irqreturn_t ret = IRQ_NONE; + + atomic_inc(&dev_priv->irq_received); +@@ -1329,27 +1340,34 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + + gt_iir = I915_READ(GTIIR); + if (gt_iir) { +- snb_gt_irq_handler(dev, dev_priv, gt_iir); ++ if (IS_GEN5(dev)) ++ ilk_gt_irq_handler(dev, dev_priv, gt_iir); ++ else ++ snb_gt_irq_handler(dev, dev_priv, gt_iir); + I915_WRITE(GTIIR, gt_iir); + ret = IRQ_HANDLED; + } + + de_iir = I915_READ(DEIIR); + if (de_iir) { +- ivb_display_irq_handler(dev, de_iir); +- ++ if (INTEL_INFO(dev)->gen >= 7) ++ ivb_display_irq_handler(dev, de_iir); ++ else ++ ilk_display_irq_handler(dev, de_iir); + I915_WRITE(DEIIR, de_iir); + ret = IRQ_HANDLED; + } + +- pm_iir = I915_READ(GEN6_PMIIR); +- if (pm_iir) { +- if (IS_HASWELL(dev)) +- hsw_pm_irq_handler(dev_priv, pm_iir); +- else if (pm_iir & GEN6_PM_RPS_EVENTS) +- gen6_rps_irq_handler(dev_priv, pm_iir); +- I915_WRITE(GEN6_PMIIR, pm_iir); +- ret = IRQ_HANDLED; ++ if (INTEL_INFO(dev)->gen >= 6) { ++ u32 pm_iir = I915_READ(GEN6_PMIIR); ++ if (pm_iir) { ++ if (IS_HASWELL(dev)) ++ hsw_pm_irq_handler(dev_priv, pm_iir); ++ else if (pm_iir & GEN6_PM_RPS_EVENTS) ++ gen6_rps_irq_handler(dev_priv, pm_iir); ++ I915_WRITE(GEN6_PMIIR, pm_iir); ++ ret = IRQ_HANDLED; ++ } + } + + if (IS_HASWELL(dev)) { +@@ -1369,75 +1387,6 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) + return ret; + } + +-static void ilk_gt_irq_handler(struct drm_device *dev, +- struct drm_i915_private *dev_priv, +- u32 gt_iir) +-{ +- if (gt_iir & +- (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT)) +- notify_ring(dev, &dev_priv->ring[RCS]); +- if (gt_iir & ILK_BSD_USER_INTERRUPT) +- notify_ring(dev, &dev_priv->ring[VCS]); +-} +- +-static irqreturn_t ironlake_irq_handler(int irq, void *arg) +-{ +- struct drm_device *dev = (struct drm_device *) arg; +- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +- int ret = IRQ_NONE; +- u32 de_iir, gt_iir, de_ier, sde_ier; +- +- atomic_inc(&dev_priv->irq_received); +- +- /* disable master interrupt before clearing iir */ +- de_ier = I915_READ(DEIER); +- I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); +- POSTING_READ(DEIER); +- +- /* Disable south interrupts. We'll only write to SDEIIR once, so further +- * interrupts will will be stored on its back queue, and then we'll be +- * able to process them after we restore SDEIER (as soon as we restore +- * it, we'll get an interrupt if SDEIIR still has something to process +- * due to its back queue). */ +- sde_ier = I915_READ(SDEIER); +- I915_WRITE(SDEIER, 0); +- POSTING_READ(SDEIER); +- +- gt_iir = I915_READ(GTIIR); +- if (gt_iir) { +- if (IS_GEN5(dev)) +- ilk_gt_irq_handler(dev, dev_priv, gt_iir); +- else +- snb_gt_irq_handler(dev, dev_priv, gt_iir); +- I915_WRITE(GTIIR, gt_iir); +- ret = IRQ_HANDLED; +- } +- +- de_iir = I915_READ(DEIIR); +- if (de_iir) { +- ilk_display_irq_handler(dev, de_iir); +- I915_WRITE(DEIIR, de_iir); +- ret = IRQ_HANDLED; +- } +- +- if (IS_GEN6(dev)) { +- u32 pm_iir = I915_READ(GEN6_PMIIR); +- if (pm_iir) { +- if (pm_iir & GEN6_PM_RPS_EVENTS) +- gen6_rps_irq_handler(dev_priv, pm_iir); +- I915_WRITE(GEN6_PMIIR, pm_iir); +- ret = IRQ_HANDLED; +- } +- } +- +- I915_WRITE(DEIER, de_ier); +- POSTING_READ(DEIER); +- I915_WRITE(SDEIER, sde_ier); +- POSTING_READ(SDEIER); +- +- return ret; +-} +- + static void i915_error_wake_up(struct drm_i915_private *dev_priv, + bool reset_completed) + { +@@ -3164,7 +3113,7 @@ void intel_irq_init(struct drm_device *dev) + dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; + } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { + /* Share uninstall handlers with ILK/SNB */ +- dev->driver->irq_handler = ivybridge_irq_handler; ++ dev->driver->irq_handler = ironlake_irq_handler; + dev->driver->irq_preinstall = ironlake_irq_preinstall; + dev->driver->irq_postinstall = ivybridge_irq_postinstall; + dev->driver->irq_uninstall = ironlake_irq_uninstall; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0505-drm-i915-kill-Ivybridge-vblank-irq-vfuncs.patch b/patches.baytrail/0505-drm-i915-kill-Ivybridge-vblank-irq-vfuncs.patch new file mode 100644 index 000000000000..38223b274d22 --- /dev/null +++ b/patches.baytrail/0505-drm-i915-kill-Ivybridge-vblank-irq-vfuncs.patch @@ -0,0 +1,110 @@ +From faf1b557b49c6bb294699ca765af752fefc6b207 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 12 Jul 2013 20:00:08 -0300 +Subject: drm/i915: kill Ivybridge vblank irq vfuncs + +The IVB funtions are exactly the same as the ILK ones, with the +exception of the bit register. So add IVB/HSW support to +ironlake_enable_vblank and ironlake_disable_vblank, then kill the +ivybridge functions. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit b518421f5f91365a08ebe55497b32fe6d90ef4df) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 41 ++++++++--------------------------------- + drivers/gpu/drm/i915/i915_reg.h | 3 +++ + 2 files changed, 11 insertions(+), 33 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index a2bcfa2908ab..31a13fdec7a7 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1704,29 +1704,14 @@ static int ironlake_enable_vblank(struct drm_device *dev, int pipe) + { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + unsigned long irqflags; ++ uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) : ++ DE_PIPE_VBLANK_ILK(pipe); + + if (!i915_pipe_enabled(dev, pipe)) + return -EINVAL; + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); +- ironlake_enable_display_irq(dev_priv, (pipe == 0) ? +- DE_PIPEA_VBLANK : DE_PIPEB_VBLANK); +- spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); +- +- return 0; +-} +- +-static int ivybridge_enable_vblank(struct drm_device *dev, int pipe) +-{ +- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +- unsigned long irqflags; +- +- if (!i915_pipe_enabled(dev, pipe)) +- return -EINVAL; +- +- spin_lock_irqsave(&dev_priv->irq_lock, irqflags); +- ironlake_enable_display_irq(dev_priv, +- DE_PIPEA_VBLANK_IVB << (5 * pipe)); ++ ironlake_enable_display_irq(dev_priv, bit); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + + return 0; +@@ -1777,21 +1762,11 @@ static void ironlake_disable_vblank(struct drm_device *dev, int pipe) + { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + unsigned long irqflags; ++ uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) : ++ DE_PIPE_VBLANK_ILK(pipe); + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); +- ironlake_disable_display_irq(dev_priv, (pipe == 0) ? +- DE_PIPEA_VBLANK : DE_PIPEB_VBLANK); +- spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); +-} +- +-static void ivybridge_disable_vblank(struct drm_device *dev, int pipe) +-{ +- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +- unsigned long irqflags; +- +- spin_lock_irqsave(&dev_priv->irq_lock, irqflags); +- ironlake_disable_display_irq(dev_priv, +- DE_PIPEA_VBLANK_IVB << (pipe * 5)); ++ ironlake_disable_display_irq(dev_priv, bit); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + } + +@@ -3117,8 +3092,8 @@ void intel_irq_init(struct drm_device *dev) + dev->driver->irq_preinstall = ironlake_irq_preinstall; + dev->driver->irq_postinstall = ivybridge_irq_postinstall; + dev->driver->irq_uninstall = ironlake_irq_uninstall; +- dev->driver->enable_vblank = ivybridge_enable_vblank; +- dev->driver->disable_vblank = ivybridge_disable_vblank; ++ dev->driver->enable_vblank = ironlake_enable_vblank; ++ dev->driver->disable_vblank = ironlake_disable_vblank; + dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup; + } else if (HAS_PCH_SPLIT(dev)) { + dev->driver->irq_handler = ironlake_irq_handler; +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 6f2df01d8562..1fa35798a94d 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -3795,6 +3795,9 @@ + #define DE_PLANEA_FLIP_DONE_IVB (1<<3) + #define DE_PIPEA_VBLANK_IVB (1<<0) + ++#define DE_PIPE_VBLANK_ILK(pipe) (1 << ((pipe * 8) + 7)) ++#define DE_PIPE_VBLANK_IVB(pipe) (1 << (pipe * 5)) ++ + #define VLV_MASTER_IER 0x4400c /* Gunit master IER */ + #define MASTER_INTERRUPT_ENABLE (1<<31) + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0506-drm-i915-kill-ivybridge_irq_postinstall.patch b/patches.baytrail/0506-drm-i915-kill-ivybridge_irq_postinstall.patch new file mode 100644 index 000000000000..aa0a16642003 --- /dev/null +++ b/patches.baytrail/0506-drm-i915-kill-ivybridge_irq_postinstall.patch @@ -0,0 +1,126 @@ +From fb2438fb26b7a7a833663f64df79cef5b97c455b Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 12 Jul 2013 20:01:56 -0300 +Subject: drm/i915: kill ivybridge_irq_postinstall + +It was very similar to ironlake_irq_postinstall, so IMHO merging both +functions results in a code that is easier to maintain. + +With this change, all the irq handler vfuncs between ironlake and +ivybridge are now unified. + +v2: Add "(" and ")" to make at least one vim user much happier (Chris) + +Signed-off-by: Paulo Zanoni +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 8e76f8dc49f180b0e9d750426c99e37a7d6162ae) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 69 ++++++++++++----------------------------- + 1 file changed, 20 insertions(+), 49 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 31a13fdec7a7..ad92161b6974 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2211,21 +2211,33 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev) + static int ironlake_irq_postinstall(struct drm_device *dev) + { + unsigned long irqflags; +- + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +- /* enable kind of interrupts always enabled */ +- u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | +- DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | +- DE_AUX_CHANNEL_A | DE_PIPEB_FIFO_UNDERRUN | +- DE_PIPEA_FIFO_UNDERRUN | DE_POISON; ++ u32 display_mask, extra_mask; ++ ++ if (INTEL_INFO(dev)->gen >= 7) { ++ display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | ++ DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | ++ DE_PLANEB_FLIP_DONE_IVB | ++ DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB | ++ DE_ERR_INT_IVB); ++ extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | ++ DE_PIPEA_VBLANK_IVB); ++ ++ I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); ++ } else { ++ display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | ++ DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | ++ DE_AUX_CHANNEL_A | DE_PIPEB_FIFO_UNDERRUN | ++ DE_PIPEA_FIFO_UNDERRUN | DE_POISON); ++ extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT; ++ } + + dev_priv->irq_mask = ~display_mask; + + /* should always can generate irq */ + I915_WRITE(DEIIR, I915_READ(DEIIR)); + I915_WRITE(DEIMR, dev_priv->irq_mask); +- I915_WRITE(DEIER, display_mask | +- DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT); ++ I915_WRITE(DEIER, display_mask | extra_mask); + POSTING_READ(DEIER); + + gen5_gt_irq_postinstall(dev); +@@ -2246,38 +2258,6 @@ static int ironlake_irq_postinstall(struct drm_device *dev) + return 0; + } + +-static int ivybridge_irq_postinstall(struct drm_device *dev) +-{ +- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +- /* enable kind of interrupts always enabled */ +- u32 display_mask = +- DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | DE_PCH_EVENT_IVB | +- DE_PLANEC_FLIP_DONE_IVB | +- DE_PLANEB_FLIP_DONE_IVB | +- DE_PLANEA_FLIP_DONE_IVB | +- DE_AUX_CHANNEL_A_IVB | +- DE_ERR_INT_IVB; +- +- dev_priv->irq_mask = ~display_mask; +- +- /* should always can generate irq */ +- I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); +- I915_WRITE(DEIIR, I915_READ(DEIIR)); +- I915_WRITE(DEIMR, dev_priv->irq_mask); +- I915_WRITE(DEIER, +- display_mask | +- DE_PIPEC_VBLANK_IVB | +- DE_PIPEB_VBLANK_IVB | +- DE_PIPEA_VBLANK_IVB); +- POSTING_READ(DEIER); +- +- gen5_gt_irq_postinstall(dev); +- +- ibx_irq_postinstall(dev); +- +- return 0; +-} +- + static int valleyview_irq_postinstall(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +@@ -3086,15 +3066,6 @@ void intel_irq_init(struct drm_device *dev) + dev->driver->enable_vblank = valleyview_enable_vblank; + dev->driver->disable_vblank = valleyview_disable_vblank; + dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; +- } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { +- /* Share uninstall handlers with ILK/SNB */ +- dev->driver->irq_handler = ironlake_irq_handler; +- dev->driver->irq_preinstall = ironlake_irq_preinstall; +- dev->driver->irq_postinstall = ivybridge_irq_postinstall; +- dev->driver->irq_uninstall = ironlake_irq_uninstall; +- dev->driver->enable_vblank = ironlake_enable_vblank; +- dev->driver->disable_vblank = ironlake_disable_vblank; +- dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup; + } else if (HAS_PCH_SPLIT(dev)) { + dev->driver->irq_handler = ironlake_irq_handler; + dev->driver->irq_preinstall = ironlake_irq_preinstall; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0507-drm-i915-Make-i915-events-part-of-uapi.patch b/patches.baytrail/0507-drm-i915-Make-i915-events-part-of-uapi.patch new file mode 100644 index 000000000000..cb75c7f47847 --- /dev/null +++ b/patches.baytrail/0507-drm-i915-Make-i915-events-part-of-uapi.patch @@ -0,0 +1,91 @@ +From d8e699c8d39f88f16b603d768a90c6d0ab13df03 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Fri, 19 Jul 2013 09:16:42 -0700 +Subject: drm/i915: Make i915 events part of uapi + +Make the uevent strings part of the user API for people who wish to +write their own listeners. + +v2: Make a space in the string concatenation. (Chad) +Use the "UEVENT" suffix intead of "EVENT" (Chad) +Make kernel-doc parseable Docbook comments (Daniel) + +v3: Undid reset change introduced in last submission (Daniel) +Fixed up comments to address removal changes. + +Thanks to Daniel Vetter for a majority of the parity error comments. + +CC: Chad Versace +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit cce723ed091ac304d48386bcc3524994c345123e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 8 ++++---- + include/uapi/drm/i915_drm.h | 24 ++++++++++++++++++++++++ + 2 files changed, 28 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index ad92161b6974..d9927f60a97e 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -812,7 +812,7 @@ static void ivybridge_parity_work(struct work_struct *work) + + mutex_unlock(&dev_priv->dev->struct_mutex); + +- parity_event[0] = "L3_PARITY_ERROR=1"; ++ parity_event[0] = I915_L3_PARITY_UEVENT "=1"; + parity_event[1] = kasprintf(GFP_KERNEL, "ROW=%d", row); + parity_event[2] = kasprintf(GFP_KERNEL, "BANK=%d", bank); + parity_event[3] = kasprintf(GFP_KERNEL, "SUBBANK=%d", subbank); +@@ -1429,9 +1429,9 @@ static void i915_error_work_func(struct work_struct *work) + drm_i915_private_t *dev_priv = container_of(error, drm_i915_private_t, + gpu_error); + struct drm_device *dev = dev_priv->dev; +- char *error_event[] = { "ERROR=1", NULL }; +- char *reset_event[] = { "RESET=1", NULL }; +- char *reset_done_event[] = { "ERROR=0", NULL }; ++ char *error_event[] = { I915_ERROR_UEVENT "=1", NULL }; ++ char *reset_event[] = { I915_RESET_UEVENT "=1", NULL }; ++ char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL }; + int ret; + + kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event); +diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h +index 923ed7fe5775..a1a7b6bd60d8 100644 +--- a/include/uapi/drm/i915_drm.h ++++ b/include/uapi/drm/i915_drm.h +@@ -33,6 +33,30 @@ + * subject to backwards-compatibility constraints. + */ + ++/** ++ * DOC: uevents generated by i915 on it's device node ++ * ++ * I915_L3_PARITY_UEVENT - Generated when the driver receives a parity mismatch ++ * event from the gpu l3 cache. Additional information supplied is ROW, ++ * BANK, SUBBANK of the affected cacheline. Userspace should keep track of ++ * these events and if a specific cache-line seems to have a persistent ++ * error remap it with the l3 remapping tool supplied in intel-gpu-tools. ++ * The value supplied with the event is always 1. ++ * ++ * I915_ERROR_UEVENT - Generated upon error detection, currently only via ++ * hangcheck. The error detection event is a good indicator of when things ++ * began to go badly. The value supplied with the event is a 1 upon error ++ * detection, and a 0 upon reset completion, signifying no more error ++ * exists. NOTE: Disabling hangcheck or reset via module parameter will ++ * cause the related events to not be seen. ++ * ++ * I915_RESET_UEVENT - Event is generated just before an attempt to reset the ++ * the GPU. The value supplied with the event is always 1. NOTE: Disable ++ * reset via module parameter will cause this event to not be seen. ++ */ ++#define I915_L3_PARITY_UEVENT "L3_PARITY_ERROR" ++#define I915_ERROR_UEVENT "ERROR" ++#define I915_RESET_UEVENT "RESET" + + /* Each region is a minimum of 16k, and there are at most 255 of them. + */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0508-drm-i915-invert-ilk-snb-_gt_irq_handler-check.patch b/patches.baytrail/0508-drm-i915-invert-ilk-snb-_gt_irq_handler-check.patch new file mode 100644 index 000000000000..7b0e1f926168 --- /dev/null +++ b/patches.baytrail/0508-drm-i915-invert-ilk-snb-_gt_irq_handler-check.patch @@ -0,0 +1,36 @@ +From 1d67dbc32fa9cf6ebb1b096c5634bac52e11bc7a Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 19 Jul 2013 18:57:55 -0300 +Subject: drm/i915: invert {ilk, snb}_gt_irq_handler check + +Requested by Chris Wilson on IRC. + +Signed-off-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit d8fc8a47105bc744000cec280269e1054921f8d6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index d9927f60a97e..52a43470e125 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1340,10 +1340,10 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + + gt_iir = I915_READ(GTIIR); + if (gt_iir) { +- if (IS_GEN5(dev)) +- ilk_gt_irq_handler(dev, dev_priv, gt_iir); +- else ++ if (INTEL_INFO(dev)->gen >= 6) + snb_gt_irq_handler(dev, dev_priv, gt_iir); ++ else ++ ilk_gt_irq_handler(dev, dev_priv, gt_iir); + I915_WRITE(GTIIR, gt_iir); + ret = IRQ_HANDLED; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0509-drm-gem-simplify-object-initialization.patch b/patches.baytrail/0509-drm-gem-simplify-object-initialization.patch new file mode 100644 index 000000000000..25bd27d09554 --- /dev/null +++ b/patches.baytrail/0509-drm-gem-simplify-object-initialization.patch @@ -0,0 +1,184 @@ +From 831337c7d33d6d219086feba2b6687334f65db8e Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Thu, 11 Jul 2013 11:56:32 +0200 +Subject: drm/gem: simplify object initialization + +drm_gem_object_init() and drm_gem_private_object_init() do exactly the +same (except for shmem alloc) so make the first use the latter to reduce +code duplication. + +Also drop the return code from drm_gem_private_object_init(). It seems +unlikely that we will extend it any time soon so no reason to keep it +around. This simplifies code paths in drivers, too. + +Last but not least, fix gma500 to call drm_gem_object_release() before +freeing objects that were allocated via drm_gem_private_object_init(). +That isn't actually necessary for now, but might be in the future. + +Signed-off-by: David Herrmann +Reviewed-by: Daniel Vetter +Reviewed-by: Patrik Jakobsson +Acked-by: Rob Clark +Signed-off-by: Dave Airlie +(cherry picked from commit 89c8233f82d9c8af5b20e72e4a185a38a7d3c50b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_gem.c | 20 ++++++++------------ + drivers/gpu/drm/gma500/framebuffer.c | 6 ++---- + drivers/gpu/drm/gma500/gem.c | 7 ++++--- + drivers/gpu/drm/i915/i915_gem_dmabuf.c | 7 +------ + drivers/gpu/drm/i915/i915_gem_stolen.c | 4 +--- + drivers/gpu/drm/omapdrm/omap_gem.c | 3 ++- + include/drm/drmP.h | 4 ++-- + 7 files changed, 20 insertions(+), 31 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index 4e7407cb0ebc..fdd8248925b8 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -132,16 +132,14 @@ drm_gem_destroy(struct drm_device *dev) + int drm_gem_object_init(struct drm_device *dev, + struct drm_gem_object *obj, size_t size) + { +- BUG_ON((size & (PAGE_SIZE - 1)) != 0); ++ struct file *filp; + +- obj->dev = dev; +- obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); +- if (IS_ERR(obj->filp)) +- return PTR_ERR(obj->filp); ++ filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); ++ if (IS_ERR(filp)) ++ return PTR_ERR(filp); + +- kref_init(&obj->refcount); +- atomic_set(&obj->handle_count, 0); +- obj->size = size; ++ drm_gem_private_object_init(dev, obj, size); ++ obj->filp = filp; + + return 0; + } +@@ -152,8 +150,8 @@ EXPORT_SYMBOL(drm_gem_object_init); + * no GEM provided backing store. Instead the caller is responsible for + * backing the object and handling it. + */ +-int drm_gem_private_object_init(struct drm_device *dev, +- struct drm_gem_object *obj, size_t size) ++void drm_gem_private_object_init(struct drm_device *dev, ++ struct drm_gem_object *obj, size_t size) + { + BUG_ON((size & (PAGE_SIZE - 1)) != 0); + +@@ -163,8 +161,6 @@ int drm_gem_private_object_init(struct drm_device *dev, + kref_init(&obj->refcount); + atomic_set(&obj->handle_count, 0); + obj->size = size; +- +- return 0; + } + EXPORT_SYMBOL(drm_gem_private_object_init); + +diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c +index 8b1b6d923abe..362dd2ad286f 100644 +--- a/drivers/gpu/drm/gma500/framebuffer.c ++++ b/drivers/gpu/drm/gma500/framebuffer.c +@@ -321,10 +321,8 @@ static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size) + /* Begin by trying to use stolen memory backing */ + backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1); + if (backing) { +- if (drm_gem_private_object_init(dev, +- &backing->gem, aligned_size) == 0) +- return backing; +- psb_gtt_free_range(dev, backing); ++ drm_gem_private_object_init(dev, &backing->gem, aligned_size); ++ return backing; + } + return NULL; + } +diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c +index eefd6cc5b80d..fe1d3320ce6a 100644 +--- a/drivers/gpu/drm/gma500/gem.c ++++ b/drivers/gpu/drm/gma500/gem.c +@@ -261,11 +261,12 @@ static int psb_gem_create_stolen(struct drm_file *file, struct drm_device *dev, + struct gtt_range *gtt = psb_gtt_alloc_range(dev, size, "gem", 1); + if (gtt == NULL) + return -ENOMEM; +- if (drm_gem_private_object_init(dev, >t->gem, size) != 0) +- goto free_gtt; ++ ++ drm_gem_private_object_init(dev, >t->gem, size); + if (drm_gem_handle_create(file, >t->gem, handle) == 0) + return 0; +-free_gtt: ++ ++ drm_gem_object_release(>t->gem); + psb_gtt_free_range(dev, gtt); + return -ENOMEM; + } +diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c +index 9e6578330801..6ed7275d0900 100644 +--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c ++++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c +@@ -297,12 +297,7 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, + goto fail_detach; + } + +- ret = drm_gem_private_object_init(dev, &obj->base, dma_buf->size); +- if (ret) { +- i915_gem_object_free(obj); +- goto fail_detach; +- } +- ++ drm_gem_private_object_init(dev, &obj->base, dma_buf->size); + i915_gem_object_init(obj, &i915_gem_object_dmabuf_ops); + obj->base.import_attach = attach; + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 27ffb4c865fa..977b3d91f4e0 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -291,9 +291,7 @@ _i915_gem_object_create_stolen(struct drm_device *dev, + if (obj == NULL) + return NULL; + +- if (drm_gem_private_object_init(dev, &obj->base, stolen->size)) +- goto cleanup; +- ++ drm_gem_private_object_init(dev, &obj->base, stolen->size); + i915_gem_object_init(obj, &i915_gem_object_stolen_ops); + + obj->pages = i915_pages_create_for_stolen(dev, +diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c +index ebbdf4132e9c..cbcd71e6ed83 100644 +--- a/drivers/gpu/drm/omapdrm/omap_gem.c ++++ b/drivers/gpu/drm/omapdrm/omap_gem.c +@@ -1427,8 +1427,9 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, + omap_obj->height = gsize.tiled.height; + } + ++ ret = 0; + if (flags & (OMAP_BO_DMA|OMAP_BO_EXT_MEM)) +- ret = drm_gem_private_object_init(dev, obj, size); ++ drm_gem_private_object_init(dev, obj, size); + else + ret = drm_gem_object_init(dev, obj, size); + +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 63d17ee9eb48..8043e53374d9 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1643,8 +1643,8 @@ struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, + size_t size); + int drm_gem_object_init(struct drm_device *dev, + struct drm_gem_object *obj, size_t size); +-int drm_gem_private_object_init(struct drm_device *dev, +- struct drm_gem_object *obj, size_t size); ++void drm_gem_private_object_init(struct drm_device *dev, ++ struct drm_gem_object *obj, size_t size); + void drm_gem_object_handle_free(struct drm_gem_object *obj); + void drm_gem_vm_open(struct vm_area_struct *vma); + void drm_gem_vm_close(struct vm_area_struct *vma); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0510-drm-i915-Add-some-debug-breadcrumbs-to-connector-det.patch b/patches.baytrail/0510-drm-i915-Add-some-debug-breadcrumbs-to-connector-det.patch new file mode 100644 index 000000000000..d753e4bae61c --- /dev/null +++ b/patches.baytrail/0510-drm-i915-Add-some-debug-breadcrumbs-to-connector-det.patch @@ -0,0 +1,127 @@ +From 8a0ef882a773379ea5b08464d0c8018dddfd3c69 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Sat, 20 Jul 2013 20:27:08 +0100 +Subject: drm/i915: Add some debug breadcrumbs to connector detection + +Try to decypher detection failures is a little tricker at the moment as +the only indicator of progress is when output_poll_execute() tells us +the result after the connector->detect() has run. This patch adds a +telltale to the start of each detect function so that we can track +progress and associate activity more clearly with each connector. + +Signed-off-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 164c8598450657d01fa75d6c997e95eb35672eef) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_crt.c | 4 ++++ + drivers/gpu/drm/i915/intel_dp.c | 3 +++ + drivers/gpu/drm/i915/intel_dvo.c | 2 ++ + drivers/gpu/drm/i915/intel_hdmi.c | 3 +++ + drivers/gpu/drm/i915/intel_lvds.c | 3 +++ + drivers/gpu/drm/i915/intel_sdvo.c | 3 +++ + drivers/gpu/drm/i915/intel_tv.c | 4 ++++ + 7 files changed, 22 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c +index 3acec8c48166..0c0d4e8d768e 100644 +--- a/drivers/gpu/drm/i915/intel_crt.c ++++ b/drivers/gpu/drm/i915/intel_crt.c +@@ -613,6 +613,10 @@ intel_crt_detect(struct drm_connector *connector, bool force) + enum drm_connector_status status; + struct intel_load_detect_pipe tmp; + ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", ++ connector->base.id, drm_get_connector_name(connector), ++ force); ++ + if (I915_HAS_HOTPLUG(dev)) { + /* We can not rely on the HPD pin always being correctly wired + * up, for example many KVM do not pass it through, and so +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index db9cb317f5ce..ccf3b6f0c9a9 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -2831,6 +2831,9 @@ intel_dp_detect(struct drm_connector *connector, bool force) + enum drm_connector_status status; + struct edid *edid = NULL; + ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", ++ connector->base.id, drm_get_connector_name(connector)); ++ + intel_dp->has_audio = false; + + if (HAS_PCH_SPLIT(dev)) +diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c +index cbbc49dc03be..8b4ad27791f3 100644 +--- a/drivers/gpu/drm/i915/intel_dvo.c ++++ b/drivers/gpu/drm/i915/intel_dvo.c +@@ -332,6 +332,8 @@ static enum drm_connector_status + intel_dvo_detect(struct drm_connector *connector, bool force) + { + struct intel_dvo *intel_dvo = intel_attached_dvo(connector); ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", ++ connector->base.id, drm_get_connector_name(connector)); + return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev); + } + +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 2fd3fd5b943e..044d11d05944 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -879,6 +879,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) + struct edid *edid; + enum drm_connector_status status = connector_status_disconnected; + ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", ++ connector->base.id, drm_get_connector_name(connector)); ++ + intel_hdmi->has_hdmi_sink = false; + intel_hdmi->has_audio = false; + intel_hdmi->rgb_quant_range_selectable = false; +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 57ecc57a6fa4..176891679ae9 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -343,6 +343,9 @@ intel_lvds_detect(struct drm_connector *connector, bool force) + struct drm_device *dev = connector->dev; + enum drm_connector_status status; + ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", ++ connector->base.id, drm_get_connector_name(connector)); ++ + status = intel_panel_detect(dev); + if (status != connector_status_unknown) + return status; +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 798df114cfd3..c3b59b8593b9 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1696,6 +1696,9 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) + struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); + enum drm_connector_status ret; + ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", ++ connector->base.id, drm_get_connector_name(connector)); ++ + if (!intel_sdvo_get_value(intel_sdvo, + SDVO_CMD_GET_ATTACHED_DISPLAYS, + &response, 2)) +diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c +index d7fe4f89f7fc..685017000087 100644 +--- a/drivers/gpu/drm/i915/intel_tv.c ++++ b/drivers/gpu/drm/i915/intel_tv.c +@@ -1313,6 +1313,10 @@ intel_tv_detect(struct drm_connector *connector, bool force) + struct intel_tv *intel_tv = intel_attached_tv(connector); + int type; + ++ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", ++ connector->base.id, drm_get_connector_name(connector), ++ force); ++ + mode = reported_modes[0]; + + if (force) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0511-drm-i915-fix-up-error-cleanup-in-i915_gem_object_bin.patch b/patches.baytrail/0511-drm-i915-fix-up-error-cleanup-in-i915_gem_object_bin.patch new file mode 100644 index 000000000000..7c6627a8294b --- /dev/null +++ b/patches.baytrail/0511-drm-i915-fix-up-error-cleanup-in-i915_gem_object_bin.patch @@ -0,0 +1,80 @@ +From 53c09e4ab5a802738c4716fe9c88f84452549687 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 22 Jul 2013 12:12:38 +0200 +Subject: drm/i915: fix up error cleanup in i915_gem_object_bind_to_gtt + +This has been broken in + +commit 2f63315692b1d3c055972ad33fc7168ae908b97b +Author: Ben Widawsky +Date: Wed Jul 17 12:19:03 2013 -0700 + + drm/i915: Create VMAs + +which resulted in an OOPS the first time around we've hit -ENOSPC. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67156 +Cc: Imre Deak +Cc: Ben Widawsky +Tested-by: meng +Reviewed-by: Chris Wilson +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit bc6bc15bd7d6bbe3dd2da65d1a81a6dec5d0fa94) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 37641c014e7a..6703fc35a0b9 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3123,8 +3123,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + + vma = i915_gem_vma_create(obj, &dev_priv->gtt.base); + if (IS_ERR(vma)) { +- i915_gem_object_unpin_pages(obj); +- return PTR_ERR(vma); ++ ret = PTR_ERR(vma); ++ goto err_unpin; + } + + search_free: +@@ -3140,17 +3140,17 @@ search_free: + if (ret == 0) + goto search_free; + +- goto err_out; ++ goto err_free_vma; + } + if (WARN_ON(!i915_gem_valid_gtt_space(dev, &vma->node, + obj->cache_level))) { + ret = -EINVAL; +- goto err_out; ++ goto err_remove_node; + } + + ret = i915_gem_gtt_prepare_object(obj); + if (ret) +- goto err_out; ++ goto err_remove_node; + + list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); + list_add_tail(&obj->mm_list, &vm->inactive_list); +@@ -3169,9 +3169,11 @@ search_free: + i915_gem_verify_gtt(dev); + return 0; + +-err_out: ++err_remove_node: + drm_mm_remove_node(&vma->node); ++err_free_vma: + i915_gem_vma_destroy(vma); ++err_unpin: + i915_gem_object_unpin_pages(obj); + return ret; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0512-drm-i915-extend-lpt_enable_clkout_dp.patch b/patches.baytrail/0512-drm-i915-extend-lpt_enable_clkout_dp.patch new file mode 100644 index 000000000000..a62b7160ce73 --- /dev/null +++ b/patches.baytrail/0512-drm-i915-extend-lpt_enable_clkout_dp.patch @@ -0,0 +1,113 @@ +From b95b1781aa152aa74d2051937a5216acde78ed92 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Tue, 23 Jul 2013 11:19:24 -0300 +Subject: drm/i915: extend lpt_enable_clkout_dp + +Now it implements 3 different sequences from BSpec and also has +support for ULT. + +v2: - Change IS_ULT checks for LPT-LP checks + - Add check for LPT-LP + with_fdi (Ben) + - Merge DBUFF0/GEN0 bit definitions since they're the same + register (Ben) + - DBUFF0 (1<<0) is Disable, not Enable + +Reviewed-by: Ben Widawsky +Signed-off-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 2fa86a1fea14c3019b2de16ea47e1a5363c60905) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 3 ++- + drivers/gpu/drm/i915/intel_display.c | 43 +++++++++++++++++++++++++----------- + 2 files changed, 32 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 1fa35798a94d..cf42bd61b420 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -4950,7 +4950,8 @@ + #define SBI_SSCAUXDIV6 0x0610 + #define SBI_SSCAUXDIV_FINALDIV2SEL(x) ((x)<<4) + #define SBI_DBUFF0 0x2a00 +-#define SBI_DBUFF0_ENABLE (1<<0) ++#define SBI_GEN0 0x1f00 ++#define SBI_GEN0_CFG_BUFFENABLE_DISABLE (1<<0) + + /* LPT PIXCLK_GATE */ + #define PIXCLK_GATE 0xC6020 +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index bf450d725fc3..216de8639c70 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5260,11 +5260,23 @@ static void lpt_program_fdi_mphy(struct drm_i915_private *dev_priv) + intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY); + } + +-/* Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O. */ +-static void lpt_enable_clkout_dp(struct drm_device *dev) ++/* Implements 3 different sequences from BSpec chapter "Display iCLK ++ * Programming" based on the parameters passed: ++ * - Sequence to enable CLKOUT_DP ++ * - Sequence to enable CLKOUT_DP without spread ++ * - Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O ++ */ ++static void lpt_enable_clkout_dp(struct drm_device *dev, bool with_spread, ++ bool with_fdi) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- uint32_t tmp; ++ uint32_t reg, tmp; ++ ++ if (WARN(with_fdi && !with_spread, "FDI requires downspread\n")) ++ with_spread = true; ++ if (WARN(dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE && ++ with_fdi, "LP PCH doesn't have FDI\n")) ++ with_fdi = false; + + mutex_lock(&dev_priv->dpio_lock); + +@@ -5275,17 +5287,22 @@ static void lpt_enable_clkout_dp(struct drm_device *dev) + + udelay(24); + +- tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); +- tmp &= ~SBI_SSCCTL_PATHALT; +- intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); ++ if (with_spread) { ++ tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); ++ tmp &= ~SBI_SSCCTL_PATHALT; ++ intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); + +- lpt_reset_fdi_mphy(dev_priv); +- lpt_program_fdi_mphy(dev_priv); ++ if (with_fdi) { ++ lpt_reset_fdi_mphy(dev_priv); ++ lpt_program_fdi_mphy(dev_priv); ++ } ++ } + +- /* ULT uses SBI_GEN0, but ULT doesn't have VGA, so we don't care. */ +- tmp = intel_sbi_read(dev_priv, SBI_DBUFF0, SBI_ICLK); +- tmp |= SBI_DBUFF0_ENABLE; +- intel_sbi_write(dev_priv, SBI_DBUFF0, tmp, SBI_ICLK); ++ reg = (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) ? ++ SBI_GEN0 : SBI_DBUFF0; ++ tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK); ++ tmp |= SBI_GEN0_CFG_BUFFENABLE_DISABLE; ++ intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK); + + mutex_unlock(&dev_priv->dpio_lock); + } +@@ -5307,7 +5324,7 @@ static void lpt_init_pch_refclk(struct drm_device *dev) + if (!has_vga) + return; + +- lpt_enable_clkout_dp(dev); ++ lpt_enable_clkout_dp(dev, true, true); + } + + /* +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0513-drm-i915-disable-CLKOUT_DP-when-it-s-not-needed.patch b/patches.baytrail/0513-drm-i915-disable-CLKOUT_DP-when-it-s-not-needed.patch new file mode 100644 index 000000000000..af5efd0ccccd --- /dev/null +++ b/patches.baytrail/0513-drm-i915-disable-CLKOUT_DP-when-it-s-not-needed.patch @@ -0,0 +1,78 @@ +From c106ff43d2181472bd3214eddf01241195dc9909 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Tue, 23 Jul 2013 11:19:25 -0300 +Subject: drm/i915: disable CLKOUT_DP when it's not needed + +We currently don't support HDMI clock bending nor use SSC for DP or +HDMI on Haswell, so the only case where we need CLKOUT_DP is for VGA. + +v2: - Replace the IS_ULT check for LPT-LP + - Simplify GEN0/DBUFF0 check due to change on the previous patch + - Also check for SBI_SSCCTL_DISABLE (Ben). + +Reviewed-by: Ben Widawsky +Signed-off-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 47701c3ba26cb33ebe8a5e899ec922ab0de621a3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 36 ++++++++++++++++++++++++++++++++---- + 1 file changed, 32 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 216de8639c70..4da60eebdf96 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5307,6 +5307,34 @@ static void lpt_enable_clkout_dp(struct drm_device *dev, bool with_spread, + mutex_unlock(&dev_priv->dpio_lock); + } + ++/* Sequence to disable CLKOUT_DP */ ++static void lpt_disable_clkout_dp(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ uint32_t reg, tmp; ++ ++ mutex_lock(&dev_priv->dpio_lock); ++ ++ reg = (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) ? ++ SBI_GEN0 : SBI_DBUFF0; ++ tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK); ++ tmp &= ~SBI_GEN0_CFG_BUFFENABLE_DISABLE; ++ intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK); ++ ++ tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); ++ if (!(tmp & SBI_SSCCTL_DISABLE)) { ++ if (!(tmp & SBI_SSCCTL_PATHALT)) { ++ tmp |= SBI_SSCCTL_PATHALT; ++ intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); ++ udelay(32); ++ } ++ tmp |= SBI_SSCCTL_DISABLE; ++ intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); ++ } ++ ++ mutex_unlock(&dev_priv->dpio_lock); ++} ++ + static void lpt_init_pch_refclk(struct drm_device *dev) + { + struct drm_mode_config *mode_config = &dev->mode_config; +@@ -5321,10 +5349,10 @@ static void lpt_init_pch_refclk(struct drm_device *dev) + } + } + +- if (!has_vga) +- return; +- +- lpt_enable_clkout_dp(dev, true, true); ++ if (has_vga) ++ lpt_enable_clkout_dp(dev, true, true); ++ else ++ lpt_disable_clkout_dp(dev); + } + + /* +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0514-drm-i915-add-functions-to-disable-and-restore-LCPLL.patch b/patches.baytrail/0514-drm-i915-add-functions-to-disable-and-restore-LCPLL.patch new file mode 100644 index 000000000000..8d52a756e2d1 --- /dev/null +++ b/patches.baytrail/0514-drm-i915-add-functions-to-disable-and-restore-LCPLL.patch @@ -0,0 +1,246 @@ +From 0f1a41c7df58bb279ba6421d5c7e6f6ab8c5562b Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Tue, 23 Jul 2013 11:19:26 -0300 +Subject: drm/i915: add functions to disable and restore LCPLL + +For now there are no callers, but these functions are going to be +needed for the code that allows Package C8+. Other future features may +also require this code. + +Also merge the commit which introduced assert_can_disable_lcpll and +had the following commit message: + +Most of the hardware needs to be disabled before LCPLL is disabled, so +let's add a function to assert some of items listed in the "Display +Sequences for LCPLL disabling" documentation. + +The idea is that hsw_disable_lcpll should not disable the hardware, +the callers need to take care of calling hsw_disable_lcpll only once +everything is already disabled. + +v2: - Rebase. + - Fix D_COMP wait timeout. +v3: - Use wait_for_atomic_use (Ben) + - Remove/add a useless/needed POSTING_READ (Ben) + - Early return in case LCPLL is already restored (Ben) + - Add ndelay(100) (Ben) +v4: - Merge the commit that added assert_can_disable_lcpll (Ben) + - Add interrupt assertions (Ben) + +Reviewed-by: Ben Widawsky +Signed-off-by: Paulo Zanoni +[danvet: Fix compile fail since there's no HAS_LP_PCH yet.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit be256dc70284c028d0dd828b18b8f804e310507b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 15 ++++ + drivers/gpu/drm/i915/intel_display.c | 136 +++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/i915/intel_drv.h | 3 + + 3 files changed, 154 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index cf42bd61b420..fbe585da44d9 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -2269,6 +2269,8 @@ + #define BLC_PWM_CPU_CTL2 0x48250 + #define BLC_PWM_CPU_CTL 0x48254 + ++#define HSW_BLC_PWM2_CTL 0x48350 ++ + /* PCH CTL1 is totally different, all but the below bits are reserved. CTL2 is + * like the normal CTL from gen4 and earlier. Hooray for confusing naming. */ + #define BLC_PWM_PCH_CTL1 0xc8250 +@@ -2277,6 +2279,12 @@ + #define BLM_PCH_POLARITY (1 << 29) + #define BLC_PWM_PCH_CTL2 0xc8254 + ++#define UTIL_PIN_CTL 0x48400 ++#define UTIL_PIN_ENABLE (1 << 31) ++ ++#define PCH_GTC_CTL 0xe7000 ++#define PCH_GTC_ENABLE (1 << 31) ++ + /* TV port control */ + #define TV_CTL 0x68000 + /** Enables the TV encoder */ +@@ -5017,7 +5025,14 @@ + #define LCPLL_CLK_FREQ_450 (0<<26) + #define LCPLL_CD_CLOCK_DISABLE (1<<25) + #define LCPLL_CD2X_CLOCK_DISABLE (1<<23) ++#define LCPLL_POWER_DOWN_ALLOW (1<<22) + #define LCPLL_CD_SOURCE_FCLK (1<<21) ++#define LCPLL_CD_SOURCE_FCLK_DONE (1<<19) ++ ++#define D_COMP (MCHBAR_MIRROR_BASE_SNB + 0x5F0C) ++#define D_COMP_RCOMP_IN_PROGRESS (1<<9) ++#define D_COMP_COMP_FORCE (1<<8) ++#define D_COMP_COMP_DISABLE (1<<0) + + /* Pipe WM_LINETIME - watermark line time */ + #define PIPE_WM_LINETIME_A 0x45270 +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 4da60eebdf96..73965dfbf149 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5922,6 +5922,142 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, + return true; + } + ++static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv) ++{ ++ struct drm_device *dev = dev_priv->dev; ++ struct intel_ddi_plls *plls = &dev_priv->ddi_plls; ++ struct intel_crtc *crtc; ++ unsigned long irqflags; ++ uint32_t val, pch_hpd_mask; ++ ++ pch_hpd_mask = SDE_PORTB_HOTPLUG_CPT | SDE_PORTC_HOTPLUG_CPT; ++ if (!(dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE)) ++ pch_hpd_mask |= SDE_PORTD_HOTPLUG_CPT | SDE_CRT_HOTPLUG_CPT; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) ++ WARN(crtc->base.enabled, "CRTC for pipe %c enabled\n", ++ pipe_name(crtc->pipe)); ++ ++ WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n"); ++ WARN(plls->spll_refcount, "SPLL enabled\n"); ++ WARN(plls->wrpll1_refcount, "WRPLL1 enabled\n"); ++ WARN(plls->wrpll2_refcount, "WRPLL2 enabled\n"); ++ WARN(I915_READ(PCH_PP_STATUS) & PP_ON, "Panel power on\n"); ++ WARN(I915_READ(BLC_PWM_CPU_CTL2) & BLM_PWM_ENABLE, ++ "CPU PWM1 enabled\n"); ++ WARN(I915_READ(HSW_BLC_PWM2_CTL) & BLM_PWM_ENABLE, ++ "CPU PWM2 enabled\n"); ++ WARN(I915_READ(BLC_PWM_PCH_CTL1) & BLM_PCH_PWM_ENABLE, ++ "PCH PWM1 enabled\n"); ++ WARN(I915_READ(UTIL_PIN_CTL) & UTIL_PIN_ENABLE, ++ "Utility pin enabled\n"); ++ WARN(I915_READ(PCH_GTC_CTL) & PCH_GTC_ENABLE, "PCH GTC enabled\n"); ++ ++ spin_lock_irqsave(&dev_priv->irq_lock, irqflags); ++ val = I915_READ(DEIMR); ++ WARN((val & ~DE_PCH_EVENT_IVB) != val, ++ "Unexpected DEIMR bits enabled: 0x%x\n", val); ++ val = I915_READ(SDEIMR); ++ WARN((val & ~pch_hpd_mask) != val, ++ "Unexpected SDEIMR bits enabled: 0x%x\n", val); ++ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); ++} ++ ++/* ++ * This function implements pieces of two sequences from BSpec: ++ * - Sequence for display software to disable LCPLL ++ * - Sequence for display software to allow package C8+ ++ * The steps implemented here are just the steps that actually touch the LCPLL ++ * register. Callers should take care of disabling all the display engine ++ * functions, doing the mode unset, fixing interrupts, etc. ++ */ ++void hsw_disable_lcpll(struct drm_i915_private *dev_priv, ++ bool switch_to_fclk, bool allow_power_down) ++{ ++ uint32_t val; ++ ++ assert_can_disable_lcpll(dev_priv); ++ ++ val = I915_READ(LCPLL_CTL); ++ ++ if (switch_to_fclk) { ++ val |= LCPLL_CD_SOURCE_FCLK; ++ I915_WRITE(LCPLL_CTL, val); ++ ++ if (wait_for_atomic_us(I915_READ(LCPLL_CTL) & ++ LCPLL_CD_SOURCE_FCLK_DONE, 1)) ++ DRM_ERROR("Switching to FCLK failed\n"); ++ ++ val = I915_READ(LCPLL_CTL); ++ } ++ ++ val |= LCPLL_PLL_DISABLE; ++ I915_WRITE(LCPLL_CTL, val); ++ POSTING_READ(LCPLL_CTL); ++ ++ if (wait_for((I915_READ(LCPLL_CTL) & LCPLL_PLL_LOCK) == 0, 1)) ++ DRM_ERROR("LCPLL still locked\n"); ++ ++ val = I915_READ(D_COMP); ++ val |= D_COMP_COMP_DISABLE; ++ I915_WRITE(D_COMP, val); ++ POSTING_READ(D_COMP); ++ ndelay(100); ++ ++ if (wait_for((I915_READ(D_COMP) & D_COMP_RCOMP_IN_PROGRESS) == 0, 1)) ++ DRM_ERROR("D_COMP RCOMP still in progress\n"); ++ ++ if (allow_power_down) { ++ val = I915_READ(LCPLL_CTL); ++ val |= LCPLL_POWER_DOWN_ALLOW; ++ I915_WRITE(LCPLL_CTL, val); ++ POSTING_READ(LCPLL_CTL); ++ } ++} ++ ++/* ++ * Fully restores LCPLL, disallowing power down and switching back to LCPLL ++ * source. ++ */ ++void hsw_restore_lcpll(struct drm_i915_private *dev_priv) ++{ ++ uint32_t val; ++ ++ val = I915_READ(LCPLL_CTL); ++ ++ if ((val & (LCPLL_PLL_LOCK | LCPLL_PLL_DISABLE | LCPLL_CD_SOURCE_FCLK | ++ LCPLL_POWER_DOWN_ALLOW)) == LCPLL_PLL_LOCK) ++ return; ++ ++ if (val & LCPLL_POWER_DOWN_ALLOW) { ++ val &= ~LCPLL_POWER_DOWN_ALLOW; ++ I915_WRITE(LCPLL_CTL, val); ++ } ++ ++ val = I915_READ(D_COMP); ++ val |= D_COMP_COMP_FORCE; ++ val &= ~D_COMP_COMP_DISABLE; ++ I915_WRITE(D_COMP, val); ++ I915_READ(D_COMP); ++ ++ val = I915_READ(LCPLL_CTL); ++ val &= ~LCPLL_PLL_DISABLE; ++ I915_WRITE(LCPLL_CTL, val); ++ ++ if (wait_for(I915_READ(LCPLL_CTL) & LCPLL_PLL_LOCK, 5)) ++ DRM_ERROR("LCPLL not locked yet\n"); ++ ++ if (val & LCPLL_CD_SOURCE_FCLK) { ++ val = I915_READ(LCPLL_CTL); ++ val &= ~LCPLL_CD_SOURCE_FCLK; ++ I915_WRITE(LCPLL_CTL, val); ++ ++ if (wait_for_atomic_us((I915_READ(LCPLL_CTL) & ++ LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1)) ++ DRM_ERROR("Switching back to LCPLL failed\n"); ++ } ++} ++ + static void haswell_modeset_global_resources(struct drm_device *dev) + { + bool enable = false; +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 31087ff6d871..3fbe80bc36bb 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -838,5 +838,8 @@ extern bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, + extern void intel_edp_psr_enable(struct intel_dp *intel_dp); + extern void intel_edp_psr_disable(struct intel_dp *intel_dp); + extern void intel_edp_psr_update(struct drm_device *dev); ++extern void hsw_disable_lcpll(struct drm_i915_private *dev_priv, ++ bool switch_to_fclk, bool allow_power_down); ++extern void hsw_restore_lcpll(struct drm_i915_private *dev_priv); + + #endif /* __INTEL_DRV_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0515-drm-i915-disable-stolen-mem-for-OVERLAY_NEEDS_PHYSIC.patch b/patches.baytrail/0515-drm-i915-disable-stolen-mem-for-OVERLAY_NEEDS_PHYSIC.patch new file mode 100644 index 000000000000..5ff340deaf48 --- /dev/null +++ b/patches.baytrail/0515-drm-i915-disable-stolen-mem-for-OVERLAY_NEEDS_PHYSIC.patch @@ -0,0 +1,39 @@ +From f9807e455d3b32ed6c661152de6974d0e171769d Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 23 Jul 2013 19:24:38 +0200 +Subject: drm/i915: disable stolen mem for OVERLAY_NEEDS_PHYSICAL + +Our phys_object code can't deal with stolen memory and so blows up. +Fixing this is quite a bit of work and not worth it much for a single +page object, so just opt-out. + +This is necessary prep work to enable stolen on gen2/3 platforms where +the overlay register file isn't stored in the gtt. + +Cc: Chris Wilson +Acked-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit f63a484c2f606b8267eb4d1dbfce5d1d3416e0bb) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_overlay.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c +index 2abb53e6f1e0..9ec5a4e12af2 100644 +--- a/drivers/gpu/drm/i915/intel_overlay.c ++++ b/drivers/gpu/drm/i915/intel_overlay.c +@@ -1333,7 +1333,9 @@ void intel_setup_overlay(struct drm_device *dev) + + overlay->dev = dev; + +- reg_bo = i915_gem_object_create_stolen(dev, PAGE_SIZE); ++ reg_bo = NULL; ++ if (!OVERLAY_NEEDS_PHYSICAL(dev)) ++ reg_bo = i915_gem_object_create_stolen(dev, PAGE_SIZE); + if (reg_bo == NULL) + reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); + if (reg_bo == NULL) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0516-drm-i915-Use-Graphics-Base-of-Stolen-Memory-on-all-g.patch b/patches.baytrail/0516-drm-i915-Use-Graphics-Base-of-Stolen-Memory-on-all-g.patch new file mode 100644 index 000000000000..f373b0f0c89d --- /dev/null +++ b/patches.baytrail/0516-drm-i915-Use-Graphics-Base-of-Stolen-Memory-on-all-g.patch @@ -0,0 +1,89 @@ +From 42d8eb1da8adc1eefac8d10f38a885f15d217e73 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Thu, 4 Jul 2013 00:23:33 +0100 +Subject: drm/i915: Use Graphics Base of Stolen Memory on all gen3+ + +So I made the mistake of missing that the desktop and mobile chipsets +have different layouts in their PCI configurations, and we were +incorrectly setting the wrong physical address for stolen memory on +mobile chipsets. + +Since all gen3+ are actually consistent in the location of the GBSM +register in the PCI configuration space on device 2 (the GPU), use it. + +Signed-off-by: Chris Wilson +Cc: Daniel Vetter +[danvet: Drop cc: stable and fudge conflicts.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 17fec8a08698bcab98788e1e89f5b8e7502ababd) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_stolen.c | 42 ++++++++++------------------------ + 1 file changed, 12 insertions(+), 30 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 977b3d91f4e0..cacf769c95fd 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -45,45 +45,27 @@ + static unsigned long i915_stolen_to_physical(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- struct pci_dev *pdev = dev_priv->bridge_dev; + struct resource *r; + u32 base; + +- /* On the machines I have tested the Graphics Base of Stolen Memory +- * is unreliable, so on those compute the base by subtracting the +- * stolen memory from the Top of Low Usable DRAM which is where the +- * BIOS places the graphics stolen memory. ++ /* Almost universally we can find the Graphics Base of Stolen Memory ++ * at offset 0x5c in the igfx configuration space. On a few (desktop) ++ * machines this is also mirrored in the bridge device at different ++ * locations, or in the MCHBAR. On gen2, the layout is again slightly ++ * different with the Graphics Segment immediately following Top of ++ * Memory (or Top of Usable DRAM). Note it appears that TOUD is only ++ * reported by 865g, so we just use the top of memory as determined ++ * by the e820 probe. + * +- * On gen2, the layout is slightly different with the Graphics Segment +- * immediately following Top of Memory (or Top of Usable DRAM). Note +- * it appears that TOUD is only reported by 865g, so we just use the +- * top of memory as determined by the e820 probe. +- * +- * XXX gen2 requires an unavailable symbol and 945gm fails with +- * its value of TOLUD. ++ * XXX However gen2 requires an unavailable symbol. + */ + base = 0; +- if (IS_VALLEYVIEW(dev)) { ++ if (INTEL_INFO(dev)->gen >= 3) { ++ /* Read Graphics Base of Stolen Memory directly */ + pci_read_config_dword(dev->pdev, 0x5c, &base); + base &= ~((1<<20) - 1); +- } else if (INTEL_INFO(dev)->gen >= 6) { +- /* Read Base Data of Stolen Memory Register (BDSM) directly. +- * Note that there is also a MCHBAR miror at 0x1080c0 or +- * we could use device 2:0x5c instead. +- */ +- pci_read_config_dword(pdev, 0xB0, &base); +- base &= ~4095; /* lower bits used for locking register */ +- } else if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) { +- /* Read Graphics Base of Stolen Memory directly */ +- pci_read_config_dword(pdev, 0xA4, &base); ++ } else { /* GEN2 */ + #if 0 +- } else if (IS_GEN3(dev)) { +- u8 val; +- /* Stolen is immediately below Top of Low Usable DRAM */ +- pci_read_config_byte(pdev, 0x9c, &val); +- base = val >> 3 << 27; +- base -= dev_priv->mm.gtt->stolen_size; +- } else { + /* Stolen is immediately above Top of Memory */ + base = max_low_pfn_mapped << PAGE_SHIFT; + #endif +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0517-drm-i915-fix-reference-counting-in-i915_gem_create.patch b/patches.baytrail/0517-drm-i915-fix-reference-counting-in-i915_gem_create.patch new file mode 100644 index 000000000000..331152236af1 --- /dev/null +++ b/patches.baytrail/0517-drm-i915-fix-reference-counting-in-i915_gem_create.patch @@ -0,0 +1,70 @@ +From ab7bc74d70e58ff6f07227bf0e5b605bc71a19b4 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 24 Jul 2013 23:25:03 +0200 +Subject: drm/i915: fix reference counting in i915_gem_create + +This function is called without the dev->struct_mutex held, hence we +need to use the _unlocked unreference variants. + +As soon as the object is registered userspace can sneak in here with a +gem_close ioctl call, so the object can (and with my new evil tests +actually does) get the final unreference in this place. The lack of +locking then results in hilarity and some good leakage. + +To fix this we simply need to revert + +Chris Wilson + +v2: We need to make the trace call _before_ we drop our ref - the +object might very well be gone by then already. + +v3: Just revert the original patch as suggested by Chris Wilson. + +Cc: Chris Wilson +Reviewed-by: Chris Wilson +[danvet: Remove the added white line again to tighten the return +block, requested by Chris.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit d861e3387650296f1fca2a4dd0dcd380c8fdddad) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 6703fc35a0b9..050eb9b92595 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -219,16 +219,10 @@ i915_gem_create(struct drm_file *file, + return -ENOMEM; + + ret = drm_gem_handle_create(file, &obj->base, &handle); +- if (ret) { +- drm_gem_object_release(&obj->base); +- i915_gem_info_remove_obj(dev->dev_private, obj->base.size); +- i915_gem_object_free(obj); +- return ret; +- } +- + /* drop reference from allocate - handle holds it now */ +- drm_gem_object_unreference(&obj->base); +- trace_i915_gem_object_create(obj); ++ drm_gem_object_unreference_unlocked(&obj->base); ++ if (ret) ++ return ret; + + *handle_p = handle; + return 0; +@@ -3942,6 +3936,8 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, + } else + obj->cache_level = I915_CACHE_NONE; + ++ trace_i915_gem_object_create(obj); ++ + return obj; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0518-drm-gem-Split-drm_gem_mmap-into-object-search-and-ob.patch b/patches.baytrail/0518-drm-gem-Split-drm_gem_mmap-into-object-search-and-ob.patch new file mode 100644 index 000000000000..18af07238baf --- /dev/null +++ b/patches.baytrail/0518-drm-gem-Split-drm_gem_mmap-into-object-search-and-ob.patch @@ -0,0 +1,151 @@ +From 2d6a5bc564be3b4a255d5448e69520526b80f13b Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart +Date: Tue, 16 Apr 2013 14:14:52 +0200 +Subject: drm/gem: Split drm_gem_mmap() into object search and object mapping + +The drm_gem_mmap() function first finds the GEM object to be mapped +based on the fake mmap offset and then maps the object. Split the object +mapping code into a standalone drm_gem_mmap_obj() function that can be +used to implement dma-buf mmap() operations. + +Signed-off-by: Laurent Pinchart +Reviewed-by: Rob Clark +(cherry picked from commit 1c5aafa6eee2d5712f774676d407e5ab6dae9a1b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_gem.c | 83 +++++++++++++++++++++++++++++------------------ + include/drm/drmP.h | 2 ++ + 2 files changed, 54 insertions(+), 31 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index fdd8248925b8..df6c89ec27ec 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -632,6 +632,55 @@ void drm_gem_vm_close(struct vm_area_struct *vma) + } + EXPORT_SYMBOL(drm_gem_vm_close); + ++/** ++ * drm_gem_mmap_obj - memory map a GEM object ++ * @obj: the GEM object to map ++ * @obj_size: the object size to be mapped, in bytes ++ * @vma: VMA for the area to be mapped ++ * ++ * Set up the VMA to prepare mapping of the GEM object using the gem_vm_ops ++ * provided by the driver. Depending on their requirements, drivers can either ++ * provide a fault handler in their gem_vm_ops (in which case any accesses to ++ * the object will be trapped, to perform migration, GTT binding, surface ++ * register allocation, or performance monitoring), or mmap the buffer memory ++ * synchronously after calling drm_gem_mmap_obj. ++ * ++ * This function is mainly intended to implement the DMABUF mmap operation, when ++ * the GEM object is not looked up based on its fake offset. To implement the ++ * DRM mmap operation, drivers should use the drm_gem_mmap() function. ++ * ++ * Return 0 or success or -EINVAL if the object size is smaller than the VMA ++ * size, or if no gem_vm_ops are provided. ++ */ ++int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size, ++ struct vm_area_struct *vma) ++{ ++ struct drm_device *dev = obj->dev; ++ ++ /* Check for valid size. */ ++ if (obj_size < vma->vm_end - vma->vm_start) ++ return -EINVAL; ++ ++ if (!dev->driver->gem_vm_ops) ++ return -EINVAL; ++ ++ vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP; ++ vma->vm_ops = dev->driver->gem_vm_ops; ++ vma->vm_private_data = obj; ++ vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); ++ ++ /* Take a ref for this mapping of the object, so that the fault ++ * handler can dereference the mmap offset's pointer to the object. ++ * This reference is cleaned up by the corresponding vm_close ++ * (which should happen whether the vma was created by this call, or ++ * by a vm_open due to mremap or partial unmap or whatever). ++ */ ++ drm_gem_object_reference(obj); ++ ++ drm_vm_open_locked(dev, vma); ++ return 0; ++} ++EXPORT_SYMBOL(drm_gem_mmap_obj); + + /** + * drm_gem_mmap - memory map routine for GEM objects +@@ -641,11 +690,9 @@ EXPORT_SYMBOL(drm_gem_vm_close); + * If a driver supports GEM object mapping, mmap calls on the DRM file + * descriptor will end up here. + * +- * If we find the object based on the offset passed in (vma->vm_pgoff will ++ * Look up the GEM object based on the offset passed in (vma->vm_pgoff will + * contain the fake offset we created when the GTT map ioctl was called on +- * the object), we set up the driver fault handler so that any accesses +- * to the object can be trapped, to perform migration, GTT binding, surface +- * register allocation, or performance monitoring. ++ * the object) and map it with a call to drm_gem_mmap_obj(). + */ + int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) + { +@@ -653,7 +700,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) + struct drm_device *dev = priv->minor->dev; + struct drm_gem_mm *mm = dev->mm_private; + struct drm_local_map *map = NULL; +- struct drm_gem_object *obj; + struct drm_hash_item *hash; + int ret = 0; + +@@ -674,32 +720,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) + goto out_unlock; + } + +- /* Check for valid size. */ +- if (map->size < vma->vm_end - vma->vm_start) { +- ret = -EINVAL; +- goto out_unlock; +- } +- +- obj = map->handle; +- if (!obj->dev->driver->gem_vm_ops) { +- ret = -EINVAL; +- goto out_unlock; +- } +- +- vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP; +- vma->vm_ops = obj->dev->driver->gem_vm_ops; +- vma->vm_private_data = map->handle; +- vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); +- +- /* Take a ref for this mapping of the object, so that the fault +- * handler can dereference the mmap offset's pointer to the object. +- * This reference is cleaned up by the corresponding vm_close +- * (which should happen whether the vma was created by this call, or +- * by a vm_open due to mremap or partial unmap or whatever). +- */ +- drm_gem_object_reference(obj); +- +- drm_vm_open_locked(dev, vma); ++ ret = drm_gem_mmap_obj(map->handle, map->size, vma); + + out_unlock: + mutex_unlock(&dev->struct_mutex); +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 8043e53374d9..5ff88ad7b23c 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1648,6 +1648,8 @@ void drm_gem_private_object_init(struct drm_device *dev, + void drm_gem_object_handle_free(struct drm_gem_object *obj); + void drm_gem_vm_open(struct vm_area_struct *vma); + void drm_gem_vm_close(struct vm_area_struct *vma); ++int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size, ++ struct vm_area_struct *vma); + int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); + + #include +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0519-drm-add-unified-vma-offset-manager.patch b/patches.baytrail/0519-drm-add-unified-vma-offset-manager.patch new file mode 100644 index 000000000000..82c7779be6e4 --- /dev/null +++ b/patches.baytrail/0519-drm-add-unified-vma-offset-manager.patch @@ -0,0 +1,588 @@ +From 8cd816e0319f1a1263e882a8f74ba33161fd9e06 Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Wed, 24 Jul 2013 21:06:15 +0200 +Subject: drm: add unified vma offset manager + +If we want to map GPU memory into user-space, we need to linearize the +addresses to not confuse mm-core. Currently, GEM and TTM both implement +their own offset-managers to assign a pgoff to each object for user-space +CPU access. GEM uses a hash-table, TTM uses an rbtree. + +This patch provides a unified implementation that can be used to replace +both. TTM allows partial mmaps with a given offset, so we cannot use +hashtables as the start address may not be known at mmap time. Hence, we +use the rbtree-implementation of TTM. + +We could easily update drm_mm to use an rbtree instead of a linked list +for it's object list and thus drop the rbtree from the vma-manager. +However, this would slow down drm_mm object allocation for all other +use-cases (rbtree insertion) and add another 4-8 bytes to each mm node. +Hence, use the separate tree but allow for later migration. + +This is a rewrite of the 2012-proposal by David Airlie + +v2: + - fix Docbook integration + - drop drm_mm_node_linked() and use drm_mm_node_allocated() + - remove unjustified likely/unlikely usage (but keep for rbtree paths) + - remove BUG_ON() as drm_mm already does that + - clarify page-based vs. byte-based addresses + - use drm_vma_node_reset() for initialization, too +v4: + - allow external locking via drm_vma_offset_un/lock_lookup() + - add locked lookup helper drm_vma_offset_lookup_locked() +v5: + - fix drm_vma_offset_lookup() to correctly validate range-mismatches + (fix (offset > start + pages)) + - fix drm_vma_offset_exact_lookup() to actually do what it says + - remove redundant vm_pages member (add drm_vma_node_size() helper) + - remove unneeded goto + - fix documentation + +Signed-off-by: David Herrmann +Reviewed-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit fe3078fa5c367186c94a6652581ffbe9ccea4640) +Signed-off-by: James Ausmus + +Conflicts: + Documentation/DocBook/drm.tmpl + (context changes) +Signed-off-by: Darren Hart +--- + Documentation/DocBook/drm.tmpl | 6 + + drivers/gpu/drm/Makefile | 2 +- + drivers/gpu/drm/drm_vma_manager.c | 281 ++++++++++++++++++++++++++++++++++++++ + include/drm/drm_vma_manager.h | 202 +++++++++++++++++++++++++++ + 4 files changed, 490 insertions(+), 1 deletion(-) + create mode 100644 drivers/gpu/drm/drm_vma_manager.c + create mode 100644 include/drm/drm_vma_manager.h + +diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl +index 7c7af25b330c..ba664d7c5a89 100644 +--- a/Documentation/DocBook/drm.tmpl ++++ b/Documentation/DocBook/drm.tmpl +@@ -2163,6 +2163,12 @@ void intel_crt_init(struct drm_device *dev) + EDID Helper Functions Reference + !Edrivers/gpu/drm/drm_edid.c + ++ ++ VMA Offset Manager ++!Pdrivers/gpu/drm/drm_vma_manager.c vma offset manager ++!Edrivers/gpu/drm/drm_vma_manager.c ++!Iinclude/drm/drm_vma_manager.h ++ + + + +diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile +index 1ecbe5b7312d..d7115ad6f20d 100644 +--- a/drivers/gpu/drm/Makefile ++++ b/drivers/gpu/drm/Makefile +@@ -13,7 +13,7 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ + drm_crtc.o drm_modes.o drm_edid.o \ + drm_info.o drm_debugfs.o drm_encoder_slave.o \ + drm_trace_points.o drm_global.o drm_prime.o \ +- drm_rect.o ++ drm_rect.o drm_vma_manager.o + + drm-$(CONFIG_COMPAT) += drm_ioc32.o + drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o +diff --git a/drivers/gpu/drm/drm_vma_manager.c b/drivers/gpu/drm/drm_vma_manager.c +new file mode 100644 +index 000000000000..b966cea95f11 +--- /dev/null ++++ b/drivers/gpu/drm/drm_vma_manager.c +@@ -0,0 +1,281 @@ ++/* ++ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA ++ * Copyright (c) 2012 David Airlie ++ * Copyright (c) 2013 David Herrmann ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/** ++ * DOC: vma offset manager ++ * ++ * The vma-manager is responsible to map arbitrary driver-dependent memory ++ * regions into the linear user address-space. It provides offsets to the ++ * caller which can then be used on the address_space of the drm-device. It ++ * takes care to not overlap regions, size them appropriately and to not ++ * confuse mm-core by inconsistent fake vm_pgoff fields. ++ * Drivers shouldn't use this for object placement in VMEM. This manager should ++ * only be used to manage mappings into linear user-space VMs. ++ * ++ * We use drm_mm as backend to manage object allocations. But it is highly ++ * optimized for alloc/free calls, not lookups. Hence, we use an rb-tree to ++ * speed up offset lookups. ++ * ++ * You must not use multiple offset managers on a single address_space. ++ * Otherwise, mm-core will be unable to tear down memory mappings as the VM will ++ * no longer be linear. Please use VM_NONLINEAR in that case and implement your ++ * own offset managers. ++ * ++ * This offset manager works on page-based addresses. That is, every argument ++ * and return code (with the exception of drm_vma_node_offset_addr()) is given ++ * in number of pages, not number of bytes. That means, object sizes and offsets ++ * must always be page-aligned (as usual). ++ * If you want to get a valid byte-based user-space address for a given offset, ++ * please see drm_vma_node_offset_addr(). ++ */ ++ ++/** ++ * drm_vma_offset_manager_init - Initialize new offset-manager ++ * @mgr: Manager object ++ * @page_offset: Offset of available memory area (page-based) ++ * @size: Size of available address space range (page-based) ++ * ++ * Initialize a new offset-manager. The offset and area size available for the ++ * manager are given as @page_offset and @size. Both are interpreted as ++ * page-numbers, not bytes. ++ * ++ * Adding/removing nodes from the manager is locked internally and protected ++ * against concurrent access. However, node allocation and destruction is left ++ * for the caller. While calling into the vma-manager, a given node must ++ * always be guaranteed to be referenced. ++ */ ++void drm_vma_offset_manager_init(struct drm_vma_offset_manager *mgr, ++ unsigned long page_offset, unsigned long size) ++{ ++ rwlock_init(&mgr->vm_lock); ++ mgr->vm_addr_space_rb = RB_ROOT; ++ drm_mm_init(&mgr->vm_addr_space_mm, page_offset, size); ++} ++EXPORT_SYMBOL(drm_vma_offset_manager_init); ++ ++/** ++ * drm_vma_offset_manager_destroy() - Destroy offset manager ++ * @mgr: Manager object ++ * ++ * Destroy an object manager which was previously created via ++ * drm_vma_offset_manager_init(). The caller must remove all allocated nodes ++ * before destroying the manager. Otherwise, drm_mm will refuse to free the ++ * requested resources. ++ * ++ * The manager must not be accessed after this function is called. ++ */ ++void drm_vma_offset_manager_destroy(struct drm_vma_offset_manager *mgr) ++{ ++ /* take the lock to protect against buggy drivers */ ++ write_lock(&mgr->vm_lock); ++ drm_mm_takedown(&mgr->vm_addr_space_mm); ++ write_unlock(&mgr->vm_lock); ++} ++EXPORT_SYMBOL(drm_vma_offset_manager_destroy); ++ ++/** ++ * drm_vma_offset_lookup() - Find node in offset space ++ * @mgr: Manager object ++ * @start: Start address for object (page-based) ++ * @pages: Size of object (page-based) ++ * ++ * Find a node given a start address and object size. This returns the _best_ ++ * match for the given node. That is, @start may point somewhere into a valid ++ * region and the given node will be returned, as long as the node spans the ++ * whole requested area (given the size in number of pages as @pages). ++ * ++ * RETURNS: ++ * Returns NULL if no suitable node can be found. Otherwise, the best match ++ * is returned. It's the caller's responsibility to make sure the node doesn't ++ * get destroyed before the caller can access it. ++ */ ++struct drm_vma_offset_node *drm_vma_offset_lookup(struct drm_vma_offset_manager *mgr, ++ unsigned long start, ++ unsigned long pages) ++{ ++ struct drm_vma_offset_node *node; ++ ++ read_lock(&mgr->vm_lock); ++ node = drm_vma_offset_lookup_locked(mgr, start, pages); ++ read_unlock(&mgr->vm_lock); ++ ++ return node; ++} ++EXPORT_SYMBOL(drm_vma_offset_lookup); ++ ++/** ++ * drm_vma_offset_lookup_locked() - Find node in offset space ++ * @mgr: Manager object ++ * @start: Start address for object (page-based) ++ * @pages: Size of object (page-based) ++ * ++ * Same as drm_vma_offset_lookup() but requires the caller to lock offset lookup ++ * manually. See drm_vma_offset_lock_lookup() for an example. ++ * ++ * RETURNS: ++ * Returns NULL if no suitable node can be found. Otherwise, the best match ++ * is returned. ++ */ ++struct drm_vma_offset_node *drm_vma_offset_lookup_locked(struct drm_vma_offset_manager *mgr, ++ unsigned long start, ++ unsigned long pages) ++{ ++ struct drm_vma_offset_node *node, *best; ++ struct rb_node *iter; ++ unsigned long offset; ++ ++ iter = mgr->vm_addr_space_rb.rb_node; ++ best = NULL; ++ ++ while (likely(iter)) { ++ node = rb_entry(iter, struct drm_vma_offset_node, vm_rb); ++ offset = node->vm_node.start; ++ if (start >= offset) { ++ iter = iter->rb_right; ++ best = node; ++ if (start == offset) ++ break; ++ } else { ++ iter = iter->rb_left; ++ } ++ } ++ ++ /* verify that the node spans the requested area */ ++ if (best) { ++ offset = best->vm_node.start + best->vm_node.size; ++ if (offset < start + pages) ++ best = NULL; ++ } ++ ++ return best; ++} ++EXPORT_SYMBOL(drm_vma_offset_lookup_locked); ++ ++/* internal helper to link @node into the rb-tree */ ++static void _drm_vma_offset_add_rb(struct drm_vma_offset_manager *mgr, ++ struct drm_vma_offset_node *node) ++{ ++ struct rb_node **iter = &mgr->vm_addr_space_rb.rb_node; ++ struct rb_node *parent = NULL; ++ struct drm_vma_offset_node *iter_node; ++ ++ while (likely(*iter)) { ++ parent = *iter; ++ iter_node = rb_entry(*iter, struct drm_vma_offset_node, vm_rb); ++ ++ if (node->vm_node.start < iter_node->vm_node.start) ++ iter = &(*iter)->rb_left; ++ else if (node->vm_node.start > iter_node->vm_node.start) ++ iter = &(*iter)->rb_right; ++ else ++ BUG(); ++ } ++ ++ rb_link_node(&node->vm_rb, parent, iter); ++ rb_insert_color(&node->vm_rb, &mgr->vm_addr_space_rb); ++} ++ ++/** ++ * drm_vma_offset_add() - Add offset node to manager ++ * @mgr: Manager object ++ * @node: Node to be added ++ * @pages: Allocation size visible to user-space (in number of pages) ++ * ++ * Add a node to the offset-manager. If the node was already added, this does ++ * nothing and return 0. @pages is the size of the object given in number of ++ * pages. ++ * After this call succeeds, you can access the offset of the node until it ++ * is removed again. ++ * ++ * If this call fails, it is safe to retry the operation or call ++ * drm_vma_offset_remove(), anyway. However, no cleanup is required in that ++ * case. ++ * ++ * @pages is not required to be the same size as the underlying memory object ++ * that you want to map. It only limits the size that user-space can map into ++ * their address space. ++ * ++ * RETURNS: ++ * 0 on success, negative error code on failure. ++ */ ++int drm_vma_offset_add(struct drm_vma_offset_manager *mgr, ++ struct drm_vma_offset_node *node, unsigned long pages) ++{ ++ int ret; ++ ++ write_lock(&mgr->vm_lock); ++ ++ if (drm_mm_node_allocated(&node->vm_node)) { ++ ret = 0; ++ goto out_unlock; ++ } ++ ++ ret = drm_mm_insert_node_generic(&mgr->vm_addr_space_mm, ++ &node->vm_node, pages, 0, 0); ++ if (ret) ++ goto out_unlock; ++ ++ _drm_vma_offset_add_rb(mgr, node); ++ ++out_unlock: ++ write_unlock(&mgr->vm_lock); ++ return ret; ++} ++EXPORT_SYMBOL(drm_vma_offset_add); ++ ++/** ++ * drm_vma_offset_remove() - Remove offset node from manager ++ * @mgr: Manager object ++ * @node: Node to be removed ++ * ++ * Remove a node from the offset manager. If the node wasn't added before, this ++ * does nothing. After this call returns, the offset and size will be 0 until a ++ * new offset is allocated via drm_vma_offset_add() again. Helper functions like ++ * drm_vma_node_start() and drm_vma_node_offset_addr() will return 0 if no ++ * offset is allocated. ++ */ ++void drm_vma_offset_remove(struct drm_vma_offset_manager *mgr, ++ struct drm_vma_offset_node *node) ++{ ++ write_lock(&mgr->vm_lock); ++ ++ if (drm_mm_node_allocated(&node->vm_node)) { ++ rb_erase(&node->vm_rb, &mgr->vm_addr_space_rb); ++ drm_mm_remove_node(&node->vm_node); ++ memset(&node->vm_node, 0, sizeof(node->vm_node)); ++ } ++ ++ write_unlock(&mgr->vm_lock); ++} ++EXPORT_SYMBOL(drm_vma_offset_remove); +diff --git a/include/drm/drm_vma_manager.h b/include/drm/drm_vma_manager.h +new file mode 100644 +index 000000000000..7ee8c4babeb9 +--- /dev/null ++++ b/include/drm/drm_vma_manager.h +@@ -0,0 +1,202 @@ ++#ifndef __DRM_VMA_MANAGER_H__ ++#define __DRM_VMA_MANAGER_H__ ++ ++/* ++ * Copyright (c) 2013 David Herrmann ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++struct drm_vma_offset_node { ++ struct drm_mm_node vm_node; ++ struct rb_node vm_rb; ++}; ++ ++struct drm_vma_offset_manager { ++ rwlock_t vm_lock; ++ struct rb_root vm_addr_space_rb; ++ struct drm_mm vm_addr_space_mm; ++}; ++ ++void drm_vma_offset_manager_init(struct drm_vma_offset_manager *mgr, ++ unsigned long page_offset, unsigned long size); ++void drm_vma_offset_manager_destroy(struct drm_vma_offset_manager *mgr); ++ ++struct drm_vma_offset_node *drm_vma_offset_lookup(struct drm_vma_offset_manager *mgr, ++ unsigned long start, ++ unsigned long pages); ++struct drm_vma_offset_node *drm_vma_offset_lookup_locked(struct drm_vma_offset_manager *mgr, ++ unsigned long start, ++ unsigned long pages); ++int drm_vma_offset_add(struct drm_vma_offset_manager *mgr, ++ struct drm_vma_offset_node *node, unsigned long pages); ++void drm_vma_offset_remove(struct drm_vma_offset_manager *mgr, ++ struct drm_vma_offset_node *node); ++ ++/** ++ * drm_vma_offset_exact_lookup() - Look up node by exact address ++ * @mgr: Manager object ++ * @start: Start address (page-based, not byte-based) ++ * @pages: Size of object (page-based) ++ * ++ * Same as drm_vma_offset_lookup() but does not allow any offset into the node. ++ * It only returns the exact object with the given start address. ++ * ++ * RETURNS: ++ * Node at exact start address @start. ++ */ ++static inline struct drm_vma_offset_node * ++drm_vma_offset_exact_lookup(struct drm_vma_offset_manager *mgr, ++ unsigned long start, ++ unsigned long pages) ++{ ++ struct drm_vma_offset_node *node; ++ ++ node = drm_vma_offset_lookup(mgr, start, pages); ++ return (node && node->vm_node.start == start) ? node : NULL; ++} ++ ++/** ++ * drm_vma_offset_lock_lookup() - Lock lookup for extended private use ++ * @mgr: Manager object ++ * ++ * Lock VMA manager for extended lookups. Only *_locked() VMA function calls ++ * are allowed while holding this lock. All other contexts are blocked from VMA ++ * until the lock is released via drm_vma_offset_unlock_lookup(). ++ * ++ * Use this if you need to take a reference to the objects returned by ++ * drm_vma_offset_lookup_locked() before releasing this lock again. ++ * ++ * This lock must not be used for anything else than extended lookups. You must ++ * not call any other VMA helpers while holding this lock. ++ * ++ * Note: You're in atomic-context while holding this lock! ++ * ++ * Example: ++ * drm_vma_offset_lock_lookup(mgr); ++ * node = drm_vma_offset_lookup_locked(mgr); ++ * if (node) ++ * kref_get_unless_zero(container_of(node, sth, entr)); ++ * drm_vma_offset_unlock_lookup(mgr); ++ */ ++static inline void drm_vma_offset_lock_lookup(struct drm_vma_offset_manager *mgr) ++{ ++ read_lock(&mgr->vm_lock); ++} ++ ++/** ++ * drm_vma_offset_unlock_lookup() - Unlock lookup for extended private use ++ * @mgr: Manager object ++ * ++ * Release lookup-lock. See drm_vma_offset_lock_lookup() for more information. ++ */ ++static inline void drm_vma_offset_unlock_lookup(struct drm_vma_offset_manager *mgr) ++{ ++ read_unlock(&mgr->vm_lock); ++} ++ ++/** ++ * drm_vma_node_reset() - Initialize or reset node object ++ * @node: Node to initialize or reset ++ * ++ * Reset a node to its initial state. This must be called if @node isn't ++ * already cleared (eg., via kzalloc) before using it with any VMA offset ++ * manager. ++ * ++ * This must not be called on an already allocated node, or you will leak ++ * memory. ++ */ ++static inline void drm_vma_node_reset(struct drm_vma_offset_node *node) ++{ ++ memset(node, 0, sizeof(*node)); ++} ++ ++/** ++ * drm_vma_node_start() - Return start address for page-based addressing ++ * @node: Node to inspect ++ * ++ * Return the start address of the given node. This can be used as offset into ++ * the linear VM space that is provided by the VMA offset manager. Note that ++ * this can only be used for page-based addressing. If you need a proper offset ++ * for user-space mappings, you must apply "<< PAGE_SHIFT" or use the ++ * drm_vma_node_offset_addr() helper instead. ++ * ++ * RETURNS: ++ * Start address of @node for page-based addressing. 0 if the node does not ++ * have an offset allocated. ++ */ ++static inline unsigned long drm_vma_node_start(struct drm_vma_offset_node *node) ++{ ++ return node->vm_node.start; ++} ++ ++/** ++ * drm_vma_node_size() - Return size (page-based) ++ * @node: Node to inspect ++ * ++ * Return the size as number of pages for the given node. This is the same size ++ * that was passed to drm_vma_offset_add(). If no offset is allocated for the ++ * node, this is 0. ++ * ++ * RETURNS: ++ * Size of @node as number of pages. 0 if the node does not have an offset ++ * allocated. ++ */ ++static inline unsigned long drm_vma_node_size(struct drm_vma_offset_node *node) ++{ ++ return node->vm_node.size; ++} ++ ++/** ++ * drm_vma_node_has_offset() - Check whether node is added to offset manager ++ * @node: Node to be checked ++ * ++ * RETURNS: ++ * true iff the node was previously allocated an offset and added to ++ * an vma offset manager. ++ */ ++static inline bool drm_vma_node_has_offset(struct drm_vma_offset_node *node) ++{ ++ return drm_mm_node_allocated(&node->vm_node); ++} ++ ++/** ++ * drm_vma_node_offset_addr() - Return sanitized offset for user-space mmaps ++ * @node: Linked offset node ++ * ++ * Same as drm_vma_node_start() but returns the address as a valid offset that ++ * can be used for user-space mappings during mmap(). ++ * This must not be called on unlinked nodes. ++ * ++ * RETURNS: ++ * Offset of @node for byte-based addressing. 0 if the node does not have an ++ * object allocated. ++ */ ++static inline __u64 drm_vma_node_offset_addr(struct drm_vma_offset_node *node) ++{ ++ return ((__u64)node->vm_node.start) << PAGE_SHIFT; ++} ++ ++#endif /* __DRM_VMA_MANAGER_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0520-drm-gem-convert-to-new-unified-vma-manager.patch b/patches.baytrail/0520-drm-gem-convert-to-new-unified-vma-manager.patch new file mode 100644 index 000000000000..1ef454237dc3 --- /dev/null +++ b/patches.baytrail/0520-drm-gem-convert-to-new-unified-vma-manager.patch @@ -0,0 +1,616 @@ +From 9f9bd2603f4383aa68ec4440cdd9997057e643f7 Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Wed, 24 Jul 2013 21:07:52 +0200 +Subject: drm/gem: convert to new unified vma manager + +Use the new vma manager instead of the old hashtable. Also convert all +drivers to use the new convenience helpers. This drops all the +(map_list.hash.key << PAGE_SHIFT) non-sense. + +Locking and access-management is exactly the same as before with an +additional lock inside of the vma-manager, which strictly wouldn't be +needed for gem. + +v2: + - rebase on drm-next + - init nodes via drm_vma_node_reset() in drm_gem.c +v3: + - fix tegra +v4: + - remove duplicate if (drm_vma_node_has_offset()) checks + - inline now trivial drm_vma_node_offset_addr() calls +v5: + - skip node-reset on gem-init due to kzalloc() + - do not allow mapping gem-objects with offsets (backwards compat) + - remove unneccessary casts + +Cc: Inki Dae +Cc: Rob Clark +Cc: Dave Airlie +Cc: Thierry Reding +Signed-off-by: David Herrmann +Acked-by: Patrik Jakobsson +Reviewed-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit 0de23977cfeb5b357ec884ba15417ae118ff9e9b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_gem.c | 89 +++++------------------------- + drivers/gpu/drm/drm_gem_cma_helper.c | 16 ++---- + drivers/gpu/drm/exynos/exynos_drm_gem.c | 14 ++--- + drivers/gpu/drm/gma500/gem.c | 15 ++--- + drivers/gpu/drm/i915/i915_gem.c | 10 ++-- + drivers/gpu/drm/omapdrm/omap_gem.c | 28 +++++----- + drivers/gpu/drm/omapdrm/omap_gem_helpers.c | 49 +--------------- + drivers/gpu/drm/udl/udl_gem.c | 13 ++--- + drivers/gpu/host1x/drm/gem.c | 5 +- + include/drm/drmP.h | 7 +-- + include/uapi/drm/drm.h | 2 +- + 11 files changed, 62 insertions(+), 186 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index df6c89ec27ec..d1ba36512fe4 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + /** @file drm_gem.c + * +@@ -102,14 +103,9 @@ drm_gem_init(struct drm_device *dev) + } + + dev->mm_private = mm; +- +- if (drm_ht_create(&mm->offset_hash, 12)) { +- kfree(mm); +- return -ENOMEM; +- } +- +- drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START, +- DRM_FILE_PAGE_OFFSET_SIZE); ++ drm_vma_offset_manager_init(&mm->vma_manager, ++ DRM_FILE_PAGE_OFFSET_START, ++ DRM_FILE_PAGE_OFFSET_SIZE); + + return 0; + } +@@ -119,8 +115,7 @@ drm_gem_destroy(struct drm_device *dev) + { + struct drm_gem_mm *mm = dev->mm_private; + +- drm_mm_takedown(&mm->offset_manager); +- drm_ht_remove(&mm->offset_hash); ++ drm_vma_offset_manager_destroy(&mm->vma_manager); + kfree(mm); + dev->mm_private = NULL; + } +@@ -302,12 +297,8 @@ drm_gem_free_mmap_offset(struct drm_gem_object *obj) + { + struct drm_device *dev = obj->dev; + struct drm_gem_mm *mm = dev->mm_private; +- struct drm_map_list *list = &obj->map_list; + +- drm_ht_remove_item(&mm->offset_hash, &list->hash); +- drm_mm_put_block(list->file_offset_node); +- kfree(list->map); +- list->map = NULL; ++ drm_vma_offset_remove(&mm->vma_manager, &obj->vma_node); + } + EXPORT_SYMBOL(drm_gem_free_mmap_offset); + +@@ -327,54 +318,9 @@ drm_gem_create_mmap_offset(struct drm_gem_object *obj) + { + struct drm_device *dev = obj->dev; + struct drm_gem_mm *mm = dev->mm_private; +- struct drm_map_list *list; +- struct drm_local_map *map; +- int ret; +- +- /* Set the object up for mmap'ing */ +- list = &obj->map_list; +- list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); +- if (!list->map) +- return -ENOMEM; +- +- map = list->map; +- map->type = _DRM_GEM; +- map->size = obj->size; +- map->handle = obj; +- +- /* Get a DRM GEM mmap offset allocated... */ +- list->file_offset_node = drm_mm_search_free(&mm->offset_manager, +- obj->size / PAGE_SIZE, 0, false); +- +- if (!list->file_offset_node) { +- DRM_ERROR("failed to allocate offset for bo %d\n", obj->name); +- ret = -ENOSPC; +- goto out_free_list; +- } + +- list->file_offset_node = drm_mm_get_block(list->file_offset_node, +- obj->size / PAGE_SIZE, 0); +- if (!list->file_offset_node) { +- ret = -ENOMEM; +- goto out_free_list; +- } +- +- list->hash.key = list->file_offset_node->start; +- ret = drm_ht_insert_item(&mm->offset_hash, &list->hash); +- if (ret) { +- DRM_ERROR("failed to add to map hash\n"); +- goto out_free_mm; +- } +- +- return 0; +- +-out_free_mm: +- drm_mm_put_block(list->file_offset_node); +-out_free_list: +- kfree(list->map); +- list->map = NULL; +- +- return ret; ++ return drm_vma_offset_add(&mm->vma_manager, &obj->vma_node, ++ obj->size / PAGE_SIZE); + } + EXPORT_SYMBOL(drm_gem_create_mmap_offset); + +@@ -699,8 +645,8 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) + struct drm_file *priv = filp->private_data; + struct drm_device *dev = priv->minor->dev; + struct drm_gem_mm *mm = dev->mm_private; +- struct drm_local_map *map = NULL; +- struct drm_hash_item *hash; ++ struct drm_gem_object *obj; ++ struct drm_vma_offset_node *node; + int ret = 0; + + if (drm_device_is_unplugged(dev)) +@@ -708,21 +654,16 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) + + mutex_lock(&dev->struct_mutex); + +- if (drm_ht_find_item(&mm->offset_hash, vma->vm_pgoff, &hash)) { ++ node = drm_vma_offset_exact_lookup(&mm->vma_manager, vma->vm_pgoff, ++ vma_pages(vma)); ++ if (!node) { + mutex_unlock(&dev->struct_mutex); + return drm_mmap(filp, vma); + } + +- map = drm_hash_entry(hash, struct drm_map_list, hash)->map; +- if (!map || +- ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) { +- ret = -EPERM; +- goto out_unlock; +- } +- +- ret = drm_gem_mmap_obj(map->handle, map->size, vma); ++ obj = container_of(node, struct drm_gem_object, vma_node); ++ ret = drm_gem_mmap_obj(obj, drm_vma_node_size(node), vma); + +-out_unlock: + mutex_unlock(&dev->struct_mutex); + + return ret; +diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c +index 0a7e011509bd..11b616ef9dc2 100644 +--- a/drivers/gpu/drm/drm_gem_cma_helper.c ++++ b/drivers/gpu/drm/drm_gem_cma_helper.c +@@ -26,11 +26,7 @@ + #include + #include + #include +- +-static unsigned int get_gem_mmap_offset(struct drm_gem_object *obj) +-{ +- return (unsigned int)obj->map_list.hash.key << PAGE_SHIFT; +-} ++#include + + static void drm_gem_cma_buf_destroy(struct drm_device *drm, + struct drm_gem_cma_object *cma_obj) +@@ -140,8 +136,7 @@ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) + { + struct drm_gem_cma_object *cma_obj; + +- if (gem_obj->map_list.map) +- drm_gem_free_mmap_offset(gem_obj); ++ drm_gem_free_mmap_offset(gem_obj); + + drm_gem_object_release(gem_obj); + +@@ -199,7 +194,7 @@ int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv, + return -EINVAL; + } + +- *offset = get_gem_mmap_offset(gem_obj); ++ *offset = drm_vma_node_offset_addr(&gem_obj->vma_node); + + drm_gem_object_unreference(gem_obj); + +@@ -255,12 +250,11 @@ void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, struct seq_file *m + { + struct drm_gem_object *obj = &cma_obj->base; + struct drm_device *dev = obj->dev; +- uint64_t off = 0; ++ uint64_t off; + + WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + +- if (obj->map_list.map) +- off = (uint64_t)obj->map_list.hash.key; ++ off = drm_vma_node_start(&obj->vma_node); + + seq_printf(m, "%2d (%2d) %08llx %08Zx %p %d", + obj->name, obj->refcount.refcount.counter, +diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c +index cf4543ffa079..408b71f4c95e 100644 +--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c +@@ -10,6 +10,7 @@ + */ + + #include ++#include + + #include + #include +@@ -154,8 +155,7 @@ out: + exynos_drm_fini_buf(obj->dev, buf); + exynos_gem_obj->buffer = NULL; + +- if (obj->map_list.map) +- drm_gem_free_mmap_offset(obj); ++ drm_gem_free_mmap_offset(obj); + + /* release file pointer to gem object. */ + drm_gem_object_release(obj); +@@ -721,13 +721,11 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, + goto unlock; + } + +- if (!obj->map_list.map) { +- ret = drm_gem_create_mmap_offset(obj); +- if (ret) +- goto out; +- } ++ ret = drm_gem_create_mmap_offset(obj); ++ if (ret) ++ goto out; + +- *offset = (u64)obj->map_list.hash.key << PAGE_SHIFT; ++ *offset = drm_vma_node_offset_addr(&obj->vma_node); + DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset); + + out: +diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c +index fe1d3320ce6a..2f77bea30b11 100644 +--- a/drivers/gpu/drm/gma500/gem.c ++++ b/drivers/gpu/drm/gma500/gem.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include "psb_drv.h" + + int psb_gem_init_object(struct drm_gem_object *obj) +@@ -38,8 +39,7 @@ void psb_gem_free_object(struct drm_gem_object *obj) + struct gtt_range *gtt = container_of(obj, struct gtt_range, gem); + + /* Remove the list map if one is present */ +- if (obj->map_list.map) +- drm_gem_free_mmap_offset(obj); ++ drm_gem_free_mmap_offset(obj); + drm_gem_object_release(obj); + + /* This must occur last as it frees up the memory of the GEM object */ +@@ -81,13 +81,10 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, + /* What validation is needed here ? */ + + /* Make it mmapable */ +- if (!obj->map_list.map) { +- ret = drm_gem_create_mmap_offset(obj); +- if (ret) +- goto out; +- } +- /* GEM should really work out the hash offsets for us */ +- *offset = (u64)obj->map_list.hash.key << PAGE_SHIFT; ++ ret = drm_gem_create_mmap_offset(obj); ++ if (ret) ++ goto out; ++ *offset = drm_vma_node_offset_addr(&obj->vma_node); + out: + drm_gem_object_unreference(obj); + unlock: +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 050eb9b92595..607dc675840e 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -26,6 +26,7 @@ + */ + + #include ++#include + #include + #include "i915_drv.h" + #include "i915_trace.h" +@@ -1424,7 +1425,7 @@ i915_gem_release_mmap(struct drm_i915_gem_object *obj) + + if (obj->base.dev->dev_mapping) + unmap_mapping_range(obj->base.dev->dev_mapping, +- (loff_t)obj->base.map_list.hash.key<base.vma_node), + obj->base.size, 1); + + obj->fault_mappable = false; +@@ -1482,7 +1483,7 @@ static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj) + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + int ret; + +- if (obj->base.map_list.map) ++ if (drm_vma_node_has_offset(&obj->base.vma_node)) + return 0; + + dev_priv->mm.shrinker_no_lock_stealing = true; +@@ -1513,9 +1514,6 @@ out: + + static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj) + { +- if (!obj->base.map_list.map) +- return; +- + drm_gem_free_mmap_offset(&obj->base); + } + +@@ -1554,7 +1552,7 @@ i915_gem_mmap_gtt(struct drm_file *file, + if (ret) + goto out; + +- *offset = (u64)obj->base.map_list.hash.key << PAGE_SHIFT; ++ *offset = drm_vma_node_offset_addr(&obj->base.vma_node); + + out: + drm_gem_object_unreference(&obj->base); +diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c +index cbcd71e6ed83..f90531fc00c9 100644 +--- a/drivers/gpu/drm/omapdrm/omap_gem.c ++++ b/drivers/gpu/drm/omapdrm/omap_gem.c +@@ -20,6 +20,7 @@ + + #include + #include ++#include + + #include "omap_drv.h" + #include "omap_dmm_tiler.h" +@@ -308,21 +309,20 @@ uint32_t omap_gem_flags(struct drm_gem_object *obj) + static uint64_t mmap_offset(struct drm_gem_object *obj) + { + struct drm_device *dev = obj->dev; ++ int ret; ++ size_t size; + + WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + +- if (!obj->map_list.map) { +- /* Make it mmapable */ +- size_t size = omap_gem_mmap_size(obj); +- int ret = _drm_gem_create_mmap_offset_size(obj, size); +- +- if (ret) { +- dev_err(dev->dev, "could not allocate mmap offset\n"); +- return 0; +- } ++ /* Make it mmapable */ ++ size = omap_gem_mmap_size(obj); ++ ret = _drm_gem_create_mmap_offset_size(obj, size); ++ if (ret) { ++ dev_err(dev->dev, "could not allocate mmap offset\n"); ++ return 0; + } + +- return (uint64_t)obj->map_list.hash.key << PAGE_SHIFT; ++ return drm_vma_node_offset_addr(&obj->vma_node); + } + + uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj) +@@ -997,12 +997,11 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m) + { + struct drm_device *dev = obj->dev; + struct omap_gem_object *omap_obj = to_omap_bo(obj); +- uint64_t off = 0; ++ uint64_t off; + + WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + +- if (obj->map_list.map) +- off = (uint64_t)obj->map_list.hash.key; ++ off = drm_vma_node_start(&obj->vma_node); + + seq_printf(m, "%08x: %2d (%2d) %08llx %08Zx (%2d) %p %4d", + omap_obj->flags, obj->name, obj->refcount.refcount.counter, +@@ -1309,8 +1308,7 @@ void omap_gem_free_object(struct drm_gem_object *obj) + + list_del(&omap_obj->mm_list); + +- if (obj->map_list.map) +- drm_gem_free_mmap_offset(obj); ++ drm_gem_free_mmap_offset(obj); + + /* this means the object is still pinned.. which really should + * not happen. I think.. +diff --git a/drivers/gpu/drm/omapdrm/omap_gem_helpers.c b/drivers/gpu/drm/omapdrm/omap_gem_helpers.c +index f9eb679eb79b..dbb157542f8f 100644 +--- a/drivers/gpu/drm/omapdrm/omap_gem_helpers.c ++++ b/drivers/gpu/drm/omapdrm/omap_gem_helpers.c +@@ -118,52 +118,7 @@ _drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size) + { + struct drm_device *dev = obj->dev; + struct drm_gem_mm *mm = dev->mm_private; +- struct drm_map_list *list; +- struct drm_local_map *map; +- int ret = 0; +- +- /* Set the object up for mmap'ing */ +- list = &obj->map_list; +- list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); +- if (!list->map) +- return -ENOMEM; +- +- map = list->map; +- map->type = _DRM_GEM; +- map->size = size; +- map->handle = obj; +- +- /* Get a DRM GEM mmap offset allocated... */ +- list->file_offset_node = drm_mm_search_free(&mm->offset_manager, +- size / PAGE_SIZE, 0, 0); +- +- if (!list->file_offset_node) { +- DRM_ERROR("failed to allocate offset for bo %d\n", obj->name); +- ret = -ENOSPC; +- goto out_free_list; +- } +- +- list->file_offset_node = drm_mm_get_block(list->file_offset_node, +- size / PAGE_SIZE, 0); +- if (!list->file_offset_node) { +- ret = -ENOMEM; +- goto out_free_list; +- } +- +- list->hash.key = list->file_offset_node->start; +- ret = drm_ht_insert_item(&mm->offset_hash, &list->hash); +- if (ret) { +- DRM_ERROR("failed to add to map hash\n"); +- goto out_free_mm; +- } +- +- return 0; +- +-out_free_mm: +- drm_mm_put_block(list->file_offset_node); +-out_free_list: +- kfree(list->map); +- list->map = NULL; + +- return ret; ++ return drm_vma_offset_add(&mm->vma_manager, &obj->vma_node, ++ size / PAGE_SIZE); + } +diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c +index ef034fa3e6f5..2a4cb2f83b36 100644 +--- a/drivers/gpu/drm/udl/udl_gem.c ++++ b/drivers/gpu/drm/udl/udl_gem.c +@@ -223,8 +223,7 @@ void udl_gem_free_object(struct drm_gem_object *gem_obj) + if (obj->pages) + udl_gem_put_pages(obj); + +- if (gem_obj->map_list.map) +- drm_gem_free_mmap_offset(gem_obj); ++ drm_gem_free_mmap_offset(gem_obj); + } + + /* the dumb interface doesn't work with the GEM straight MMAP +@@ -247,13 +246,11 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, + ret = udl_gem_get_pages(gobj, GFP_KERNEL); + if (ret) + goto out; +- if (!gobj->base.map_list.map) { +- ret = drm_gem_create_mmap_offset(obj); +- if (ret) +- goto out; +- } ++ ret = drm_gem_create_mmap_offset(obj); ++ if (ret) ++ goto out; + +- *offset = (u64)gobj->base.map_list.hash.key << PAGE_SHIFT; ++ *offset = drm_vma_node_offset_addr(&gobj->base.vma_node); + + out: + drm_gem_object_unreference(&gobj->base); +diff --git a/drivers/gpu/host1x/drm/gem.c b/drivers/gpu/host1x/drm/gem.c +index c5e9a9b494c2..bc323b3dbe4d 100644 +--- a/drivers/gpu/host1x/drm/gem.c ++++ b/drivers/gpu/host1x/drm/gem.c +@@ -108,7 +108,7 @@ static void tegra_bo_destroy(struct drm_device *drm, struct tegra_bo *bo) + + unsigned int tegra_bo_get_mmap_offset(struct tegra_bo *bo) + { +- return (unsigned int)bo->gem.map_list.hash.key << PAGE_SHIFT; ++ return (unsigned int)drm_vma_node_offset_addr(&bo->gem.vma_node); + } + + struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size) +@@ -182,8 +182,7 @@ void tegra_bo_free_object(struct drm_gem_object *gem) + { + struct tegra_bo *bo = to_tegra_bo(gem); + +- if (gem->map_list.map) +- drm_gem_free_mmap_offset(gem); ++ drm_gem_free_mmap_offset(gem); + + drm_gem_object_release(gem); + tegra_bo_destroy(gem->dev, bo); +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 5ff88ad7b23c..bf677c0b4cae 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -74,6 +74,7 @@ + #include + #include + #include ++#include + + #include + +@@ -590,7 +591,6 @@ struct drm_map_list { + struct drm_local_map *map; /**< mapping */ + uint64_t user_token; + struct drm_master *master; +- struct drm_mm_node *file_offset_node; /**< fake offset */ + }; + + /** +@@ -625,8 +625,7 @@ struct drm_ati_pcigart_info { + * GEM specific mm private for tracking GEM objects + */ + struct drm_gem_mm { +- struct drm_mm offset_manager; /**< Offset mgmt for buffer objects */ +- struct drm_open_hash offset_hash; /**< User token hash table for maps */ ++ struct drm_vma_offset_manager vma_manager; + }; + + /** +@@ -647,7 +646,7 @@ struct drm_gem_object { + struct file *filp; + + /* Mapping info for this object */ +- struct drm_map_list map_list; ++ struct drm_vma_offset_node vma_node; + + /** + * Size of the object, in bytes. Immutable over the object's +diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h +index 5a57be68bab7..1d1c6f03021e 100644 +--- a/include/uapi/drm/drm.h ++++ b/include/uapi/drm/drm.h +@@ -181,7 +181,7 @@ enum drm_map_type { + _DRM_AGP = 3, /**< AGP/GART */ + _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ + _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ +- _DRM_GEM = 6, /**< GEM object */ ++ _DRM_GEM = 6, /**< GEM object (obsolete) */ + }; + + /** +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0521-drm-gem-fix-mmap-vma-size-calculations.patch b/patches.baytrail/0521-drm-gem-fix-mmap-vma-size-calculations.patch new file mode 100644 index 000000000000..59bb0ef72729 --- /dev/null +++ b/patches.baytrail/0521-drm-gem-fix-mmap-vma-size-calculations.patch @@ -0,0 +1,45 @@ +From 3331761cbf57b3819e5075eef1bfc42e58bd8f20 Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Fri, 26 Jul 2013 12:09:32 +0200 +Subject: drm/gem: fix mmap vma size calculations + +The VMA manager is page-size based so drm_vma_node_size() returns the size +in pages. However, drm_gem_mmap_obj() requires the size in bytes. Apply +PAGE_SHIFT so we no longer get EINVAL during mmaps due to too small +buffers. + +This bug was introduced in commit: + 0de23977cfeb5b357ec884ba15417ae118ff9e9b + "drm/gem: convert to new unified vma manager" + +Fixes i915 gtt mmap failure reported by Sedat Dilek in: + Re: linux-next: Tree for Jul 25 [ call-trace: drm | drm-intel related? ] + +Cc: Daniel Vetter +Cc: Chris Wilson +Signed-off-by: David Herrmann +Reported-by: Sedat Dilek +Tested-by: Sedat Dilek +Signed-off-by: Dave Airlie +(cherry picked from commit aed2c03c8d96ea471b86761129c213e05ab6fbef) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_gem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index d1ba36512fe4..2688795172f9 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -662,7 +662,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) + } + + obj = container_of(node, struct drm_gem_object, vma_node); +- ret = drm_gem_mmap_obj(obj, drm_vma_node_size(node), vma); ++ ret = drm_gem_mmap_obj(obj, drm_vma_node_size(node) << PAGE_SHIFT, vma); + + mutex_unlock(&dev->struct_mutex); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0522-drm-ttm-convert-to-unified-vma-offset-manager.patch b/patches.baytrail/0522-drm-ttm-convert-to-unified-vma-offset-manager.patch new file mode 100644 index 000000000000..2089d5e7a56b --- /dev/null +++ b/patches.baytrail/0522-drm-ttm-convert-to-unified-vma-offset-manager.patch @@ -0,0 +1,595 @@ +From 8db22e0b6d06a7666fcdc9434e82cb3b6a58c774 Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Wed, 24 Jul 2013 21:08:53 +0200 +Subject: drm/ttm: convert to unified vma offset manager + +Use the new vma-manager infrastructure. This doesn't change any +implementation details as the vma-offset-manager is nearly copied 1-to-1 +from TTM. + +The vm_lock is moved into the offset manager so we can drop it from TTM. +During lookup, we use the vma locking helpers to take a reference to the +found object. +In all other scenarios, locking stays the same as before. We always +guarantee that drm_vma_offset_remove() is called only during destruction. +Hence, helpers like drm_vma_node_offset_addr() are always safe as long as +the node has a valid offset. + +This also drops the addr_space_offset member as it is a copy of vm_start +in vma_node objects. Use the accessor functions instead. + +v4: + - remove vm_lock + - use drm_vma_offset_lock_lookup() to protect lookup (instead of vm_lock) + +Cc: Dave Airlie +Cc: Ben Skeggs +Cc: Maarten Lankhorst +Cc: Martin Peres +Cc: Alex Deucher +Cc: Thomas Hellstrom +Signed-off-by: David Herrmann +Reviewed-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit 72525b3f333de54fa0c42ef87f27861e41478f1e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/ast/ast_main.c | 2 +- + drivers/gpu/drm/cirrus/cirrus_main.c | 2 +- + drivers/gpu/drm/mgag200/mgag200_main.c | 2 +- + drivers/gpu/drm/nouveau/nouveau_display.c | 2 +- + drivers/gpu/drm/nouveau/nouveau_gem.c | 2 +- + drivers/gpu/drm/qxl/qxl_object.h | 2 +- + drivers/gpu/drm/qxl/qxl_release.c | 2 +- + drivers/gpu/drm/radeon/radeon_object.h | 5 +- + drivers/gpu/drm/ttm/ttm_bo.c | 89 ++++++------------------------- + drivers/gpu/drm/ttm/ttm_bo_util.c | 3 +- + drivers/gpu/drm/ttm/ttm_bo_vm.c | 81 +++++++++++----------------- + drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 4 +- + include/drm/ttm/ttm_bo_api.h | 15 ++---- + include/drm/ttm/ttm_bo_driver.h | 10 ++-- + 14 files changed, 66 insertions(+), 155 deletions(-) + +diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c +index f60fd7bd1183..c195dc2abc09 100644 +--- a/drivers/gpu/drm/ast/ast_main.c ++++ b/drivers/gpu/drm/ast/ast_main.c +@@ -487,7 +487,7 @@ void ast_gem_free_object(struct drm_gem_object *obj) + + static inline u64 ast_bo_mmap_offset(struct ast_bo *bo) + { +- return bo->bo.addr_space_offset; ++ return drm_vma_node_offset_addr(&bo->bo.vma_node); + } + int + ast_dumb_mmap_offset(struct drm_file *file, +diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c +index 35cbae827771..3a7a0efe3675 100644 +--- a/drivers/gpu/drm/cirrus/cirrus_main.c ++++ b/drivers/gpu/drm/cirrus/cirrus_main.c +@@ -294,7 +294,7 @@ void cirrus_gem_free_object(struct drm_gem_object *obj) + + static inline u64 cirrus_bo_mmap_offset(struct cirrus_bo *bo) + { +- return bo->bo.addr_space_offset; ++ return drm_vma_node_offset_addr(&bo->bo.vma_node); + } + + int +diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c +index dafe049fb1ae..2d56e28d2b21 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_main.c ++++ b/drivers/gpu/drm/mgag200/mgag200_main.c +@@ -330,7 +330,7 @@ void mgag200_gem_free_object(struct drm_gem_object *obj) + + static inline u64 mgag200_bo_mmap_offset(struct mgag200_bo *bo) + { +- return bo->bo.addr_space_offset; ++ return drm_vma_node_offset_addr(&bo->bo.vma_node); + } + + int +diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c +index f17dc2ab03ec..52498de87a3b 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_display.c ++++ b/drivers/gpu/drm/nouveau/nouveau_display.c +@@ -705,7 +705,7 @@ nouveau_display_dumb_map_offset(struct drm_file *file_priv, + gem = drm_gem_object_lookup(dev, file_priv, handle); + if (gem) { + struct nouveau_bo *bo = gem->driver_private; +- *poffset = bo->bo.addr_space_offset; ++ *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node); + drm_gem_object_unreference_unlocked(gem); + return 0; + } +diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c +index 5bccf31cc974..3b11fc07a88b 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_gem.c ++++ b/drivers/gpu/drm/nouveau/nouveau_gem.c +@@ -192,7 +192,7 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem, + } + + rep->size = nvbo->bo.mem.num_pages << PAGE_SHIFT; +- rep->map_handle = nvbo->bo.addr_space_offset; ++ rep->map_handle = drm_vma_node_offset_addr(&nvbo->bo.vma_node); + rep->tile_mode = nvbo->tile_mode; + rep->tile_flags = nvbo->tile_flags; + return 0; +diff --git a/drivers/gpu/drm/qxl/qxl_object.h b/drivers/gpu/drm/qxl/qxl_object.h +index b4fd89fbd8b7..1fc4e4b833a3 100644 +--- a/drivers/gpu/drm/qxl/qxl_object.h ++++ b/drivers/gpu/drm/qxl/qxl_object.h +@@ -64,7 +64,7 @@ static inline bool qxl_bo_is_reserved(struct qxl_bo *bo) + + static inline u64 qxl_bo_mmap_offset(struct qxl_bo *bo) + { +- return bo->tbo.addr_space_offset; ++ return drm_vma_node_offset_addr(&bo->tbo.vma_node); + } + + static inline int qxl_bo_wait(struct qxl_bo *bo, u32 *mem_type, +diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c +index b443d6751d5f..1a648e1da6a6 100644 +--- a/drivers/gpu/drm/qxl/qxl_release.c ++++ b/drivers/gpu/drm/qxl/qxl_release.c +@@ -87,7 +87,7 @@ qxl_release_free(struct qxl_device *qdev, + + for (i = 0 ; i < release->bo_count; ++i) { + QXL_INFO(qdev, "release %llx\n", +- release->bos[i]->tbo.addr_space_offset ++ drm_vma_node_offset_addr(&release->bos[i]->tbo.vma_node) + - DRM_FILE_OFFSET); + qxl_fence_remove_release(&release->bos[i]->fence, release->id); + qxl_bo_unref(&release->bos[i]); +diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h +index 294382394608..a185b0f46dd3 100644 +--- a/drivers/gpu/drm/radeon/radeon_object.h ++++ b/drivers/gpu/drm/radeon/radeon_object.h +@@ -98,13 +98,10 @@ static inline unsigned radeon_bo_gpu_page_alignment(struct radeon_bo *bo) + * @bo: radeon object for which we query the offset + * + * Returns mmap offset of the object. +- * +- * Note: addr_space_offset is constant after ttm bo init thus isn't protected +- * by any lock. + */ + static inline u64 radeon_bo_mmap_offset(struct radeon_bo *bo) + { +- return bo->tbo.addr_space_offset; ++ return drm_vma_node_offset_addr(&bo->tbo.vma_node); + } + + extern int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, +diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c +index 57f9766e1135..447010fbc2cd 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo.c ++++ b/drivers/gpu/drm/ttm/ttm_bo.c +@@ -775,13 +775,7 @@ static void ttm_bo_release(struct kref *kref) + struct ttm_bo_device *bdev = bo->bdev; + struct ttm_mem_type_manager *man = &bdev->man[bo->mem.mem_type]; + +- write_lock(&bdev->vm_lock); +- if (likely(bo->vm_node != NULL)) { +- rb_erase(&bo->vm_rb, &bdev->addr_space_rb); +- drm_mm_put_block(bo->vm_node); +- bo->vm_node = NULL; +- } +- write_unlock(&bdev->vm_lock); ++ drm_vma_offset_remove(&bdev->vma_manager, &bo->vma_node); + ttm_mem_io_lock(man, false); + ttm_mem_io_free_vm(bo); + ttm_mem_io_unlock(man); +@@ -1297,6 +1291,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, + bo->acc_size = acc_size; + bo->sg = sg; + atomic_inc(&bo->glob->bo_count); ++ drm_vma_node_reset(&bo->vma_node); + + ret = ttm_bo_check_placement(bo, placement); + if (unlikely(ret != 0)) +@@ -1596,10 +1591,7 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev) + TTM_DEBUG("Swap list was clean\n"); + spin_unlock(&glob->lru_lock); + +- BUG_ON(!drm_mm_clean(&bdev->addr_space_mm)); +- write_lock(&bdev->vm_lock); +- drm_mm_takedown(&bdev->addr_space_mm); +- write_unlock(&bdev->vm_lock); ++ drm_vma_offset_manager_destroy(&bdev->vma_manager); + + return ret; + } +@@ -1613,7 +1605,6 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev, + { + int ret = -EINVAL; + +- rwlock_init(&bdev->vm_lock); + bdev->driver = driver; + + memset(bdev->man, 0, sizeof(bdev->man)); +@@ -1626,9 +1617,8 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev, + if (unlikely(ret != 0)) + goto out_no_sys; + +- bdev->addr_space_rb = RB_ROOT; +- drm_mm_init(&bdev->addr_space_mm, file_page_offset, 0x10000000); +- ++ drm_vma_offset_manager_init(&bdev->vma_manager, file_page_offset, ++ 0x10000000); + INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue); + INIT_LIST_HEAD(&bdev->ddestroy); + bdev->dev_mapping = NULL; +@@ -1670,12 +1660,17 @@ bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) + void ttm_bo_unmap_virtual_locked(struct ttm_buffer_object *bo) + { + struct ttm_bo_device *bdev = bo->bdev; +- loff_t offset = (loff_t) bo->addr_space_offset; +- loff_t holelen = ((loff_t) bo->mem.num_pages) << PAGE_SHIFT; ++ loff_t offset, holelen; + + if (!bdev->dev_mapping) + return; +- unmap_mapping_range(bdev->dev_mapping, offset, holelen, 1); ++ ++ if (drm_vma_node_has_offset(&bo->vma_node)) { ++ offset = (loff_t) drm_vma_node_offset_addr(&bo->vma_node); ++ holelen = ((loff_t) bo->mem.num_pages) << PAGE_SHIFT; ++ ++ unmap_mapping_range(bdev->dev_mapping, offset, holelen, 1); ++ } + ttm_mem_io_free_vm(bo); + } + +@@ -1692,31 +1687,6 @@ void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo) + + EXPORT_SYMBOL(ttm_bo_unmap_virtual); + +-static void ttm_bo_vm_insert_rb(struct ttm_buffer_object *bo) +-{ +- struct ttm_bo_device *bdev = bo->bdev; +- struct rb_node **cur = &bdev->addr_space_rb.rb_node; +- struct rb_node *parent = NULL; +- struct ttm_buffer_object *cur_bo; +- unsigned long offset = bo->vm_node->start; +- unsigned long cur_offset; +- +- while (*cur) { +- parent = *cur; +- cur_bo = rb_entry(parent, struct ttm_buffer_object, vm_rb); +- cur_offset = cur_bo->vm_node->start; +- if (offset < cur_offset) +- cur = &parent->rb_left; +- else if (offset > cur_offset) +- cur = &parent->rb_right; +- else +- BUG(); +- } +- +- rb_link_node(&bo->vm_rb, parent, cur); +- rb_insert_color(&bo->vm_rb, &bdev->addr_space_rb); +-} +- + /** + * ttm_bo_setup_vm: + * +@@ -1731,38 +1701,9 @@ static void ttm_bo_vm_insert_rb(struct ttm_buffer_object *bo) + static int ttm_bo_setup_vm(struct ttm_buffer_object *bo) + { + struct ttm_bo_device *bdev = bo->bdev; +- int ret; +- +-retry_pre_get: +- ret = drm_mm_pre_get(&bdev->addr_space_mm); +- if (unlikely(ret != 0)) +- return ret; +- +- write_lock(&bdev->vm_lock); +- bo->vm_node = drm_mm_search_free(&bdev->addr_space_mm, +- bo->mem.num_pages, 0, 0); +- +- if (unlikely(bo->vm_node == NULL)) { +- ret = -ENOMEM; +- goto out_unlock; +- } + +- bo->vm_node = drm_mm_get_block_atomic(bo->vm_node, +- bo->mem.num_pages, 0); +- +- if (unlikely(bo->vm_node == NULL)) { +- write_unlock(&bdev->vm_lock); +- goto retry_pre_get; +- } +- +- ttm_bo_vm_insert_rb(bo); +- write_unlock(&bdev->vm_lock); +- bo->addr_space_offset = ((uint64_t) bo->vm_node->start) << PAGE_SHIFT; +- +- return 0; +-out_unlock: +- write_unlock(&bdev->vm_lock); +- return ret; ++ return drm_vma_offset_add(&bdev->vma_manager, &bo->vma_node, ++ bo->mem.num_pages); + } + + int ttm_bo_wait(struct ttm_buffer_object *bo, +diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c +index b7f757158df7..7f6e018055bc 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo_util.c ++++ b/drivers/gpu/drm/ttm/ttm_bo_util.c +@@ -30,6 +30,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -458,7 +459,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, + INIT_LIST_HEAD(&fbo->lru); + INIT_LIST_HEAD(&fbo->swap); + INIT_LIST_HEAD(&fbo->io_reserve_lru); +- fbo->vm_node = NULL; ++ drm_vma_node_reset(&fbo->vma_node); + atomic_set(&fbo->cpu_writers, 0); + + spin_lock(&bdev->fence_lock); +diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c +index 3df9f16b041c..8c0e2c020215 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c ++++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -40,37 +41,6 @@ + + #define TTM_BO_VM_NUM_PREFAULT 16 + +-static struct ttm_buffer_object *ttm_bo_vm_lookup_rb(struct ttm_bo_device *bdev, +- unsigned long page_start, +- unsigned long num_pages) +-{ +- struct rb_node *cur = bdev->addr_space_rb.rb_node; +- unsigned long cur_offset; +- struct ttm_buffer_object *bo; +- struct ttm_buffer_object *best_bo = NULL; +- +- while (likely(cur != NULL)) { +- bo = rb_entry(cur, struct ttm_buffer_object, vm_rb); +- cur_offset = bo->vm_node->start; +- if (page_start >= cur_offset) { +- cur = cur->rb_right; +- best_bo = bo; +- if (page_start == cur_offset) +- break; +- } else +- cur = cur->rb_left; +- } +- +- if (unlikely(best_bo == NULL)) +- return NULL; +- +- if (unlikely((best_bo->vm_node->start + best_bo->num_pages) < +- (page_start + num_pages))) +- return NULL; +- +- return best_bo; +-} +- + static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + { + struct ttm_buffer_object *bo = (struct ttm_buffer_object *) +@@ -146,9 +116,9 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + } + + page_offset = ((address - vma->vm_start) >> PAGE_SHIFT) + +- bo->vm_node->start - vma->vm_pgoff; ++ drm_vma_node_start(&bo->vma_node) - vma->vm_pgoff; + page_last = vma_pages(vma) + +- bo->vm_node->start - vma->vm_pgoff; ++ drm_vma_node_start(&bo->vma_node) - vma->vm_pgoff; + + if (unlikely(page_offset >= bo->num_pages)) { + retval = VM_FAULT_SIGBUS; +@@ -249,6 +219,30 @@ static const struct vm_operations_struct ttm_bo_vm_ops = { + .close = ttm_bo_vm_close + }; + ++static struct ttm_buffer_object *ttm_bo_vm_lookup(struct ttm_bo_device *bdev, ++ unsigned long offset, ++ unsigned long pages) ++{ ++ struct drm_vma_offset_node *node; ++ struct ttm_buffer_object *bo = NULL; ++ ++ drm_vma_offset_lock_lookup(&bdev->vma_manager); ++ ++ node = drm_vma_offset_lookup_locked(&bdev->vma_manager, offset, pages); ++ if (likely(node)) { ++ bo = container_of(node, struct ttm_buffer_object, vma_node); ++ if (!kref_get_unless_zero(&bo->kref)) ++ bo = NULL; ++ } ++ ++ drm_vma_offset_unlock_lookup(&bdev->vma_manager); ++ ++ if (!bo) ++ pr_err("Could not find buffer object to map\n"); ++ ++ return bo; ++} ++ + int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma, + struct ttm_bo_device *bdev) + { +@@ -256,17 +250,9 @@ int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma, + struct ttm_buffer_object *bo; + int ret; + +- read_lock(&bdev->vm_lock); +- bo = ttm_bo_vm_lookup_rb(bdev, vma->vm_pgoff, +- vma_pages(vma)); +- if (likely(bo != NULL) && !kref_get_unless_zero(&bo->kref)) +- bo = NULL; +- read_unlock(&bdev->vm_lock); +- +- if (unlikely(bo == NULL)) { +- pr_err("Could not find buffer object to map\n"); ++ bo = ttm_bo_vm_lookup(bdev, vma->vm_pgoff, vma_pages(vma)); ++ if (unlikely(!bo)) + return -EINVAL; +- } + + driver = bo->bdev->driver; + if (unlikely(!driver->verify_access)) { +@@ -324,12 +310,7 @@ ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp, + bool no_wait = false; + bool dummy; + +- read_lock(&bdev->vm_lock); +- bo = ttm_bo_vm_lookup_rb(bdev, dev_offset, 1); +- if (likely(bo != NULL)) +- ttm_bo_reference(bo); +- read_unlock(&bdev->vm_lock); +- ++ bo = ttm_bo_vm_lookup(bdev, dev_offset, 1); + if (unlikely(bo == NULL)) + return -EFAULT; + +@@ -343,7 +324,7 @@ ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp, + if (unlikely(ret != 0)) + goto out_unref; + +- kmap_offset = dev_offset - bo->vm_node->start; ++ kmap_offset = dev_offset - drm_vma_node_start(&bo->vma_node); + if (unlikely(kmap_offset >= bo->num_pages)) { + ret = -EFBIG; + goto out_unref; +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +index 407d7f9fe8a8..40a4d91168f2 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +@@ -500,7 +500,7 @@ int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data, + goto out_no_dmabuf; + + rep->handle = handle; +- rep->map_handle = dma_buf->base.addr_space_offset; ++ rep->map_handle = drm_vma_node_offset_addr(&dma_buf->base.vma_node); + rep->cur_gmr_id = handle; + rep->cur_gmr_offset = 0; + +@@ -834,7 +834,7 @@ int vmw_dumb_map_offset(struct drm_file *file_priv, + if (ret != 0) + return -EINVAL; + +- *offset = out_buf->base.addr_space_offset; ++ *offset = drm_vma_node_offset_addr(&out_buf->base.vma_node); + vmw_dmabuf_unreference(&out_buf); + return 0; + } +diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h +index 3cb5d848fb66..fcbe1983cc9a 100644 +--- a/include/drm/ttm/ttm_bo_api.h ++++ b/include/drm/ttm/ttm_bo_api.h +@@ -32,12 +32,12 @@ + #define _TTM_BO_API_H_ + + #include ++#include + #include + #include + #include + #include + #include +-#include + #include + + struct ttm_bo_device; +@@ -144,7 +144,6 @@ struct ttm_tt; + * @type: The bo type. + * @destroy: Destruction function. If NULL, kfree is used. + * @num_pages: Actual number of pages. +- * @addr_space_offset: Address space offset. + * @acc_size: Accounted size for this object. + * @kref: Reference count of this buffer object. When this refcount reaches + * zero, the object is put on the delayed delete list. +@@ -172,8 +171,7 @@ struct ttm_tt; + * @reserved: Deadlock-free lock used for synchronization state transitions. + * @sync_obj: Pointer to a synchronization object. + * @priv_flags: Flags describing buffer object internal state. +- * @vm_rb: Rb node for the vm rb tree. +- * @vm_node: Address space manager node. ++ * @vma_node: Address space manager node. + * @offset: The current GPU offset, which can have different meanings + * depending on the memory type. For SYSTEM type memory, it should be 0. + * @cur_placement: Hint of current placement. +@@ -200,7 +198,6 @@ struct ttm_buffer_object { + enum ttm_bo_type type; + void (*destroy) (struct ttm_buffer_object *); + unsigned long num_pages; +- uint64_t addr_space_offset; + size_t acc_size; + + /** +@@ -254,13 +251,7 @@ struct ttm_buffer_object { + void *sync_obj; + unsigned long priv_flags; + +- /** +- * Members protected by the bdev::vm_lock +- */ +- +- struct rb_node vm_rb; +- struct drm_mm_node *vm_node; +- ++ struct drm_vma_offset_node vma_node; + + /** + * Special members that are protected by the reserve lock +diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h +index 9c8dca79808e..8cc4c73d9bc4 100644 +--- a/include/drm/ttm/ttm_bo_driver.h ++++ b/include/drm/ttm/ttm_bo_driver.h +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -517,7 +518,7 @@ struct ttm_bo_global { + * @man: An array of mem_type_managers. + * @fence_lock: Protects the synchronizing members on *all* bos belonging + * to this device. +- * @addr_space_mm: Range manager for the device address space. ++ * @vma_manager: Address space manager + * lru_lock: Spinlock that protects the buffer+device lru lists and + * ddestroy lists. + * @val_seq: Current validation sequence. +@@ -535,14 +536,13 @@ struct ttm_bo_device { + struct list_head device_list; + struct ttm_bo_global *glob; + struct ttm_bo_driver *driver; +- rwlock_t vm_lock; + struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES]; + spinlock_t fence_lock; ++ + /* +- * Protected by the vm lock. ++ * Protected by internal locks. + */ +- struct rb_root addr_space_rb; +- struct drm_mm addr_space_mm; ++ struct drm_vma_offset_manager vma_manager; + + /* + * Protected by the global:lru lock. +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0523-drm-vma-provide-drm_vma_node_unmap-helper.patch b/patches.baytrail/0523-drm-vma-provide-drm_vma_node_unmap-helper.patch new file mode 100644 index 000000000000..660eb02889fe --- /dev/null +++ b/patches.baytrail/0523-drm-vma-provide-drm_vma_node_unmap-helper.patch @@ -0,0 +1,108 @@ +From 32a9d247c614b7b396211a1205bade73c92a9d46 Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Wed, 24 Jul 2013 21:10:03 +0200 +Subject: drm/vma: provide drm_vma_node_unmap() helper + +Instead of unmapping the nodes in TTM and GEM users manually, we provide +a generic wrapper which does the correct thing for all vma-nodes. + +v2: remove bdev->dev_mapping test in ttm_bo_unmap_virtual_unlocked() as +ttm_mem_io_free_vm() does nothing in that case (io_reserved_vm is 0). +v4: Fix docbook comments +v5: use drm_vma_node_size() + +Cc: Dave Airlie +Cc: Maarten Lankhorst +Cc: Thomas Hellstrom +Signed-off-by: David Herrmann +Reviewed-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit 51335df9f044ccfafb029f4d7fbeb11c4526340a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 6 +----- + drivers/gpu/drm/ttm/ttm_bo.c | 11 +---------- + include/drm/drm_vma_manager.h | 22 ++++++++++++++++++++++ + 3 files changed, 24 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 607dc675840e..7221793239c3 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -1423,11 +1423,7 @@ i915_gem_release_mmap(struct drm_i915_gem_object *obj) + if (!obj->fault_mappable) + return; + +- if (obj->base.dev->dev_mapping) +- unmap_mapping_range(obj->base.dev->dev_mapping, +- (loff_t)drm_vma_node_offset_addr(&obj->base.vma_node), +- obj->base.size, 1); +- ++ drm_vma_node_unmap(&obj->base.vma_node, obj->base.dev->dev_mapping); + obj->fault_mappable = false; + } + +diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c +index 447010fbc2cd..80db5b3b31e5 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo.c ++++ b/drivers/gpu/drm/ttm/ttm_bo.c +@@ -1660,17 +1660,8 @@ bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) + void ttm_bo_unmap_virtual_locked(struct ttm_buffer_object *bo) + { + struct ttm_bo_device *bdev = bo->bdev; +- loff_t offset, holelen; + +- if (!bdev->dev_mapping) +- return; +- +- if (drm_vma_node_has_offset(&bo->vma_node)) { +- offset = (loff_t) drm_vma_node_offset_addr(&bo->vma_node); +- holelen = ((loff_t) bo->mem.num_pages) << PAGE_SHIFT; +- +- unmap_mapping_range(bdev->dev_mapping, offset, holelen, 1); +- } ++ drm_vma_node_unmap(&bo->vma_node, bdev->dev_mapping); + ttm_mem_io_free_vm(bo); + } + +diff --git a/include/drm/drm_vma_manager.h b/include/drm/drm_vma_manager.h +index 7ee8c4babeb9..22eedac046ac 100644 +--- a/include/drm/drm_vma_manager.h ++++ b/include/drm/drm_vma_manager.h +@@ -24,6 +24,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -199,4 +200,25 @@ static inline __u64 drm_vma_node_offset_addr(struct drm_vma_offset_node *node) + return ((__u64)node->vm_node.start) << PAGE_SHIFT; + } + ++/** ++ * drm_vma_node_unmap() - Unmap offset node ++ * @node: Offset node ++ * @file_mapping: Address space to unmap @node from ++ * ++ * Unmap all userspace mappings for a given offset node. The mappings must be ++ * associated with the @file_mapping address-space. If no offset exists or ++ * the address-space is invalid, nothing is done. ++ * ++ * This call is unlocked. The caller must guarantee that drm_vma_offset_remove() ++ * is not called on this node concurrently. ++ */ ++static inline void drm_vma_node_unmap(struct drm_vma_offset_node *node, ++ struct address_space *file_mapping) ++{ ++ if (file_mapping && drm_vma_node_has_offset(node)) ++ unmap_mapping_range(file_mapping, ++ drm_vma_node_offset_addr(node), ++ drm_vma_node_size(node) << PAGE_SHIFT, 1); ++} ++ + #endif /* __DRM_VMA_MANAGER_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0524-Re-create-dirty-merge-cb54b53.patch b/patches.baytrail/0524-Re-create-dirty-merge-cb54b53.patch new file mode 100644 index 000000000000..e0a2c4c2fe76 --- /dev/null +++ b/patches.baytrail/0524-Re-create-dirty-merge-cb54b53.patch @@ -0,0 +1,48 @@ +From 98fe2cb687466b92fce162dfc0058656d4881557 Mon Sep 17 00:00:00 2001 +From: James Ausmus +Date: Thu, 10 Oct 2013 18:30:59 -0700 +Subject: Re-create dirty merge cb54b53 + +Fix code up to post-merge state after cb54b53adae70701bdd77d848cea4b9b39b61cf9 +("Merge commit 'Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux'") + +Signed-off-by: James Ausmus +(cherry picked from + https://chromium.googlesource.com/chromiumos/third_party/kernel-next + chromeos-3.10, e362220fa6a86569cf3c2dfa47ce24935da661d6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 2 +- + drivers/gpu/drm/i915/i915_gem.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 3bbf8ef0f984..d71e765b814d 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1492,8 +1492,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + + spin_lock_init(&dev_priv->irq_lock); + spin_lock_init(&dev_priv->gpu_error.lock); +- spin_lock_init(&dev_priv->gt_lock); + spin_lock_init(&dev_priv->backlight.lock); ++ spin_lock_init(&dev_priv->gt_lock); + mutex_init(&dev_priv->dpio_lock); + mutex_init(&dev_priv->rps.hw_lock); + mutex_init(&dev_priv->modeset_restore_lock); +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 7221793239c3..73521ed14eeb 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -4643,7 +4643,7 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) + list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) + if (obj->pages_pin_count == 0) + cnt += obj->base.size >> PAGE_SHIFT; +- list_for_each_entry(obj, &vm->inactive_list, global_list) ++ list_for_each_entry(obj, &vm->inactive_list, mm_list) + if (obj->pin_count == 0 && obj->pages_pin_count == 0) + cnt += obj->base.size >> PAGE_SHIFT; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0525-drm-i915-Colocate-all-GT-access-routines-in-the-same.patch b/patches.baytrail/0525-drm-i915-Colocate-all-GT-access-routines-in-the-same.patch new file mode 100644 index 000000000000..afcd2fc08805 --- /dev/null +++ b/patches.baytrail/0525-drm-i915-Colocate-all-GT-access-routines-in-the-same.patch @@ -0,0 +1,1423 @@ +From 130059e2fe52f76a0c8456856e75d84c9d478441 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Fri, 19 Jul 2013 20:36:52 +0100 +Subject: drm/i915: Colocate all GT access routines in the same file + +Currently, the register access code is split between i915_drv.c and +intel_pm.c. It only bares a superficial resemblance to the reset of the +powermanagement code, so move it all into its own file. This is to ease +further patches to enforce serialised register access. + +v2: Scan for random abuse of I915_WRITE_NOTRACE +v3: Take the opportunity to rename the GT functions as uncore. Uncore is +the term used by the hardware design (and bspec) for all functions +outside of the GPU (and CPU) cores in what is also known as the System +Agent. +v4: Rebase onto SNB rc6 fixes + +Signed-off-by: Chris Wilson +Reviewed-by: Ben Widawsky +[danvet: Wrestle patch into applying and inline +intel_uncore_early_sanitize (plus move the old comment to the new +function). Also keep the _santize postfix for intel_uncore_sanitize.] +[danvet: Squash in fixup spotted by Chris on irc: We need to call +intel_pm_init before intel_uncore_sanitize since the later will call +cancel_work on the delayed rps setup work the former initializes.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 907b28c56ea40629aa6595ddfa414ec2fc7da41c) +Signed-off-by: James Ausmus + +Conflicts: + drivers/gpu/drm/i915/i915_dma.c + drivers/gpu/drm/i915/intel_pm.c + (context changes) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/Makefile | 1 + + drivers/gpu/drm/i915/i915_debugfs.c | 12 +- + drivers/gpu/drm/i915/i915_dma.c | 24 +- + drivers/gpu/drm/i915/i915_drv.c | 271 +---------------- + drivers/gpu/drm/i915/i915_drv.h | 31 +- + drivers/gpu/drm/i915/i915_irq.c | 6 +- + drivers/gpu/drm/i915/intel_display.c | 3 +- + drivers/gpu/drm/i915/intel_drv.h | 1 - + drivers/gpu/drm/i915/intel_pm.c | 264 +--------------- + drivers/gpu/drm/i915/intel_uncore.c | 571 +++++++++++++++++++++++++++++++++++ + 10 files changed, 613 insertions(+), 571 deletions(-) + create mode 100644 drivers/gpu/drm/i915/intel_uncore.c + +diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile +index 9d1da7cceb21..b8449a84a0dc 100644 +--- a/drivers/gpu/drm/i915/Makefile ++++ b/drivers/gpu/drm/i915/Makefile +@@ -38,6 +38,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ + intel_sprite.o \ + intel_opregion.o \ + intel_sideband.o \ ++ intel_uncore.o \ + dvo_ch7xxx.o \ + dvo_ch7017.o \ + dvo_ivch.o \ +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 9d871c7eeaee..0e904986f3e9 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -989,9 +989,9 @@ static int gen6_drpc_info(struct seq_file *m) + if (ret) + return ret; + +- spin_lock_irq(&dev_priv->gt_lock); +- forcewake_count = dev_priv->forcewake_count; +- spin_unlock_irq(&dev_priv->gt_lock); ++ spin_lock_irq(&dev_priv->uncore.lock); ++ forcewake_count = dev_priv->uncore.forcewake_count; ++ spin_unlock_irq(&dev_priv->uncore.lock); + + if (forcewake_count) { + seq_puts(m, "RC information inaccurate because somebody " +@@ -1375,9 +1375,9 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned forcewake_count; + +- spin_lock_irq(&dev_priv->gt_lock); +- forcewake_count = dev_priv->forcewake_count; +- spin_unlock_irq(&dev_priv->gt_lock); ++ spin_lock_irq(&dev_priv->uncore.lock); ++ forcewake_count = dev_priv->uncore.forcewake_count; ++ spin_unlock_irq(&dev_priv->uncore.lock); + + seq_printf(m, "forcewake count = %u\n", forcewake_count); + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index d71e765b814d..dcc44597ea14 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1436,22 +1436,6 @@ static void i915_dump_device_info(struct drm_i915_private *dev_priv) + } + + /** +- * intel_early_sanitize_regs - clean up BIOS state +- * @dev: DRM device +- * +- * This function must be called before we do any I915_READ or I915_WRITE. Its +- * purpose is to clean up any state left by the BIOS that may affect us when +- * reading and/or writing registers. +- */ +-static void intel_early_sanitize_regs(struct drm_device *dev) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- +- if (HAS_FPGA_DBG_UNCLAIMED(dev)) +- I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); +-} +- +-/** + * i915_driver_load - setup chip and create an initial config + * @dev: DRM device + * @flags: startup flags +@@ -1493,7 +1477,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + spin_lock_init(&dev_priv->irq_lock); + spin_lock_init(&dev_priv->gpu_error.lock); + spin_lock_init(&dev_priv->backlight.lock); +- spin_lock_init(&dev_priv->gt_lock); ++ spin_lock_init(&dev_priv->uncore.lock); + mutex_init(&dev_priv->dpio_lock); + mutex_init(&dev_priv->rps.hw_lock); + mutex_init(&dev_priv->modeset_restore_lock); +@@ -1529,7 +1513,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + goto put_bridge; + } + +- intel_early_sanitize_regs(dev); ++ intel_uncore_early_sanitize(dev); + + if (IS_HASWELL(dev) && (I915_READ(HSW_EDRAM_PRESENT) == 1)) { + /* The docs do not explain exactly how the calculation can be +@@ -1603,8 +1587,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + + intel_irq_init(dev); + intel_pm_init(dev); +- intel_gt_sanitize(dev); +- intel_gt_init(dev); ++ intel_uncore_sanitize(dev); ++ intel_uncore_init(dev); + + /* Try to make sure MCHBAR is enabled before poking at it */ + intel_setup_mchbar(dev); +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 5849b0a91b4e..01d63a0435fb 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -723,7 +723,7 @@ static int i915_drm_thaw(struct drm_device *dev) + { + int error = 0; + +- intel_gt_sanitize(dev); ++ intel_uncore_sanitize(dev); + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + mutex_lock(&dev->struct_mutex); +@@ -749,7 +749,7 @@ int i915_resume(struct drm_device *dev) + + pci_set_master(dev->pdev); + +- intel_gt_sanitize(dev); ++ intel_uncore_sanitize(dev); + + /* + * Platforms with opregion should have sane BIOS, older ones (gen3 and +@@ -770,140 +770,6 @@ int i915_resume(struct drm_device *dev) + return 0; + } + +-static int i8xx_do_reset(struct drm_device *dev) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- +- if (IS_I85X(dev)) +- return -ENODEV; +- +- I915_WRITE(D_STATE, I915_READ(D_STATE) | DSTATE_GFX_RESET_I830); +- POSTING_READ(D_STATE); +- +- if (IS_I830(dev) || IS_845G(dev)) { +- I915_WRITE(DEBUG_RESET_I830, +- DEBUG_RESET_DISPLAY | +- DEBUG_RESET_RENDER | +- DEBUG_RESET_FULL); +- POSTING_READ(DEBUG_RESET_I830); +- msleep(1); +- +- I915_WRITE(DEBUG_RESET_I830, 0); +- POSTING_READ(DEBUG_RESET_I830); +- } +- +- msleep(1); +- +- I915_WRITE(D_STATE, I915_READ(D_STATE) & ~DSTATE_GFX_RESET_I830); +- POSTING_READ(D_STATE); +- +- return 0; +-} +- +-static int i965_reset_complete(struct drm_device *dev) +-{ +- u8 gdrst; +- pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst); +- return (gdrst & GRDOM_RESET_ENABLE) == 0; +-} +- +-static int i965_do_reset(struct drm_device *dev) +-{ +- int ret; +- +- /* +- * Set the domains we want to reset (GRDOM/bits 2 and 3) as +- * well as the reset bit (GR/bit 0). Setting the GR bit +- * triggers the reset; when done, the hardware will clear it. +- */ +- pci_write_config_byte(dev->pdev, I965_GDRST, +- GRDOM_RENDER | GRDOM_RESET_ENABLE); +- ret = wait_for(i965_reset_complete(dev), 500); +- if (ret) +- return ret; +- +- /* We can't reset render&media without also resetting display ... */ +- pci_write_config_byte(dev->pdev, I965_GDRST, +- GRDOM_MEDIA | GRDOM_RESET_ENABLE); +- +- ret = wait_for(i965_reset_complete(dev), 500); +- if (ret) +- return ret; +- +- pci_write_config_byte(dev->pdev, I965_GDRST, 0); +- +- return 0; +-} +- +-static int ironlake_do_reset(struct drm_device *dev) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- u32 gdrst; +- int ret; +- +- gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); +- gdrst &= ~GRDOM_MASK; +- I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, +- gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE); +- ret = wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); +- if (ret) +- return ret; +- +- /* We can't reset render&media without also resetting display ... */ +- gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); +- gdrst &= ~GRDOM_MASK; +- I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, +- gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE); +- return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); +-} +- +-static int gen6_do_reset(struct drm_device *dev) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- int ret; +- unsigned long irqflags; +- +- /* Hold gt_lock across reset to prevent any register access +- * with forcewake not set correctly +- */ +- spin_lock_irqsave(&dev_priv->gt_lock, irqflags); +- +- /* Reset the chip */ +- +- /* GEN6_GDRST is not in the gt power well, no need to check +- * for fifo space for the write or forcewake the chip for +- * the read +- */ +- I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL); +- +- /* Spin waiting for the device to ack the reset request */ +- ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); +- +- /* If reset with a user forcewake, try to restore, otherwise turn it off */ +- if (dev_priv->forcewake_count) +- dev_priv->gt.force_wake_get(dev_priv); +- else +- dev_priv->gt.force_wake_put(dev_priv); +- +- /* Restore fifo count */ +- dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); +- +- spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); +- return ret; +-} +- +-int intel_gpu_reset(struct drm_device *dev) +-{ +- switch (INTEL_INFO(dev)->gen) { +- case 7: +- case 6: return gen6_do_reset(dev); +- case 5: return ironlake_do_reset(dev); +- case 4: return i965_do_reset(dev); +- case 2: return i8xx_do_reset(dev); +- default: return -ENODEV; +- } +-} +- + /** + * i915_reset - reset chip after a hang + * @dev: drm device to reset +@@ -1233,136 +1099,3 @@ module_exit(i915_exit); + MODULE_AUTHOR(DRIVER_AUTHOR); + MODULE_DESCRIPTION(DRIVER_DESC); + MODULE_LICENSE("GPL and additional rights"); +- +-/* We give fast paths for the really cool registers */ +-#define NEEDS_FORCE_WAKE(dev_priv, reg) \ +- ((HAS_FORCE_WAKE((dev_priv)->dev)) && \ +- ((reg) < 0x40000) && \ +- ((reg) != FORCEWAKE)) +-static void +-ilk_dummy_write(struct drm_i915_private *dev_priv) +-{ +- /* WaIssueDummyWriteToWakeupFromRC6:ilk Issue a dummy write to wake up +- * the chip from rc6 before touching it for real. MI_MODE is masked, +- * hence harmless to write 0 into. */ +- I915_WRITE_NOTRACE(MI_MODE, 0); +-} +- +-static void +-hsw_unclaimed_reg_clear(struct drm_i915_private *dev_priv, u32 reg) +-{ +- if (HAS_FPGA_DBG_UNCLAIMED(dev_priv->dev) && +- (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { +- DRM_ERROR("Unknown unclaimed register before writing to %x\n", +- reg); +- I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); +- } +-} +- +-static void +-hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) +-{ +- if (HAS_FPGA_DBG_UNCLAIMED(dev_priv->dev) && +- (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { +- DRM_ERROR("Unclaimed write to %x\n", reg); +- I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); +- } +-} +- +-#define __i915_read(x, y) \ +-u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ +- unsigned long irqflags; \ +- u##x val = 0; \ +- spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ +- if (IS_GEN5(dev_priv->dev)) \ +- ilk_dummy_write(dev_priv); \ +- if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ +- if (dev_priv->forcewake_count == 0) \ +- dev_priv->gt.force_wake_get(dev_priv); \ +- val = read##y(dev_priv->regs + reg); \ +- if (dev_priv->forcewake_count == 0) \ +- dev_priv->gt.force_wake_put(dev_priv); \ +- } else { \ +- val = read##y(dev_priv->regs + reg); \ +- } \ +- spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ +- trace_i915_reg_rw(false, reg, val, sizeof(val)); \ +- return val; \ +-} +- +-__i915_read(8, b) +-__i915_read(16, w) +-__i915_read(32, l) +-__i915_read(64, q) +-#undef __i915_read +- +-#define __i915_write(x, y) \ +-void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ +- unsigned long irqflags; \ +- u32 __fifo_ret = 0; \ +- trace_i915_reg_rw(true, reg, val, sizeof(val)); \ +- spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ +- if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ +- __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ +- } \ +- if (IS_GEN5(dev_priv->dev)) \ +- ilk_dummy_write(dev_priv); \ +- hsw_unclaimed_reg_clear(dev_priv, reg); \ +- write##y(val, dev_priv->regs + reg); \ +- if (unlikely(__fifo_ret)) { \ +- gen6_gt_check_fifodbg(dev_priv); \ +- } \ +- hsw_unclaimed_reg_check(dev_priv, reg); \ +- spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ +-} +-__i915_write(8, b) +-__i915_write(16, w) +-__i915_write(32, l) +-__i915_write(64, q) +-#undef __i915_write +- +-static const struct register_whitelist { +- uint64_t offset; +- uint32_t size; +- uint32_t gen_bitmask; /* support gens, 0x10 for 4, 0x30 for 4 and 5, etc. */ +-} whitelist[] = { +- { RING_TIMESTAMP(RENDER_RING_BASE), 8, 0xF0 }, +-}; +- +-int i915_reg_read_ioctl(struct drm_device *dev, +- void *data, struct drm_file *file) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- struct drm_i915_reg_read *reg = data; +- struct register_whitelist const *entry = whitelist; +- int i; +- +- for (i = 0; i < ARRAY_SIZE(whitelist); i++, entry++) { +- if (entry->offset == reg->offset && +- (1 << INTEL_INFO(dev)->gen & entry->gen_bitmask)) +- break; +- } +- +- if (i == ARRAY_SIZE(whitelist)) +- return -EINVAL; +- +- switch (entry->size) { +- case 8: +- reg->val = I915_READ64(reg->offset); +- break; +- case 4: +- reg->val = I915_READ(reg->offset); +- break; +- case 2: +- reg->val = I915_READ16(reg->offset); +- break; +- case 1: +- reg->val = I915_READ8(reg->offset); +- break; +- default: +- WARN_ON(1); +- return -EINVAL; +- } +- +- return 0; +-} +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 452b2ae84c4e..928a7309b7c3 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -391,11 +391,20 @@ struct drm_i915_display_funcs { + /* pll clock increase/decrease */ + }; + +-struct drm_i915_gt_funcs { ++struct intel_uncore_funcs { + void (*force_wake_get)(struct drm_i915_private *dev_priv); + void (*force_wake_put)(struct drm_i915_private *dev_priv); + }; + ++struct intel_uncore { ++ spinlock_t lock; /** lock is also taken in irq contexts. */ ++ ++ struct intel_uncore_funcs funcs; ++ ++ unsigned fifo_count; ++ unsigned forcewake_count; ++}; ++ + #define DEV_INFO_FOR_EACH_FLAG(func, sep) \ + func(is_mobile) sep \ + func(is_i85x) sep \ +@@ -1045,14 +1054,7 @@ typedef struct drm_i915_private { + + void __iomem *regs; + +- struct drm_i915_gt_funcs gt; +- /** gt_fifo_count and the subsequent register write are synchronized +- * with dev->struct_mutex. */ +- unsigned gt_fifo_count; +- /** forcewake_count is protected by gt_lock */ +- unsigned forcewake_count; +- /** gt_lock is also taken in irq contexts. */ +- spinlock_t gt_lock; ++ struct intel_uncore uncore; + + struct intel_gmbus gmbus[GMBUS_NUM_PORTS]; + +@@ -1671,8 +1673,14 @@ void i915_handle_error(struct drm_device *dev, bool wedged); + extern void intel_irq_init(struct drm_device *dev); + extern void intel_pm_init(struct drm_device *dev); + extern void intel_hpd_init(struct drm_device *dev); +-extern void intel_gt_init(struct drm_device *dev); +-extern void intel_gt_sanitize(struct drm_device *dev); ++extern void intel_pm_init(struct drm_device *dev); ++ ++extern void intel_uncore_sanitize(struct drm_device *dev); ++extern void intel_uncore_early_sanitize(struct drm_device *dev); ++extern void intel_uncore_init(struct drm_device *dev); ++extern void intel_uncore_reset(struct drm_device *dev); ++extern void intel_uncore_clear_errors(struct drm_device *dev); ++extern void intel_uncore_check_errors(struct drm_device *dev); + + void + i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); +@@ -2108,7 +2116,6 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e, + */ + void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); + void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); +-int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); + + int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val); + int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val); +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 52a43470e125..a588cd5745aa 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1307,11 +1307,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + + /* We get interrupts on unclaimed registers, so check for this before we + * do any I915_{READ,WRITE}. */ +- if (IS_HASWELL(dev) && +- (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { +- DRM_ERROR("Unclaimed register before interrupt\n"); +- I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); +- } ++ intel_uncore_check_errors(dev); + + /* disable master interrupt before clearing iir */ + de_ier = I915_READ(DEIER); +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 73965dfbf149..afac090a4f3d 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -10481,8 +10481,7 @@ intel_display_capture_error_state(struct drm_device *dev) + * well was on, so here we have to clear the FPGA_DBG_RM_NOCLAIM bit to + * prevent the next I915_WRITE from detecting it and printing an error + * message. */ +- if (HAS_POWER_WELL(dev)) +- I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); ++ intel_uncore_clear_errors(dev); + + return error; + } +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 3fbe80bc36bb..d9f50e368fe9 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -806,7 +806,6 @@ extern void intel_init_power_well(struct drm_device *dev); + extern void intel_set_power_well(struct drm_device *dev, bool enable); + extern void intel_enable_gt_powersave(struct drm_device *dev); + extern void intel_disable_gt_powersave(struct drm_device *dev); +-extern void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv); + extern void ironlake_teardown_rc6(struct drm_device *dev); + + extern bool intel_ddi_get_hw_state(struct intel_encoder *encoder, +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 948c171d7f73..5d7d0e76da7f 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -32,8 +32,6 @@ + #include + #include + +-#define FORCEWAKE_ACK_TIMEOUT_MS 2 +- + /* FBC, or Frame Buffer Compression, is a technique employed to compress the + * framebuffer contents in-memory, aiming at reducing the required bandwidth + * during in-memory transfers and, therefore, reduce the power packet. +@@ -5307,260 +5305,6 @@ void intel_init_pm(struct drm_device *dev) + } + } + +-static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) +-{ +- u32 gt_thread_status_mask; +- +- if (IS_HASWELL(dev_priv->dev)) +- gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK_HSW; +- else +- gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK; +- +- /* w/a for a sporadic read returning 0 by waiting for the GT +- * thread to wake up. +- */ +- if (wait_for_atomic_us((I915_READ_NOTRACE(GEN6_GT_THREAD_STATUS_REG) & gt_thread_status_mask) == 0, 500)) +- DRM_ERROR("GT thread status wait timed out\n"); +-} +- +-static void __gen6_gt_force_wake_reset(struct drm_i915_private *dev_priv) +-{ +- I915_WRITE_NOTRACE(FORCEWAKE, 0); +- POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */ +-} +- +-static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) +-{ +- if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0, +- FORCEWAKE_ACK_TIMEOUT_MS)) +- DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); +- +- I915_WRITE_NOTRACE(FORCEWAKE, 1); +- POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */ +- +- if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1), +- FORCEWAKE_ACK_TIMEOUT_MS)) +- DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); +- +- /* WaRsForcewakeWaitTC0:snb */ +- __gen6_gt_wait_for_thread_c0(dev_priv); +-} +- +-static void __gen6_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv) +-{ +- I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff)); +- /* something from same cacheline, but !FORCEWAKE_MT */ +- POSTING_READ(ECOBUS); +-} +- +-static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) +-{ +- u32 forcewake_ack; +- +- if (IS_HASWELL(dev_priv->dev)) +- forcewake_ack = FORCEWAKE_ACK_HSW; +- else +- forcewake_ack = FORCEWAKE_MT_ACK; +- +- if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & FORCEWAKE_KERNEL) == 0, +- FORCEWAKE_ACK_TIMEOUT_MS)) +- DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); +- +- I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); +- /* something from same cacheline, but !FORCEWAKE_MT */ +- POSTING_READ(ECOBUS); +- +- if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & FORCEWAKE_KERNEL), +- FORCEWAKE_ACK_TIMEOUT_MS)) +- DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); +- +- /* WaRsForcewakeWaitTC0:ivb,hsw */ +- __gen6_gt_wait_for_thread_c0(dev_priv); +-} +- +-/* +- * Generally this is called implicitly by the register read function. However, +- * if some sequence requires the GT to not power down then this function should +- * be called at the beginning of the sequence followed by a call to +- * gen6_gt_force_wake_put() at the end of the sequence. +- */ +-void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) +-{ +- unsigned long irqflags; +- +- spin_lock_irqsave(&dev_priv->gt_lock, irqflags); +- if (dev_priv->forcewake_count++ == 0) +- dev_priv->gt.force_wake_get(dev_priv); +- spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); +-} +- +-void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) +-{ +- u32 gtfifodbg; +- gtfifodbg = I915_READ_NOTRACE(GTFIFODBG); +- if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK, +- "MMIO read or write has been dropped %x\n", gtfifodbg)) +- I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK); +-} +- +-static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) +-{ +- I915_WRITE_NOTRACE(FORCEWAKE, 0); +- /* something from same cacheline, but !FORCEWAKE */ +- POSTING_READ(ECOBUS); +- gen6_gt_check_fifodbg(dev_priv); +-} +- +-static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) +-{ +- I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); +- /* something from same cacheline, but !FORCEWAKE_MT */ +- POSTING_READ(ECOBUS); +- gen6_gt_check_fifodbg(dev_priv); +-} +- +-/* +- * see gen6_gt_force_wake_get() +- */ +-void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) +-{ +- unsigned long irqflags; +- +- spin_lock_irqsave(&dev_priv->gt_lock, irqflags); +- if (--dev_priv->forcewake_count == 0) +- dev_priv->gt.force_wake_put(dev_priv); +- spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); +-} +- +-int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) +-{ +- int ret = 0; +- +- if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) { +- int loop = 500; +- u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); +- while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) { +- udelay(10); +- fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); +- } +- if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES)) +- ++ret; +- dev_priv->gt_fifo_count = fifo; +- } +- dev_priv->gt_fifo_count--; +- +- return ret; +-} +- +-static void vlv_force_wake_reset(struct drm_i915_private *dev_priv) +-{ +- I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_DISABLE(0xffff)); +- /* something from same cacheline, but !FORCEWAKE_VLV */ +- POSTING_READ(FORCEWAKE_ACK_VLV); +-} +- +-static void vlv_force_wake_get(struct drm_i915_private *dev_priv) +-{ +- if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL) == 0, +- FORCEWAKE_ACK_TIMEOUT_MS)) +- DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); +- +- I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); +- I915_WRITE_NOTRACE(FORCEWAKE_MEDIA_VLV, +- _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); +- +- if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL), +- FORCEWAKE_ACK_TIMEOUT_MS)) +- DRM_ERROR("Timed out waiting for GT to ack forcewake request.\n"); +- +- if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_MEDIA_VLV) & +- FORCEWAKE_KERNEL), +- FORCEWAKE_ACK_TIMEOUT_MS)) +- DRM_ERROR("Timed out waiting for media to ack forcewake request.\n"); +- +- /* WaRsForcewakeWaitTC0:vlv */ +- __gen6_gt_wait_for_thread_c0(dev_priv); +-} +- +-static void vlv_force_wake_put(struct drm_i915_private *dev_priv) +-{ +- I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); +- I915_WRITE_NOTRACE(FORCEWAKE_MEDIA_VLV, +- _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); +- /* The below doubles as a POSTING_READ */ +- gen6_gt_check_fifodbg(dev_priv); +-} +- +-void intel_gt_sanitize(struct drm_device *dev) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- +- if (IS_VALLEYVIEW(dev)) { +- vlv_force_wake_reset(dev_priv); +- } else if (INTEL_INFO(dev)->gen >= 6) { +- __gen6_gt_force_wake_reset(dev_priv); +- if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) +- __gen6_gt_force_wake_mt_reset(dev_priv); +- } +- +- /* BIOS often leaves RC6 enabled, but disable it for hw init */ +- if (INTEL_INFO(dev)->gen >= 6) +- intel_disable_gt_powersave(dev); +-} +- +-void intel_gt_init(struct drm_device *dev) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- +- if (IS_VALLEYVIEW(dev)) { +- dev_priv->gt.force_wake_get = vlv_force_wake_get; +- dev_priv->gt.force_wake_put = vlv_force_wake_put; +- } else if (IS_HASWELL(dev)) { +- dev_priv->gt.force_wake_get = __gen6_gt_force_wake_mt_get; +- dev_priv->gt.force_wake_put = __gen6_gt_force_wake_mt_put; +- } else if (IS_IVYBRIDGE(dev)) { +- u32 ecobus; +- +- /* IVB configs may use multi-threaded forcewake */ +- +- /* A small trick here - if the bios hasn't configured +- * MT forcewake, and if the device is in RC6, then +- * force_wake_mt_get will not wake the device and the +- * ECOBUS read will return zero. Which will be +- * (correctly) interpreted by the test below as MT +- * forcewake being disabled. +- */ +- mutex_lock(&dev->struct_mutex); +- __gen6_gt_force_wake_mt_get(dev_priv); +- ecobus = I915_READ_NOTRACE(ECOBUS); +- __gen6_gt_force_wake_mt_put(dev_priv); +- mutex_unlock(&dev->struct_mutex); +- +- if (ecobus & FORCEWAKE_MT_ENABLE) { +- dev_priv->gt.force_wake_get = +- __gen6_gt_force_wake_mt_get; +- dev_priv->gt.force_wake_put = +- __gen6_gt_force_wake_mt_put; +- } else { +- DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n"); +- DRM_INFO("when using vblank-synced partial screen updates.\n"); +- dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get; +- dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put; +- } +- } else if (IS_GEN6(dev)) { +- dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get; +- dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put; +- } +-} +- +-void intel_pm_init(struct drm_device *dev) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; +- +- INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, +- intel_gen6_powersave_work); +-} +- + int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) + { + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); +@@ -5663,3 +5407,11 @@ int vlv_freq_opcode(int ddr_freq, int val) + return val; + } + ++void intel_pm_init(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, ++ intel_gen6_powersave_work); ++} ++ +diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c +new file mode 100644 +index 000000000000..97e8b1b86476 +--- /dev/null ++++ b/drivers/gpu/drm/i915/intel_uncore.c +@@ -0,0 +1,571 @@ ++/* ++ * Copyright © 2013 Intel Corporation ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ */ ++ ++#include "i915_drv.h" ++#include "intel_drv.h" ++ ++#define FORCEWAKE_ACK_TIMEOUT_MS 2 ++ ++static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) ++{ ++ u32 gt_thread_status_mask; ++ ++ if (IS_HASWELL(dev_priv->dev)) ++ gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK_HSW; ++ else ++ gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK; ++ ++ /* w/a for a sporadic read returning 0 by waiting for the GT ++ * thread to wake up. ++ */ ++ if (wait_for_atomic_us((I915_READ_NOTRACE(GEN6_GT_THREAD_STATUS_REG) & gt_thread_status_mask) == 0, 500)) ++ DRM_ERROR("GT thread status wait timed out\n"); ++} ++ ++static void __gen6_gt_force_wake_reset(struct drm_i915_private *dev_priv) ++{ ++ I915_WRITE_NOTRACE(FORCEWAKE, 0); ++ POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */ ++} ++ ++static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) ++{ ++ if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0, ++ FORCEWAKE_ACK_TIMEOUT_MS)) ++ DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); ++ ++ I915_WRITE_NOTRACE(FORCEWAKE, 1); ++ POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */ ++ ++ if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1), ++ FORCEWAKE_ACK_TIMEOUT_MS)) ++ DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); ++ ++ /* WaRsForcewakeWaitTC0:snb */ ++ __gen6_gt_wait_for_thread_c0(dev_priv); ++} ++ ++static void __gen6_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv) ++{ ++ I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff)); ++ /* something from same cacheline, but !FORCEWAKE_MT */ ++ POSTING_READ(ECOBUS); ++} ++ ++static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) ++{ ++ u32 forcewake_ack; ++ ++ if (IS_HASWELL(dev_priv->dev)) ++ forcewake_ack = FORCEWAKE_ACK_HSW; ++ else ++ forcewake_ack = FORCEWAKE_MT_ACK; ++ ++ if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & FORCEWAKE_KERNEL) == 0, ++ FORCEWAKE_ACK_TIMEOUT_MS)) ++ DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); ++ ++ I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); ++ /* something from same cacheline, but !FORCEWAKE_MT */ ++ POSTING_READ(ECOBUS); ++ ++ if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & FORCEWAKE_KERNEL), ++ FORCEWAKE_ACK_TIMEOUT_MS)) ++ DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); ++ ++ /* WaRsForcewakeWaitTC0:ivb,hsw */ ++ __gen6_gt_wait_for_thread_c0(dev_priv); ++} ++ ++static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) ++{ ++ u32 gtfifodbg; ++ gtfifodbg = I915_READ_NOTRACE(GTFIFODBG); ++ if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK, ++ "MMIO read or write has been dropped %x\n", gtfifodbg)) ++ I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK); ++} ++ ++static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) ++{ ++ I915_WRITE_NOTRACE(FORCEWAKE, 0); ++ /* something from same cacheline, but !FORCEWAKE */ ++ POSTING_READ(ECOBUS); ++ gen6_gt_check_fifodbg(dev_priv); ++} ++ ++static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) ++{ ++ I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); ++ /* something from same cacheline, but !FORCEWAKE_MT */ ++ POSTING_READ(ECOBUS); ++ gen6_gt_check_fifodbg(dev_priv); ++} ++ ++static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) ++{ ++ int ret = 0; ++ ++ if (dev_priv->uncore.fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) { ++ int loop = 500; ++ u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); ++ while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) { ++ udelay(10); ++ fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); ++ } ++ if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES)) ++ ++ret; ++ dev_priv->uncore.fifo_count = fifo; ++ } ++ dev_priv->uncore.fifo_count--; ++ ++ return ret; ++} ++ ++static void vlv_force_wake_reset(struct drm_i915_private *dev_priv) ++{ ++ I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_DISABLE(0xffff)); ++ /* something from same cacheline, but !FORCEWAKE_VLV */ ++ POSTING_READ(FORCEWAKE_ACK_VLV); ++} ++ ++static void vlv_force_wake_get(struct drm_i915_private *dev_priv) ++{ ++ if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL) == 0, ++ FORCEWAKE_ACK_TIMEOUT_MS)) ++ DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); ++ ++ I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); ++ I915_WRITE_NOTRACE(FORCEWAKE_MEDIA_VLV, ++ _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); ++ ++ if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL), ++ FORCEWAKE_ACK_TIMEOUT_MS)) ++ DRM_ERROR("Timed out waiting for GT to ack forcewake request.\n"); ++ ++ if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_MEDIA_VLV) & ++ FORCEWAKE_KERNEL), ++ FORCEWAKE_ACK_TIMEOUT_MS)) ++ DRM_ERROR("Timed out waiting for media to ack forcewake request.\n"); ++ ++ /* WaRsForcewakeWaitTC0:vlv */ ++ __gen6_gt_wait_for_thread_c0(dev_priv); ++} ++ ++static void vlv_force_wake_put(struct drm_i915_private *dev_priv) ++{ ++ I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); ++ I915_WRITE_NOTRACE(FORCEWAKE_MEDIA_VLV, ++ _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); ++ /* The below doubles as a POSTING_READ */ ++ gen6_gt_check_fifodbg(dev_priv); ++} ++ ++void intel_uncore_early_sanitize(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (HAS_FPGA_DBG_UNCLAIMED(dev)) ++ I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); ++} ++ ++void intel_uncore_init(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (IS_VALLEYVIEW(dev)) { ++ dev_priv->uncore.funcs.force_wake_get = vlv_force_wake_get; ++ dev_priv->uncore.funcs.force_wake_put = vlv_force_wake_put; ++ } else if (IS_HASWELL(dev)) { ++ dev_priv->uncore.funcs.force_wake_get = __gen6_gt_force_wake_mt_get; ++ dev_priv->uncore.funcs.force_wake_put = __gen6_gt_force_wake_mt_put; ++ } else if (IS_IVYBRIDGE(dev)) { ++ u32 ecobus; ++ ++ /* IVB configs may use multi-threaded forcewake */ ++ ++ /* A small trick here - if the bios hasn't configured ++ * MT forcewake, and if the device is in RC6, then ++ * force_wake_mt_get will not wake the device and the ++ * ECOBUS read will return zero. Which will be ++ * (correctly) interpreted by the test below as MT ++ * forcewake being disabled. ++ */ ++ mutex_lock(&dev->struct_mutex); ++ __gen6_gt_force_wake_mt_get(dev_priv); ++ ecobus = I915_READ_NOTRACE(ECOBUS); ++ __gen6_gt_force_wake_mt_put(dev_priv); ++ mutex_unlock(&dev->struct_mutex); ++ ++ if (ecobus & FORCEWAKE_MT_ENABLE) { ++ dev_priv->uncore.funcs.force_wake_get = ++ __gen6_gt_force_wake_mt_get; ++ dev_priv->uncore.funcs.force_wake_put = ++ __gen6_gt_force_wake_mt_put; ++ } else { ++ DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n"); ++ DRM_INFO("when using vblank-synced partial screen updates.\n"); ++ dev_priv->uncore.funcs.force_wake_get = ++ __gen6_gt_force_wake_get; ++ dev_priv->uncore.funcs.force_wake_put = ++ __gen6_gt_force_wake_put; ++ } ++ } else if (IS_GEN6(dev)) { ++ dev_priv->uncore.funcs.force_wake_get = ++ __gen6_gt_force_wake_get; ++ dev_priv->uncore.funcs.force_wake_put = ++ __gen6_gt_force_wake_put; ++ } ++} ++ ++void intel_uncore_sanitize(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (IS_VALLEYVIEW(dev)) { ++ vlv_force_wake_reset(dev_priv); ++ } else if (INTEL_INFO(dev)->gen >= 6) { ++ __gen6_gt_force_wake_reset(dev_priv); ++ if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) ++ __gen6_gt_force_wake_mt_reset(dev_priv); ++ } ++ ++ /* BIOS often leaves RC6 enabled, but disable it for hw init */ ++ intel_disable_gt_powersave(dev); ++} ++ ++/* ++ * Generally this is called implicitly by the register read function. However, ++ * if some sequence requires the GT to not power down then this function should ++ * be called at the beginning of the sequence followed by a call to ++ * gen6_gt_force_wake_put() at the end of the sequence. ++ */ ++void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) ++{ ++ unsigned long irqflags; ++ ++ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); ++ if (dev_priv->uncore.forcewake_count++ == 0) ++ dev_priv->uncore.funcs.force_wake_get(dev_priv); ++ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); ++} ++ ++/* ++ * see gen6_gt_force_wake_get() ++ */ ++void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) ++{ ++ unsigned long irqflags; ++ ++ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); ++ if (--dev_priv->uncore.forcewake_count == 0) ++ dev_priv->uncore.funcs.force_wake_put(dev_priv); ++ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); ++} ++ ++/* We give fast paths for the really cool registers */ ++#define NEEDS_FORCE_WAKE(dev_priv, reg) \ ++ ((HAS_FORCE_WAKE((dev_priv)->dev)) && \ ++ ((reg) < 0x40000) && \ ++ ((reg) != FORCEWAKE)) ++ ++static void ++ilk_dummy_write(struct drm_i915_private *dev_priv) ++{ ++ /* WaIssueDummyWriteToWakeupFromRC6:ilk Issue a dummy write to wake up ++ * the chip from rc6 before touching it for real. MI_MODE is masked, ++ * hence harmless to write 0 into. */ ++ I915_WRITE_NOTRACE(MI_MODE, 0); ++} ++ ++static void ++hsw_unclaimed_reg_clear(struct drm_i915_private *dev_priv, u32 reg) ++{ ++ if (HAS_FPGA_DBG_UNCLAIMED(dev_priv->dev) && ++ (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { ++ DRM_ERROR("Unknown unclaimed register before writing to %x\n", ++ reg); ++ I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); ++ } ++} ++ ++static void ++hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) ++{ ++ if (HAS_FPGA_DBG_UNCLAIMED(dev_priv->dev) && ++ (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { ++ DRM_ERROR("Unclaimed write to %x\n", reg); ++ I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); ++ } ++} ++ ++#define __i915_read(x, y) \ ++u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ ++ unsigned long irqflags; \ ++ u##x val = 0; \ ++ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); \ ++ if (IS_GEN5(dev_priv->dev)) \ ++ ilk_dummy_write(dev_priv); \ ++ if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ ++ if (dev_priv->uncore.forcewake_count == 0) \ ++ dev_priv->uncore.funcs.force_wake_get(dev_priv); \ ++ val = read##y(dev_priv->regs + reg); \ ++ if (dev_priv->uncore.forcewake_count == 0) \ ++ dev_priv->uncore.funcs.force_wake_put(dev_priv); \ ++ } else { \ ++ val = read##y(dev_priv->regs + reg); \ ++ } \ ++ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \ ++ trace_i915_reg_rw(false, reg, val, sizeof(val)); \ ++ return val; \ ++} ++ ++__i915_read(8, b) ++__i915_read(16, w) ++__i915_read(32, l) ++__i915_read(64, q) ++#undef __i915_read ++ ++#define __i915_write(x, y) \ ++void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ ++ unsigned long irqflags; \ ++ u32 __fifo_ret = 0; \ ++ trace_i915_reg_rw(true, reg, val, sizeof(val)); \ ++ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); \ ++ if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ ++ __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ ++ } \ ++ if (IS_GEN5(dev_priv->dev)) \ ++ ilk_dummy_write(dev_priv); \ ++ hsw_unclaimed_reg_clear(dev_priv, reg); \ ++ write##y(val, dev_priv->regs + reg); \ ++ if (unlikely(__fifo_ret)) { \ ++ gen6_gt_check_fifodbg(dev_priv); \ ++ } \ ++ hsw_unclaimed_reg_check(dev_priv, reg); \ ++ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \ ++} ++__i915_write(8, b) ++__i915_write(16, w) ++__i915_write(32, l) ++__i915_write(64, q) ++#undef __i915_write ++ ++static const struct register_whitelist { ++ uint64_t offset; ++ uint32_t size; ++ uint32_t gen_bitmask; /* support gens, 0x10 for 4, 0x30 for 4 and 5, etc. */ ++} whitelist[] = { ++ { RING_TIMESTAMP(RENDER_RING_BASE), 8, 0xF0 }, ++}; ++ ++int i915_reg_read_ioctl(struct drm_device *dev, ++ void *data, struct drm_file *file) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_i915_reg_read *reg = data; ++ struct register_whitelist const *entry = whitelist; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(whitelist); i++, entry++) { ++ if (entry->offset == reg->offset && ++ (1 << INTEL_INFO(dev)->gen & entry->gen_bitmask)) ++ break; ++ } ++ ++ if (i == ARRAY_SIZE(whitelist)) ++ return -EINVAL; ++ ++ switch (entry->size) { ++ case 8: ++ reg->val = I915_READ64(reg->offset); ++ break; ++ case 4: ++ reg->val = I915_READ(reg->offset); ++ break; ++ case 2: ++ reg->val = I915_READ16(reg->offset); ++ break; ++ case 1: ++ reg->val = I915_READ8(reg->offset); ++ break; ++ default: ++ WARN_ON(1); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int i8xx_do_reset(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (IS_I85X(dev)) ++ return -ENODEV; ++ ++ I915_WRITE(D_STATE, I915_READ(D_STATE) | DSTATE_GFX_RESET_I830); ++ POSTING_READ(D_STATE); ++ ++ if (IS_I830(dev) || IS_845G(dev)) { ++ I915_WRITE(DEBUG_RESET_I830, ++ DEBUG_RESET_DISPLAY | ++ DEBUG_RESET_RENDER | ++ DEBUG_RESET_FULL); ++ POSTING_READ(DEBUG_RESET_I830); ++ msleep(1); ++ ++ I915_WRITE(DEBUG_RESET_I830, 0); ++ POSTING_READ(DEBUG_RESET_I830); ++ } ++ ++ msleep(1); ++ ++ I915_WRITE(D_STATE, I915_READ(D_STATE) & ~DSTATE_GFX_RESET_I830); ++ POSTING_READ(D_STATE); ++ ++ return 0; ++} ++ ++static int i965_reset_complete(struct drm_device *dev) ++{ ++ u8 gdrst; ++ pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst); ++ return (gdrst & GRDOM_RESET_ENABLE) == 0; ++} ++ ++static int i965_do_reset(struct drm_device *dev) ++{ ++ int ret; ++ ++ /* ++ * Set the domains we want to reset (GRDOM/bits 2 and 3) as ++ * well as the reset bit (GR/bit 0). Setting the GR bit ++ * triggers the reset; when done, the hardware will clear it. ++ */ ++ pci_write_config_byte(dev->pdev, I965_GDRST, ++ GRDOM_RENDER | GRDOM_RESET_ENABLE); ++ ret = wait_for(i965_reset_complete(dev), 500); ++ if (ret) ++ return ret; ++ ++ /* We can't reset render&media without also resetting display ... */ ++ pci_write_config_byte(dev->pdev, I965_GDRST, ++ GRDOM_MEDIA | GRDOM_RESET_ENABLE); ++ ++ ret = wait_for(i965_reset_complete(dev), 500); ++ if (ret) ++ return ret; ++ ++ pci_write_config_byte(dev->pdev, I965_GDRST, 0); ++ ++ return 0; ++} ++ ++static int ironlake_do_reset(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ u32 gdrst; ++ int ret; ++ ++ gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); ++ gdrst &= ~GRDOM_MASK; ++ I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, ++ gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE); ++ ret = wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); ++ if (ret) ++ return ret; ++ ++ /* We can't reset render&media without also resetting display ... */ ++ gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); ++ gdrst &= ~GRDOM_MASK; ++ I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, ++ gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE); ++ return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); ++} ++ ++static int gen6_do_reset(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int ret; ++ unsigned long irqflags; ++ ++ /* Hold uncore.lock across reset to prevent any register access ++ * with forcewake not set correctly ++ */ ++ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); ++ ++ /* Reset the chip */ ++ ++ /* GEN6_GDRST is not in the gt power well, no need to check ++ * for fifo space for the write or forcewake the chip for ++ * the read ++ */ ++ I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL); ++ ++ /* Spin waiting for the device to ack the reset request */ ++ ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); ++ ++ /* If reset with a user forcewake, try to restore, otherwise turn it off */ ++ if (dev_priv->uncore.forcewake_count) ++ dev_priv->uncore.funcs.force_wake_get(dev_priv); ++ else ++ dev_priv->uncore.funcs.force_wake_put(dev_priv); ++ ++ /* Restore fifo count */ ++ dev_priv->uncore.fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); ++ ++ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); ++ return ret; ++} ++ ++int intel_gpu_reset(struct drm_device *dev) ++{ ++ switch (INTEL_INFO(dev)->gen) { ++ case 7: ++ case 6: return gen6_do_reset(dev); ++ case 5: return ironlake_do_reset(dev); ++ case 4: return i965_do_reset(dev); ++ case 2: return i8xx_do_reset(dev); ++ default: return -ENODEV; ++ } ++} ++ ++void intel_uncore_clear_errors(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (HAS_FPGA_DBG_UNCLAIMED(dev)) ++ I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); ++} ++ ++void intel_uncore_check_errors(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (HAS_FPGA_DBG_UNCLAIMED(dev) && ++ (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { ++ DRM_ERROR("Unclaimed register before interrupt\n"); ++ I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); ++ } ++} +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0526-drm-i915-Use-a-private-interface-for-register-access.patch b/patches.baytrail/0526-drm-i915-Use-a-private-interface-for-register-access.patch new file mode 100644 index 000000000000..9bc54b39423d --- /dev/null +++ b/patches.baytrail/0526-drm-i915-Use-a-private-interface-for-register-access.patch @@ -0,0 +1,410 @@ +From 68ca0e9ca7290951c0e87a380a6715af573a00e7 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Fri, 19 Jul 2013 20:36:53 +0100 +Subject: drm/i915: Use a private interface for register access within GT + +The GT functions for enabling register access also need to occasionally +write to and read from registers. To avoid the potential recursion as we +modify the public interface to be stricter, introduce a private register +access API for the GT functions. + +v2: Rebase +v3: Rebase onto uncore +v4: Use raw interfaces consistently so that we only use the low-level + readN functions from a single location. + +Signed-off-by: Chris Wilson +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 6af5d92f909796cb706f3b9efefd75cb0f5afcff) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 22 +++--- + drivers/gpu/drm/i915/intel_uncore.c | 136 +++++++++++++++++++++--------------- + 2 files changed, 90 insertions(+), 68 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 928a7309b7c3..ababee4f2f2e 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -2134,22 +2134,20 @@ void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value, + int vlv_gpu_freq(int ddr_freq, int val); + int vlv_freq_opcode(int ddr_freq, int val); + +-#define __i915_read(x, y) \ ++#define __i915_read(x) \ + u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg); +- +-__i915_read(8, b) +-__i915_read(16, w) +-__i915_read(32, l) +-__i915_read(64, q) ++__i915_read(8) ++__i915_read(16) ++__i915_read(32) ++__i915_read(64) + #undef __i915_read + +-#define __i915_write(x, y) \ ++#define __i915_write(x) \ + void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val); +- +-__i915_write(8, b) +-__i915_write(16, w) +-__i915_write(32, l) +-__i915_write(64, q) ++__i915_write(8) ++__i915_write(16) ++__i915_write(32) ++__i915_write(64) + #undef __i915_write + + #define I915_READ8(reg) i915_read8(dev_priv, (reg)) +diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c +index 97e8b1b86476..228bc7a3f373 100644 +--- a/drivers/gpu/drm/i915/intel_uncore.c ++++ b/drivers/gpu/drm/i915/intel_uncore.c +@@ -26,6 +26,21 @@ + + #define FORCEWAKE_ACK_TIMEOUT_MS 2 + ++#define __raw_i915_read8(dev_priv__, reg__) readb((dev_priv__)->regs + (reg__)) ++#define __raw_i915_write8(dev_priv__, reg__, val__) writeb(val__, (dev_priv__)->regs + (reg__)) ++ ++#define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__)) ++#define __raw_i915_write16(dev_priv__, reg__, val__) writew(val__, (dev_priv__)->regs + (reg__)) ++ ++#define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__)) ++#define __raw_i915_write32(dev_priv__, reg__, val__) writel(val__, (dev_priv__)->regs + (reg__)) ++ ++#define __raw_i915_read64(dev_priv__, reg__) readq((dev_priv__)->regs + (reg__)) ++#define __raw_i915_write64(dev_priv__, reg__, val__) writeq(val__, (dev_priv__)->regs + (reg__)) ++ ++#define __raw_posting_read(dev_priv__, reg__) (void)__raw_i915_read32(dev_priv__, reg__) ++ ++ + static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) + { + u32 gt_thread_status_mask; +@@ -38,26 +53,28 @@ static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) + /* w/a for a sporadic read returning 0 by waiting for the GT + * thread to wake up. + */ +- if (wait_for_atomic_us((I915_READ_NOTRACE(GEN6_GT_THREAD_STATUS_REG) & gt_thread_status_mask) == 0, 500)) ++ if (wait_for_atomic_us((__raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG) & gt_thread_status_mask) == 0, 500)) + DRM_ERROR("GT thread status wait timed out\n"); + } + + static void __gen6_gt_force_wake_reset(struct drm_i915_private *dev_priv) + { +- I915_WRITE_NOTRACE(FORCEWAKE, 0); +- POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */ ++ __raw_i915_write32(dev_priv, FORCEWAKE, 0); ++ /* something from same cacheline, but !FORCEWAKE */ ++ __raw_posting_read(dev_priv, ECOBUS); + } + + static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) + { +- if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0, ++ if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1) == 0, + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); + +- I915_WRITE_NOTRACE(FORCEWAKE, 1); +- POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */ ++ __raw_i915_write32(dev_priv, FORCEWAKE, 1); ++ /* something from same cacheline, but !FORCEWAKE */ ++ __raw_posting_read(dev_priv, ECOBUS); + +- if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK) & 1), ++ if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1), + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); + +@@ -67,9 +84,9 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) + + static void __gen6_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv) + { +- I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff)); ++ __raw_i915_write32(dev_priv, FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff)); + /* something from same cacheline, but !FORCEWAKE_MT */ +- POSTING_READ(ECOBUS); ++ __raw_posting_read(dev_priv, ECOBUS); + } + + static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) +@@ -81,15 +98,16 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) + else + forcewake_ack = FORCEWAKE_MT_ACK; + +- if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & FORCEWAKE_KERNEL) == 0, ++ if (wait_for_atomic((__raw_i915_read32(dev_priv, forcewake_ack) & FORCEWAKE_KERNEL) == 0, + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); + +- I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); ++ __raw_i915_write32(dev_priv, FORCEWAKE_MT, ++ _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); + /* something from same cacheline, but !FORCEWAKE_MT */ +- POSTING_READ(ECOBUS); ++ __raw_posting_read(dev_priv, ECOBUS); + +- if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & FORCEWAKE_KERNEL), ++ if (wait_for_atomic((__raw_i915_read32(dev_priv, forcewake_ack) & FORCEWAKE_KERNEL), + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); + +@@ -100,25 +118,27 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) + static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) + { + u32 gtfifodbg; +- gtfifodbg = I915_READ_NOTRACE(GTFIFODBG); ++ ++ gtfifodbg = __raw_i915_read32(dev_priv, GTFIFODBG); + if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK, + "MMIO read or write has been dropped %x\n", gtfifodbg)) +- I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK); ++ __raw_i915_write32(dev_priv, GTFIFODBG, GT_FIFO_CPU_ERROR_MASK); + } + + static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) + { +- I915_WRITE_NOTRACE(FORCEWAKE, 0); ++ __raw_i915_write32(dev_priv, FORCEWAKE, 0); + /* something from same cacheline, but !FORCEWAKE */ +- POSTING_READ(ECOBUS); ++ __raw_posting_read(dev_priv, ECOBUS); + gen6_gt_check_fifodbg(dev_priv); + } + + static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) + { +- I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); ++ __raw_i915_write32(dev_priv, FORCEWAKE_MT, ++ _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); + /* something from same cacheline, but !FORCEWAKE_MT */ +- POSTING_READ(ECOBUS); ++ __raw_posting_read(dev_priv, ECOBUS); + gen6_gt_check_fifodbg(dev_priv); + } + +@@ -128,10 +148,10 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) + + if (dev_priv->uncore.fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) { + int loop = 500; +- u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); ++ u32 fifo = __raw_i915_read32(dev_priv, GT_FIFO_FREE_ENTRIES); + while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) { + udelay(10); +- fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); ++ fifo = __raw_i915_read32(dev_priv, GT_FIFO_FREE_ENTRIES); + } + if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES)) + ++ret; +@@ -144,26 +164,28 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) + + static void vlv_force_wake_reset(struct drm_i915_private *dev_priv) + { +- I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_DISABLE(0xffff)); ++ __raw_i915_write32(dev_priv, FORCEWAKE_VLV, ++ _MASKED_BIT_DISABLE(0xffff)); + /* something from same cacheline, but !FORCEWAKE_VLV */ +- POSTING_READ(FORCEWAKE_ACK_VLV); ++ __raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV); + } + + static void vlv_force_wake_get(struct drm_i915_private *dev_priv) + { +- if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL) == 0, ++ if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL) == 0, + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); + +- I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); +- I915_WRITE_NOTRACE(FORCEWAKE_MEDIA_VLV, ++ __raw_i915_write32(dev_priv, FORCEWAKE_VLV, ++ _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); ++ __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV, + _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); + +- if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL), ++ if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL), + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out waiting for GT to ack forcewake request.\n"); + +- if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_MEDIA_VLV) & ++ if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK_MEDIA_VLV) & + FORCEWAKE_KERNEL), + FORCEWAKE_ACK_TIMEOUT_MS)) + DRM_ERROR("Timed out waiting for media to ack forcewake request.\n"); +@@ -174,8 +196,9 @@ static void vlv_force_wake_get(struct drm_i915_private *dev_priv) + + static void vlv_force_wake_put(struct drm_i915_private *dev_priv) + { +- I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); +- I915_WRITE_NOTRACE(FORCEWAKE_MEDIA_VLV, ++ __raw_i915_write32(dev_priv, FORCEWAKE_VLV, ++ _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); ++ __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV, + _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); + /* The below doubles as a POSTING_READ */ + gen6_gt_check_fifodbg(dev_priv); +@@ -186,7 +209,7 @@ void intel_uncore_early_sanitize(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + + if (HAS_FPGA_DBG_UNCLAIMED(dev)) +- I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); ++ __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); + } + + void intel_uncore_init(struct drm_device *dev) +@@ -213,7 +236,7 @@ void intel_uncore_init(struct drm_device *dev) + */ + mutex_lock(&dev->struct_mutex); + __gen6_gt_force_wake_mt_get(dev_priv); +- ecobus = I915_READ_NOTRACE(ECOBUS); ++ ecobus = __raw_i915_read32(dev_priv, ECOBUS); + __gen6_gt_force_wake_mt_put(dev_priv); + mutex_unlock(&dev->struct_mutex); + +@@ -295,17 +318,17 @@ ilk_dummy_write(struct drm_i915_private *dev_priv) + /* WaIssueDummyWriteToWakeupFromRC6:ilk Issue a dummy write to wake up + * the chip from rc6 before touching it for real. MI_MODE is masked, + * hence harmless to write 0 into. */ +- I915_WRITE_NOTRACE(MI_MODE, 0); ++ __raw_i915_write32(dev_priv, MI_MODE, 0); + } + + static void + hsw_unclaimed_reg_clear(struct drm_i915_private *dev_priv, u32 reg) + { + if (HAS_FPGA_DBG_UNCLAIMED(dev_priv->dev) && +- (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { ++ (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { + DRM_ERROR("Unknown unclaimed register before writing to %x\n", + reg); +- I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); ++ __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); + } + } + +@@ -313,13 +336,13 @@ static void + hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) + { + if (HAS_FPGA_DBG_UNCLAIMED(dev_priv->dev) && +- (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { ++ (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { + DRM_ERROR("Unclaimed write to %x\n", reg); +- I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); ++ __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); + } + } + +-#define __i915_read(x, y) \ ++#define __i915_read(x) \ + u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ + unsigned long irqflags; \ + u##x val = 0; \ +@@ -329,24 +352,24 @@ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ + if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ + if (dev_priv->uncore.forcewake_count == 0) \ + dev_priv->uncore.funcs.force_wake_get(dev_priv); \ +- val = read##y(dev_priv->regs + reg); \ ++ val = __raw_i915_read##x(dev_priv, reg); \ + if (dev_priv->uncore.forcewake_count == 0) \ + dev_priv->uncore.funcs.force_wake_put(dev_priv); \ + } else { \ +- val = read##y(dev_priv->regs + reg); \ ++ val = __raw_i915_read##x(dev_priv, reg); \ + } \ + spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \ + trace_i915_reg_rw(false, reg, val, sizeof(val)); \ + return val; \ + } + +-__i915_read(8, b) +-__i915_read(16, w) +-__i915_read(32, l) +-__i915_read(64, q) ++__i915_read(8) ++__i915_read(16) ++__i915_read(32) ++__i915_read(64) + #undef __i915_read + +-#define __i915_write(x, y) \ ++#define __i915_write(x) \ + void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ + unsigned long irqflags; \ + u32 __fifo_ret = 0; \ +@@ -358,17 +381,17 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ + if (IS_GEN5(dev_priv->dev)) \ + ilk_dummy_write(dev_priv); \ + hsw_unclaimed_reg_clear(dev_priv, reg); \ +- write##y(val, dev_priv->regs + reg); \ ++ __raw_i915_write##x(dev_priv, reg, val); \ + if (unlikely(__fifo_ret)) { \ + gen6_gt_check_fifodbg(dev_priv); \ + } \ + hsw_unclaimed_reg_check(dev_priv, reg); \ + spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \ + } +-__i915_write(8, b) +-__i915_write(16, w) +-__i915_write(32, l) +-__i915_write(64, q) ++__i915_write(8) ++__i915_write(16) ++__i915_write(32) ++__i915_write(64) + #undef __i915_write + + static const struct register_whitelist { +@@ -521,10 +544,10 @@ static int gen6_do_reset(struct drm_device *dev) + * for fifo space for the write or forcewake the chip for + * the read + */ +- I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL); ++ __raw_i915_write32(dev_priv, GEN6_GDRST, GEN6_GRDOM_FULL); + + /* Spin waiting for the device to ack the reset request */ +- ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); ++ ret = wait_for((__raw_i915_read32(dev_priv, GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); + + /* If reset with a user forcewake, try to restore, otherwise turn it off */ + if (dev_priv->uncore.forcewake_count) +@@ -533,7 +556,7 @@ static int gen6_do_reset(struct drm_device *dev) + dev_priv->uncore.funcs.force_wake_put(dev_priv); + + /* Restore fifo count */ +- dev_priv->uncore.fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); ++ dev_priv->uncore.fifo_count = __raw_i915_read32(dev_priv, GT_FIFO_FREE_ENTRIES); + + spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); + return ret; +@@ -555,8 +578,9 @@ void intel_uncore_clear_errors(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + ++ /* XXX needs spinlock around caller's grouping */ + if (HAS_FPGA_DBG_UNCLAIMED(dev)) +- I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); ++ __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); + } + + void intel_uncore_check_errors(struct drm_device *dev) +@@ -564,8 +588,8 @@ void intel_uncore_check_errors(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + + if (HAS_FPGA_DBG_UNCLAIMED(dev) && +- (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { ++ (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { + DRM_ERROR("Unclaimed register before interrupt\n"); +- I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); ++ __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); + } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0527-drm-i915-Use-the-common-register-access-functions-fo.patch b/patches.baytrail/0527-drm-i915-Use-the-common-register-access-functions-fo.patch new file mode 100644 index 000000000000..7a5a64aa2c78 --- /dev/null +++ b/patches.baytrail/0527-drm-i915-Use-the-common-register-access-functions-fo.patch @@ -0,0 +1,114 @@ +From 23cd4eb0e4a3c1048ff92f0bace88a60e12c3459 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Fri, 19 Jul 2013 20:36:54 +0100 +Subject: drm/i915: Use the common register access functions for NOTRACE + variants + +Detangle the confusion that NOTRACE variants of the register read/write +routines were directly using the raw register access. We need for those +routines to reuse the common code for serializing register access and +ensuring the correct register power states. This is only possible now +that the only routines that required raw access use their own API. + +Signed-off-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit dba8e41f2be04de58eadf78f524b3f981bf438c2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 28 ++++++++++++++-------------- + drivers/gpu/drm/i915/intel_uncore.c | 8 ++++---- + 2 files changed, 18 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index ababee4f2f2e..2f8699b03722 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -2135,7 +2135,7 @@ int vlv_gpu_freq(int ddr_freq, int val); + int vlv_freq_opcode(int ddr_freq, int val); + + #define __i915_read(x) \ +- u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg); ++ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg, bool trace); + __i915_read(8) + __i915_read(16) + __i915_read(32) +@@ -2143,28 +2143,28 @@ __i915_read(64) + #undef __i915_read + + #define __i915_write(x) \ +- void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val); ++ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val, bool trace); + __i915_write(8) + __i915_write(16) + __i915_write(32) + __i915_write(64) + #undef __i915_write + +-#define I915_READ8(reg) i915_read8(dev_priv, (reg)) +-#define I915_WRITE8(reg, val) i915_write8(dev_priv, (reg), (val)) ++#define I915_READ8(reg) i915_read8(dev_priv, (reg), true) ++#define I915_WRITE8(reg, val) i915_write8(dev_priv, (reg), (val), true) + +-#define I915_READ16(reg) i915_read16(dev_priv, (reg)) +-#define I915_WRITE16(reg, val) i915_write16(dev_priv, (reg), (val)) +-#define I915_READ16_NOTRACE(reg) readw(dev_priv->regs + (reg)) +-#define I915_WRITE16_NOTRACE(reg, val) writew(val, dev_priv->regs + (reg)) ++#define I915_READ16(reg) i915_read16(dev_priv, (reg), true) ++#define I915_WRITE16(reg, val) i915_write16(dev_priv, (reg), (val), true) ++#define I915_READ16_NOTRACE(reg) i915_read16(dev_priv, (reg), false) ++#define I915_WRITE16_NOTRACE(reg, val) i915_write16(dev_priv, (reg), (val), false) + +-#define I915_READ(reg) i915_read32(dev_priv, (reg)) +-#define I915_WRITE(reg, val) i915_write32(dev_priv, (reg), (val)) +-#define I915_READ_NOTRACE(reg) readl(dev_priv->regs + (reg)) +-#define I915_WRITE_NOTRACE(reg, val) writel(val, dev_priv->regs + (reg)) ++#define I915_READ(reg) i915_read32(dev_priv, (reg), true) ++#define I915_WRITE(reg, val) i915_write32(dev_priv, (reg), (val), true) ++#define I915_READ_NOTRACE(reg) i915_read32(dev_priv, (reg), false) ++#define I915_WRITE_NOTRACE(reg, val) i915_write32(dev_priv, (reg), (val), false) + +-#define I915_WRITE64(reg, val) i915_write64(dev_priv, (reg), (val)) +-#define I915_READ64(reg) i915_read64(dev_priv, (reg)) ++#define I915_WRITE64(reg, val) i915_write64(dev_priv, (reg), (val), true) ++#define I915_READ64(reg) i915_read64(dev_priv, (reg), true) + + #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) + #define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) +diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c +index 228bc7a3f373..2dcf682d8dad 100644 +--- a/drivers/gpu/drm/i915/intel_uncore.c ++++ b/drivers/gpu/drm/i915/intel_uncore.c +@@ -343,7 +343,7 @@ hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) + } + + #define __i915_read(x) \ +-u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ ++u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg, bool trace) { \ + unsigned long irqflags; \ + u##x val = 0; \ + spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); \ +@@ -359,7 +359,7 @@ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ + val = __raw_i915_read##x(dev_priv, reg); \ + } \ + spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \ +- trace_i915_reg_rw(false, reg, val, sizeof(val)); \ ++ if (trace) trace_i915_reg_rw(false, reg, val, sizeof(val)); \ + return val; \ + } + +@@ -370,10 +370,10 @@ __i915_read(64) + #undef __i915_read + + #define __i915_write(x) \ +-void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ ++void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val, bool trace) { \ + unsigned long irqflags; \ + u32 __fifo_ret = 0; \ +- trace_i915_reg_rw(true, reg, val, sizeof(val)); \ ++ if (trace) trace_i915_reg_rw(true, reg, val, sizeof(val)); \ + spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); \ + if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ + __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0528-drm-i915-Squash-gen-lookup-through-multiple-indirect.patch b/patches.baytrail/0528-drm-i915-Squash-gen-lookup-through-multiple-indirect.patch new file mode 100644 index 000000000000..c9207ed17369 --- /dev/null +++ b/patches.baytrail/0528-drm-i915-Squash-gen-lookup-through-multiple-indirect.patch @@ -0,0 +1,44 @@ +From 825b81dd06095d52bf121707f4cb1677ceec0433 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Fri, 19 Jul 2013 20:36:55 +0100 +Subject: drm/i915: Squash gen lookup through multiple indirections inside GT + access + +The INTEL_INFO() macro extracts the dev_private pointer from the device, +so passing in the dev_private->dev is a long winded circumlocution. + +v2: rebase onto uncore + +Signed-off-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit a7f31ee0b00203fcf47fb74a1d61a1c9be8d142e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_uncore.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c +index 2dcf682d8dad..89bb9da377fc 100644 +--- a/drivers/gpu/drm/i915/intel_uncore.c ++++ b/drivers/gpu/drm/i915/intel_uncore.c +@@ -347,7 +347,7 @@ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg, bool trace) { \ + unsigned long irqflags; \ + u##x val = 0; \ + spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); \ +- if (IS_GEN5(dev_priv->dev)) \ ++ if (dev_priv->info->gen == 5) \ + ilk_dummy_write(dev_priv); \ + if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ + if (dev_priv->uncore.forcewake_count == 0) \ +@@ -378,7 +378,7 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val, bool tr + if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ + __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ + } \ +- if (IS_GEN5(dev_priv->dev)) \ ++ if (dev_priv->info->gen == 5) \ + ilk_dummy_write(dev_priv); \ + hsw_unclaimed_reg_clear(dev_priv, reg); \ + __raw_i915_write##x(dev_priv, reg, val); \ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0529-drm-i915-Convert-the-register-access-tracepoint-to-b.patch b/patches.baytrail/0529-drm-i915-Convert-the-register-access-tracepoint-to-b.patch new file mode 100644 index 000000000000..af196ade0d05 --- /dev/null +++ b/patches.baytrail/0529-drm-i915-Convert-the-register-access-tracepoint-to-b.patch @@ -0,0 +1,79 @@ +From e5a42eea249706b6c224da0944bd1877383976ef Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Fri, 19 Jul 2013 20:36:56 +0100 +Subject: drm/i915: Convert the register access tracepoint to be conditional + +The TRACE_EVENT_CONDITION is supposed to generate more efficient code +than if (cond) trace(), which is what we are currently using inside the +register access functions. + +v2: Rebase onto uncore + +Signed-off-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit ed71f1b48e95408d0b3ded014a15fb9d52ac5a86) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 2 +- + drivers/gpu/drm/i915/i915_trace.h | 8 +++++--- + drivers/gpu/drm/i915/intel_uncore.c | 4 ++-- + 3 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 0e904986f3e9..ed72fe08217c 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1004,7 +1004,7 @@ static int gen6_drpc_info(struct seq_file *m) + } + + gt_core_status = readl(dev_priv->regs + GEN6_GT_CORE_STATUS); +- trace_i915_reg_rw(false, GEN6_GT_CORE_STATUS, gt_core_status, 4); ++ trace_i915_reg_rw(false, GEN6_GT_CORE_STATUS, gt_core_status, 4, true); + + rpmodectl1 = I915_READ(GEN6_RP_CONTROL); + rcctl1 = I915_READ(GEN6_RC_CONTROL); +diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h +index 7d283b5fcbf9..2933e2ffeaa4 100644 +--- a/drivers/gpu/drm/i915/i915_trace.h ++++ b/drivers/gpu/drm/i915/i915_trace.h +@@ -406,10 +406,12 @@ TRACE_EVENT(i915_flip_complete, + TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj) + ); + +-TRACE_EVENT(i915_reg_rw, +- TP_PROTO(bool write, u32 reg, u64 val, int len), ++TRACE_EVENT_CONDITION(i915_reg_rw, ++ TP_PROTO(bool write, u32 reg, u64 val, int len, bool trace), + +- TP_ARGS(write, reg, val, len), ++ TP_ARGS(write, reg, val, len, trace), ++ ++ TP_CONDITION(trace), + + TP_STRUCT__entry( + __field(u64, val) +diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c +index 89bb9da377fc..8f5bc869c023 100644 +--- a/drivers/gpu/drm/i915/intel_uncore.c ++++ b/drivers/gpu/drm/i915/intel_uncore.c +@@ -359,7 +359,7 @@ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg, bool trace) { \ + val = __raw_i915_read##x(dev_priv, reg); \ + } \ + spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \ +- if (trace) trace_i915_reg_rw(false, reg, val, sizeof(val)); \ ++ trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \ + return val; \ + } + +@@ -373,7 +373,7 @@ __i915_read(64) + void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val, bool trace) { \ + unsigned long irqflags; \ + u32 __fifo_ret = 0; \ +- if (trace) trace_i915_reg_rw(true, reg, val, sizeof(val)); \ ++ trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \ + spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); \ + if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ + __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0530-drm-i915-fix-the-racy-object-accounting.patch b/patches.baytrail/0530-drm-i915-fix-the-racy-object-accounting.patch new file mode 100644 index 000000000000..54e23e54e6cd --- /dev/null +++ b/patches.baytrail/0530-drm-i915-fix-the-racy-object-accounting.patch @@ -0,0 +1,75 @@ +From 92ea2894437ba14514dfddef4ad27ee506e780a5 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 24 Jul 2013 22:40:23 +0200 +Subject: drm/i915: fix the racy object accounting + +Just use a spinlock to protect them. + +v2: Rebase onto the new object create refcount fix patch. + +v3: Don't kill dev_priv->mm.object_memory as requested by Chris and +hence just use a spinlock instead of atomic_t. + +Cc: Chris Wilson +Reviewed-by: Chris Wilson +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67287 +Signed-off-by: Daniel Vetter +(cherry picked from commit c20e835586c0e4d08f891362b3c829d45ef45f9d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 1 + + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/i915_gem.c | 4 ++++ + 3 files changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index dcc44597ea14..de611f64bb16 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1478,6 +1478,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + spin_lock_init(&dev_priv->gpu_error.lock); + spin_lock_init(&dev_priv->backlight.lock); + spin_lock_init(&dev_priv->uncore.lock); ++ spin_lock_init(&dev_priv->mm.object_stat_lock); + mutex_init(&dev_priv->dpio_lock); + mutex_init(&dev_priv->rps.hw_lock); + mutex_init(&dev_priv->modeset_restore_lock); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 2f8699b03722..f31a1b0adbda 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -935,6 +935,7 @@ struct i915_gem_mm { + struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; + + /* accounting, useful for userland debugging */ ++ spinlock_t object_stat_lock; + size_t object_memory; + u32 object_count; + }; +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 73521ed14eeb..3a5d4baa4c53 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -76,15 +76,19 @@ static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj) + static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, + size_t size) + { ++ spin_lock(&dev_priv->mm.object_stat_lock); + dev_priv->mm.object_count++; + dev_priv->mm.object_memory += size; ++ spin_unlock(&dev_priv->mm.object_stat_lock); + } + + static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv, + size_t size) + { ++ spin_lock(&dev_priv->mm.object_stat_lock); + dev_priv->mm.object_count--; + dev_priv->mm.object_memory -= size; ++ spin_unlock(&dev_priv->mm.object_stat_lock); + } + + static int +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0531-drm-i915-dvo_ch7xxx-fix-vsync-polarity-setting.patch b/patches.baytrail/0531-drm-i915-dvo_ch7xxx-fix-vsync-polarity-setting.patch new file mode 100644 index 000000000000..35cc9bfa42a7 --- /dev/null +++ b/patches.baytrail/0531-drm-i915-dvo_ch7xxx-fix-vsync-polarity-setting.patch @@ -0,0 +1,34 @@ +From 5631557b638676dc7433e55f7bcf64990c104d42 Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Thu, 25 Jul 2013 16:22:31 +0300 +Subject: drm/i915: dvo_ch7xxx: fix vsync polarity setting + +This fixes a typo which set the wrong vsync and possibly also hsync +polarity for any modes with positive vsync polarity. + +Signed-off-by: Imre Deak +Cc: Jesse Barnes +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 3b27af3560f3cfe4e09171024515fa304ebae93b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/dvo_ch7xxx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c +index 757e0fa11043..af42e94f6846 100644 +--- a/drivers/gpu/drm/i915/dvo_ch7xxx.c ++++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c +@@ -307,7 +307,7 @@ static void ch7xxx_mode_set(struct intel_dvo_device *dvo, + idf |= CH7xxx_IDF_HSP; + + if (mode->flags & DRM_MODE_FLAG_PVSYNC) +- idf |= CH7xxx_IDF_HSP; ++ idf |= CH7xxx_IDF_VSP; + + ch7xxx_writeb(dvo, CH7xxx_IDF, idf); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0532-drm-i915-Add-messages-useful-for-HPD-storm-detection.patch b/patches.baytrail/0532-drm-i915-Add-messages-useful-for-HPD-storm-detection.patch new file mode 100644 index 000000000000..34fae282d24c --- /dev/null +++ b/patches.baytrail/0532-drm-i915-Add-messages-useful-for-HPD-storm-detection.patch @@ -0,0 +1,56 @@ +From e8b83ad337464dbd862bbae90e82be22031a1a6f Mon Sep 17 00:00:00 2001 +From: Egbert Eich +Date: Fri, 26 Jul 2013 14:14:24 +0200 +Subject: drm/i915: Add messages useful for HPD storm detection debugging (v2) + +For HPD storm detection we now mask out individual interrupt source +bits. We have already seen a case where HPD interrupt enable bits +were assigned to the wrong pins. To track these conditions more +easily add some debugging messages. + +v2: Spelling fixes as suggested by Jani Nikula + +Signed-off-by: Egbert Eich +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit b8f102e8bf71cacf33326360fdf9dcfd1a63925b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index a588cd5745aa..97f60282d397 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -919,6 +919,10 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, + spin_lock(&dev_priv->irq_lock); + for (i = 1; i < HPD_NUM_PINS; i++) { + ++ WARN(((hpd[i] & hotplug_trigger) && ++ dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED), ++ "Received HPD interrupt although disabled\n"); ++ + if (!(hpd[i] & hotplug_trigger) || + dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) + continue; +@@ -929,6 +933,7 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, + + msecs_to_jiffies(HPD_STORM_DETECT_PERIOD))) { + dev_priv->hpd_stats[i].hpd_last_jiffies = jiffies; + dev_priv->hpd_stats[i].hpd_cnt = 0; ++ DRM_DEBUG_KMS("Received HPD interrupt on PIN %d - cnt: 0\n", i); + } else if (dev_priv->hpd_stats[i].hpd_cnt > HPD_STORM_THRESHOLD) { + dev_priv->hpd_stats[i].hpd_mark = HPD_MARK_DISABLED; + dev_priv->hpd_event_bits &= ~(1 << i); +@@ -936,6 +941,8 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, + storm_detected = true; + } else { + dev_priv->hpd_stats[i].hpd_cnt++; ++ DRM_DEBUG_KMS("Received HPD interrupt on PIN %d - cnt: %d\n", i, ++ dev_priv->hpd_stats[i].hpd_cnt); + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0533-drm-i915-Retry-DP-aux_ch-communications-with-a-diffe.patch b/patches.baytrail/0533-drm-i915-Retry-DP-aux_ch-communications-with-a-diffe.patch new file mode 100644 index 000000000000..32b93a133b1f --- /dev/null +++ b/patches.baytrail/0533-drm-i915-Retry-DP-aux_ch-communications-with-a-diffe.patch @@ -0,0 +1,169 @@ +From 0e455435d45fda47c39a7efcfcb78b6db355c97c Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Sun, 21 Jul 2013 16:00:03 +0100 +Subject: drm/i915: Retry DP aux_ch communications with a different clock after + failure + +The w/a db makes the recommendation to both use a non-default value for +the initial clock and then to retry with an alternative clock for +Haswell with the Lakeport PCH. + +"On LPT:H, use a divider value of 63 decimal (03Fh). If there is a +failure, retry at least three times with 63, then retry at least three +times with 72 decimal (048h)." + +Signed-off-by: Chris Wilson +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit bc86625a4ff7574d4d4dba79723457711eb784e0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 92 +++++++++++++++++++++++------------------ + 1 file changed, 51 insertions(+), 41 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index ccf3b6f0c9a9..8b41cd9d9329 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -276,7 +276,8 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) + return status; + } + +-static uint32_t get_aux_clock_divider(struct intel_dp *intel_dp) ++static uint32_t get_aux_clock_divider(struct intel_dp *intel_dp, ++ int index) + { + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = intel_dig_port->base.base.dev; +@@ -290,22 +291,27 @@ static uint32_t get_aux_clock_divider(struct intel_dp *intel_dp) + * clock divider. + */ + if (IS_VALLEYVIEW(dev)) { +- return 100; ++ return index ? 0 : 100; + } else if (intel_dig_port->port == PORT_A) { ++ if (index) ++ return 0; + if (HAS_DDI(dev)) +- return DIV_ROUND_CLOSEST( +- intel_ddi_get_cdclk_freq(dev_priv), 2000); ++ return DIV_ROUND_CLOSEST(intel_ddi_get_cdclk_freq(dev_priv), 2000); + else if (IS_GEN6(dev) || IS_GEN7(dev)) + return 200; /* SNB & IVB eDP input clock at 400Mhz */ + else + return 225; /* eDP input clock at 450Mhz */ + } else if (dev_priv->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { + /* Workaround for non-ULT HSW */ +- return 74; ++ switch (index) { ++ case 0: return 63; ++ case 1: return 72; ++ default: return 0; ++ } + } else if (HAS_PCH_SPLIT(dev)) { +- return DIV_ROUND_UP(intel_pch_rawclk(dev), 2); ++ return index ? 0 : DIV_ROUND_UP(intel_pch_rawclk(dev), 2); + } else { +- return intel_hrawclk(dev) / 2; ++ return index ? 0 :intel_hrawclk(dev) / 2; + } + } + +@@ -319,10 +325,10 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t ch_ctl = intel_dp->aux_ch_ctl_reg; + uint32_t ch_data = ch_ctl + 4; ++ uint32_t aux_clock_divider; + int i, ret, recv_bytes; + uint32_t status; +- uint32_t aux_clock_divider = get_aux_clock_divider(intel_dp); +- int try, precharge; ++ int try, precharge, clock = 0; + bool has_aux_irq = INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev); + + /* dp aux is extremely sensitive to irq latency, hence request the +@@ -353,37 +359,41 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, + goto out; + } + +- /* Must try at least 3 times according to DP spec */ +- for (try = 0; try < 5; try++) { +- /* Load the send data into the aux channel data registers */ +- for (i = 0; i < send_bytes; i += 4) +- I915_WRITE(ch_data + i, +- pack_aux(send + i, send_bytes - i)); +- +- /* Send the command and wait for it to complete */ +- I915_WRITE(ch_ctl, +- DP_AUX_CH_CTL_SEND_BUSY | +- (has_aux_irq ? DP_AUX_CH_CTL_INTERRUPT : 0) | +- DP_AUX_CH_CTL_TIME_OUT_400us | +- (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | +- (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | +- (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | +- DP_AUX_CH_CTL_DONE | +- DP_AUX_CH_CTL_TIME_OUT_ERROR | +- DP_AUX_CH_CTL_RECEIVE_ERROR); +- +- status = intel_dp_aux_wait_done(intel_dp, has_aux_irq); +- +- /* Clear done status and any errors */ +- I915_WRITE(ch_ctl, +- status | +- DP_AUX_CH_CTL_DONE | +- DP_AUX_CH_CTL_TIME_OUT_ERROR | +- DP_AUX_CH_CTL_RECEIVE_ERROR); +- +- if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR | +- DP_AUX_CH_CTL_RECEIVE_ERROR)) +- continue; ++ while ((aux_clock_divider = get_aux_clock_divider(intel_dp, clock++))) { ++ /* Must try at least 3 times according to DP spec */ ++ for (try = 0; try < 5; try++) { ++ /* Load the send data into the aux channel data registers */ ++ for (i = 0; i < send_bytes; i += 4) ++ I915_WRITE(ch_data + i, ++ pack_aux(send + i, send_bytes - i)); ++ ++ /* Send the command and wait for it to complete */ ++ I915_WRITE(ch_ctl, ++ DP_AUX_CH_CTL_SEND_BUSY | ++ (has_aux_irq ? DP_AUX_CH_CTL_INTERRUPT : 0) | ++ DP_AUX_CH_CTL_TIME_OUT_400us | ++ (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | ++ (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | ++ (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | ++ DP_AUX_CH_CTL_DONE | ++ DP_AUX_CH_CTL_TIME_OUT_ERROR | ++ DP_AUX_CH_CTL_RECEIVE_ERROR); ++ ++ status = intel_dp_aux_wait_done(intel_dp, has_aux_irq); ++ ++ /* Clear done status and any errors */ ++ I915_WRITE(ch_ctl, ++ status | ++ DP_AUX_CH_CTL_DONE | ++ DP_AUX_CH_CTL_TIME_OUT_ERROR | ++ DP_AUX_CH_CTL_RECEIVE_ERROR); ++ ++ if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR | ++ DP_AUX_CH_CTL_RECEIVE_ERROR)) ++ continue; ++ if (status & DP_AUX_CH_CTL_DONE) ++ break; ++ } + if (status & DP_AUX_CH_CTL_DONE) + break; + } +@@ -1464,7 +1474,7 @@ static void intel_edp_psr_enable_sink(struct intel_dp *intel_dp) + { + struct drm_device *dev = intel_dp_to_dev(intel_dp); + struct drm_i915_private *dev_priv = dev->dev_private; +- uint32_t aux_clock_divider = get_aux_clock_divider(intel_dp); ++ uint32_t aux_clock_divider = get_aux_clock_divider(intel_dp, 0); + int precharge = 0x3; + int msg_size = 5; /* Header(4) + Message(1) */ + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0534-drm-i915-Replace-open-coded-offset_in_page.patch b/patches.baytrail/0534-drm-i915-Replace-open-coded-offset_in_page.patch new file mode 100644 index 000000000000..4ede45322957 --- /dev/null +++ b/patches.baytrail/0534-drm-i915-Replace-open-coded-offset_in_page.patch @@ -0,0 +1,38 @@ +From 941f20f10b1b911f61354a3910f183e7799f41bc Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Sun, 21 Jul 2013 17:23:11 +0100 +Subject: drm/i915: Replace open-coded offset_in_page() + +Signed-off-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit de51f04f06d5e4a37f8e5a2b1019eb34140480f0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 1734825bef34..5b6d764e9bb2 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -255,7 +255,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, + + reloc->delta += target_offset; + if (use_cpu_reloc(obj)) { +- uint32_t page_offset = reloc->offset & ~PAGE_MASK; ++ uint32_t page_offset = offset_in_page(reloc->offset); + char *vaddr; + + ret = i915_gem_object_set_to_cpu_domain(obj, 1); +@@ -284,7 +284,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, + reloc_page = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, + reloc->offset & PAGE_MASK); + reloc_entry = (uint32_t __iomem *) +- (reloc_page + (reloc->offset & ~PAGE_MASK)); ++ (reloc_page + offset_in_page(reloc->offset)); + iowrite32(reloc->delta, reloc_entry); + io_mapping_unmap_atomic(reloc_page); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0535-drm-i915-fix-pnv-display-core-clock-readout-out.patch b/patches.baytrail/0535-drm-i915-fix-pnv-display-core-clock-readout-out.patch new file mode 100644 index 000000000000..79c79df6b680 --- /dev/null +++ b/patches.baytrail/0535-drm-i915-fix-pnv-display-core-clock-readout-out.patch @@ -0,0 +1,92 @@ +From d5785745998c402eb10cea7f7bea3862e9ec8162 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Fri, 26 Jul 2013 08:35:42 +0200 +Subject: drm/i915: fix pnv display core clock readout out +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We need the correct clock to accurately assess whether we need to +enable the double wide pipe mode or not. + +Cc: Chris Wilson +Cc: Stéphane Marchesin +Cc: Stuart Abercrombie +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 257a7ffcfaf68718c963db6e9978d1f4f647986b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 6 ++++++ + drivers/gpu/drm/i915/intel_display.c | 29 ++++++++++++++++++++++++++++- + 2 files changed, 34 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index fbe585da44d9..615d66717016 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -61,6 +61,12 @@ + #define GC_LOW_FREQUENCY_ENABLE (1 << 7) + #define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4) + #define GC_DISPLAY_CLOCK_333_MHZ (4 << 4) ++#define GC_DISPLAY_CLOCK_267_MHZ_PNV (0 << 4) ++#define GC_DISPLAY_CLOCK_333_MHZ_PNV (1 << 4) ++#define GC_DISPLAY_CLOCK_444_MHZ_PNV (2 << 4) ++#define GC_DISPLAY_CLOCK_200_MHZ_PNV (5 << 4) ++#define GC_DISPLAY_CLOCK_133_MHZ_PNV (6 << 4) ++#define GC_DISPLAY_CLOCK_167_MHZ_PNV (7 << 4) + #define GC_DISPLAY_CLOCK_MASK (7 << 4) + #define GM45_GC_RENDER_CLOCK_MASK (0xf << 0) + #define GM45_GC_RENDER_CLOCK_266_MHZ (8 << 0) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index afac090a4f3d..cf78f44dc4bf 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4159,6 +4159,30 @@ static int i9xx_misc_get_display_clock_speed(struct drm_device *dev) + return 200000; + } + ++static int pnv_get_display_clock_speed(struct drm_device *dev) ++{ ++ u16 gcfgc = 0; ++ ++ pci_read_config_word(dev->pdev, GCFGC, &gcfgc); ++ ++ switch (gcfgc & GC_DISPLAY_CLOCK_MASK) { ++ case GC_DISPLAY_CLOCK_267_MHZ_PNV: ++ return 267000; ++ case GC_DISPLAY_CLOCK_333_MHZ_PNV: ++ return 333000; ++ case GC_DISPLAY_CLOCK_444_MHZ_PNV: ++ return 444000; ++ case GC_DISPLAY_CLOCK_200_MHZ_PNV: ++ return 200000; ++ default: ++ DRM_ERROR("Unknown pnv display core clock 0x%04x\n", gcfgc); ++ case GC_DISPLAY_CLOCK_133_MHZ_PNV: ++ return 133000; ++ case GC_DISPLAY_CLOCK_167_MHZ_PNV: ++ return 167000; ++ } ++} ++ + static int i915gm_get_display_clock_speed(struct drm_device *dev) + { + u16 gcfgc = 0; +@@ -9611,9 +9635,12 @@ static void intel_init_display(struct drm_device *dev) + else if (IS_I915G(dev)) + dev_priv->display.get_display_clock_speed = + i915_get_display_clock_speed; +- else if (IS_I945GM(dev) || IS_845G(dev) || IS_PINEVIEW_M(dev)) ++ else if (IS_I945GM(dev) || IS_845G(dev)) + dev_priv->display.get_display_clock_speed = + i9xx_misc_get_display_clock_speed; ++ else if (IS_PINEVIEW(dev)) ++ dev_priv->display.get_display_clock_speed = ++ pnv_get_display_clock_speed; + else if (IS_I915GM(dev)) + dev_priv->display.get_display_clock_speed = + i915gm_get_display_clock_speed; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0536-drm-i915-Do-not-dereference-NULL-crtc-or-fb-until-af.patch b/patches.baytrail/0536-drm-i915-Do-not-dereference-NULL-crtc-or-fb-until-af.patch new file mode 100644 index 000000000000..bf40bb64a4f8 --- /dev/null +++ b/patches.baytrail/0536-drm-i915-Do-not-dereference-NULL-crtc-or-fb-until-af.patch @@ -0,0 +1,53 @@ +From ca58dc081fef5c5ad2f0e8c1be00ed80cbf190c0 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Fri, 2 Aug 2013 20:39:49 +0100 +Subject: drm/i915: Do not dereference NULL crtc or fb until after checking + +Fixes regression from +commit 4906557eb37b7fef84fad4304acef6dedf919880 +Author: Rodrigo Vivi +Date: Thu Jul 11 18:45:05 2013 -0300 + + drm/i915: Hook PSR functionality + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67526 +Signed-off-by: Chris Wilson +Cc: Rodrigo Vivi +Cc: Daniel Vetter +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit cd234b0bfd5ab012e42274b24aae420fa1823d58) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 8b41cd9d9329..42ddfd457ca6 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1556,12 +1556,21 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp) + return false; + } + ++ crtc = dig_port->base.base.crtc; ++ if (crtc == NULL) { ++ DRM_DEBUG_KMS("crtc not active for PSR\n"); ++ dev_priv->no_psr_reason = PSR_CRTC_NOT_ACTIVE; ++ return false; ++ } ++ ++ intel_crtc = to_intel_crtc(crtc); + if (!intel_crtc->active || !crtc->fb || !crtc->mode.clock) { + DRM_DEBUG_KMS("crtc not active for PSR\n"); + dev_priv->no_psr_reason = PSR_CRTC_NOT_ACTIVE; + return false; + } + ++ obj = to_intel_framebuffer(crtc->fb)->obj; + if (obj->tiling_mode != I915_TILING_X || + obj->fence_reg == I915_FENCE_REG_NONE) { + DRM_DEBUG_KMS("PSR condition failed: fb not tiled or fenced\n"); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0537-drm-i915-dvo-use-intel_encoder-to-the-upcast-macro.patch b/patches.baytrail/0537-drm-i915-dvo-use-intel_encoder-to-the-upcast-macro.patch new file mode 100644 index 000000000000..6e26ef7948e8 --- /dev/null +++ b/patches.baytrail/0537-drm-i915-dvo-use-intel_encoder-to-the-upcast-macro.patch @@ -0,0 +1,97 @@ +From d75e863623bb3ae1846e87fd8d4c4a639fecc3ee Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 21:36:57 +0200 +Subject: drm/i915/dvo: use intel_encoder to the upcast macro + +More natural and will soon be even better! + +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 69438e64afc7343e641afa57f6e73618e46d8984) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dvo.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c +index 8b4ad27791f3..39cf596cc42c 100644 +--- a/drivers/gpu/drm/i915/intel_dvo.c ++++ b/drivers/gpu/drm/i915/intel_dvo.c +@@ -100,9 +100,9 @@ struct intel_dvo { + bool panel_wants_dither; + }; + +-static struct intel_dvo *enc_to_intel_dvo(struct drm_encoder *encoder) ++static struct intel_dvo *enc_to_dvo(struct intel_encoder *encoder) + { +- return container_of(encoder, struct intel_dvo, base.base); ++ return container_of(encoder, struct intel_dvo, base); + } + + static struct intel_dvo *intel_attached_dvo(struct drm_connector *connector) +@@ -123,7 +123,7 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder, + { + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); ++ struct intel_dvo *intel_dvo = enc_to_dvo(encoder); + u32 tmp; + + tmp = I915_READ(intel_dvo->dev.dvo_reg); +@@ -140,7 +140,7 @@ static void intel_dvo_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) + { + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; +- struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); ++ struct intel_dvo *intel_dvo = enc_to_dvo(encoder); + u32 tmp, flags = 0; + + tmp = I915_READ(intel_dvo->dev.dvo_reg); +@@ -159,7 +159,7 @@ static void intel_dvo_get_config(struct intel_encoder *encoder, + static void intel_disable_dvo(struct intel_encoder *encoder) + { + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; +- struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); ++ struct intel_dvo *intel_dvo = enc_to_dvo(encoder); + u32 dvo_reg = intel_dvo->dev.dvo_reg; + u32 temp = I915_READ(dvo_reg); + +@@ -171,7 +171,7 @@ static void intel_disable_dvo(struct intel_encoder *encoder) + static void intel_enable_dvo(struct intel_encoder *encoder) + { + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; +- struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); ++ struct intel_dvo *intel_dvo = enc_to_dvo(encoder); + u32 dvo_reg = intel_dvo->dev.dvo_reg; + u32 temp = I915_READ(dvo_reg); + +@@ -245,7 +245,7 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) + { +- struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); ++ struct intel_dvo *intel_dvo = enc_to_dvo(to_intel_encoder(encoder)); + + /* If we have timings from the BIOS for the panel, put them in + * to the adjusted mode. The CRTC will be set up for this mode, +@@ -279,7 +279,7 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); +- struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); ++ struct intel_dvo *intel_dvo = enc_to_dvo(to_intel_encoder(encoder)); + int pipe = intel_crtc->pipe; + u32 dvo_val; + u32 dvo_reg = intel_dvo->dev.dvo_reg, dvo_srcdim_reg; +@@ -391,7 +391,7 @@ static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs + + static void intel_dvo_enc_destroy(struct drm_encoder *encoder) + { +- struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); ++ struct intel_dvo *intel_dvo = enc_to_dvo(to_intel_encoder(encoder)); + + if (intel_dvo->dev.dev_ops->destroy) + intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0538-drm-i915-dvo-switch-mode_fixup-to-compute_config.patch b/patches.baytrail/0538-drm-i915-dvo-switch-mode_fixup-to-compute_config.patch new file mode 100644 index 000000000000..e1b755e27676 --- /dev/null +++ b/patches.baytrail/0538-drm-i915-dvo-switch-mode_fixup-to-compute_config.patch @@ -0,0 +1,76 @@ +From 303c303e7dd6b08ad8f5e4d02db287bf157e8d15 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 21:36:58 +0200 +Subject: drm/i915/dvo: switch ->mode_fixup to ->compute_config + +This is the last encoder ->mode_fixup callback we have left, so +convert it. + +Note that we want to only rip out the encoder->mode_fixup callback. +But we still have the dvo_slave->mode_fixup callback. dvo is gen2 +only, so we won't ever touch this again. Hence why I didn't go through +all 6-7 dvo slave drivers and give them the same treatment. I'll add a +note to the commit message about this when merging, presuming there's +nothing else in the patch that needs to be fixed up. + +Reviewed-by: Rodrigo Vivi +[danvet: Add note about why we keep the dvo->mode_fixup callback to +answer a question from Rodrigo's review.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit a34703752e0b682ab4e6fccf1ce675176cf1dad2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dvo.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c +index 39cf596cc42c..51eadc944d9a 100644 +--- a/drivers/gpu/drm/i915/intel_dvo.c ++++ b/drivers/gpu/drm/i915/intel_dvo.c +@@ -241,11 +241,11 @@ static int intel_dvo_mode_valid(struct drm_connector *connector, + return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode); + } + +-static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, +- const struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) ++static bool intel_dvo_compute_config(struct intel_encoder *encoder, ++ struct intel_crtc_config *pipe_config) + { +- struct intel_dvo *intel_dvo = enc_to_dvo(to_intel_encoder(encoder)); ++ struct intel_dvo *intel_dvo = enc_to_dvo(encoder); ++ struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; + + /* If we have timings from the BIOS for the panel, put them in + * to the adjusted mode. The CRTC will be set up for this mode, +@@ -267,7 +267,9 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, + } + + if (intel_dvo->dev.dev_ops->mode_fixup) +- return intel_dvo->dev.dev_ops->mode_fixup(&intel_dvo->dev, mode, adjusted_mode); ++ return intel_dvo->dev.dev_ops->mode_fixup(&intel_dvo->dev, ++ &pipe_config->requested_mode, ++ adjusted_mode); + + return true; + } +@@ -372,7 +374,6 @@ static void intel_dvo_destroy(struct drm_connector *connector) + } + + static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { +- .mode_fixup = intel_dvo_mode_fixup, + .mode_set = intel_dvo_mode_set, + }; + +@@ -470,6 +471,7 @@ void intel_dvo_init(struct drm_device *dev) + intel_encoder->enable = intel_enable_dvo; + intel_encoder->get_hw_state = intel_dvo_get_hw_state; + intel_encoder->get_config = intel_dvo_get_config; ++ intel_encoder->compute_config = intel_dvo_compute_config; + intel_connector->get_hw_state = intel_dvo_connector_get_hw_state; + + /* Now, try to find a controller */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0539-drm-i915-rip-out-legacy-encoder-mode_fixup-logic.patch b/patches.baytrail/0539-drm-i915-rip-out-legacy-encoder-mode_fixup-logic.patch new file mode 100644 index 000000000000..148235824514 --- /dev/null +++ b/patches.baytrail/0539-drm-i915-rip-out-legacy-encoder-mode_fixup-logic.patch @@ -0,0 +1,63 @@ +From b09cffb594e2f62dc0d97a5f9435281869f75600 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 21:36:59 +0200 +Subject: drm/i915: rip out legacy encoder->mode_fixup logic + +Everyone is now using our own ->compute_config callback, which means +we can now also make that callback mandatory. + +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit efea6e8e49388478be405b3ae62644ef06dca9a1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 19 +++---------------- + 1 file changed, 3 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index cf78f44dc4bf..4a3b386bc642 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4105,7 +4105,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, + } + + /* All interlaced capable intel hw wants timings in frames. Note though +- * that intel_lvds_mode_fixup does some funny tricks with the crtc ++ * that intel_lvds_compute_config does some funny tricks with the crtc + * timings, so we need to be careful not to clobber these.*/ + if (!pipe_config->timings_set) + drm_mode_set_crtcinfo(adjusted_mode, 0); +@@ -8065,7 +8065,6 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, + struct drm_display_mode *mode) + { + struct drm_device *dev = crtc->dev; +- struct drm_encoder_helper_funcs *encoder_funcs; + struct intel_encoder *encoder; + struct intel_crtc_config *pipe_config; + int plane_bpp, ret = -EINVAL; +@@ -8110,20 +8109,8 @@ encoder_retry: + if (&encoder->new_crtc->base != crtc) + continue; + +- if (encoder->compute_config) { +- if (!(encoder->compute_config(encoder, pipe_config))) { +- DRM_DEBUG_KMS("Encoder config failure\n"); +- goto fail; +- } +- +- continue; +- } +- +- encoder_funcs = encoder->base.helper_private; +- if (!(encoder_funcs->mode_fixup(&encoder->base, +- &pipe_config->requested_mode, +- &pipe_config->adjusted_mode))) { +- DRM_DEBUG_KMS("Encoder fixup failed\n"); ++ if (!(encoder->compute_config(encoder, pipe_config))) { ++ DRM_DEBUG_KMS("Encoder config failure\n"); + goto fail; + } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0540-drm-i915-dvo-use-native-encoder-mode_set-callback.patch b/patches.baytrail/0540-drm-i915-dvo-use-native-encoder-mode_set-callback.patch new file mode 100644 index 000000000000..5c6b91f05363 --- /dev/null +++ b/patches.baytrail/0540-drm-i915-dvo-use-native-encoder-mode_set-callback.patch @@ -0,0 +1,92 @@ +From 4d3d1edf776cc509e3f4b434768645edba82930e Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 21:37:00 +0200 +Subject: drm/i915/dvo: use native encoder ->mode_set callback + +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 79fde3011fe03f4cef31e55eff607180e1c7c5fd) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dvo.c | 28 +++++++++++----------------- + 1 file changed, 11 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c +index 51eadc944d9a..406303b509c1 100644 +--- a/drivers/gpu/drm/i915/intel_dvo.c ++++ b/drivers/gpu/drm/i915/intel_dvo.c +@@ -107,8 +107,7 @@ static struct intel_dvo *enc_to_dvo(struct intel_encoder *encoder) + + static struct intel_dvo *intel_attached_dvo(struct drm_connector *connector) + { +- return container_of(intel_attached_encoder(connector), +- struct intel_dvo, base); ++ return enc_to_dvo(intel_attached_encoder(connector)); + } + + static bool intel_dvo_connector_get_hw_state(struct intel_connector *connector) +@@ -274,15 +273,14 @@ static bool intel_dvo_compute_config(struct intel_encoder *encoder, + return true; + } + +-static void intel_dvo_mode_set(struct drm_encoder *encoder, +- struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) ++static void intel_dvo_mode_set(struct intel_encoder *encoder) + { +- struct drm_device *dev = encoder->dev; ++ struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); +- struct intel_dvo *intel_dvo = enc_to_dvo(to_intel_encoder(encoder)); +- int pipe = intel_crtc->pipe; ++ struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); ++ struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode; ++ struct intel_dvo *intel_dvo = enc_to_dvo(encoder); ++ int pipe = crtc->pipe; + u32 dvo_val; + u32 dvo_reg = intel_dvo->dev.dvo_reg, dvo_srcdim_reg; + +@@ -299,7 +297,9 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, + break; + } + +- intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, mode, adjusted_mode); ++ intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, ++ &crtc->config.requested_mode, ++ adjusted_mode); + + /* Save the data order, since I don't know what it should be set to. */ + dvo_val = I915_READ(dvo_reg) & +@@ -373,10 +373,6 @@ static void intel_dvo_destroy(struct drm_connector *connector) + kfree(connector); + } + +-static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { +- .mode_set = intel_dvo_mode_set, +-}; +- + static const struct drm_connector_funcs intel_dvo_connector_funcs = { + .dpms = intel_dvo_dpms, + .detect = intel_dvo_detect, +@@ -472,6 +468,7 @@ void intel_dvo_init(struct drm_device *dev) + intel_encoder->get_hw_state = intel_dvo_get_hw_state; + intel_encoder->get_config = intel_dvo_get_config; + intel_encoder->compute_config = intel_dvo_compute_config; ++ intel_encoder->mode_set = intel_dvo_mode_set; + intel_connector->get_hw_state = intel_dvo_connector_get_hw_state; + + /* Now, try to find a controller */ +@@ -538,9 +535,6 @@ void intel_dvo_init(struct drm_device *dev) + connector->interlace_allowed = false; + connector->doublescan_allowed = false; + +- drm_encoder_helper_add(&intel_encoder->base, +- &intel_dvo_helper_funcs); +- + intel_connector_attach_encoder(intel_connector, intel_encoder); + if (dvo->type == INTEL_DVO_CHIP_LVDS) { + /* For our LVDS chipsets, we should hopefully be able +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0541-drm-i915-sdvo-use-intel_encoder-for-upcast-helper.patch b/patches.baytrail/0541-drm-i915-sdvo-use-intel_encoder-for-upcast-helper.patch new file mode 100644 index 000000000000..7f69d5889f5f --- /dev/null +++ b/patches.baytrail/0541-drm-i915-sdvo-use-intel_encoder-for-upcast-helper.patch @@ -0,0 +1,114 @@ +From e97b6edc877481a13874661526a726ac43870d3c Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 21:37:01 +0200 +Subject: drm/i915/sdvo: use intel_encoder for upcast helper + +It's what all callers (except for the destroy callback which is called +from drm core) actually want. + +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 8aca63aae07681a0c9a2a0ebcca82ca5f7f6aa08) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sdvo.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index c3b59b8593b9..47423f31f82b 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -202,15 +202,14 @@ struct intel_sdvo_connector { + u32 cur_dot_crawl, max_dot_crawl; + }; + +-static struct intel_sdvo *to_intel_sdvo(struct drm_encoder *encoder) ++static struct intel_sdvo *to_sdvo(struct intel_encoder *encoder) + { +- return container_of(encoder, struct intel_sdvo, base.base); ++ return container_of(encoder, struct intel_sdvo, base); + } + + static struct intel_sdvo *intel_attached_sdvo(struct drm_connector *connector) + { +- return container_of(intel_attached_encoder(connector), +- struct intel_sdvo, base); ++ return to_sdvo(intel_attached_encoder(connector)); + } + + static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) +@@ -1084,7 +1083,7 @@ static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_config *pipe_config) + static bool intel_sdvo_compute_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) + { +- struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); ++ struct intel_sdvo *intel_sdvo = to_sdvo(encoder); + struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; + struct drm_display_mode *mode = &pipe_config->requested_mode; + +@@ -1154,7 +1153,7 @@ static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder) + struct drm_display_mode *adjusted_mode = + &intel_crtc->config.adjusted_mode; + struct drm_display_mode *mode = &intel_crtc->config.requested_mode; +- struct intel_sdvo *intel_sdvo = to_intel_sdvo(&intel_encoder->base); ++ struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder); + u32 sdvox; + struct intel_sdvo_in_out_map in_out; + struct intel_sdvo_dtd input_dtd, output_dtd; +@@ -1292,7 +1291,7 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, + { + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); ++ struct intel_sdvo *intel_sdvo = to_sdvo(encoder); + u16 active_outputs = 0; + u32 tmp; + +@@ -1315,7 +1314,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, + { + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); ++ struct intel_sdvo *intel_sdvo = to_sdvo(encoder); + struct intel_sdvo_dtd dtd; + int encoder_pixel_multiplier = 0; + u32 flags = 0, sdvox; +@@ -1380,7 +1379,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, + static void intel_disable_sdvo(struct intel_encoder *encoder) + { + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; +- struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); ++ struct intel_sdvo *intel_sdvo = to_sdvo(encoder); + u32 temp; + + intel_sdvo_set_active_outputs(intel_sdvo, 0); +@@ -1422,7 +1421,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder) + { + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); ++ struct intel_sdvo *intel_sdvo = to_sdvo(encoder); + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + u32 temp; + bool input1, input2; +@@ -1583,7 +1582,7 @@ static uint16_t intel_sdvo_get_hotplug_support(struct intel_sdvo *intel_sdvo) + + static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder) + { +- struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); ++ struct intel_sdvo *intel_sdvo = to_sdvo(encoder); + + intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, + &intel_sdvo->hotplug_active, 2); +@@ -2190,7 +2189,7 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs + + static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) + { +- struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); ++ struct intel_sdvo *intel_sdvo = to_sdvo(to_intel_encoder(encoder)); + + if (intel_sdvo->sdvo_lvds_fixed_mode != NULL) + drm_mode_destroy(encoder->dev, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0542-drm-i915-tv-Use-native-encoder-mode_set-callback.patch b/patches.baytrail/0542-drm-i915-tv-Use-native-encoder-mode_set-callback.patch new file mode 100644 index 000000000000..41de720ede83 --- /dev/null +++ b/patches.baytrail/0542-drm-i915-tv-Use-native-encoder-mode_set-callback.patch @@ -0,0 +1,98 @@ +From 7fe9cc566bde9f8e4c8f34a1c25382f2f53c34cc Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 21:37:02 +0200 +Subject: drm/i915/tv: Use native encoder->mode_set callback + +Also switch to intel_encoder for the upcast helper while at it. + +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit cd91ef23c426fe5aeee6ca8090551547b3a8795e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_tv.c | 27 +++++++++------------------ + 1 file changed, 9 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c +index 685017000087..dd6f84bf6c22 100644 +--- a/drivers/gpu/drm/i915/intel_tv.c ++++ b/drivers/gpu/drm/i915/intel_tv.c +@@ -823,16 +823,14 @@ static const struct tv_mode tv_modes[] = { + }, + }; + +-static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) ++static struct intel_tv *enc_to_tv(struct intel_encoder *encoder) + { +- return container_of(encoder, struct intel_tv, base.base); ++ return container_of(encoder, struct intel_tv, base); + } + + static struct intel_tv *intel_attached_tv(struct drm_connector *connector) + { +- return container_of(intel_attached_encoder(connector), +- struct intel_tv, +- base); ++ return enc_to_tv(intel_attached_encoder(connector)); + } + + static bool +@@ -908,7 +906,7 @@ static bool + intel_tv_compute_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) + { +- struct intel_tv *intel_tv = enc_to_intel_tv(&encoder->base); ++ struct intel_tv *intel_tv = enc_to_tv(encoder); + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); + + if (!tv_mode) +@@ -929,15 +927,12 @@ intel_tv_compute_config(struct intel_encoder *encoder, + return true; + } + +-static void +-intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) ++static void intel_tv_mode_set(struct intel_encoder *encoder) + { +- struct drm_device *dev = encoder->dev; ++ struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct drm_crtc *crtc = encoder->crtc; +- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- struct intel_tv *intel_tv = enc_to_intel_tv(encoder); ++ struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); ++ struct intel_tv *intel_tv = enc_to_tv(encoder); + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); + u32 tv_ctl; + u32 hctl1, hctl2, hctl3; +@@ -1495,10 +1490,6 @@ out: + return ret; + } + +-static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = { +- .mode_set = intel_tv_mode_set, +-}; +- + static const struct drm_connector_funcs intel_tv_connector_funcs = { + .dpms = intel_connector_dpms, + .detect = intel_tv_detect, +@@ -1631,6 +1622,7 @@ intel_tv_init(struct drm_device *dev) + DRM_MODE_ENCODER_TVDAC); + + intel_encoder->compute_config = intel_tv_compute_config; ++ intel_encoder->mode_set = intel_tv_mode_set; + intel_encoder->enable = intel_enable_tv; + intel_encoder->disable = intel_disable_tv; + intel_encoder->get_hw_state = intel_tv_get_hw_state; +@@ -1652,7 +1644,6 @@ intel_tv_init(struct drm_device *dev) + + intel_tv->tv_format = tv_modes[initial_mode].name; + +- drm_encoder_helper_add(&intel_encoder->base, &intel_tv_helper_funcs); + drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); + connector->interlace_allowed = false; + connector->doublescan_allowed = false; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0543-drm-i915-crt-use-native-encoder-mode_set-callback.patch b/patches.baytrail/0543-drm-i915-crt-use-native-encoder-mode_set-callback.patch new file mode 100644 index 000000000000..958568ec5882 --- /dev/null +++ b/patches.baytrail/0543-drm-i915-crt-use-native-encoder-mode_set-callback.patch @@ -0,0 +1,111 @@ +From c074cd0d33191d5d1ce6962f661d83f9124dc9e9 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 21:37:03 +0200 +Subject: drm/i915/crt: use native encoder->mode_set callback + +Also drop the intel_ prefix from the local intel_crtc variable and +reorder the upcast macros a bit for more reuse. + +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit eebe6f0b3d4207a05000921a5e60b4161f89ca35) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_crt.c | 34 +++++++++++++--------------------- + 1 file changed, 13 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c +index 0c0d4e8d768e..b5a3875f22c7 100644 +--- a/drivers/gpu/drm/i915/intel_crt.c ++++ b/drivers/gpu/drm/i915/intel_crt.c +@@ -52,15 +52,14 @@ struct intel_crt { + u32 adpa_reg; + }; + +-static struct intel_crt *intel_attached_crt(struct drm_connector *connector) ++static struct intel_crt *intel_encoder_to_crt(struct intel_encoder *encoder) + { +- return container_of(intel_attached_encoder(connector), +- struct intel_crt, base); ++ return container_of(encoder, struct intel_crt, base); + } + +-static struct intel_crt *intel_encoder_to_crt(struct intel_encoder *encoder) ++static struct intel_crt *intel_attached_crt(struct drm_connector *connector) + { +- return container_of(encoder, struct intel_crt, base); ++ return intel_encoder_to_crt(intel_attached_encoder(connector)); + } + + static bool intel_crt_get_hw_state(struct intel_encoder *encoder, +@@ -238,17 +237,14 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder, + return true; + } + +-static void intel_crt_mode_set(struct drm_encoder *encoder, +- struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) ++static void intel_crt_mode_set(struct intel_encoder *encoder) + { + +- struct drm_device *dev = encoder->dev; +- struct drm_crtc *crtc = encoder->crtc; +- struct intel_crt *crt = +- intel_encoder_to_crt(to_intel_encoder(encoder)); +- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ struct drm_device *dev = encoder->base.dev; ++ struct intel_crt *crt = intel_encoder_to_crt(encoder); ++ struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); + struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode; + u32 adpa; + + if (HAS_PCH_SPLIT(dev)) +@@ -265,14 +261,14 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, + if (HAS_PCH_LPT(dev)) + ; /* Those bits don't exist here */ + else if (HAS_PCH_CPT(dev)) +- adpa |= PORT_TRANS_SEL_CPT(intel_crtc->pipe); +- else if (intel_crtc->pipe == 0) ++ adpa |= PORT_TRANS_SEL_CPT(crtc->pipe); ++ else if (crtc->pipe == 0) + adpa |= ADPA_PIPE_A_SELECT; + else + adpa |= ADPA_PIPE_B_SELECT; + + if (!HAS_PCH_SPLIT(dev)) +- I915_WRITE(BCLRPAT(intel_crtc->pipe), 0); ++ I915_WRITE(BCLRPAT(crtc->pipe), 0); + + I915_WRITE(crt->adpa_reg, adpa); + } +@@ -711,10 +707,6 @@ static void intel_crt_reset(struct drm_connector *connector) + * Routines for controlling stuff on the analog port + */ + +-static const struct drm_encoder_helper_funcs crt_encoder_funcs = { +- .mode_set = intel_crt_mode_set, +-}; +- + static const struct drm_connector_funcs intel_crt_connector_funcs = { + .reset = intel_crt_reset, + .dpms = intel_crt_dpms, +@@ -804,6 +796,7 @@ void intel_crt_init(struct drm_device *dev) + crt->adpa_reg = ADPA; + + crt->base.compute_config = intel_crt_compute_config; ++ crt->base.mode_set = intel_crt_mode_set; + crt->base.disable = intel_disable_crt; + crt->base.enable = intel_enable_crt; + crt->base.get_config = intel_crt_get_config; +@@ -815,7 +808,6 @@ void intel_crt_init(struct drm_device *dev) + crt->base.get_hw_state = intel_crt_get_hw_state; + intel_connector->get_hw_state = intel_connector_get_hw_state; + +- drm_encoder_helper_add(&crt->base.base, &crt_encoder_funcs); + drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); + + drm_sysfs_connector_add(connector); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0544-drm-i915-hdmi-use-native-encoder-mode_set-callback.patch b/patches.baytrail/0544-drm-i915-hdmi-use-native-encoder-mode_set-callback.patch new file mode 100644 index 000000000000..89de529a20fe --- /dev/null +++ b/patches.baytrail/0544-drm-i915-hdmi-use-native-encoder-mode_set-callback.patch @@ -0,0 +1,103 @@ +From 754df95a7c0312c9f1c5011aa51cb691ee741aef Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 21:37:04 +0200 +Subject: drm/i915/hdmi: use native encoder mode_set callback + +Again drop the intel_ prefix from the intel_crtc local variable to +save a bit of space. But here I didn't switch the upcast macros to +intel_encoder since all our infoframe interfaces still use +drm_encoder. That needs to be changed first. + +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit c59423a3dd4186ed4c352537c2b572a9bb950fe9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_hdmi.c | 29 ++++++++++++----------------- + 1 file changed, 12 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 044d11d05944..e82cd816bde9 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -591,14 +591,13 @@ static void hsw_set_infoframes(struct drm_encoder *encoder, + intel_hdmi_set_spd_infoframe(encoder); + } + +-static void intel_hdmi_mode_set(struct drm_encoder *encoder, +- struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) ++static void intel_hdmi_mode_set(struct intel_encoder *encoder) + { +- struct drm_device *dev = encoder->dev; ++ struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); +- struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); ++ struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); ++ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); ++ struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode; + u32 hdmi_val; + + hdmi_val = SDVO_ENCODING_HDMI; +@@ -609,7 +608,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, + if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) + hdmi_val |= SDVO_HSYNC_ACTIVE_HIGH; + +- if (intel_crtc->config.pipe_bpp > 24) ++ if (crtc->config.pipe_bpp > 24) + hdmi_val |= HDMI_COLOR_FORMAT_12bpc; + else + hdmi_val |= SDVO_COLOR_FORMAT_8bpc; +@@ -620,21 +619,21 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, + + if (intel_hdmi->has_audio) { + DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n", +- pipe_name(intel_crtc->pipe)); ++ pipe_name(crtc->pipe)); + hdmi_val |= SDVO_AUDIO_ENABLE; + hdmi_val |= HDMI_MODE_SELECT_HDMI; +- intel_write_eld(encoder, adjusted_mode); ++ intel_write_eld(&encoder->base, adjusted_mode); + } + + if (HAS_PCH_CPT(dev)) +- hdmi_val |= SDVO_PIPE_SEL_CPT(intel_crtc->pipe); ++ hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe); + else +- hdmi_val |= SDVO_PIPE_SEL(intel_crtc->pipe); ++ hdmi_val |= SDVO_PIPE_SEL(crtc->pipe); + + I915_WRITE(intel_hdmi->hdmi_reg, hdmi_val); + POSTING_READ(intel_hdmi->hdmi_reg); + +- intel_hdmi->set_infoframes(encoder, adjusted_mode); ++ intel_hdmi->set_infoframes(&encoder->base, adjusted_mode); + } + + static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, +@@ -1116,10 +1115,6 @@ static void intel_hdmi_destroy(struct drm_connector *connector) + kfree(connector); + } + +-static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { +- .mode_set = intel_hdmi_mode_set, +-}; +- + static const struct drm_connector_funcs intel_hdmi_connector_funcs = { + .dpms = intel_connector_dpms, + .detect = intel_hdmi_detect, +@@ -1242,9 +1237,9 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) + + drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs, + DRM_MODE_ENCODER_TMDS); +- drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs); + + intel_encoder->compute_config = intel_hdmi_compute_config; ++ intel_encoder->mode_set = intel_hdmi_mode_set; + intel_encoder->enable = intel_enable_hdmi; + intel_encoder->disable = intel_disable_hdmi; + intel_encoder->get_hw_state = intel_hdmi_get_hw_state; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0545-drm-i915-dp-use-native-encoder-mode_set-callback.patch b/patches.baytrail/0545-drm-i915-dp-use-native-encoder-mode_set-callback.patch new file mode 100644 index 000000000000..cea739c564a9 --- /dev/null +++ b/patches.baytrail/0545-drm-i915-dp-use-native-encoder-mode_set-callback.patch @@ -0,0 +1,76 @@ +From 4f337b2af7ab8d4fb9761d5424be9ba6645d7b39 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 21:37:05 +0200 +Subject: drm/i915/dp: use native encoder ->mode_set callback + +Usual drill applies. Again I've not switched the upcast helpers to use +intel_encoder instead of drm_encoder since that's much more invasive +and will change also the hdmi and ddi encoders. + +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit b934223d7abae2f52d22b4734a02b9a0867eafe3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 19 +++++++------------ + 1 file changed, 7 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 42ddfd457ca6..44972a679517 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -844,15 +844,14 @@ static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp) + udelay(500); + } + +-static void +-intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) ++static void intel_dp_mode_set(struct intel_encoder *encoder) + { +- struct drm_device *dev = encoder->dev; ++ struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct intel_dp *intel_dp = enc_to_intel_dp(encoder); ++ struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + enum port port = dp_to_dig_port(intel_dp)->port; +- struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); ++ struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); ++ struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode; + + /* + * There are four kinds of DP registers: +@@ -884,7 +883,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, + DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n", + pipe_name(crtc->pipe)); + intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; +- intel_write_eld(encoder, adjusted_mode); ++ intel_write_eld(&encoder->base, adjusted_mode); + } + + intel_dp_init_link_config(intel_dp); +@@ -3046,10 +3045,6 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) + kfree(intel_dig_port); + } + +-static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { +- .mode_set = intel_dp_mode_set, +-}; +- + static const struct drm_connector_funcs intel_dp_connector_funcs = { + .dpms = intel_connector_dpms, + .detect = intel_dp_detect, +@@ -3529,9 +3524,9 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) + + drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs, + DRM_MODE_ENCODER_TMDS); +- drm_encoder_helper_add(&intel_encoder->base, &intel_dp_helper_funcs); + + intel_encoder->compute_config = intel_dp_compute_config; ++ intel_encoder->mode_set = intel_dp_mode_set; + intel_encoder->enable = intel_enable_dp; + intel_encoder->pre_enable = intel_pre_enable_dp; + intel_encoder->disable = intel_disable_dp; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0546-drm-i915-lvds-use-the-native-encoder-mode_set-callba.patch b/patches.baytrail/0546-drm-i915-lvds-use-the-native-encoder-mode_set-callba.patch new file mode 100644 index 000000000000..55f8ab2aabd2 --- /dev/null +++ b/patches.baytrail/0546-drm-i915-lvds-use-the-native-encoder-mode_set-callba.patch @@ -0,0 +1,69 @@ +From 11d6d834ae9e3521231d520b8dde663b8cc39646 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 21:37:06 +0200 +Subject: drm/i915/lvds: use the native encoder ->mode_set callback + +Does nothing, so trivial conversion. But update the outdated comment +while at it. + +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 66df24d926fe0686034bb8d47a0f586310602178) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_lvds.c | 16 +++++----------- + 1 file changed, 5 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 176891679ae9..acaaafc75502 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -319,14 +319,12 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, + return true; + } + +-static void intel_lvds_mode_set(struct drm_encoder *encoder, +- struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) ++static void intel_lvds_mode_set(struct intel_encoder *encoder) + { + /* +- * The LVDS pin pair will already have been turned on in the +- * intel_crtc_mode_set since it has a large impact on the DPLL +- * settings. ++ * We don't do anything here, the LVDS port is fully set up in the pre ++ * enable hook - the ordering constraints for enabling the lvds port vs. ++ * enabling the display pll are too strict. + */ + } + +@@ -507,10 +505,6 @@ static int intel_lvds_set_property(struct drm_connector *connector, + return 0; + } + +-static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { +- .mode_set = intel_lvds_mode_set, +-}; +- + static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { + .get_modes = intel_lvds_get_modes, + .mode_valid = intel_lvds_mode_valid, +@@ -987,6 +981,7 @@ void intel_lvds_init(struct drm_device *dev) + intel_encoder->enable = intel_enable_lvds; + intel_encoder->pre_enable = intel_pre_enable_lvds; + intel_encoder->compute_config = intel_lvds_compute_config; ++ intel_encoder->mode_set = intel_lvds_mode_set; + intel_encoder->disable = intel_disable_lvds; + intel_encoder->get_hw_state = intel_lvds_get_hw_state; + intel_encoder->get_config = intel_lvds_get_config; +@@ -1003,7 +998,6 @@ void intel_lvds_init(struct drm_device *dev) + else + intel_encoder->crtc_mask = (1 << 1); + +- drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); + drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); + connector->display_info.subpixel_order = SubPixelHorizontalRGB; + connector->interlace_allowed = false; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0547-drm-i915-ddi-use-the-native-encoder-mode_set-callbac.patch b/patches.baytrail/0547-drm-i915-ddi-use-the-native-encoder-mode_set-callbac.patch new file mode 100644 index 000000000000..f715554aff9a --- /dev/null +++ b/patches.baytrail/0547-drm-i915-ddi-use-the-native-encoder-mode_set-callbac.patch @@ -0,0 +1,118 @@ +From 69bf13ad09f5cd1485f069e44538ecf48b074fb3 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 21:37:07 +0200 +Subject: drm/i915/ddi: use the native encoder ->mode_set callback + +Same conversion as for hdmi/dp. + +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit c7d8be305aa28dd809dedd401adcd4da8e4f9144) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 39 ++++++++++++++++----------------------- + 1 file changed, 16 insertions(+), 23 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index 931b4bb1f9dc..b361c0862373 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -281,25 +281,22 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) + DRM_ERROR("FDI link training failed!\n"); + } + +-static void intel_ddi_mode_set(struct drm_encoder *encoder, +- struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) ++static void intel_ddi_mode_set(struct intel_encoder *encoder) + { +- struct drm_crtc *crtc = encoder->crtc; +- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- struct intel_encoder *intel_encoder = to_intel_encoder(encoder); +- int port = intel_ddi_get_encoder_port(intel_encoder); +- int pipe = intel_crtc->pipe; +- int type = intel_encoder->type; ++ struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); ++ int port = intel_ddi_get_encoder_port(encoder); ++ int pipe = crtc->pipe; ++ int type = encoder->type; ++ struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode; + + DRM_DEBUG_KMS("Preparing DDI mode on port %c, pipe %c\n", + port_name(port), pipe_name(pipe)); + +- intel_crtc->eld_vld = false; ++ crtc->eld_vld = false; + if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { +- struct intel_dp *intel_dp = enc_to_intel_dp(encoder); ++ struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + struct intel_digital_port *intel_dig_port = +- enc_to_dig_port(encoder); ++ enc_to_dig_port(&encoder->base); + + intel_dp->DP = intel_dig_port->saved_port_bits | + DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; +@@ -307,17 +304,17 @@ static void intel_ddi_mode_set(struct drm_encoder *encoder, + + if (intel_dp->has_audio) { + DRM_DEBUG_DRIVER("DP audio on pipe %c on DDI\n", +- pipe_name(intel_crtc->pipe)); ++ pipe_name(crtc->pipe)); + + /* write eld */ + DRM_DEBUG_DRIVER("DP audio: write eld information\n"); +- intel_write_eld(encoder, adjusted_mode); ++ intel_write_eld(&encoder->base, adjusted_mode); + } + + intel_dp_init_link_config(intel_dp); + + } else if (type == INTEL_OUTPUT_HDMI) { +- struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); ++ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); + + if (intel_hdmi->has_audio) { + /* Proper support for digital audio needs a new logic +@@ -325,14 +322,14 @@ static void intel_ddi_mode_set(struct drm_encoder *encoder, + * patch bombing. + */ + DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n", +- pipe_name(intel_crtc->pipe)); ++ pipe_name(crtc->pipe)); + + /* write eld */ + DRM_DEBUG_DRIVER("HDMI audio: write eld information\n"); +- intel_write_eld(encoder, adjusted_mode); ++ intel_write_eld(&encoder->base, adjusted_mode); + } + +- intel_hdmi->set_infoframes(encoder, adjusted_mode); ++ intel_hdmi->set_infoframes(&encoder->base, adjusted_mode); + } + } + +@@ -1311,10 +1308,6 @@ static const struct drm_encoder_funcs intel_ddi_funcs = { + .destroy = intel_ddi_destroy, + }; + +-static const struct drm_encoder_helper_funcs intel_ddi_helper_funcs = { +- .mode_set = intel_ddi_mode_set, +-}; +- + void intel_ddi_init(struct drm_device *dev, enum port port) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -1339,9 +1332,9 @@ void intel_ddi_init(struct drm_device *dev, enum port port) + + drm_encoder_init(dev, encoder, &intel_ddi_funcs, + DRM_MODE_ENCODER_TMDS); +- drm_encoder_helper_add(encoder, &intel_ddi_helper_funcs); + + intel_encoder->compute_config = intel_ddi_compute_config; ++ intel_encoder->mode_set = intel_ddi_mode_set; + intel_encoder->enable = intel_enable_ddi; + intel_encoder->pre_enable = intel_ddi_pre_enable; + intel_encoder->disable = intel_disable_ddi; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0548-drm-i915-rip-out-legacy-encoder-mode_set-callback.patch b/patches.baytrail/0548-drm-i915-rip-out-legacy-encoder-mode_set-callback.patch new file mode 100644 index 000000000000..6bc891f4febf --- /dev/null +++ b/patches.baytrail/0548-drm-i915-rip-out-legacy-encoder-mode_set-callback.patch @@ -0,0 +1,49 @@ +From 5ee1b46ef995844b1390ac095ef5accd6ef820ac Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 21:37:08 +0200 +Subject: drm/i915: rip out legacy encoder->mode_set callback + +The encoder->mode_set callback from the crtc helpers is now completely +unused in our driver. Good riddance! + +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 36f2d1f151215c48d902947d64b86dc5ab277e19) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 4a3b386bc642..d67285745d6e 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -6220,11 +6220,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + { + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct drm_encoder_helper_funcs *encoder_funcs; + struct intel_encoder *encoder; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- struct drm_display_mode *adjusted_mode = +- &intel_crtc->config.adjusted_mode; + struct drm_display_mode *mode = &intel_crtc->config.requested_mode; + int pipe = intel_crtc->pipe; + int ret; +@@ -6243,12 +6240,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + encoder->base.base.id, + drm_get_encoder_name(&encoder->base), + mode->base.id, mode->name); +- if (encoder->mode_set) { +- encoder->mode_set(encoder); +- } else { +- encoder_funcs = encoder->base.helper_private; +- encoder_funcs->mode_set(&encoder->base, mode, adjusted_mode); +- } ++ encoder->mode_set(encoder); + } + + return 0; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0549-drm-i915-clean-up-crtc-timings-computation.patch b/patches.baytrail/0549-drm-i915-clean-up-crtc-timings-computation.patch new file mode 100644 index 000000000000..321bf54efbab --- /dev/null +++ b/patches.baytrail/0549-drm-i915-clean-up-crtc-timings-computation.patch @@ -0,0 +1,110 @@ +From fde9d0f5e2f884b674711fce03cbee00bbad8681 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 21 Jul 2013 21:37:09 +0200 +Subject: drm/i915: clean up crtc timings computation + +In the old days of the crtc helpers we've only had the encoder and +crtc ->mode_fixup callbacks. So when the lvds connector wanted to +adjust the crtc timings it had to set a driver-private mode flag to +tell the crtc mode fixup code to not overwrite them with the generic +ones. + +When converting things to the new infrastructure I've kept the entire +logic and only moved the flag to pipe_config->timings_set. But this +logic is pretty tricky and already caused regressions: + +commit 21d8a4756af5fdf4a42e79a77cf3b6f52678d443 +Author: Daniel Vetter +Date: Fri Jul 12 08:07:30 2013 +0200 + + drm/i915: fix pfit regression for non-autoscaled resolutions + +So take advantage of the flexibility our own modeset infrastructure +affords us and prefill default crtc timings. This allows us to rip out +->timings_set. Note that we overwrite things again when retrying the +pipe config computation due to bandwidth constraints to avoid bogus +crtc timings if the encoder only does relative adjustments (which is +how the pfit code works). Only a theoretical concern though since +platforms where we retry (pch-split platforms) do not need +adjustements (since only the old gmch pfit needs that). But let's +better be safe than sorry. + +Since we now initialize the crtc timings before calling the +encoder->compute_config functions the crtc initialization in the gmch +pfit code is now redudant and so can be removed. + +Cc: Jesse Barnes +Cc: Mika Kuoppala +Reviewed-by: Rodrigo Vivi +[danvet: Add a paragraph to the commit message to explain why we can +ditch the crtc timings initialization call from the gmch pfit code, to +answer a question from Rodrigo's review.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 135c81b8c3c9a70d7b55758c9c2a247a4abb7b64) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 9 +++------ + drivers/gpu/drm/i915/intel_drv.h | 4 ---- + drivers/gpu/drm/i915/intel_panel.c | 3 --- + 3 files changed, 3 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index d67285745d6e..722c99e16dc4 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4104,12 +4104,6 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, + return -EINVAL; + } + +- /* All interlaced capable intel hw wants timings in frames. Note though +- * that intel_lvds_compute_config does some funny tricks with the crtc +- * timings, so we need to be careful not to clobber these.*/ +- if (!pipe_config->timings_set) +- drm_mode_set_crtcinfo(adjusted_mode, 0); +- + /* Cantiga+ cannot handle modes with a hsync front porch of 0. + * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw. + */ +@@ -8091,6 +8085,9 @@ encoder_retry: + pipe_config->port_clock = 0; + pipe_config->pixel_multiplier = 1; + ++ /* Fill in default crtc timings, allow encoders to overwrite them. */ ++ drm_mode_set_crtcinfo(&pipe_config->adjusted_mode, 0); ++ + /* Pass our mode to the connectors and the CRTC to give them a chance to + * adjust it according to limitations or connector properties, and also + * a chance to reject the mode entirely. +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index d9f50e368fe9..474797be1fc2 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -208,10 +208,6 @@ struct intel_crtc_config { + + struct drm_display_mode requested_mode; + struct drm_display_mode adjusted_mode; +- /* This flag must be set by the encoder's compute_config callback if it +- * changes the crtc timings in the mode to prevent the crtc fixup from +- * overwriting them. Currently only lvds needs that. */ +- bool timings_set; + /* Whether to set up the PCH/FDI. Note that we never allow sharing + * between pch encoders and cpu encoders. */ + bool has_pch_encoder; +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index 5950888ae1d0..a43c33bc4a35 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -194,9 +194,6 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, + adjusted_mode->vdisplay == mode->vdisplay) + goto out; + +- drm_mode_set_crtcinfo(adjusted_mode, 0); +- pipe_config->timings_set = true; +- + switch (fitting_mode) { + case DRM_MODE_SCALE_CENTER: + /* +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0550-drm-i915-Squelch-repeated-reasoning-for-why-FBC-cann.patch b/patches.baytrail/0550-drm-i915-Squelch-repeated-reasoning-for-why-FBC-cann.patch new file mode 100644 index 000000000000..301b9711423a --- /dev/null +++ b/patches.baytrail/0550-drm-i915-Squelch-repeated-reasoning-for-why-FBC-cann.patch @@ -0,0 +1,196 @@ +From 6cb2ab7901882146e6d41a4d4e29a96584c4946a Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Sat, 27 Jul 2013 17:23:55 +0100 +Subject: drm/i915: Squelch repeated reasoning for why FBC cannot be activated + +Almost invariably the reason why FBC cannot be turned on is the same +every time (disabled via parameter, too many pipes, pipe too large etc) +as modesetting and framebuffer configuration changes less frequently +than trying to enable FBC. + +Signed-off-by: Chris Wilson +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 29ebf90f8157f9d01dda2b1555b4a08e9e542b21) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 6 ++++ + drivers/gpu/drm/i915/i915_drv.h | 4 ++- + drivers/gpu/drm/i915/intel_pm.c | 59 +++++++++++++++++++++++-------------- + 3 files changed, 46 insertions(+), 23 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index ed72fe08217c..eed2f4ca9a76 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1099,6 +1099,12 @@ static int i915_fbc_status(struct seq_file *m, void *unused) + } else { + seq_puts(m, "FBC disabled: "); + switch (dev_priv->fbc.no_fbc_reason) { ++ case FBC_OK: ++ seq_puts(m, "FBC actived, but currently disabled in hardware"); ++ break; ++ case FBC_UNSUPPORTED: ++ seq_puts(m, "unsupported by this chipset"); ++ break; + case FBC_NO_OUTPUT: + seq_puts(m, "no outputs"); + break; +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index f31a1b0adbda..f8ea9179728a 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -589,7 +589,9 @@ struct i915_fbc { + int interval; + } *fbc_work; + +- enum { ++ enum no_fbc_reason { ++ FBC_OK, /* FBC is enabled */ ++ FBC_UNSUPPORTED, /* FBC is not supported by this chipset */ + FBC_NO_OUTPUT, /* no outputs enabled to compress */ + FBC_STOLEN_TOO_SMALL, /* not enough space for buffers */ + FBC_UNSUPPORTED_MODE, /* interlace or doublescanned mode */ +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 5d7d0e76da7f..c11aae3ae18d 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -421,6 +421,16 @@ void intel_disable_fbc(struct drm_device *dev) + dev_priv->fbc.plane = -1; + } + ++static bool set_no_fbc_reason(struct drm_i915_private *dev_priv, ++ enum no_fbc_reason reason) ++{ ++ if (dev_priv->fbc.no_fbc_reason == reason) ++ return false; ++ ++ dev_priv->fbc.no_fbc_reason = reason; ++ return true; ++} ++ + /** + * intel_update_fbc - enable/disable FBC as needed + * @dev: the drm_device +@@ -450,11 +460,16 @@ void intel_update_fbc(struct drm_device *dev) + struct drm_i915_gem_object *obj; + unsigned int max_hdisplay, max_vdisplay; + +- if (!i915_powersave) ++ if (!I915_HAS_FBC(dev)) { ++ set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED); + return; ++ } + +- if (!I915_HAS_FBC(dev)) ++ if (!i915_powersave) { ++ if (set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM)) ++ DRM_DEBUG_KMS("fbc disabled per module param\n"); + return; ++ } + + /* + * If FBC is already on, we just have to verify that we can +@@ -469,9 +484,8 @@ void intel_update_fbc(struct drm_device *dev) + if (intel_crtc_active(tmp_crtc) && + !to_intel_crtc(tmp_crtc)->primary_disabled) { + if (crtc) { +- DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); +- dev_priv->fbc.no_fbc_reason = +- FBC_MULTIPLE_PIPES; ++ if (set_no_fbc_reason(dev_priv, FBC_MULTIPLE_PIPES)) ++ DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); + goto out_disable; + } + crtc = tmp_crtc; +@@ -479,8 +493,8 @@ void intel_update_fbc(struct drm_device *dev) + } + + if (!crtc || crtc->fb == NULL) { +- DRM_DEBUG_KMS("no output, disabling\n"); +- dev_priv->fbc.no_fbc_reason = FBC_NO_OUTPUT; ++ if (set_no_fbc_reason(dev_priv, FBC_NO_OUTPUT)) ++ DRM_DEBUG_KMS("no output, disabling\n"); + goto out_disable; + } + +@@ -491,20 +505,20 @@ void intel_update_fbc(struct drm_device *dev) + + if (i915_enable_fbc < 0 && + INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) { +- DRM_DEBUG_KMS("disabled per chip default\n"); +- dev_priv->fbc.no_fbc_reason = FBC_CHIP_DEFAULT; ++ if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT)) ++ DRM_DEBUG_KMS("disabled per chip default\n"); + goto out_disable; + } + if (!i915_enable_fbc) { +- DRM_DEBUG_KMS("fbc disabled per module param\n"); +- dev_priv->fbc.no_fbc_reason = FBC_MODULE_PARAM; ++ if (set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM)) ++ DRM_DEBUG_KMS("fbc disabled per module param\n"); + goto out_disable; + } + if ((crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) || + (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)) { +- DRM_DEBUG_KMS("mode incompatible with compression, " +- "disabling\n"); +- dev_priv->fbc.no_fbc_reason = FBC_UNSUPPORTED_MODE; ++ if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE)) ++ DRM_DEBUG_KMS("mode incompatible with compression, " ++ "disabling\n"); + goto out_disable; + } + +@@ -517,14 +531,14 @@ void intel_update_fbc(struct drm_device *dev) + } + if ((crtc->mode.hdisplay > max_hdisplay) || + (crtc->mode.vdisplay > max_vdisplay)) { +- DRM_DEBUG_KMS("mode too large for compression, disabling\n"); +- dev_priv->fbc.no_fbc_reason = FBC_MODE_TOO_LARGE; ++ if (set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE)) ++ DRM_DEBUG_KMS("mode too large for compression, disabling\n"); + goto out_disable; + } + if ((IS_I915GM(dev) || IS_I945GM(dev) || IS_HASWELL(dev)) && + intel_crtc->plane != 0) { +- DRM_DEBUG_KMS("plane not 0, disabling compression\n"); +- dev_priv->fbc.no_fbc_reason = FBC_BAD_PLANE; ++ if (set_no_fbc_reason(dev_priv, FBC_BAD_PLANE)) ++ DRM_DEBUG_KMS("plane not 0, disabling compression\n"); + goto out_disable; + } + +@@ -533,8 +547,8 @@ void intel_update_fbc(struct drm_device *dev) + */ + if (obj->tiling_mode != I915_TILING_X || + obj->fence_reg == I915_FENCE_REG_NONE) { +- DRM_DEBUG_KMS("framebuffer not tiled or fenced, disabling compression\n"); +- dev_priv->fbc.no_fbc_reason = FBC_NOT_TILED; ++ if (set_no_fbc_reason(dev_priv, FBC_NOT_TILED)) ++ DRM_DEBUG_KMS("framebuffer not tiled or fenced, disabling compression\n"); + goto out_disable; + } + +@@ -543,8 +557,8 @@ void intel_update_fbc(struct drm_device *dev) + goto out_disable; + + if (i915_gem_stolen_setup_compression(dev, intel_fb->obj->base.size)) { +- DRM_DEBUG_KMS("framebuffer too large, disabling compression\n"); +- dev_priv->fbc.no_fbc_reason = FBC_STOLEN_TOO_SMALL; ++ if (set_no_fbc_reason(dev_priv, FBC_STOLEN_TOO_SMALL)) ++ DRM_DEBUG_KMS("framebuffer too large, disabling compression\n"); + goto out_disable; + } + +@@ -587,6 +601,7 @@ void intel_update_fbc(struct drm_device *dev) + } + + intel_enable_fbc(crtc, 500); ++ dev_priv->fbc.no_fbc_reason = FBC_OK; + return; + + out_disable: +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0551-drm-i915-Use-the-same-pte_encoding-for-ppgtt-as-for-.patch b/patches.baytrail/0551-drm-i915-Use-the-same-pte_encoding-for-ppgtt-as-for-.patch new file mode 100644 index 000000000000..a0007f81a684 --- /dev/null +++ b/patches.baytrail/0551-drm-i915-Use-the-same-pte_encoding-for-ppgtt-as-for-.patch @@ -0,0 +1,55 @@ +From 75a13a01efd883ebb54e127d5710c10066827c96 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Tue, 30 Jul 2013 19:04:37 +0100 +Subject: drm/i915: Use the same pte_encoding for ppgtt as for gtt + +The PTE layouts are the same for both ppgtt and gtt, so we can simplify +the setup for ppgtt by copying the encoding function pointer from gtt. +This prevents bugs where we update one function pointer, but forget the +other. + +For instance, + +commit 4d15c145a6234d999c0452eec0d275c1fbf0688c +Author: Ben Widawsky +Date: Thu Jul 4 11:02:06 2013 -0700 + + drm/i915: Use eLLC/LLC by default when available + +only extends the gtt to use eLLC/LLC cacheing and forgets to also update +the ppgtt function pointer. + +v2: Actually mention the bug being fixed (Kenneth) + +Signed-off-by: Chris Wilson +Reviewed-by: Kenneth Graunke +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 08c45263a62af33348e674765710cb49dd3959e0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_gtt.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 3b639a94dddf..e7b420495516 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -298,13 +298,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) + * now. */ + first_pd_entry_in_global_pt = gtt_total_entries(dev_priv->gtt); + +- if (IS_HASWELL(dev)) { +- ppgtt->base.pte_encode = hsw_pte_encode; +- } else if (IS_VALLEYVIEW(dev)) { +- ppgtt->base.pte_encode = byt_pte_encode; +- } else { +- ppgtt->base.pte_encode = gen6_pte_encode; +- } ++ ppgtt->base.pte_encode = dev_priv->gtt.base.pte_encode; + ppgtt->num_pd_entries = GEN6_PPGTT_PD_ENTRIES; + ppgtt->enable = gen6_ppgtt_enable; + ppgtt->base.clear_range = gen6_ppgtt_clear_range; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0552-drm-i915-Remove-useless-define.patch b/patches.baytrail/0552-drm-i915-Remove-useless-define.patch new file mode 100644 index 000000000000..fd262bf1c6c8 --- /dev/null +++ b/patches.baytrail/0552-drm-i915-Remove-useless-define.patch @@ -0,0 +1,32 @@ +From 8c17a0e220ac83d1d5e63914d961ca9ebc6d7221 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?St=C3=A9phane=20Marchesin?= +Date: Wed, 31 Jul 2013 00:11:07 -0700 +Subject: drm/i915: Remove useless define +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Stéphane Marchesin +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit b3ae96a8ea1cbd0970459b6efd7ea7550fe033c6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 722c99e16dc4..3fd109df65a6 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -59,7 +59,6 @@ typedef struct { + int p2_slow, p2_fast; + } intel_p2_t; + +-#define INTEL_P2_NUM 2 + typedef struct intel_limit intel_limit_t; + struct intel_limit { + intel_range_t dot, vco, n, m, m1, m2, p, p1; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0553-drm-i915-Tidy-the-macro-casting-by-using-an-inline-f.patch b/patches.baytrail/0553-drm-i915-Tidy-the-macro-casting-by-using-an-inline-f.patch new file mode 100644 index 000000000000..46e5e59d8d72 --- /dev/null +++ b/patches.baytrail/0553-drm-i915-Tidy-the-macro-casting-by-using-an-inline-f.patch @@ -0,0 +1,69 @@ +From eb844c2530cd98fb2b6fc979aeae2e3aaefe5704 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Thu, 1 Aug 2013 18:39:55 +0100 +Subject: drm/i915: Tidy the macro casting by using an inline function + +Some of our macros we trying to convert from an drm_device to a +drm_i915_private and then use the pointer inline. This is not only +cumbersome but prone to error. Replacing it with a typesafe function +should help catch those errors in future. + +Signed-off-by: Chris Wilson +Reviewed-by: Paulo Zanoni +Signed-off-by: Ben Widawsky +[danvet: Squash in fixup to correctly order static vs. inline +qualifiers, static comes first. Also fix up another offender.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 2c1792a10b10e41dcf34c97304fb8f75e52e7112) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index f8ea9179728a..fbd2522462bb 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1223,6 +1223,11 @@ typedef struct drm_i915_private { + struct i915_ums_state ums; + } drm_i915_private_t; + ++static inline struct drm_i915_private *to_i915(const struct drm_device *dev) ++{ ++ return dev->dev_private; ++} ++ + /* Iterate over initialised rings */ + #define for_each_ring(ring__, dev_priv__, i__) \ + for ((i__) = 0; (i__) < I915_NUM_RINGS; (i__)++) \ +@@ -1484,7 +1489,7 @@ struct drm_i915_file_private { + struct i915_ctx_hang_stats hang_stats; + }; + +-#define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) ++#define INTEL_INFO(dev) (to_i915(dev)->info) + + #define IS_I830(dev) ((dev)->pci_device == 0x3577) + #define IS_845G(dev) ((dev)->pci_device == 0x2562) +@@ -1578,7 +1583,7 @@ struct drm_i915_file_private { + #define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00 + #define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00 + +-#define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) ++#define INTEL_PCH_TYPE(dev) (to_i915(dev)->pch_type) + #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT) + #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) + #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) +@@ -1976,7 +1981,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + void i915_gem_object_release_stolen(struct drm_i915_gem_object *obj); + + /* i915_gem_tiling.c */ +-inline static bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) ++static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) + { + drm_i915_private_t *dev_priv = obj->base.dev->dev_private; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0554-drm-i915-Add-scaled-paramater-to-update_sprite_water.patch b/patches.baytrail/0554-drm-i915-Add-scaled-paramater-to-update_sprite_water.patch new file mode 100644 index 000000000000..d11876d7be7d --- /dev/null +++ b/patches.baytrail/0554-drm-i915-Add-scaled-paramater-to-update_sprite_water.patch @@ -0,0 +1,165 @@ +From b8abaed21da362bc49f643220dbb61c6e7a03599 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 5 Jul 2013 11:57:13 +0300 +Subject: drm/i915: Add scaled paramater to update_sprite_watermarks() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For calculating watermarks we want to know whether sprites are +scaled. Pass that information to update_sprite_watermarks() so that +eventually we may do some watermark pre-computing. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit bdd57d0386d892e5c470a3d615c3034389700964) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 +- + drivers/gpu/drm/i915/intel_drv.h | 7 ++++--- + drivers/gpu/drm/i915/intel_pm.c | 13 +++++++------ + drivers/gpu/drm/i915/intel_sprite.c | 11 +++++++---- + 4 files changed, 19 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index fbd2522462bb..bb7d0ba5589b 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -361,7 +361,7 @@ struct drm_i915_display_funcs { + void (*update_wm)(struct drm_device *dev); + void (*update_sprite_wm)(struct drm_device *dev, int pipe, + uint32_t sprite_width, int pixel_size, +- bool enable); ++ bool enable, bool scaled); + void (*modeset_global_resources)(struct drm_device *dev); + /* Returns the active state of the crtc, and if the crtc is active, + * fills out the pipe-config with the hw state. */ +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 474797be1fc2..ed33976c194b 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -349,7 +349,8 @@ struct intel_plane { + * for the watermark calculations. Currently only Haswell uses this. + */ + struct { +- bool enable; ++ bool enabled; ++ bool scaled; + uint8_t bytes_per_pixel; + uint32_t horiz_pixels; + } wm; +@@ -770,8 +771,8 @@ extern void intel_ddi_init(struct drm_device *dev, enum port port); + /* For use by IVB LP watermark workaround in intel_sprite.c */ + extern void intel_update_watermarks(struct drm_device *dev); + extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, +- uint32_t sprite_width, +- int pixel_size, bool enable); ++ uint32_t sprite_width, int pixel_size, ++ bool enabled, bool scaled); + + extern unsigned long intel_gen4_compute_page_offset(int *x, int *y, + unsigned int tiling_mode, +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index c11aae3ae18d..5799324a8c4d 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2403,7 +2403,7 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, + pipe = intel_plane->pipe; + p = ¶ms[pipe]; + +- p->sprite_enabled = intel_plane->wm.enable; ++ p->sprite_enabled = intel_plane->wm.enabled; + p->spr_bytes_per_pixel = intel_plane->wm.bytes_per_pixel; + p->spr_horiz_pixels = intel_plane->wm.horiz_pixels; + +@@ -2631,7 +2631,7 @@ static void haswell_update_wm(struct drm_device *dev) + + static void haswell_update_sprite_wm(struct drm_device *dev, int pipe, + uint32_t sprite_width, int pixel_size, +- bool enable) ++ bool enabled, bool scaled) + { + struct drm_plane *plane; + +@@ -2639,7 +2639,8 @@ static void haswell_update_sprite_wm(struct drm_device *dev, int pipe, + struct intel_plane *intel_plane = to_intel_plane(plane); + + if (intel_plane->pipe == pipe) { +- intel_plane->wm.enable = enable; ++ intel_plane->wm.enabled = enabled; ++ intel_plane->wm.scaled = scaled; + intel_plane->wm.horiz_pixels = sprite_width + 1; + intel_plane->wm.bytes_per_pixel = pixel_size; + break; +@@ -2727,7 +2728,7 @@ sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane, + + static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, + uint32_t sprite_width, int pixel_size, +- bool enable) ++ bool enable, bool scaled) + { + struct drm_i915_private *dev_priv = dev->dev_private; + int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ +@@ -2850,13 +2851,13 @@ void intel_update_watermarks(struct drm_device *dev) + + void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, + uint32_t sprite_width, int pixel_size, +- bool enable) ++ bool enable, bool scaled) + { + struct drm_i915_private *dev_priv = dev->dev_private; + + if (dev_priv->display.update_sprite_wm) + dev_priv->display.update_sprite_wm(dev, pipe, sprite_width, +- pixel_size, enable); ++ pixel_size, enable, scaled); + } + + static struct drm_i915_gem_object * +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index 55bdf70b548b..069155f17edb 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -114,7 +114,8 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb, + crtc_w--; + crtc_h--; + +- intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true); ++ intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true, ++ src_w != crtc_w || src_h != crtc_h); + + I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); + I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); +@@ -268,7 +269,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, + crtc_w--; + crtc_h--; + +- intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true); ++ intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true, ++ src_w != crtc_w || src_h != crtc_h); + + /* + * IVB workaround: must disable low power watermarks for at least +@@ -336,7 +338,7 @@ ivb_disable_plane(struct drm_plane *plane) + + dev_priv->sprite_scaling_enabled &= ~(1 << pipe); + +- intel_update_sprite_watermarks(dev, pipe, 0, 0, false); ++ intel_update_sprite_watermarks(dev, pipe, 0, 0, false, false); + + /* potentially re-enable LP watermarks */ + if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) +@@ -456,7 +458,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, + crtc_w--; + crtc_h--; + +- intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true); ++ intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true, ++ src_w != crtc_w || src_h != crtc_h); + + dvsscale = 0; + if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0555-drm-i915-Pass-the-actual-sprite-width-to-watermarks-.patch b/patches.baytrail/0555-drm-i915-Pass-the-actual-sprite-width-to-watermarks-.patch new file mode 100644 index 000000000000..4da05d63f020 --- /dev/null +++ b/patches.baytrail/0555-drm-i915-Pass-the-actual-sprite-width-to-watermarks-.patch @@ -0,0 +1,97 @@ +From 498124bceb005d793a9c672a46994393e6a8f340 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 5 Jul 2013 11:57:14 +0300 +Subject: drm/i915: Pass the actual sprite width to watermarks functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Don't subtract one from the sprite width before watermark calculations. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 67ca28f30af8e7555f40b916c28148b432168eec) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 2 +- + drivers/gpu/drm/i915/intel_sprite.c | 18 +++++++++--------- + 2 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 5799324a8c4d..901479fb2695 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2641,7 +2641,7 @@ static void haswell_update_sprite_wm(struct drm_device *dev, int pipe, + if (intel_plane->pipe == pipe) { + intel_plane->wm.enabled = enabled; + intel_plane->wm.scaled = scaled; +- intel_plane->wm.horiz_pixels = sprite_width + 1; ++ intel_plane->wm.horiz_pixels = sprite_width; + intel_plane->wm.bytes_per_pixel = pixel_size; + break; + } +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index 069155f17edb..3e3a6d01cff6 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -108,15 +108,15 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb, + + sprctl |= SP_ENABLE; + ++ intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true, ++ src_w != crtc_w || src_h != crtc_h); ++ + /* Sizes are 0 based */ + src_w--; + src_h--; + crtc_w--; + crtc_h--; + +- intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true, +- src_w != crtc_w || src_h != crtc_h); +- + I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); + I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); + +@@ -263,15 +263,15 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, + if (IS_HASWELL(dev)) + sprctl |= SPRITE_PIPE_CSC_ENABLE; + ++ intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true, ++ src_w != crtc_w || src_h != crtc_h); ++ + /* Sizes are 0 based */ + src_w--; + src_h--; + crtc_w--; + crtc_h--; + +- intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true, +- src_w != crtc_w || src_h != crtc_h); +- + /* + * IVB workaround: must disable low power watermarks for at least + * one frame before enabling scaling. LP watermarks can be re-enabled +@@ -452,15 +452,15 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, + dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ + dvscntr |= DVS_ENABLE; + ++ intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true, ++ src_w != crtc_w || src_h != crtc_h); ++ + /* Sizes are 0 based */ + src_w--; + src_h--; + crtc_w--; + crtc_h--; + +- intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true, +- src_w != crtc_w || src_h != crtc_h); +- + dvsscale = 0; + if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) + dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0556-drm-i915-Calculate-the-sprite-WM-based-on-the-source.patch b/patches.baytrail/0556-drm-i915-Calculate-the-sprite-WM-based-on-the-source.patch new file mode 100644 index 000000000000..980c19996230 --- /dev/null +++ b/patches.baytrail/0556-drm-i915-Calculate-the-sprite-WM-based-on-the-source.patch @@ -0,0 +1,60 @@ +From ed1197848495e5949c4295ece90cccf9f59b6136 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 5 Jul 2013 11:57:15 +0300 +Subject: drm/i915: Calculate the sprite WM based on the source width instead + of the destination width +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Using the destination width in the sprite WM calculations isn't correct. +We should be using the source width. + +Note: This doesn't affect hsw since it does not support sprite +scaling. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +[danvet: Add review note from Paulo to the commit message.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit ec4c4aa14720b284af8eadd2d65d5131519fc29f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sprite.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index 3e3a6d01cff6..5a36afb6ea03 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -108,7 +108,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb, + + sprctl |= SP_ENABLE; + +- intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true, ++ intel_update_sprite_watermarks(dev, pipe, src_w, pixel_size, true, + src_w != crtc_w || src_h != crtc_h); + + /* Sizes are 0 based */ +@@ -263,7 +263,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, + if (IS_HASWELL(dev)) + sprctl |= SPRITE_PIPE_CSC_ENABLE; + +- intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true, ++ intel_update_sprite_watermarks(dev, pipe, src_w, pixel_size, true, + src_w != crtc_w || src_h != crtc_h); + + /* Sizes are 0 based */ +@@ -452,7 +452,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, + dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ + dvscntr |= DVS_ENABLE; + +- intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true, ++ intel_update_sprite_watermarks(dev, pipe, src_w, pixel_size, true, + src_w != crtc_w || src_h != crtc_h); + + /* Sizes are 0 based */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0557-drm-i915-Rename-hsw_wm_get_pixel_rate-to-ilk_pipe_pi.patch b/patches.baytrail/0557-drm-i915-Rename-hsw_wm_get_pixel_rate-to-ilk_pipe_pi.patch new file mode 100644 index 000000000000..df21a0d9c5b8 --- /dev/null +++ b/patches.baytrail/0557-drm-i915-Rename-hsw_wm_get_pixel_rate-to-ilk_pipe_pi.patch @@ -0,0 +1,48 @@ +From 6216be4a48e617722822d76387792cc2c357cef1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 5 Jul 2013 11:57:16 +0300 +Subject: drm/i915: Rename hsw_wm_get_pixel_rate to ilk_pipe_pixel_rate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +hsw_wm_get_pixel_rate() isn't specific to HSW. In fact it should be made +to handle all gens, but for now it depends on the PCH panel fitter +state, so give it an ilk_ prefix. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 3658729a72b19f5e1cb92bd972939a13db970168) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 901479fb2695..73e99cfeff48 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2095,8 +2095,8 @@ static void ivybridge_update_wm(struct drm_device *dev) + cursor_wm); + } + +-static uint32_t hsw_wm_get_pixel_rate(struct drm_device *dev, +- struct drm_crtc *crtc) ++static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev, ++ struct drm_crtc *crtc) + { + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + uint32_t pixel_rate, pfit_size; +@@ -2388,7 +2388,7 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, + pipes_active++; + + p->pipe_htotal = intel_crtc->config.adjusted_mode.htotal; +- p->pixel_rate = hsw_wm_get_pixel_rate(dev, crtc); ++ p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc); + p->pri_bytes_per_pixel = crtc->fb->bits_per_pixel / 8; + p->cur_bytes_per_pixel = 4; + p->pri_horiz_pixels = +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0558-drm-i915-Rename-most-wm-compute-functions-to-ilk_-pr.patch b/patches.baytrail/0558-drm-i915-Rename-most-wm-compute-functions-to-ilk_-pr.patch new file mode 100644 index 000000000000..e509ba8ba63e --- /dev/null +++ b/patches.baytrail/0558-drm-i915-Rename-most-wm-compute-functions-to-ilk_-pr.patch @@ -0,0 +1,162 @@ +From 15af91ef1315c736e8bdb8826ed79117af564093 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 5 Jul 2013 11:57:17 +0300 +Subject: drm/i915: Rename most wm compute functions to ilk_ prefix +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These functions are appropriate for everything since ILK. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 23297044ac70da5c87b1c1ef7d5cf32c84b2fd00) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 40 ++++++++++++++++++++-------------------- + 1 file changed, 20 insertions(+), 20 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 73e99cfeff48..e2842614bf76 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2126,7 +2126,7 @@ static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev, + return pixel_rate; + } + +-static uint32_t hsw_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel, ++static uint32_t ilk_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel, + uint32_t latency) + { + uint64_t ret; +@@ -2137,7 +2137,7 @@ static uint32_t hsw_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel, + return ret; + } + +-static uint32_t hsw_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, ++static uint32_t ilk_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, + uint32_t horiz_pixels, uint8_t bytes_per_pixel, + uint32_t latency) + { +@@ -2149,7 +2149,7 @@ static uint32_t hsw_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, + return ret; + } + +-static uint32_t hsw_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels, ++static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels, + uint8_t bytes_per_pixel) + { + return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2; +@@ -2198,7 +2198,7 @@ enum hsw_data_buf_partitioning { + }; + + /* For both WM_PIPE and WM_LP. */ +-static uint32_t hsw_compute_pri_wm(struct hsw_pipe_wm_parameters *params, ++static uint32_t ilk_compute_pri_wm(struct hsw_pipe_wm_parameters *params, + uint32_t mem_value, + bool is_lp) + { +@@ -2208,14 +2208,14 @@ static uint32_t hsw_compute_pri_wm(struct hsw_pipe_wm_parameters *params, + if (!params->active) + return 0; + +- method1 = hsw_wm_method1(params->pixel_rate, ++ method1 = ilk_wm_method1(params->pixel_rate, + params->pri_bytes_per_pixel, + mem_value); + + if (!is_lp) + return method1; + +- method2 = hsw_wm_method2(params->pixel_rate, ++ method2 = ilk_wm_method2(params->pixel_rate, + params->pipe_htotal, + params->pri_horiz_pixels, + params->pri_bytes_per_pixel, +@@ -2225,7 +2225,7 @@ static uint32_t hsw_compute_pri_wm(struct hsw_pipe_wm_parameters *params, + } + + /* For both WM_PIPE and WM_LP. */ +-static uint32_t hsw_compute_spr_wm(struct hsw_pipe_wm_parameters *params, ++static uint32_t ilk_compute_spr_wm(struct hsw_pipe_wm_parameters *params, + uint32_t mem_value) + { + uint32_t method1, method2; +@@ -2233,10 +2233,10 @@ static uint32_t hsw_compute_spr_wm(struct hsw_pipe_wm_parameters *params, + if (!params->active || !params->sprite_enabled) + return 0; + +- method1 = hsw_wm_method1(params->pixel_rate, ++ method1 = ilk_wm_method1(params->pixel_rate, + params->spr_bytes_per_pixel, + mem_value); +- method2 = hsw_wm_method2(params->pixel_rate, ++ method2 = ilk_wm_method2(params->pixel_rate, + params->pipe_htotal, + params->spr_horiz_pixels, + params->spr_bytes_per_pixel, +@@ -2245,13 +2245,13 @@ static uint32_t hsw_compute_spr_wm(struct hsw_pipe_wm_parameters *params, + } + + /* For both WM_PIPE and WM_LP. */ +-static uint32_t hsw_compute_cur_wm(struct hsw_pipe_wm_parameters *params, ++static uint32_t ilk_compute_cur_wm(struct hsw_pipe_wm_parameters *params, + uint32_t mem_value) + { + if (!params->active) + return 0; + +- return hsw_wm_method2(params->pixel_rate, ++ return ilk_wm_method2(params->pixel_rate, + params->pipe_htotal, + params->cur_horiz_pixels, + params->cur_bytes_per_pixel, +@@ -2259,14 +2259,14 @@ static uint32_t hsw_compute_cur_wm(struct hsw_pipe_wm_parameters *params, + } + + /* Only for WM_LP. */ +-static uint32_t hsw_compute_fbc_wm(struct hsw_pipe_wm_parameters *params, ++static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params, + uint32_t pri_val, + uint32_t mem_value) + { + if (!params->active) + return 0; + +- return hsw_wm_fbc(pri_val, ++ return ilk_wm_fbc(pri_val, + params->pri_horiz_pixels, + params->pri_bytes_per_pixel); + } +@@ -2281,10 +2281,10 @@ static bool hsw_compute_lp_wm(uint32_t mem_value, struct hsw_wm_maximums *max, + for (pipe = PIPE_A; pipe <= PIPE_C; pipe++) { + struct hsw_pipe_wm_parameters *p = ¶ms[pipe]; + +- pri_val[pipe] = hsw_compute_pri_wm(p, mem_value, true); +- spr_val[pipe] = hsw_compute_spr_wm(p, mem_value); +- cur_val[pipe] = hsw_compute_cur_wm(p, mem_value); +- fbc_val[pipe] = hsw_compute_fbc_wm(p, pri_val[pipe], mem_value); ++ pri_val[pipe] = ilk_compute_pri_wm(p, mem_value, true); ++ spr_val[pipe] = ilk_compute_spr_wm(p, mem_value); ++ cur_val[pipe] = ilk_compute_cur_wm(p, mem_value); ++ fbc_val[pipe] = ilk_compute_fbc_wm(p, pri_val[pipe], mem_value); + } + + result->pri_val = max3(pri_val[0], pri_val[1], pri_val[2]); +@@ -2311,9 +2311,9 @@ static uint32_t hsw_compute_wm_pipe(struct drm_i915_private *dev_priv, + { + uint32_t pri_val, cur_val, spr_val; + +- pri_val = hsw_compute_pri_wm(params, mem_value, false); +- spr_val = hsw_compute_spr_wm(params, mem_value); +- cur_val = hsw_compute_cur_wm(params, mem_value); ++ pri_val = ilk_compute_pri_wm(params, mem_value, false); ++ spr_val = ilk_compute_spr_wm(params, mem_value); ++ cur_val = ilk_compute_cur_wm(params, mem_value); + + WARN(pri_val > 127, + "Primary WM error, mode not supported for pipe %c\n", +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0559-drm-i915-Don-t-pass-mem_value-to-ilk_compute_fbc_wm.patch b/patches.baytrail/0559-drm-i915-Don-t-pass-mem_value-to-ilk_compute_fbc_wm.patch new file mode 100644 index 000000000000..4f0ea74d35b0 --- /dev/null +++ b/patches.baytrail/0559-drm-i915-Don-t-pass-mem_value-to-ilk_compute_fbc_wm.patch @@ -0,0 +1,51 @@ +From 00b87c74b30ace16d028aeb50796d7101086cf09 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 5 Jul 2013 11:57:19 +0300 +Subject: drm/i915: Don't pass "mem_value" to ilk_compute_fbc_wm +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The FBC watermark doesn't depend on the latency value, so no point in +passing it in. + +Note: It actually depends upon the latency, but only through priv_val +... + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +[danvet: Add review comment from Paulo to the commit message.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 1fda9882ca0ba134134c5bf04b8d4f4f06b52649) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index e2842614bf76..573c13c3046e 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2260,8 +2260,7 @@ static uint32_t ilk_compute_cur_wm(struct hsw_pipe_wm_parameters *params, + + /* Only for WM_LP. */ + static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params, +- uint32_t pri_val, +- uint32_t mem_value) ++ uint32_t pri_val) + { + if (!params->active) + return 0; +@@ -2284,7 +2283,7 @@ static bool hsw_compute_lp_wm(uint32_t mem_value, struct hsw_wm_maximums *max, + pri_val[pipe] = ilk_compute_pri_wm(p, mem_value, true); + spr_val[pipe] = ilk_compute_spr_wm(p, mem_value); + cur_val[pipe] = ilk_compute_cur_wm(p, mem_value); +- fbc_val[pipe] = ilk_compute_fbc_wm(p, pri_val[pipe], mem_value); ++ fbc_val[pipe] = ilk_compute_fbc_wm(p, pri_val[pipe]); + } + + result->pri_val = max3(pri_val[0], pri_val[1], pri_val[2]); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0560-drm-i915-Change-the-watermark-latency-type-to-uint16.patch b/patches.baytrail/0560-drm-i915-Change-the-watermark-latency-type-to-uint16.patch new file mode 100644 index 000000000000..d9e695146326 --- /dev/null +++ b/patches.baytrail/0560-drm-i915-Change-the-watermark-latency-type-to-uint16.patch @@ -0,0 +1,53 @@ +From a37f63762cb81b1cd999314fc50d04b6f5417e4a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 5 Jul 2013 11:57:20 +0300 +Subject: drm/i915: Change the watermark latency type to uint16_t +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The latency values fit in uint16_t, so let's save a few bytes. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 888fd1594e38c21f8dc5aa28b90a556df32f61e0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 573c13c3046e..eef173df268b 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2353,7 +2353,7 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) + + static void hsw_compute_wm_parameters(struct drm_device *dev, + struct hsw_pipe_wm_parameters *params, +- uint32_t *wm, ++ uint16_t *wm, + struct hsw_wm_maximums *lp_max_1_2, + struct hsw_wm_maximums *lp_max_5_6) + { +@@ -2426,7 +2426,7 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, + + static void hsw_compute_wm_results(struct drm_device *dev, + struct hsw_pipe_wm_parameters *params, +- uint32_t *wm, ++ uint16_t *wm, + struct hsw_wm_maximums *lp_maximums, + struct hsw_wm_values *results) + { +@@ -2608,7 +2608,7 @@ static void haswell_update_wm(struct drm_device *dev) + struct hsw_wm_maximums lp_max_1_2, lp_max_5_6; + struct hsw_pipe_wm_parameters params[3]; + struct hsw_wm_values results_1_2, results_5_6, *best_results; +- uint32_t wm[5]; ++ uint16_t wm[5]; + enum hsw_data_buf_partitioning partitioning; + + hsw_compute_wm_parameters(dev, params, wm, &lp_max_1_2, &lp_max_5_6); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0561-drm-i915-Split-out-reading-of-HSW-watermark-latency-.patch b/patches.baytrail/0561-drm-i915-Split-out-reading-of-HSW-watermark-latency-.patch new file mode 100644 index 000000000000..f669e6efe072 --- /dev/null +++ b/patches.baytrail/0561-drm-i915-Split-out-reading-of-HSW-watermark-latency-.patch @@ -0,0 +1,95 @@ +From bd5245b1b7a008c00cd4f25fd1204f25f27bec61 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 5 Jul 2013 11:57:21 +0300 +Subject: drm/i915: Split out reading of HSW watermark latency values +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Move parsing of MCH_SSKPD to a separate function, we'll add other +platforms there later. + +Note: Chris spotted an empty struct initializer and wondered whether +that is hiding a compilier warning. Ville explained that it should +have been part of the patch that extends this function to snb/ivb, +which don't have all levels hsw has. I've figured it's ok to keep it +here with a small note. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +[danvet: Add note about the ominous struct initializer.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 12b134df4e42ea1ac141388e563346777f8a1605) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 34 ++++++++++++++++++++-------------- + 1 file changed, 20 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index eef173df268b..aa7dd82d4489 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2351,28 +2351,33 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) + PIPE_WM_LINETIME_TIME(linetime); + } + ++static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5]) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (IS_HASWELL(dev)) { ++ uint64_t sskpd = I915_READ64(MCH_SSKPD); ++ ++ wm[0] = (sskpd >> 56) & 0xFF; ++ if (wm[0] == 0) ++ wm[0] = sskpd & 0xF; ++ wm[1] = ((sskpd >> 4) & 0xFF) * 5; ++ wm[2] = ((sskpd >> 12) & 0xFF) * 5; ++ wm[3] = ((sskpd >> 20) & 0x1FF) * 5; ++ wm[4] = ((sskpd >> 32) & 0x1FF) * 5; ++ } ++} ++ + static void hsw_compute_wm_parameters(struct drm_device *dev, + struct hsw_pipe_wm_parameters *params, +- uint16_t *wm, + struct hsw_wm_maximums *lp_max_1_2, + struct hsw_wm_maximums *lp_max_5_6) + { +- struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + struct drm_plane *plane; +- uint64_t sskpd = I915_READ64(MCH_SSKPD); + enum pipe pipe; + int pipes_active = 0, sprites_enabled = 0; + +- if ((sskpd >> 56) & 0xFF) +- wm[0] = (sskpd >> 56) & 0xFF; +- else +- wm[0] = sskpd & 0xF; +- wm[1] = ((sskpd >> 4) & 0xFF) * 5; +- wm[2] = ((sskpd >> 12) & 0xFF) * 5; +- wm[3] = ((sskpd >> 20) & 0x1FF) * 5; +- wm[4] = ((sskpd >> 32) & 0x1FF) * 5; +- + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct hsw_pipe_wm_parameters *p; +@@ -2608,10 +2613,11 @@ static void haswell_update_wm(struct drm_device *dev) + struct hsw_wm_maximums lp_max_1_2, lp_max_5_6; + struct hsw_pipe_wm_parameters params[3]; + struct hsw_wm_values results_1_2, results_5_6, *best_results; +- uint16_t wm[5]; ++ uint16_t wm[5] = {}; + enum hsw_data_buf_partitioning partitioning; + +- hsw_compute_wm_parameters(dev, params, wm, &lp_max_1_2, &lp_max_5_6); ++ intel_read_wm_latency(dev, wm); ++ hsw_compute_wm_parameters(dev, params, &lp_max_1_2, &lp_max_5_6); + + hsw_compute_wm_results(dev, params, wm, &lp_max_1_2, &results_1_2); + if (lp_max_1_2.pri != lp_max_5_6.pri) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0562-drm-i915-Don-t-multiply-the-watermark-latency-values.patch b/patches.baytrail/0562-drm-i915-Don-t-multiply-the-watermark-latency-values.patch new file mode 100644 index 000000000000..8644b74ba06c --- /dev/null +++ b/patches.baytrail/0562-drm-i915-Don-t-multiply-the-watermark-latency-values.patch @@ -0,0 +1,59 @@ +From 177a0ab7aa7203fd5e5c4db111b7cda654d3c414 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 5 Jul 2013 11:57:22 +0300 +Subject: drm/i915: Don't multiply the watermark latency values too early +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The LP1+ watermark latency values need to be multiplied by 5 to +make them suitable for watermark calculations. However on pre-HSW +platforms we're going to need the raw value later when we have to +write it to the WM_LPn registers' latency field. So delay the +multiplication until it's needed. + +Note: Paulo complains that the units of wm (now in 100ns) aren't +really clear and I agree. But that can be fixed later on ... + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +[danvet: Add a comment about the unit obfuscation.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit e5d5019e95415a99b1c0bca3dab6d8fcd39f4c65) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index aa7dd82d4489..c2b993fe82ca 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2361,10 +2361,10 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5]) + wm[0] = (sskpd >> 56) & 0xFF; + if (wm[0] == 0) + wm[0] = sskpd & 0xF; +- wm[1] = ((sskpd >> 4) & 0xFF) * 5; +- wm[2] = ((sskpd >> 12) & 0xFF) * 5; +- wm[3] = ((sskpd >> 20) & 0x1FF) * 5; +- wm[4] = ((sskpd >> 32) & 0x1FF) * 5; ++ wm[1] = (sskpd >> 4) & 0xFF; ++ wm[2] = (sskpd >> 12) & 0xFF; ++ wm[3] = (sskpd >> 20) & 0x1FF; ++ wm[4] = (sskpd >> 32) & 0x1FF; + } + } + +@@ -2442,7 +2442,7 @@ static void hsw_compute_wm_results(struct drm_device *dev, + int level, max_level, wm_lp; + + for (level = 1; level <= 4; level++) +- if (!hsw_compute_lp_wm(wm[level], lp_maximums, params, ++ if (!hsw_compute_lp_wm(wm[level] * 5, lp_maximums, params, + &lp_results[level - 1])) + break; + max_level = level - 1; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0563-drm-i915-Add-SNB-IVB-support-to-intel_read_wm_latenc.patch b/patches.baytrail/0563-drm-i915-Add-SNB-IVB-support-to-intel_read_wm_latenc.patch new file mode 100644 index 000000000000..6ba12516deeb --- /dev/null +++ b/patches.baytrail/0563-drm-i915-Add-SNB-IVB-support-to-intel_read_wm_latenc.patch @@ -0,0 +1,41 @@ +From 9683ce954bc6585d96dbe66f6bd697b69b78d8fc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 5 Jul 2013 11:57:23 +0300 +Subject: drm/i915: Add SNB/IVB support to intel_read_wm_latency +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +SNB and IVB have slightly a different way to read out the +watermark latency values. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 63cf9a131ee60fa2458d75f5c0d7a3a5dcaa2b3e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index c2b993fe82ca..03fa8656155d 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2365,6 +2365,13 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5]) + wm[2] = (sskpd >> 12) & 0xFF; + wm[3] = (sskpd >> 20) & 0x1FF; + wm[4] = (sskpd >> 32) & 0x1FF; ++ } else if (INTEL_INFO(dev)->gen >= 6) { ++ uint32_t sskpd = I915_READ(MCH_SSKPD); ++ ++ wm[0] = (sskpd >> SSKPD_WM0_SHIFT) & SSKPD_WM_MASK; ++ wm[1] = (sskpd >> SSKPD_WM1_SHIFT) & SSKPD_WM_MASK; ++ wm[2] = (sskpd >> SSKPD_WM2_SHIFT) & SSKPD_WM_MASK; ++ wm[3] = (sskpd >> SSKPD_WM3_SHIFT) & SSKPD_WM_MASK; + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0564-drm-i915-enable-IPS-for-bpp-24.patch b/patches.baytrail/0564-drm-i915-enable-IPS-for-bpp-24.patch new file mode 100644 index 000000000000..fe22102a2d31 --- /dev/null +++ b/patches.baytrail/0564-drm-i915-enable-IPS-for-bpp-24.patch @@ -0,0 +1,34 @@ +From 4695860630dae079809f30df5630bc6c1170ebaf Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Thu, 25 Jul 2013 10:06:50 -0700 +Subject: drm/i915: enable IPS for bpp <= 24 + +Art confirms that this should work fine. Since most panels are 18bpp +with dithering from 24bpp, the existing code wouldn't be enabled in most +cases. + +Signed-off-by: Jesse Barnes +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit b6dfdc9b7f0d7859ea146b6c869aa2cfe6d713f3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 3fd109df65a6..5521fb66f2a4 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -4087,7 +4087,7 @@ static void hsw_compute_ips_config(struct intel_crtc *crtc, + { + pipe_config->ips_enabled = i915_enable_ips && + hsw_crtc_supports_ips(crtc) && +- pipe_config->pipe_bpp == 24; ++ pipe_config->pipe_bpp <= 24; + } + + static int intel_crtc_compute_config(struct intel_crtc *crtc, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0565-drm-i915-Acquire-dpio_lock-for-VLV-sideband-programm.patch b/patches.baytrail/0565-drm-i915-Acquire-dpio_lock-for-VLV-sideband-programm.patch new file mode 100644 index 000000000000..0c81c3c0c9da --- /dev/null +++ b/patches.baytrail/0565-drm-i915-Acquire-dpio_lock-for-VLV-sideband-programm.patch @@ -0,0 +1,157 @@ +From 63b712d08cf564097c2ae1977252d641991baea2 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Fri, 26 Jul 2013 19:57:35 +0100 +Subject: drm/i915: Acquire dpio_lock for VLV sideband programming in DP/HDMI + +Otherwise we get flooded by the kernel warning us that we are doing +long sequences of IO without serialisation. For example, + + WARNING: CPU: 0 PID: 11136 at drivers/gpu/drm/i915/intel_sideband.c:40 vlv_sideband_rw+0x48/0x1ef() + Modules linked in: + CPU: 0 PID: 11136 Comm: kworker/u2:0 Tainted: G W 3.11.0-rc2+ #4 + Call Trace: + [] ? warn_slowpath_common+0x63/0x78 + [] ? vlv_sideband_rw+0x48/0x1ef + [] ? warn_slowpath_null+0xf/0x13 + [] ? vlv_sideband_rw+0x48/0x1ef + [] ? vlv_dpio_write+0x1c/0x21 + [] ? intel_dp_set_signal_levels+0x24a/0x385 + [] ? intel_dp_complete_link_train+0x25/0x1d1 + [] ? intel_dp_check_link_status+0xf7/0x106 + [] ? i915_hotplug_work_func+0x17b/0x221 + [] ? process_one_work+0x12e/0x210 + [] ? worker_thread+0x116/0x1ad + [] ? rescuer_thread+0x1cb/0x1cb + [] ? kthread+0x67/0x6c + [] ? ret_from_kernel_thread+0x1b/0x30 + [] ? init_completion+0x18/0x18 + +v2: Retire the locking in vlv_crtc_enable() and do it close to the meat. + +Signed-off-by: Chris Wilson +Reviewed-by: Jani Nikula +[danvet: Squash in a s/mutex_lock/mutex_unlock/ fixup spotted by the 0 +day kernel build/coccinelle and reported by Dan Carpenter.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 0980a60fba7a9afa3259390e8af16b6ce486858a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ---- + drivers/gpu/drm/i915/intel_dp.c | 6 ++++++ + drivers/gpu/drm/i915/intel_hdmi.c | 4 ++++ + 3 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 5521fb66f2a4..20510cb59085 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3652,8 +3652,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) + intel_crtc->active = true; + intel_update_watermarks(dev); + +- mutex_lock(&dev_priv->dpio_lock); +- + for_each_encoder_on_crtc(dev, crtc, encoder) + if (encoder->pre_pll_enable) + encoder->pre_pll_enable(encoder); +@@ -3678,8 +3676,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) + intel_crtc_update_cursor(crtc, true); + + intel_update_fbc(dev); +- +- mutex_unlock(&dev_priv->dpio_lock); + } + + static void i9xx_crtc_enable(struct drm_crtc *crtc) +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 44972a679517..57d9b979a846 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1738,6 +1738,7 @@ static void intel_pre_enable_dp(struct intel_encoder *encoder) + int pipe = intel_crtc->pipe; + u32 val; + ++ mutex_lock(&dev_priv->dpio_lock); + val = vlv_dpio_read(dev_priv, DPIO_DATA_LANE_A(port)); + val = 0; + if (pipe) +@@ -1751,6 +1752,7 @@ static void intel_pre_enable_dp(struct intel_encoder *encoder) + 0x00760018); + vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port), + 0x00400888); ++ mutex_unlock(&dev_priv->dpio_lock); + } + } + +@@ -1765,6 +1767,7 @@ static void intel_dp_pre_pll_enable(struct intel_encoder *encoder) + return; + + /* Program Tx lane resets to default */ ++ mutex_lock(&dev_priv->dpio_lock); + vlv_dpio_write(dev_priv, DPIO_PCS_TX(port), + DPIO_PCS_TX_LANE2_RESET | + DPIO_PCS_TX_LANE1_RESET); +@@ -1778,6 +1781,7 @@ static void intel_dp_pre_pll_enable(struct intel_encoder *encoder) + vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER1(port), 0x00750f00); + vlv_dpio_write(dev_priv, DPIO_TX_CTL(port), 0x00001500); + vlv_dpio_write(dev_priv, DPIO_TX_LANE(port), 0x40400000); ++ mutex_unlock(&dev_priv->dpio_lock); + } + + /* +@@ -1989,6 +1993,7 @@ static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp) + return 0; + } + ++ mutex_lock(&dev_priv->dpio_lock); + vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x00000000); + vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(port), demph_reg_value); + vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(port), +@@ -1997,6 +2002,7 @@ static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp) + vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER0(port), 0x00030000); + vlv_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port), preemph_reg_value); + vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x80000000); ++ mutex_unlock(&dev_priv->dpio_lock); + + return 0; + } +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index e82cd816bde9..1e602058d475 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -1032,6 +1032,7 @@ static void intel_hdmi_pre_enable(struct intel_encoder *encoder) + return; + + /* Enable clock channels for this port */ ++ mutex_lock(&dev_priv->dpio_lock); + val = vlv_dpio_read(dev_priv, DPIO_DATA_LANE_A(port)); + val = 0; + if (pipe) +@@ -1062,6 +1063,7 @@ static void intel_hdmi_pre_enable(struct intel_encoder *encoder) + 0x00760018); + vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port), + 0x00400888); ++ mutex_unlock(&dev_priv->dpio_lock); + } + + static void intel_hdmi_pre_pll_enable(struct intel_encoder *encoder) +@@ -1075,6 +1077,7 @@ static void intel_hdmi_pre_pll_enable(struct intel_encoder *encoder) + return; + + /* Program Tx lane resets to default */ ++ mutex_lock(&dev_priv->dpio_lock); + vlv_dpio_write(dev_priv, DPIO_PCS_TX(port), + DPIO_PCS_TX_LANE2_RESET | + DPIO_PCS_TX_LANE1_RESET); +@@ -1093,6 +1096,7 @@ static void intel_hdmi_pre_pll_enable(struct intel_encoder *encoder) + 0x00002000); + vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), + DPIO_TX_OCALINIT_EN); ++ mutex_unlock(&dev_priv->dpio_lock); + } + + static void intel_hdmi_post_disable(struct intel_encoder *encoder) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0566-drm-i915-rearrange-vlv-dp-enable-and-pre_enable-call.patch b/patches.baytrail/0566-drm-i915-rearrange-vlv-dp-enable-and-pre_enable-call.patch new file mode 100644 index 000000000000..58c00fe5dc33 --- /dev/null +++ b/patches.baytrail/0566-drm-i915-rearrange-vlv-dp-enable-and-pre_enable-call.patch @@ -0,0 +1,145 @@ +From 20397ab650e3678471b68e06a48aaa5db2d3a962 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 30 Jul 2013 12:20:30 +0300 +Subject: drm/i915: rearrange vlv dp enable and pre_enable callbacks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +VLV wants encoder enabling before the pipe is up. This is currently +achieved through calling the ->enable callback early, right after the +->pre_enable callback, in valleyview_crtc_enable(). This loses both the +distinction between ->pre_enable and ->enable on VLV and the possibility +to use a hook at the end of the modeset sequence. + +Rearrange the DP callbacks to make it possible to move ->enable call +later. Basically do everything in ->pre_enable on VLV, and make ->enable +a NOP. + +There should be no functional changes. + +v2: Rebase. + +v3: Explain why this is needed in the commit message (Chris). + +Signed-off-by: Jani Nikula +Reviewed-by: Chris Wilson +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit ab1f90f9662482021fddd0e7868005401f62866f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dp.c | 73 ++++++++++++++++++++++------------------- + 1 file changed, 39 insertions(+), 34 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 57d9b979a846..9e22bfd850df 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1711,49 +1711,50 @@ static void intel_enable_dp(struct intel_encoder *encoder) + intel_dp_complete_link_train(intel_dp); + intel_dp_stop_link_train(intel_dp); + ironlake_edp_backlight_on(intel_dp); ++} + +- if (IS_VALLEYVIEW(dev)) { +- struct intel_digital_port *dport = +- enc_to_dig_port(&encoder->base); +- int channel = vlv_dport_to_channel(dport); +- +- vlv_wait_port_ready(dev_priv, channel); +- } ++static void vlv_enable_dp(struct intel_encoder *encoder) ++{ + } + + static void intel_pre_enable_dp(struct intel_encoder *encoder) + { + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + struct intel_digital_port *dport = dp_to_dig_port(intel_dp); ++ ++ if (dport->port == PORT_A) ++ ironlake_edp_pll_on(intel_dp); ++} ++ ++static void vlv_pre_enable_dp(struct intel_encoder *encoder) ++{ ++ struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); ++ struct intel_digital_port *dport = dp_to_dig_port(intel_dp); + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; ++ struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); ++ int port = vlv_dport_to_channel(dport); ++ int pipe = intel_crtc->pipe; ++ u32 val; + +- if (dport->port == PORT_A && !IS_VALLEYVIEW(dev)) +- ironlake_edp_pll_on(intel_dp); ++ mutex_lock(&dev_priv->dpio_lock); + +- if (IS_VALLEYVIEW(dev)) { +- struct intel_crtc *intel_crtc = +- to_intel_crtc(encoder->base.crtc); +- int port = vlv_dport_to_channel(dport); +- int pipe = intel_crtc->pipe; +- u32 val; +- +- mutex_lock(&dev_priv->dpio_lock); +- val = vlv_dpio_read(dev_priv, DPIO_DATA_LANE_A(port)); +- val = 0; +- if (pipe) +- val |= (1<<21); +- else +- val &= ~(1<<21); +- val |= 0x001000c4; +- vlv_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val); ++ val = vlv_dpio_read(dev_priv, DPIO_DATA_LANE_A(port)); ++ val = 0; ++ if (pipe) ++ val |= (1<<21); ++ else ++ val &= ~(1<<21); ++ val |= 0x001000c4; ++ vlv_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val); ++ vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port), 0x00760018); ++ vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port), 0x00400888); + +- vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port), +- 0x00760018); +- vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port), +- 0x00400888); +- mutex_unlock(&dev_priv->dpio_lock); +- } ++ mutex_unlock(&dev_priv->dpio_lock); ++ ++ intel_enable_dp(encoder); ++ ++ vlv_wait_port_ready(dev_priv, port); + } + + static void intel_dp_pre_pll_enable(struct intel_encoder *encoder) +@@ -3533,14 +3534,18 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) + + intel_encoder->compute_config = intel_dp_compute_config; + intel_encoder->mode_set = intel_dp_mode_set; +- intel_encoder->enable = intel_enable_dp; +- intel_encoder->pre_enable = intel_pre_enable_dp; + intel_encoder->disable = intel_disable_dp; + intel_encoder->post_disable = intel_post_disable_dp; + intel_encoder->get_hw_state = intel_dp_get_hw_state; + intel_encoder->get_config = intel_dp_get_config; +- if (IS_VALLEYVIEW(dev)) ++ if (IS_VALLEYVIEW(dev)) { + intel_encoder->pre_pll_enable = intel_dp_pre_pll_enable; ++ intel_encoder->pre_enable = vlv_pre_enable_dp; ++ intel_encoder->enable = vlv_enable_dp; ++ } else { ++ intel_encoder->pre_enable = intel_pre_enable_dp; ++ intel_encoder->enable = intel_enable_dp; ++ } + + intel_dig_port->port = port; + intel_dig_port->dp.output_reg = output_reg; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0567-drm-i915-rearrange-vlv-hdmi-enable-and-pre_enable-ca.patch b/patches.baytrail/0567-drm-i915-rearrange-vlv-hdmi-enable-and-pre_enable-ca.patch new file mode 100644 index 000000000000..4f74b19cb7b6 --- /dev/null +++ b/patches.baytrail/0567-drm-i915-rearrange-vlv-hdmi-enable-and-pre_enable-ca.patch @@ -0,0 +1,89 @@ +From 262be8838a9892f97e034e991e9c8139ffd8f538 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 30 Jul 2013 12:20:31 +0300 +Subject: drm/i915: rearrange vlv hdmi enable and pre_enable callbacks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +VLV wants encoder enabling before the pipe is up. This is currently +achieved through calling the ->enable callback early, right after the +->pre_enable callback, in valleyview_crtc_enable(). This loses both the +distinction between ->pre_enable and ->enable on VLV and the possibility +to use a hook at the end of the modeset sequence. + +Rearrange the HDMI callbacks to make it possible to move ->enable call +later. Basically do everything in ->pre_enable on VLV, and make ->enable +a NOP. + +There should be no functional changes. + +v2: Rebase. + +v3: Explain why this is needed in the commit message (Chris). + +Signed-off-by: Jani Nikula +Reviewed-by: Chris Wilson +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit b76cf76bfa76246c8acce104de8f2fdd001069fb) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_hdmi.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 1e602058d475..0b3750f11a97 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -718,14 +718,10 @@ static void intel_enable_hdmi(struct intel_encoder *encoder) + I915_WRITE(intel_hdmi->hdmi_reg, temp); + POSTING_READ(intel_hdmi->hdmi_reg); + } ++} + +- if (IS_VALLEYVIEW(dev)) { +- struct intel_digital_port *dport = +- enc_to_dig_port(&encoder->base); +- int channel = vlv_dport_to_channel(dport); +- +- vlv_wait_port_ready(dev_priv, channel); +- } ++static void vlv_enable_hdmi(struct intel_encoder *encoder) ++{ + } + + static void intel_disable_hdmi(struct intel_encoder *encoder) +@@ -1064,6 +1060,10 @@ static void intel_hdmi_pre_enable(struct intel_encoder *encoder) + vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port), + 0x00400888); + mutex_unlock(&dev_priv->dpio_lock); ++ ++ intel_enable_hdmi(encoder); ++ ++ vlv_wait_port_ready(dev_priv, port); + } + + static void intel_hdmi_pre_pll_enable(struct intel_encoder *encoder) +@@ -1244,14 +1244,16 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) + + intel_encoder->compute_config = intel_hdmi_compute_config; + intel_encoder->mode_set = intel_hdmi_mode_set; +- intel_encoder->enable = intel_enable_hdmi; + intel_encoder->disable = intel_disable_hdmi; + intel_encoder->get_hw_state = intel_hdmi_get_hw_state; + intel_encoder->get_config = intel_hdmi_get_config; + if (IS_VALLEYVIEW(dev)) { +- intel_encoder->pre_enable = intel_hdmi_pre_enable; + intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable; ++ intel_encoder->pre_enable = intel_hdmi_pre_enable; ++ intel_encoder->enable = vlv_enable_hdmi; + intel_encoder->post_disable = intel_hdmi_post_disable; ++ } else { ++ intel_encoder->enable = intel_enable_hdmi; + } + + intel_encoder->type = INTEL_OUTPUT_HDMI; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0568-drm-i915-move-encoder-enable-callback-later-in-VLV-c.patch b/patches.baytrail/0568-drm-i915-move-encoder-enable-callback-later-in-VLV-c.patch new file mode 100644 index 000000000000..97367b8ad03a --- /dev/null +++ b/patches.baytrail/0568-drm-i915-move-encoder-enable-callback-later-in-VLV-c.patch @@ -0,0 +1,60 @@ +From 5c9b0d896db72e6b777ed60f663652ef45f0cacf Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 30 Jul 2013 12:20:32 +0300 +Subject: drm/i915: move encoder->enable callback later in VLV crtc enable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +VLV wants encoder enabling before the pipe is up. With the previously +rearranged VLV DP and HDMI ->pre_enable and ->enable callbacks in place, +this no longer depends on the early ->enable hook call. Move the +->enable call at the end of the sequence, similar to the crtc enable on +other platforms. This will be needed e.g. for moving the eDP backlight +enabling to the right place in the sequence, currently done too early on +VLV. + +There should be no functional changes. + +v2: Rebase. + +v3: Explain why this is needed in the commit message (Chris). + +Signed-off-by: Jani Nikula +Reviewed-by: Chris Wilson +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 5004945f1d6c0282c0288afa89ad85d7f2bea4d5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 20510cb59085..41ce30eac8ec 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3662,10 +3662,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) + if (encoder->pre_enable) + encoder->pre_enable(encoder); + +- /* VLV wants encoder enabling _before_ the pipe is up. */ +- for_each_encoder_on_crtc(dev, crtc, encoder) +- encoder->enable(encoder); +- + i9xx_pfit_enable(intel_crtc); + + intel_crtc_load_lut(crtc); +@@ -3676,6 +3672,9 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) + intel_crtc_update_cursor(crtc, true); + + intel_update_fbc(dev); ++ ++ for_each_encoder_on_crtc(dev, crtc, encoder) ++ encoder->enable(encoder); + } + + static void i9xx_crtc_enable(struct drm_crtc *crtc) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0569-drm-i915-make-user-mode-sync-polarity-setting-explic.patch b/patches.baytrail/0569-drm-i915-make-user-mode-sync-polarity-setting-explic.patch new file mode 100644 index 000000000000..c9c23f0545e0 --- /dev/null +++ b/patches.baytrail/0569-drm-i915-make-user-mode-sync-polarity-setting-explic.patch @@ -0,0 +1,59 @@ +From bd601bcf434dbc2cb43751f507e24a0163401c62 Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Tue, 30 Jul 2013 13:36:32 +0300 +Subject: drm/i915: make user mode sync polarity setting explicit + +Userspace can pass a mode with an unspecified vsync/hsync polarity +setting. All encoders in the Intel driver take this to mean a negative +polarity setting. The HW readout/state checker code on the other hand +needs these flags to be explicitly set, otherwise the state checker will +WARN about the mismatch. + +Get rid of the WARN by making the polarity setting explicit in the +adjusted mode flags based on the requested mode flags. This will keep +the existing behavior otherwise. + +Note that we could guess from the other timing parameters whether the +user wanted a VESA or other standard mode and set the polarity +accordingly. This is what the NV driver does +(drivers/gpu/drm/nouveau/dispnv04/crtc.c), but I think that's not very +exact and would change the existing behavior of the Intel driver. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65442 +Signed-off-by: Imre Deak +Tested-by: cancan,feng +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 2960bc9cceecb5d556ce1c07656a6609e2f7e8b0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 41ce30eac8ec..bd3591af3395 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8065,6 +8065,19 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, + (enum transcoder) to_intel_crtc(crtc)->pipe; + pipe_config->shared_dpll = DPLL_ID_PRIVATE; + ++ /* ++ * Sanitize sync polarity flags based on requested ones. If neither ++ * positive or negative polarity is requested, treat this as meaning ++ * negative polarity. ++ */ ++ if (!(pipe_config->adjusted_mode.flags & ++ (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC))) ++ pipe_config->adjusted_mode.flags |= DRM_MODE_FLAG_NHSYNC; ++ ++ if (!(pipe_config->adjusted_mode.flags & ++ (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC))) ++ pipe_config->adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC; ++ + /* Compute a starting value for pipe_config->pipe_bpp taking the source + * plane pixel format and any sink constraints into account. Returns the + * source plane bpp so that dithering can be selected on mismatches +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0570-i915-fix-ACPI-_DSM-warning.patch b/patches.baytrail/0570-i915-fix-ACPI-_DSM-warning.patch new file mode 100644 index 000000000000..38b26e137616 --- /dev/null +++ b/patches.baytrail/0570-i915-fix-ACPI-_DSM-warning.patch @@ -0,0 +1,75 @@ +From 769c4bfea7d9f6c47ed7e40fe42cca7dcaadfb66 Mon Sep 17 00:00:00 2001 +From: Peter Wu +Date: Thu, 1 Aug 2013 18:21:28 +0200 +Subject: i915: fix ACPI _DSM warning + +Since commit 29a241c (ACPICA: Add argument typechecking for all +predefined ACPI names), _DSM parameters are validated which trigger the +following warning: + + ACPI Warning: \_SB_.PCI0.GFX0._DSM: Argument #4 type mismatch - Found [Integer], ACPI requires [Package] (20130517/nsarguments-95) + ACPI Warning: \_SB_.PCI0.GFX0._DSM: Argument #4 type mismatch - Found [Integer], ACPI requires [Package] (20130517/nsarguments-95) + ACPI Warning: \_SB_.PCI0.P0P2.PEGP._DSM: Argument #4 type mismatch - Found [Integer], ACPI requires [Package] (20130517/nsarguments-95) + ACPI Warning: \_SB_.PCI0.P0P2.PEGP._DSM: Argument #4 type mismatch - Found [Integer], ACPI requires [Package] (20130517/nsarguments-95) + +As the Intel _DSM method seems to ignore this parameter, let's comply to +the ACPI spec and use a Package instead. + +Signed-off-by: Peter Wu +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=32602 +Signed-off-by: Daniel Vetter +(cherry picked from commit 6d5c2d8ca3c15a191a8078316e547c1f4e5ad6eb) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_acpi.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c +index bcbbaea2a78e..57fe1ae32a0d 100644 +--- a/drivers/gpu/drm/i915/intel_acpi.c ++++ b/drivers/gpu/drm/i915/intel_acpi.c +@@ -28,7 +28,7 @@ static const u8 intel_dsm_guid[] = { + 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c + }; + +-static int intel_dsm(acpi_handle handle, int func, int arg) ++static int intel_dsm(acpi_handle handle, int func) + { + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_object_list input; +@@ -46,8 +46,9 @@ static int intel_dsm(acpi_handle handle, int func, int arg) + params[1].integer.value = INTEL_DSM_REVISION_ID; + params[2].type = ACPI_TYPE_INTEGER; + params[2].integer.value = func; +- params[3].type = ACPI_TYPE_INTEGER; +- params[3].integer.value = arg; ++ params[3].type = ACPI_TYPE_PACKAGE; ++ params[3].package.count = 0; ++ params[3].package.elements = NULL; + + ret = acpi_evaluate_object(handle, "_DSM", &input, &output); + if (ret) { +@@ -151,8 +152,9 @@ static void intel_dsm_platform_mux_info(void) + params[1].integer.value = INTEL_DSM_REVISION_ID; + params[2].type = ACPI_TYPE_INTEGER; + params[2].integer.value = INTEL_DSM_FN_PLATFORM_MUX_INFO; +- params[3].type = ACPI_TYPE_INTEGER; +- params[3].integer.value = 0; ++ params[3].type = ACPI_TYPE_PACKAGE; ++ params[3].package.count = 0; ++ params[3].package.elements = NULL; + + ret = acpi_evaluate_object(intel_dsm_priv.dhandle, "_DSM", &input, + &output); +@@ -205,7 +207,7 @@ static bool intel_dsm_pci_probe(struct pci_dev *pdev) + return false; + } + +- ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS, 0); ++ ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS); + if (ret < 0) { + DRM_DEBUG_KMS("failed to get supported _DSM functions\n"); + return false; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0571-drm-i915-hsw-Change-default-LLC-age-to-3.patch b/patches.baytrail/0571-drm-i915-hsw-Change-default-LLC-age-to-3.patch new file mode 100644 index 000000000000..055b04cea435 --- /dev/null +++ b/patches.baytrail/0571-drm-i915-hsw-Change-default-LLC-age-to-3.patch @@ -0,0 +1,69 @@ +From 7809753376f1dbacf3b24318baf0a90cb40908a8 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Sun, 4 Aug 2013 23:47:29 -0700 +Subject: drm/i915/hsw: Change default LLC age to 3 + +The default LLC age was changed: +commit 0d8ff15e9a15f2b393e53337a107b7a1e5919b6d +Author: Ben Widawsky +Date: Thu Jul 4 11:02:03 2013 -0700 + +drm/i915/hsw: Set correct Haswell PTE encodings. + +On the surface it would seem setting a default age wouldn't matter +because all GEM BOs are aged similarly, so the order in which objects +are evicted would not be subject to aging. The current working theory as +to why this caused a regression though is that LLC is a bit special in +that it is shared with the CPU. Presumably (not verified) the CPU +fetches cachelines with age 3, and therefore recently cached GPU objects +would be evicted before similar CPU object first when the LLC is full. +It stands to reason therefore that this would negatively impact CPU +bound benchmarks - but those seem to be low on the priority list. + +eLLC OTOH does not have this same property as LLC. It should be used +entirely for the GPU, and so the age really shouldn't matter. +Furthermore, we have no evidence to suggest one is better than another +on eLLC. Since we've never properly supported eLLC before no, there +should be no regression. If the GPU client really wants "younger" +objects, they should use MOCS. + +v2: Drop the extra #define (Chad) + +v3: Actually git add + +v4: Pimped commit message + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67062 +Signed-off-by: Ben Widawsky +Reviewed-by: Chad Versace +Signed-off-by: Daniel Vetter +(cherry picked from commit 87a6b688ccc78b2c54bee56879c6d195d2457ebe) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_gtt.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index e7b420495516..3e7f1242af91 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -52,6 +52,7 @@ + */ + #define HSW_CACHEABILITY_CONTROL(bits) ((((bits) & 0x7) << 1) | \ + (((bits) & 0x8) << (11 - 3))) ++#define HSW_WB_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x2) + #define HSW_WB_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x3) + #define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb) + +@@ -105,7 +106,7 @@ static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr, + pte |= HSW_PTE_ADDR_ENCODE(addr); + + if (level != I915_CACHE_NONE) +- pte |= HSW_WB_LLC_AGE0; ++ pte |= HSW_WB_LLC_AGE3; + + return pte; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0572-drm-i915-Create-an-init-vm.patch b/patches.baytrail/0572-drm-i915-Create-an-init-vm.patch new file mode 100644 index 000000000000..9c619f5ef59a --- /dev/null +++ b/patches.baytrail/0572-drm-i915-Create-an-init-vm.patch @@ -0,0 +1,70 @@ +From 6b9875e68984ff9b2be13ad1c97506da6f951fba Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 16:59:54 -0700 +Subject: drm/i915: Create an init vm + +Move all the similar address space (VM) initialization code to one +function. Until we have multiple VMs, there should only ever be 1 VM. +The aliasing ppgtt is a special case without it's own VM (since it +doesn't need it's own address space management). + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit fc8c067eee712b274e554be5cc87c79366cc5ad2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 4 ---- + drivers/gpu/drm/i915/i915_gem.c | 15 +++++++++++++-- + 2 files changed, 13 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index de611f64bb16..e4e98dfb7f25 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1485,10 +1485,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + + i915_dump_device_info(dev_priv); + +- INIT_LIST_HEAD(&dev_priv->vm_list); +- INIT_LIST_HEAD(&dev_priv->gtt.base.global_link); +- list_add(&dev_priv->gtt.base.global_link, &dev_priv->vm_list); +- + if (i915_get_bridge_dev(dev)) { + ret = -EIO; + goto free_priv; +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 3a5d4baa4c53..8f9ee89ed971 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -4334,6 +4334,16 @@ init_ring_lists(struct intel_ring_buffer *ring) + INIT_LIST_HEAD(&ring->request_list); + } + ++static void i915_init_vm(struct drm_i915_private *dev_priv, ++ struct i915_address_space *vm) ++{ ++ vm->dev = dev_priv->dev; ++ INIT_LIST_HEAD(&vm->active_list); ++ INIT_LIST_HEAD(&vm->inactive_list); ++ INIT_LIST_HEAD(&vm->global_link); ++ list_add(&vm->global_link, &dev_priv->vm_list); ++} ++ + void + i915_gem_load(struct drm_device *dev) + { +@@ -4346,8 +4356,9 @@ i915_gem_load(struct drm_device *dev) + SLAB_HWCACHE_ALIGN, + NULL); + +- INIT_LIST_HEAD(&dev_priv->gtt.base.active_list); +- INIT_LIST_HEAD(&dev_priv->gtt.base.inactive_list); ++ INIT_LIST_HEAD(&dev_priv->vm_list); ++ i915_init_vm(dev_priv, &dev_priv->gtt.base); ++ + INIT_LIST_HEAD(&dev_priv->mm.unbound_list); + INIT_LIST_HEAD(&dev_priv->mm.bound_list); + INIT_LIST_HEAD(&dev_priv->mm.fence_list); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0573-drm-i915-Rework-drop-caches-for-checkpatch.patch b/patches.baytrail/0573-drm-i915-Rework-drop-caches-for-checkpatch.patch new file mode 100644 index 000000000000..76b358eab649 --- /dev/null +++ b/patches.baytrail/0573-drm-i915-Rework-drop-caches-for-checkpatch.patch @@ -0,0 +1,48 @@ +From 21ed6373813736ade99edab76808d6c611757a08 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 16:59:55 -0700 +Subject: drm/i915: Rework drop caches for checkpatch + +With an upcoming change to bind, to make checkpatch happy and keep the +code clean, we need to rework this code a bit. + +This should have no functional impact. + +Signed-off-by: Ben Widawsky +[danvet: Add the newline Chris requested.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 31a46c9c092afc6558e7be7eaa42eb9bd4d3de8b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index eed2f4ca9a76..04debcedac2d 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1784,12 +1784,14 @@ i915_drop_caches_set(void *data, u64 val) + + if (val & DROP_BOUND) { + list_for_each_entry_safe(obj, next, &vm->inactive_list, +- mm_list) +- if (obj->pin_count == 0) { +- ret = i915_gem_object_unbind(obj); +- if (ret) +- goto unlock; +- } ++ mm_list) { ++ if (obj->pin_count) ++ continue; ++ ++ ret = i915_gem_object_unbind(obj); ++ if (ret) ++ goto unlock; ++ } + } + + if (val & DROP_UNBOUND) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0574-drm-i915-Make-proper-functions-for-VMs.patch b/patches.baytrail/0574-drm-i915-Make-proper-functions-for-VMs.patch new file mode 100644 index 000000000000..2af190e5e1c3 --- /dev/null +++ b/patches.baytrail/0574-drm-i915-Make-proper-functions-for-VMs.patch @@ -0,0 +1,283 @@ +From 57f6bf0985349cc6e143765725575c1776e0883a Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 16:59:56 -0700 +Subject: drm/i915: Make proper functions for VMs + +Earlier in the conversion sequence we attempted to quickly wedge in the +transitional interface as static inlines. + +Now that we're sure these interfaces are sane, for easier debug and to +decrease code size (since many of these functions may be called quite a +bit), make them real functions + +While at it, kill off the set_color interface. We'll always have the +VMA, or easily get to it. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit a70a3148b0c61cb7c588ea650db785b261b378a3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 83 ++++++++++++++++------------------- + drivers/gpu/drm/i915/i915_gem.c | 78 ++++++++++++++++++++++++++++++-- + drivers/gpu/drm/i915/i915_gem_evict.c | 8 ++-- + drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- + 4 files changed, 118 insertions(+), 53 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index bb7d0ba5589b..5fe98c572ba3 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1393,52 +1393,6 @@ struct drm_i915_gem_object { + + #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) + +-/* This is a temporary define to help transition us to real VMAs. If you see +- * this, you're either reviewing code, or bisecting it. */ +-static inline struct i915_vma * +-__i915_gem_obj_to_vma(struct drm_i915_gem_object *obj) +-{ +- if (list_empty(&obj->vma_list)) +- return NULL; +- return list_first_entry(&obj->vma_list, struct i915_vma, vma_link); +-} +- +-/* Whether or not this object is currently mapped by the translation tables */ +-static inline bool +-i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *o) +-{ +- struct i915_vma *vma = __i915_gem_obj_to_vma(o); +- if (vma == NULL) +- return false; +- return drm_mm_node_allocated(&vma->node); +-} +- +-/* Offset of the first PTE pointing to this object */ +-static inline unsigned long +-i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o) +-{ +- BUG_ON(list_empty(&o->vma_list)); +- return __i915_gem_obj_to_vma(o)->node.start; +-} +- +-/* The size used in the translation tables may be larger than the actual size of +- * the object on GEN2/GEN3 because of the way tiling is handled. See +- * i915_gem_get_gtt_size() for more details. +- */ +-static inline unsigned long +-i915_gem_obj_ggtt_size(struct drm_i915_gem_object *o) +-{ +- BUG_ON(list_empty(&o->vma_list)); +- return __i915_gem_obj_to_vma(o)->node.size; +-} +- +-static inline void +-i915_gem_obj_ggtt_set_color(struct drm_i915_gem_object *o, +- enum i915_cache_level color) +-{ +- __i915_gem_obj_to_vma(o)->node.color = color; +-} +- + /** + * Request queue structure. + * +@@ -1907,6 +1861,43 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev, + + void i915_gem_restore_fences(struct drm_device *dev); + ++unsigned long i915_gem_obj_offset(struct drm_i915_gem_object *o, ++ struct i915_address_space *vm); ++bool i915_gem_obj_bound_any(struct drm_i915_gem_object *o); ++bool i915_gem_obj_bound(struct drm_i915_gem_object *o, ++ struct i915_address_space *vm); ++unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o, ++ struct i915_address_space *vm); ++struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, ++ struct i915_address_space *vm); ++/* Some GGTT VM helpers */ ++#define obj_to_ggtt(obj) \ ++ (&((struct drm_i915_private *)(obj)->base.dev->dev_private)->gtt.base) ++static inline bool i915_is_ggtt(struct i915_address_space *vm) ++{ ++ struct i915_address_space *ggtt = ++ &((struct drm_i915_private *)(vm)->dev->dev_private)->gtt.base; ++ return vm == ggtt; ++} ++ ++static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj) ++{ ++ return i915_gem_obj_bound(obj, obj_to_ggtt(obj)); ++} ++ ++static inline unsigned long ++i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *obj) ++{ ++ return i915_gem_obj_offset(obj, obj_to_ggtt(obj)); ++} ++ ++static inline unsigned long ++i915_gem_obj_ggtt_size(struct drm_i915_gem_object *obj) ++{ ++ return i915_gem_obj_size(obj, obj_to_ggtt(obj)); ++} ++#undef obj_to_ggtt ++ + /* i915_gem_context.c */ + void i915_gem_context_init(struct drm_device *dev); + void i915_gem_context_fini(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 8f9ee89ed971..f99fffb61b8a 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2625,7 +2625,7 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) + /* Avoid an unnecessary call to unbind on rebind. */ + obj->map_and_fenceable = true; + +- vma = __i915_gem_obj_to_vma(obj); ++ vma = i915_gem_obj_to_vma(obj, &dev_priv->gtt.base); + list_del(&vma->vma_link); + drm_mm_remove_node(&vma->node); + i915_gem_vma_destroy(vma); +@@ -3313,7 +3313,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + { + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; +- struct i915_vma *vma = __i915_gem_obj_to_vma(obj); ++ struct i915_vma *vma = i915_gem_obj_to_vma(obj, &dev_priv->gtt.base); + int ret; + + if (obj->cache_level == cache_level) +@@ -3353,7 +3353,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt, + obj, cache_level); + +- i915_gem_obj_ggtt_set_color(obj, cache_level); ++ i915_gem_obj_to_vma(obj, &dev_priv->gtt.base)->node.color = cache_level; + } + + if (cache_level == I915_CACHE_NONE) { +@@ -4666,3 +4666,75 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) + mutex_unlock(&dev->struct_mutex); + return cnt; + } ++ ++/* All the new VM stuff */ ++unsigned long i915_gem_obj_offset(struct drm_i915_gem_object *o, ++ struct i915_address_space *vm) ++{ ++ struct drm_i915_private *dev_priv = o->base.dev->dev_private; ++ struct i915_vma *vma; ++ ++ if (vm == &dev_priv->mm.aliasing_ppgtt->base) ++ vm = &dev_priv->gtt.base; ++ ++ BUG_ON(list_empty(&o->vma_list)); ++ list_for_each_entry(vma, &o->vma_list, vma_link) { ++ if (vma->vm == vm) ++ return vma->node.start; ++ ++ } ++ return -1; ++} ++ ++bool i915_gem_obj_bound(struct drm_i915_gem_object *o, ++ struct i915_address_space *vm) ++{ ++ struct i915_vma *vma; ++ ++ list_for_each_entry(vma, &o->vma_list, vma_link) ++ if (vma->vm == vm) ++ return true; ++ ++ return false; ++} ++ ++bool i915_gem_obj_bound_any(struct drm_i915_gem_object *o) ++{ ++ struct drm_i915_private *dev_priv = o->base.dev->dev_private; ++ struct i915_address_space *vm; ++ ++ list_for_each_entry(vm, &dev_priv->vm_list, global_link) ++ if (i915_gem_obj_bound(o, vm)) ++ return true; ++ ++ return false; ++} ++ ++unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o, ++ struct i915_address_space *vm) ++{ ++ struct drm_i915_private *dev_priv = o->base.dev->dev_private; ++ struct i915_vma *vma; ++ ++ if (vm == &dev_priv->mm.aliasing_ppgtt->base) ++ vm = &dev_priv->gtt.base; ++ ++ BUG_ON(list_empty(&o->vma_list)); ++ ++ list_for_each_entry(vma, &o->vma_list, vma_link) ++ if (vma->vm == vm) ++ return vma->node.size; ++ ++ return 0; ++} ++ ++struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, ++ struct i915_address_space *vm) ++{ ++ struct i915_vma *vma; ++ list_for_each_entry(vma, &obj->vma_list, vma_link) ++ if (vma->vm == vm) ++ return vma; ++ ++ return NULL; ++} +diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c +index df61f338dea1..33d85a4447a6 100644 +--- a/drivers/gpu/drm/i915/i915_gem_evict.c ++++ b/drivers/gpu/drm/i915/i915_gem_evict.c +@@ -34,7 +34,9 @@ + static bool + mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind) + { +- struct i915_vma *vma = __i915_gem_obj_to_vma(obj); ++ struct drm_device *dev = obj->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct i915_vma *vma = i915_gem_obj_to_vma(obj, &dev_priv->gtt.base); + + if (obj->pin_count) + return false; +@@ -109,7 +111,7 @@ none: + obj = list_first_entry(&unwind_list, + struct drm_i915_gem_object, + exec_list); +- vma = __i915_gem_obj_to_vma(obj); ++ vma = i915_gem_obj_to_vma(obj, &dev_priv->gtt.base); + ret = drm_mm_scan_remove_block(&vma->node); + BUG_ON(ret); + +@@ -130,7 +132,7 @@ found: + obj = list_first_entry(&unwind_list, + struct drm_i915_gem_object, + exec_list); +- vma = __i915_gem_obj_to_vma(obj); ++ vma = i915_gem_obj_to_vma(obj, &dev_priv->gtt.base); + if (drm_mm_scan_remove_block(&vma->node)) { + list_move(&obj->exec_list, &eviction_list); + drm_gem_object_reference(&obj->base); +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 3e7f1242af91..90a276e35909 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -657,7 +657,7 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + + /* Mark any preallocated objects as occupied */ + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { +- struct i915_vma *vma = __i915_gem_obj_to_vma(obj); ++ struct i915_vma *vma = i915_gem_obj_to_vma(obj, &dev_priv->gtt.base); + int ret; + DRM_DEBUG_KMS("reserving preallocated space: %lx + %zx\n", + i915_gem_obj_ggtt_offset(obj), obj->base.size); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0575-drm-i915-Use-bound-list-for-inactive-shrink.patch b/patches.baytrail/0575-drm-i915-Use-bound-list-for-inactive-shrink.patch new file mode 100644 index 000000000000..7ff2c8b913b8 --- /dev/null +++ b/patches.baytrail/0575-drm-i915-Use-bound-list-for-inactive-shrink.patch @@ -0,0 +1,51 @@ +From 815cd2437d7f2b92b87d70c4dc2f28fb4c69430d Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 16:59:57 -0700 +Subject: drm/i915: Use bound list for inactive shrink + +Do to the move active/inactive lists, it no longer makes sense to use +them for shrinking, since shrinking isn't VM specific (such a need may +also exist, but doesn't yet). + +What we can do instead is use the global bound list to find all objects +which aren't active. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit fcb4a57805e04dee04f736c25a5648ec7bebe30f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index f99fffb61b8a..c7e0db1ff8f5 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -4629,7 +4629,6 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) + struct drm_i915_private, + mm.inactive_shrinker); + struct drm_device *dev = dev_priv->dev; +- struct i915_address_space *vm = &dev_priv->gtt.base; + struct drm_i915_gem_object *obj; + int nr_to_scan = sc->nr_to_scan; + bool unlock = true; +@@ -4658,9 +4657,14 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) + list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) + if (obj->pages_pin_count == 0) + cnt += obj->base.size >> PAGE_SHIFT; +- list_for_each_entry(obj, &vm->inactive_list, mm_list) ++ ++ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { ++ if (obj->active) ++ continue; ++ + if (obj->pin_count == 0 && obj->pages_pin_count == 0) + cnt += obj->base.size >> PAGE_SHIFT; ++ } + + if (unlock) + mutex_unlock(&dev->struct_mutex); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0576-drm-i915-Add-VM-to-pin.patch b/patches.baytrail/0576-drm-i915-Add-VM-to-pin.patch new file mode 100644 index 000000000000..fb50be8799d8 --- /dev/null +++ b/patches.baytrail/0576-drm-i915-Add-VM-to-pin.patch @@ -0,0 +1,211 @@ +From 1895dade01f62a6396dd2f4735ef61d26785fda0 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 16:59:58 -0700 +Subject: drm/i915: Add VM to pin + +To verbalize it, one can say, "pin an object into the given address +space." The semantics of pinning remain the same otherwise. + +Certain objects will always have to be bound into the global GTT. +Therefore, global GTT is a special case, and keep a special interface +around for it (i915_gem_obj_ggtt_pin). + +v2: s/i915_gem_ggtt_pin/i915_gem_obj_ggtt_pin + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit c37e22046148971a35a89931aa1f951bb99d5514) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 11 +++++++++++ + drivers/gpu/drm/i915/i915_gem.c | 9 +++++---- + drivers/gpu/drm/i915/i915_gem_context.c | 4 ++-- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 +++- + drivers/gpu/drm/i915/intel_overlay.c | 2 +- + drivers/gpu/drm/i915/intel_pm.c | 2 +- + drivers/gpu/drm/i915/intel_ringbuffer.c | 8 ++++---- + 7 files changed, 27 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 5fe98c572ba3..356970c9368a 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1711,6 +1711,7 @@ struct i915_vma *i915_gem_vma_create(struct drm_i915_gem_object *obj, + void i915_gem_vma_destroy(struct i915_vma *vma); + + int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, ++ struct i915_address_space *vm, + uint32_t alignment, + bool map_and_fenceable, + bool nonblocking); +@@ -1896,6 +1897,16 @@ i915_gem_obj_ggtt_size(struct drm_i915_gem_object *obj) + { + return i915_gem_obj_size(obj, obj_to_ggtt(obj)); + } ++ ++static inline int __must_check ++i915_gem_obj_ggtt_pin(struct drm_i915_gem_object *obj, ++ uint32_t alignment, ++ bool map_and_fenceable, ++ bool nonblocking) ++{ ++ return i915_gem_object_pin(obj, obj_to_ggtt(obj), alignment, ++ map_and_fenceable, nonblocking); ++} + #undef obj_to_ggtt + + /* i915_gem_context.c */ +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index c7e0db1ff8f5..d2d1d58ff3d0 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -593,7 +593,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, + char __user *user_data; + int page_offset, page_length, ret; + +- ret = i915_gem_object_pin(obj, 0, true, true); ++ ret = i915_gem_obj_ggtt_pin(obj, 0, true, true); + if (ret) + goto out; + +@@ -1347,7 +1347,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + } + + /* Now bind it into the GTT if needed */ +- ret = i915_gem_object_pin(obj, 0, true, false); ++ ret = i915_gem_obj_ggtt_pin(obj, 0, true, false); + if (ret) + goto unlock; + +@@ -3482,7 +3482,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, + * (e.g. libkms for the bootup splash), we have to ensure that we + * always use map_and_fenceable for all scanout buffers. + */ +- ret = i915_gem_object_pin(obj, alignment, true, false); ++ ret = i915_gem_obj_ggtt_pin(obj, alignment, true, false); + if (ret) + return ret; + +@@ -3625,6 +3625,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) + + int + i915_gem_object_pin(struct drm_i915_gem_object *obj, ++ struct i915_address_space *vm, + uint32_t alignment, + bool map_and_fenceable, + bool nonblocking) +@@ -3714,7 +3715,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, + } + + if (obj->user_pin_count == 0) { +- ret = i915_gem_object_pin(obj, args->alignment, true, false); ++ ret = i915_gem_obj_ggtt_pin(obj, args->alignment, true, false); + if (ret) + goto out; + } +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index 2470206a4d07..d1cb28cbc71e 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -214,7 +214,7 @@ static int create_default_context(struct drm_i915_private *dev_priv) + * default context. + */ + dev_priv->ring[RCS].default_context = ctx; +- ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false, false); ++ ret = i915_gem_obj_ggtt_pin(ctx->obj, CONTEXT_ALIGN, false, false); + if (ret) { + DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret); + goto err_destroy; +@@ -400,7 +400,7 @@ static int do_switch(struct i915_hw_context *to) + if (from == to) + return 0; + +- ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false, false); ++ ret = i915_gem_obj_ggtt_pin(to->obj, CONTEXT_ALIGN, false, false); + if (ret) + return ret; + +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 5b6d764e9bb2..7addab31783f 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -409,7 +409,9 @@ i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj, + obj->tiling_mode != I915_TILING_NONE; + need_mappable = need_fence || need_reloc_mappable(obj); + +- ret = i915_gem_object_pin(obj, entry->alignment, need_mappable, false); ++ /* FIXME: vm plubming */ ++ ret = i915_gem_object_pin(obj, &dev_priv->gtt.base, entry->alignment, ++ need_mappable, false); + if (ret) + return ret; + +diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c +index 9ec5a4e12af2..ddfd0aefe0c0 100644 +--- a/drivers/gpu/drm/i915/intel_overlay.c ++++ b/drivers/gpu/drm/i915/intel_overlay.c +@@ -1352,7 +1352,7 @@ void intel_setup_overlay(struct drm_device *dev) + } + overlay->flip_addr = reg_bo->phys_obj->handle->busaddr; + } else { +- ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true, false); ++ ret = i915_gem_obj_ggtt_pin(reg_bo, PAGE_SIZE, true, false); + if (ret) { + DRM_ERROR("failed to pin overlay register bo\n"); + goto out_free_bo; +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 03fa8656155d..af4ca44bbad2 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2886,7 +2886,7 @@ intel_alloc_context_page(struct drm_device *dev) + return NULL; + } + +- ret = i915_gem_object_pin(ctx, 4096, true, false); ++ ret = i915_gem_obj_ggtt_pin(ctx, 4096, true, false); + if (ret) { + DRM_ERROR("failed to pin power context: %d\n", ret); + goto err_unref; +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index bc78c794ae81..89a9c908c99d 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -501,7 +501,7 @@ init_pipe_control(struct intel_ring_buffer *ring) + + i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); + +- ret = i915_gem_object_pin(obj, 4096, true, false); ++ ret = i915_gem_obj_ggtt_pin(obj, 4096, true, false); + if (ret) + goto err_unref; + +@@ -1236,7 +1236,7 @@ static int init_status_page(struct intel_ring_buffer *ring) + + i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); + +- ret = i915_gem_object_pin(obj, 4096, true, false); ++ ret = i915_gem_obj_ggtt_pin(obj, 4096, true, false); + if (ret != 0) { + goto err_unref; + } +@@ -1319,7 +1319,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, + + ring->obj = obj; + +- ret = i915_gem_object_pin(obj, PAGE_SIZE, true, false); ++ ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, true, false); + if (ret) + goto err_unref; + +@@ -1840,7 +1840,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) + return -ENOMEM; + } + +- ret = i915_gem_object_pin(obj, 0, true, false); ++ ret = i915_gem_obj_ggtt_pin(obj, 0, true, false); + if (ret != 0) { + drm_gem_object_unreference(&obj->base); + DRM_ERROR("Failed to ping batch bo\n"); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0577-drm-i915-Use-ggtt_vm-to-save-some-typing.patch b/patches.baytrail/0577-drm-i915-Use-ggtt_vm-to-save-some-typing.patch new file mode 100644 index 000000000000..c59a9f56b8a6 --- /dev/null +++ b/patches.baytrail/0577-drm-i915-Use-ggtt_vm-to-save-some-typing.patch @@ -0,0 +1,122 @@ +From fa7f50823f9bb75a1e7239eb785370c6f098e5cd Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 16:59:59 -0700 +Subject: drm/i915: Use ggtt_vm to save some typing + +Just some small cleanups, and a rename of vm->ggtt_vm requested by +Daniel. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 40d74980d3ada5ad76e333dfcc87645f3f7e9820) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_gtt.c | 19 ++++++++----------- + drivers/gpu/drm/i915/i915_gem_stolen.c | 10 +++++----- + 2 files changed, 13 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 90a276e35909..f38cc696be7f 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -643,7 +643,8 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + * aperture. One page should be enough to keep any prefetching inside + * of the aperture. + */ +- drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct i915_address_space *ggtt_vm = &dev_priv->gtt.base; + struct drm_mm_node *entry; + struct drm_i915_gem_object *obj; + unsigned long hole_start, hole_end; +@@ -651,19 +652,19 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + BUG_ON(mappable_end > end); + + /* Subtract the guard page ... */ +- drm_mm_init(&dev_priv->gtt.base.mm, start, end - start - PAGE_SIZE); ++ drm_mm_init(&ggtt_vm->mm, start, end - start - PAGE_SIZE); + if (!HAS_LLC(dev)) + dev_priv->gtt.base.mm.color_adjust = i915_gtt_color_adjust; + + /* Mark any preallocated objects as occupied */ + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { +- struct i915_vma *vma = i915_gem_obj_to_vma(obj, &dev_priv->gtt.base); ++ struct i915_vma *vma = i915_gem_obj_to_vma(obj, ggtt_vm); + int ret; + DRM_DEBUG_KMS("reserving preallocated space: %lx + %zx\n", + i915_gem_obj_ggtt_offset(obj), obj->base.size); + + WARN_ON(i915_gem_obj_ggtt_bound(obj)); +- ret = drm_mm_reserve_node(&dev_priv->gtt.base.mm, &vma->node); ++ ret = drm_mm_reserve_node(&ggtt_vm->mm, &vma->node); + if (ret) + DRM_DEBUG_KMS("Reservation failed\n"); + obj->has_global_gtt_mapping = 1; +@@ -674,19 +675,15 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, + dev_priv->gtt.base.total = end - start; + + /* Clear any non-preallocated blocks */ +- drm_mm_for_each_hole(entry, &dev_priv->gtt.base.mm, +- hole_start, hole_end) { ++ drm_mm_for_each_hole(entry, &ggtt_vm->mm, hole_start, hole_end) { + const unsigned long count = (hole_end - hole_start) / PAGE_SIZE; + DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", + hole_start, hole_end); +- dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, +- hole_start / PAGE_SIZE, +- count); ++ ggtt_vm->clear_range(ggtt_vm, hole_start / PAGE_SIZE, count); + } + + /* And finally clear the reserved guard page */ +- dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, +- end / PAGE_SIZE - 1, 1); ++ ggtt_vm->clear_range(ggtt_vm, end / PAGE_SIZE - 1, 1); + } + + static bool +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index cacf769c95fd..5531643136f5 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -331,7 +331,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + u32 size) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- struct i915_address_space *vm = &dev_priv->gtt.base; ++ struct i915_address_space *ggtt = &dev_priv->gtt.base; + struct drm_i915_gem_object *obj; + struct drm_mm_node *stolen; + struct i915_vma *vma; +@@ -374,7 +374,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + if (gtt_offset == I915_GTT_OFFSET_NONE) + return obj; + +- vma = i915_gem_vma_create(obj, &dev_priv->gtt.base); ++ vma = i915_gem_vma_create(obj, ggtt); + if (IS_ERR(vma)) { + ret = PTR_ERR(vma); + goto err_out; +@@ -387,8 +387,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + */ + vma->node.start = gtt_offset; + vma->node.size = size; +- if (drm_mm_initialized(&dev_priv->gtt.base.mm)) { +- ret = drm_mm_reserve_node(&dev_priv->gtt.base.mm, &vma->node); ++ if (drm_mm_initialized(&ggtt->mm)) { ++ ret = drm_mm_reserve_node(&ggtt->mm, &vma->node); + if (ret) { + DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); + i915_gem_vma_destroy(vma); +@@ -399,7 +399,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + obj->has_global_gtt_mapping = 1; + + list_add_tail(&obj->global_list, &dev_priv->mm.bound_list); +- list_add_tail(&obj->mm_list, &vm->inactive_list); ++ list_add_tail(&obj->mm_list, &ggtt->inactive_list); + + return obj; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0578-drm-i915-Update-describe_obj.patch b/patches.baytrail/0578-drm-i915-Update-describe_obj.patch new file mode 100644 index 000000000000..863c8970addd --- /dev/null +++ b/patches.baytrail/0578-drm-i915-Update-describe_obj.patch @@ -0,0 +1,68 @@ +From 34004cbab5bb27341c7fedc250e77a2f9e76e9c2 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:00 -0700 +Subject: drm/i915: Update describe_obj + +Make it aware of which domain it is bound into GGTT, or PPGTT. + +While modifying the function, add a global gtt flag to the object +description. Global is more interesting than aliasing since aliasing is +the default. + +v2: Access VMA directly for start/size instead of helpers (Daniel) + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 1d693bcc37461a66fafd13ff171c4496aee0df98) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 04debcedac2d..748af58b0cea 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -89,13 +89,20 @@ static const char *get_tiling_flag(struct drm_i915_gem_object *obj) + } + } + ++static inline const char *get_global_flag(struct drm_i915_gem_object *obj) ++{ ++ return obj->has_global_gtt_mapping ? "g" : " "; ++} ++ + static void + describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) + { +- seq_printf(m, "%pK: %s%s %8zdKiB %02x %02x %d %d %d%s%s%s", ++ struct i915_vma *vma; ++ seq_printf(m, "%pK: %s%s%s %8zdKiB %02x %02x %d %d %d%s%s%s", + &obj->base, + get_pin_flag(obj), + get_tiling_flag(obj), ++ get_global_flag(obj), + obj->base.size / 1024, + obj->base.read_domains, + obj->base.write_domain, +@@ -111,9 +118,14 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) + seq_printf(m, " (pinned x %d)", obj->pin_count); + if (obj->fence_reg != I915_FENCE_REG_NONE) + seq_printf(m, " (fence: %d)", obj->fence_reg); +- if (i915_gem_obj_ggtt_bound(obj)) +- seq_printf(m, " (gtt offset: %08lx, size: %08x)", +- i915_gem_obj_ggtt_offset(obj), (unsigned int)i915_gem_obj_ggtt_size(obj)); ++ list_for_each_entry(vma, &obj->vma_list, vma_link) { ++ if (!i915_is_ggtt(vma->vm)) ++ seq_puts(m, " (pp"); ++ else ++ seq_puts(m, " (g"); ++ seq_printf(m, "gtt offset: %08lx, size: %08lx)", ++ vma->node.start, vma->node.size); ++ } + if (obj->stolen) + seq_printf(m, " (stolen: %08lx)", obj->stolen->start); + if (obj->pin_mappable || obj->fault_mappable) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0579-drm-i915-thread-address-space-through-execbuf.patch b/patches.baytrail/0579-drm-i915-thread-address-space-through-execbuf.patch new file mode 100644 index 000000000000..65395c767b0f --- /dev/null +++ b/patches.baytrail/0579-drm-i915-thread-address-space-through-execbuf.patch @@ -0,0 +1,302 @@ +From df38f653b5913040aa286a391a3b3ab7964e6eb6 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:02 -0700 +Subject: drm/i915: thread address space through execbuf + +This represents the first half of hooking up VMs to execbuf. Here we +basically pass an address space all around to the different internal +functions. It should be much more readable, and have less risk than the +second half, which begins switching over to using VMAs instead of an +obj,vm. + +The overall series echoes this style of, "add a VM, then make it smart +later" + +Signed-off-by: Ben Widawsky +[danvet: Switch a BUG_ON to WARN_ON.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 28d6a7bfa2560cb94727a68511ed68561e84dcc8) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 77 +++++++++++++++++++----------- + 1 file changed, 49 insertions(+), 28 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 7addab31783f..9939d2ef3ea9 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -174,7 +174,8 @@ static inline int use_cpu_reloc(struct drm_i915_gem_object *obj) + static int + i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, + struct eb_objects *eb, +- struct drm_i915_gem_relocation_entry *reloc) ++ struct drm_i915_gem_relocation_entry *reloc, ++ struct i915_address_space *vm) + { + struct drm_device *dev = obj->base.dev; + struct drm_gem_object *target_obj; +@@ -297,7 +298,8 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, + + static int + i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, +- struct eb_objects *eb) ++ struct eb_objects *eb, ++ struct i915_address_space *vm) + { + #define N_RELOC(x) ((x) / sizeof(struct drm_i915_gem_relocation_entry)) + struct drm_i915_gem_relocation_entry stack_reloc[N_RELOC(512)]; +@@ -321,7 +323,8 @@ i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, + do { + u64 offset = r->presumed_offset; + +- ret = i915_gem_execbuffer_relocate_entry(obj, eb, r); ++ ret = i915_gem_execbuffer_relocate_entry(obj, eb, r, ++ vm); + if (ret) + return ret; + +@@ -344,13 +347,15 @@ i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, + static int + i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, + struct eb_objects *eb, +- struct drm_i915_gem_relocation_entry *relocs) ++ struct drm_i915_gem_relocation_entry *relocs, ++ struct i915_address_space *vm) + { + const struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; + int i, ret; + + for (i = 0; i < entry->relocation_count; i++) { +- ret = i915_gem_execbuffer_relocate_entry(obj, eb, &relocs[i]); ++ ret = i915_gem_execbuffer_relocate_entry(obj, eb, &relocs[i], ++ vm); + if (ret) + return ret; + } +@@ -359,7 +364,8 @@ i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, + } + + static int +-i915_gem_execbuffer_relocate(struct eb_objects *eb) ++i915_gem_execbuffer_relocate(struct eb_objects *eb, ++ struct i915_address_space *vm) + { + struct drm_i915_gem_object *obj; + int ret = 0; +@@ -373,7 +379,7 @@ i915_gem_execbuffer_relocate(struct eb_objects *eb) + */ + pagefault_disable(); + list_for_each_entry(obj, &eb->objects, exec_list) { +- ret = i915_gem_execbuffer_relocate_object(obj, eb); ++ ret = i915_gem_execbuffer_relocate_object(obj, eb, vm); + if (ret) + break; + } +@@ -395,6 +401,7 @@ need_reloc_mappable(struct drm_i915_gem_object *obj) + static int + i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *ring, ++ struct i915_address_space *vm, + bool *need_reloc) + { + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; +@@ -409,9 +416,8 @@ i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj, + obj->tiling_mode != I915_TILING_NONE; + need_mappable = need_fence || need_reloc_mappable(obj); + +- /* FIXME: vm plubming */ +- ret = i915_gem_object_pin(obj, &dev_priv->gtt.base, entry->alignment, +- need_mappable, false); ++ ret = i915_gem_object_pin(obj, vm, entry->alignment, need_mappable, ++ false); + if (ret) + return ret; + +@@ -438,8 +444,8 @@ i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj, + obj->has_aliasing_ppgtt_mapping = 1; + } + +- if (entry->offset != i915_gem_obj_ggtt_offset(obj)) { +- entry->offset = i915_gem_obj_ggtt_offset(obj); ++ if (entry->offset != i915_gem_obj_offset(obj, vm)) { ++ entry->offset = i915_gem_obj_offset(obj, vm); + *need_reloc = true; + } + +@@ -477,6 +483,7 @@ i915_gem_execbuffer_unreserve_object(struct drm_i915_gem_object *obj) + static int + i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, + struct list_head *objects, ++ struct i915_address_space *vm, + bool *need_relocs) + { + struct drm_i915_gem_object *obj; +@@ -531,32 +538,37 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, + list_for_each_entry(obj, objects, exec_list) { + struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; + bool need_fence, need_mappable; ++ u32 obj_offset; + +- if (!i915_gem_obj_ggtt_bound(obj)) ++ if (!i915_gem_obj_bound(obj, vm)) + continue; + ++ obj_offset = i915_gem_obj_offset(obj, vm); + need_fence = + has_fenced_gpu_access && + entry->flags & EXEC_OBJECT_NEEDS_FENCE && + obj->tiling_mode != I915_TILING_NONE; + need_mappable = need_fence || need_reloc_mappable(obj); + ++ WARN_ON((need_mappable || need_fence) && ++ !i915_is_ggtt(vm)); ++ + if ((entry->alignment && +- i915_gem_obj_ggtt_offset(obj) & (entry->alignment - 1)) || ++ obj_offset & (entry->alignment - 1)) || + (need_mappable && !obj->map_and_fenceable)) + ret = i915_gem_object_unbind(obj); + else +- ret = i915_gem_execbuffer_reserve_object(obj, ring, need_relocs); ++ ret = i915_gem_execbuffer_reserve_object(obj, ring, vm, need_relocs); + if (ret) + goto err; + } + + /* Bind fresh objects */ + list_for_each_entry(obj, objects, exec_list) { +- if (i915_gem_obj_ggtt_bound(obj)) ++ if (i915_gem_obj_bound(obj, vm)) + continue; + +- ret = i915_gem_execbuffer_reserve_object(obj, ring, need_relocs); ++ ret = i915_gem_execbuffer_reserve_object(obj, ring, vm, need_relocs); + if (ret) + goto err; + } +@@ -580,7 +592,8 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, + struct drm_file *file, + struct intel_ring_buffer *ring, + struct eb_objects *eb, +- struct drm_i915_gem_exec_object2 *exec) ++ struct drm_i915_gem_exec_object2 *exec, ++ struct i915_address_space *vm) + { + struct drm_i915_gem_relocation_entry *reloc; + struct drm_i915_gem_object *obj; +@@ -664,14 +677,15 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, + goto err; + + need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; +- ret = i915_gem_execbuffer_reserve(ring, &eb->objects, &need_relocs); ++ ret = i915_gem_execbuffer_reserve(ring, &eb->objects, vm, &need_relocs); + if (ret) + goto err; + + list_for_each_entry(obj, &eb->objects, exec_list) { + int offset = obj->exec_entry - exec; + ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, +- reloc + reloc_offset[offset]); ++ reloc + reloc_offset[offset], ++ vm); + if (ret) + goto err; + } +@@ -772,6 +786,7 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, + + static void + i915_gem_execbuffer_move_to_active(struct list_head *objects, ++ struct i915_address_space *vm, + struct intel_ring_buffer *ring) + { + struct drm_i915_gem_object *obj; +@@ -840,7 +855,8 @@ static int + i915_gem_do_execbuffer(struct drm_device *dev, void *data, + struct drm_file *file, + struct drm_i915_gem_execbuffer2 *args, +- struct drm_i915_gem_exec_object2 *exec) ++ struct drm_i915_gem_exec_object2 *exec, ++ struct i915_address_space *vm) + { + drm_i915_private_t *dev_priv = dev->dev_private; + struct eb_objects *eb; +@@ -1002,17 +1018,17 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + + /* Move the objects en-masse into the GTT, evicting if necessary. */ + need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; +- ret = i915_gem_execbuffer_reserve(ring, &eb->objects, &need_relocs); ++ ret = i915_gem_execbuffer_reserve(ring, &eb->objects, vm, &need_relocs); + if (ret) + goto err; + + /* The objects are in their final locations, apply the relocations. */ + if (need_relocs) +- ret = i915_gem_execbuffer_relocate(eb); ++ ret = i915_gem_execbuffer_relocate(eb, vm); + if (ret) { + if (ret == -EFAULT) { + ret = i915_gem_execbuffer_relocate_slow(dev, args, file, ring, +- eb, exec); ++ eb, exec, vm); + BUG_ON(!mutex_is_locked(&dev->struct_mutex)); + } + if (ret) +@@ -1063,7 +1079,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + goto err; + } + +- exec_start = i915_gem_obj_ggtt_offset(batch_obj) + args->batch_start_offset; ++ exec_start = i915_gem_obj_offset(batch_obj, vm) + ++ args->batch_start_offset; + exec_len = args->batch_len; + if (cliprects) { + for (i = 0; i < args->num_cliprects; i++) { +@@ -1088,7 +1105,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + + trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags); + +- i915_gem_execbuffer_move_to_active(&eb->objects, ring); ++ i915_gem_execbuffer_move_to_active(&eb->objects, vm, ring); + i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj); + + err: +@@ -1109,6 +1126,7 @@ int + i915_gem_execbuffer(struct drm_device *dev, void *data, + struct drm_file *file) + { ++ struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_execbuffer *args = data; + struct drm_i915_gem_execbuffer2 exec2; + struct drm_i915_gem_exec_object *exec_list = NULL; +@@ -1164,7 +1182,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, + exec2.flags = I915_EXEC_RENDER; + i915_execbuffer2_set_context_id(exec2, 0); + +- ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list); ++ ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list, ++ &dev_priv->gtt.base); + if (!ret) { + /* Copy the new buffer offsets back to the user's exec list. */ + for (i = 0; i < args->buffer_count; i++) +@@ -1190,6 +1209,7 @@ int + i915_gem_execbuffer2(struct drm_device *dev, void *data, + struct drm_file *file) + { ++ struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_execbuffer2 *args = data; + struct drm_i915_gem_exec_object2 *exec2_list = NULL; + int ret; +@@ -1220,7 +1240,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, + return -EFAULT; + } + +- ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list); ++ ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list, ++ &dev_priv->gtt.base); + if (!ret) { + /* Copy the new buffer offsets back to the user's exec list. */ + ret = copy_to_user(to_user_ptr(args->buffers_ptr), +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0580-drm-i915-make-caching-operate-on-all-address-spaces.patch b/patches.baytrail/0580-drm-i915-make-caching-operate-on-all-address-spaces.patch new file mode 100644 index 000000000000..b17fd2341504 --- /dev/null +++ b/patches.baytrail/0580-drm-i915-make-caching-operate-on-all-address-spaces.patch @@ -0,0 +1,77 @@ +From 65fa56208d00a95516844c70b9a6f5ee00446823 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:03 -0700 +Subject: drm/i915: make caching operate on all address spaces + +For now, objects will maintain the same cache levels amongst all address +spaces. This is to limit the risk of bugs, as playing with cacheability +in the different domains can be very error prone. + +In the future, it may be optimal to allow setting domains per VMA (ie. +an object bound into an address space). + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 3089c6f239d7d2c4cb2dd5c353e8984cf79af1d7) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index d2d1d58ff3d0..fd8fc1b8a28e 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3313,7 +3313,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + { + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; +- struct i915_vma *vma = i915_gem_obj_to_vma(obj, &dev_priv->gtt.base); ++ struct i915_vma *vma; + int ret; + + if (obj->cache_level == cache_level) +@@ -3324,13 +3324,17 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + return -EBUSY; + } + +- if (vma && !i915_gem_valid_gtt_space(dev, &vma->node, cache_level)) { +- ret = i915_gem_object_unbind(obj); +- if (ret) +- return ret; ++ list_for_each_entry(vma, &obj->vma_list, vma_link) { ++ if (!i915_gem_valid_gtt_space(dev, &vma->node, cache_level)) { ++ ret = i915_gem_object_unbind(obj); ++ if (ret) ++ return ret; ++ ++ break; ++ } + } + +- if (i915_gem_obj_ggtt_bound(obj)) { ++ if (i915_gem_obj_bound_any(obj)) { + ret = i915_gem_object_finish_gpu(obj); + if (ret) + return ret; +@@ -3352,8 +3356,6 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + if (obj->has_aliasing_ppgtt_mapping) + i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt, + obj, cache_level); +- +- i915_gem_obj_to_vma(obj, &dev_priv->gtt.base)->node.color = cache_level; + } + + if (cache_level == I915_CACHE_NONE) { +@@ -3379,6 +3381,8 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + old_write_domain); + } + ++ list_for_each_entry(vma, &obj->vma_list, vma_link) ++ vma->node.color = cache_level; + obj->cache_level = cache_level; + i915_gem_verify_gtt(dev); + return 0; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0581-drm-i915-BUG_ON-put_pages-later.patch b/patches.baytrail/0581-drm-i915-BUG_ON-put_pages-later.patch new file mode 100644 index 000000000000..bd5a04351068 --- /dev/null +++ b/patches.baytrail/0581-drm-i915-BUG_ON-put_pages-later.patch @@ -0,0 +1,42 @@ +From c89b8524afc1a3badf10bcd2192e200f434c2fa4 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:04 -0700 +Subject: drm/i915: BUG_ON put_pages later + +With multiple VMs, the eviction code benefits from being able to blindly +put pages without needing to know if there are any entities still +holding on to those pages. As such it's preferable to return the -EBUSY +before the BUG. + +Eviction code is the only user for now, but overall it makes sense +anyway, IMO. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 3e12302705a961cfe86d52155b4a8cbb34214748) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index fd8fc1b8a28e..17b17170b348 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -1662,11 +1662,11 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj) + if (obj->pages == NULL) + return 0; + +- BUG_ON(i915_gem_obj_ggtt_bound(obj)); +- + if (obj->pages_pin_count) + return -EBUSY; + ++ BUG_ON(i915_gem_obj_ggtt_bound(obj)); ++ + /* ->put_pages might need to allocate memory for the bit17 swizzle + * array, hence protect them from being reaped by removing them from gtt + * lists early. */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0582-drm-i915-make-reset-hangcheck-code-VM-aware.patch b/patches.baytrail/0582-drm-i915-make-reset-hangcheck-code-VM-aware.patch new file mode 100644 index 000000000000..f26d5531db2c --- /dev/null +++ b/patches.baytrail/0582-drm-i915-make-reset-hangcheck-code-VM-aware.patch @@ -0,0 +1,98 @@ +From bc22ce70e3fdd9236e9aa84480a91bacce7cc367 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:05 -0700 +Subject: drm/i915: make reset&hangcheck code VM aware + +Hangcheck, and some of the recent reset code for guilty batches need to +know which address space the object was in at the time of a hangcheck. +This is because we use offsets in the (PP|G)GTT to determine this +information, and those offsets can differ depending on which VM they are +bound into. + +Since we still only have 1 VM ever, this code shouldn't yet have any +impact. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit d1ccbb5d711ba4994eb36c4aac84e0269b5365fe) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 30 +++++++++++++++++++++++------- + 1 file changed, 23 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 17b17170b348..bd6eb646d541 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2113,10 +2113,11 @@ i915_gem_request_remove_from_client(struct drm_i915_gem_request *request) + spin_unlock(&file_priv->mm.lock); + } + +-static bool i915_head_inside_object(u32 acthd, struct drm_i915_gem_object *obj) ++static bool i915_head_inside_object(u32 acthd, struct drm_i915_gem_object *obj, ++ struct i915_address_space *vm) + { +- if (acthd >= i915_gem_obj_ggtt_offset(obj) && +- acthd < i915_gem_obj_ggtt_offset(obj) + obj->base.size) ++ if (acthd >= i915_gem_obj_offset(obj, vm) && ++ acthd < i915_gem_obj_offset(obj, vm) + obj->base.size) + return true; + + return false; +@@ -2139,6 +2140,17 @@ static bool i915_head_inside_request(const u32 acthd_unmasked, + return false; + } + ++static struct i915_address_space * ++request_to_vm(struct drm_i915_gem_request *request) ++{ ++ struct drm_i915_private *dev_priv = request->ring->dev->dev_private; ++ struct i915_address_space *vm; ++ ++ vm = &dev_priv->gtt.base; ++ ++ return vm; ++} ++ + static bool i915_request_guilty(struct drm_i915_gem_request *request, + const u32 acthd, bool *inside) + { +@@ -2146,9 +2158,9 @@ static bool i915_request_guilty(struct drm_i915_gem_request *request, + * pointing inside the ring, matches the batch_obj address range. + * However this is extremely unlikely. + */ +- + if (request->batch_obj) { +- if (i915_head_inside_object(acthd, request->batch_obj)) { ++ if (i915_head_inside_object(acthd, request->batch_obj, ++ request_to_vm(request))) { + *inside = true; + return true; + } +@@ -2168,17 +2180,21 @@ static void i915_set_reset_status(struct intel_ring_buffer *ring, + { + struct i915_ctx_hang_stats *hs = NULL; + bool inside, guilty; ++ unsigned long offset = 0; + + /* Innocent until proven guilty */ + guilty = false; + ++ if (request->batch_obj) ++ offset = i915_gem_obj_offset(request->batch_obj, ++ request_to_vm(request)); ++ + if (ring->hangcheck.action != wait && + i915_request_guilty(request, acthd, &inside)) { + DRM_ERROR("%s hung %s bo (0x%lx ctx %d) at 0x%x\n", + ring->name, + inside ? "inside" : "flushing", +- request->batch_obj ? +- i915_gem_obj_ggtt_offset(request->batch_obj) : 0, ++ offset, + request->ctx ? request->ctx->id : 0, + acthd); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0583-drm-i915-Add-ILK-support-to-intel_read_wm_latency.patch b/patches.baytrail/0583-drm-i915-Add-ILK-support-to-intel_read_wm_latency.patch new file mode 100644 index 000000000000..5ab06e6620b7 --- /dev/null +++ b/patches.baytrail/0583-drm-i915-Add-ILK-support-to-intel_read_wm_latency.patch @@ -0,0 +1,43 @@ +From 7d8cdee45c7c79cef8c022bc1fc12bc1b7144336 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Thu, 1 Aug 2013 16:18:49 +0300 +Subject: drm/i915: Add ILK support to intel_read_wm_latency +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +ILK has a slightly different way to read out the watermark +latency values. On ILK the LP0 latenciy values are in fact +not stored in any register, and instead we must use fixed +values. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 3a88d0ac809a7fff315b2404559d90d8e74c716c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index af4ca44bbad2..568511ffb87f 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2372,6 +2372,13 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5]) + wm[1] = (sskpd >> SSKPD_WM1_SHIFT) & SSKPD_WM_MASK; + wm[2] = (sskpd >> SSKPD_WM2_SHIFT) & SSKPD_WM_MASK; + wm[3] = (sskpd >> SSKPD_WM3_SHIFT) & SSKPD_WM_MASK; ++ } else if (INTEL_INFO(dev)->gen >= 5) { ++ uint32_t mltr = I915_READ(MLTR_ILK); ++ ++ /* ILK primary LP0 latency is 700 ns */ ++ wm[0] = 7; ++ wm[1] = (mltr >> MLTR_WM1_SHIFT) & ILK_SRLT_MASK; ++ wm[2] = (mltr >> MLTR_WM2_SHIFT) & ILK_SRLT_MASK; + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0584-drm-i915-Store-the-watermark-latency-values-in-dev_p.patch b/patches.baytrail/0584-drm-i915-Store-the-watermark-latency-values-in-dev_p.patch new file mode 100644 index 000000000000..3ac061e3194d --- /dev/null +++ b/patches.baytrail/0584-drm-i915-Store-the-watermark-latency-values-in-dev_p.patch @@ -0,0 +1,169 @@ +From a99efa21bd1147e3170bf705f9081d440d83397a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Thu, 1 Aug 2013 16:18:50 +0300 +Subject: drm/i915: Store the watermark latency values in dev_priv +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Rather than having to read the latency values out every time, just +store them in dev_priv. + +On ILK and IVB there is a difference between some of the latency +values for different planes, so store the latency values for each +plane type separately, and apply the necesary fixups during init. + +v2: Fix some checkpatch complaints + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 53615a5e129534fa161e882fc3c1c4f269166b76) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 14 ++++++++++ + drivers/gpu/drm/i915/intel_pm.c | 62 +++++++++++++++++++++++++++++++++++------ + 2 files changed, 67 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 356970c9368a..ec7692cb2726 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1216,6 +1216,20 @@ typedef struct drm_i915_private { + + struct i915_suspend_saved_registers regfile; + ++ struct { ++ /* ++ * Raw watermark latency values: ++ * in 0.1us units for WM0, ++ * in 0.5us units for WM1+. ++ */ ++ /* primary */ ++ uint16_t pri_latency[5]; ++ /* sprite */ ++ uint16_t spr_latency[5]; ++ /* cursor */ ++ uint16_t cur_latency[5]; ++ } wm; ++ + /* Old dri1 support infrastructure, beware the dragons ya fools entering + * here! */ + struct i915_dri1_state dri1; +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 568511ffb87f..306f4dc46a6f 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2382,6 +2382,39 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[5]) + } + } + ++static void intel_fixup_spr_wm_latency(struct drm_device *dev, uint16_t wm[5]) ++{ ++ /* ILK sprite LP0 latency is 1300 ns */ ++ if (INTEL_INFO(dev)->gen == 5) ++ wm[0] = 13; ++} ++ ++static void intel_fixup_cur_wm_latency(struct drm_device *dev, uint16_t wm[5]) ++{ ++ /* ILK cursor LP0 latency is 1300 ns */ ++ if (INTEL_INFO(dev)->gen == 5) ++ wm[0] = 13; ++ ++ /* WaDoubleCursorLP3Latency:ivb */ ++ if (IS_IVYBRIDGE(dev)) ++ wm[3] *= 2; ++} ++ ++static void intel_setup_wm_latency(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ intel_read_wm_latency(dev, dev_priv->wm.pri_latency); ++ ++ memcpy(dev_priv->wm.spr_latency, dev_priv->wm.pri_latency, ++ sizeof(dev_priv->wm.pri_latency)); ++ memcpy(dev_priv->wm.cur_latency, dev_priv->wm.pri_latency, ++ sizeof(dev_priv->wm.pri_latency)); ++ ++ intel_fixup_spr_wm_latency(dev, dev_priv->wm.spr_latency); ++ intel_fixup_cur_wm_latency(dev, dev_priv->wm.cur_latency); ++} ++ + static void hsw_compute_wm_parameters(struct drm_device *dev, + struct hsw_pipe_wm_parameters *params, + struct hsw_wm_maximums *lp_max_1_2, +@@ -2627,16 +2660,17 @@ static void haswell_update_wm(struct drm_device *dev) + struct hsw_wm_maximums lp_max_1_2, lp_max_5_6; + struct hsw_pipe_wm_parameters params[3]; + struct hsw_wm_values results_1_2, results_5_6, *best_results; +- uint16_t wm[5] = {}; + enum hsw_data_buf_partitioning partitioning; + +- intel_read_wm_latency(dev, wm); + hsw_compute_wm_parameters(dev, params, &lp_max_1_2, &lp_max_5_6); + +- hsw_compute_wm_results(dev, params, wm, &lp_max_1_2, &results_1_2); ++ hsw_compute_wm_results(dev, params, ++ dev_priv->wm.pri_latency, ++ &lp_max_1_2, &results_1_2); + if (lp_max_1_2.pri != lp_max_5_6.pri) { +- hsw_compute_wm_results(dev, params, wm, &lp_max_5_6, +- &results_5_6); ++ hsw_compute_wm_results(dev, params, ++ dev_priv->wm.pri_latency, ++ &lp_max_5_6, &results_5_6); + best_results = hsw_find_best_result(&results_1_2, &results_5_6); + } else { + best_results = &results_1_2; +@@ -5247,8 +5281,12 @@ void intel_init_pm(struct drm_device *dev) + + /* For FIFO watermark updates */ + if (HAS_PCH_SPLIT(dev)) { ++ intel_setup_wm_latency(dev); ++ + if (IS_GEN5(dev)) { +- if (I915_READ(MLTR_ILK) & ILK_SRLT_MASK) ++ if (dev_priv->wm.pri_latency[1] && ++ dev_priv->wm.spr_latency[1] && ++ dev_priv->wm.cur_latency[1]) + dev_priv->display.update_wm = ironlake_update_wm; + else { + DRM_DEBUG_KMS("Failed to get proper latency. " +@@ -5257,7 +5295,9 @@ void intel_init_pm(struct drm_device *dev) + } + dev_priv->display.init_clock_gating = ironlake_init_clock_gating; + } else if (IS_GEN6(dev)) { +- if (SNB_READ_WM0_LATENCY()) { ++ if (dev_priv->wm.pri_latency[0] && ++ dev_priv->wm.spr_latency[0] && ++ dev_priv->wm.cur_latency[0]) { + dev_priv->display.update_wm = sandybridge_update_wm; + dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; + } else { +@@ -5267,7 +5307,9 @@ void intel_init_pm(struct drm_device *dev) + } + dev_priv->display.init_clock_gating = gen6_init_clock_gating; + } else if (IS_IVYBRIDGE(dev)) { +- if (SNB_READ_WM0_LATENCY()) { ++ if (dev_priv->wm.pri_latency[0] && ++ dev_priv->wm.spr_latency[0] && ++ dev_priv->wm.cur_latency[0]) { + dev_priv->display.update_wm = ivybridge_update_wm; + dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; + } else { +@@ -5277,7 +5319,9 @@ void intel_init_pm(struct drm_device *dev) + } + dev_priv->display.init_clock_gating = ivybridge_init_clock_gating; + } else if (IS_HASWELL(dev)) { +- if (I915_READ64(MCH_SSKPD)) { ++ if (dev_priv->wm.pri_latency[0] && ++ dev_priv->wm.spr_latency[0] && ++ dev_priv->wm.cur_latency[0]) { + dev_priv->display.update_wm = haswell_update_wm; + dev_priv->display.update_sprite_wm = + haswell_update_sprite_wm; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0585-drm-i915-Use-the-stored-cursor-and-plane-latencies-p.patch b/patches.baytrail/0585-drm-i915-Use-the-stored-cursor-and-plane-latencies-p.patch new file mode 100644 index 000000000000..329d5798b4fc --- /dev/null +++ b/patches.baytrail/0585-drm-i915-Use-the-stored-cursor-and-plane-latencies-p.patch @@ -0,0 +1,122 @@ +From 1c68768406c569198fc0c08e316a13561487f999 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Thu, 1 Aug 2013 16:18:51 +0300 +Subject: drm/i915: Use the stored cursor and plane latencies properly +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Rather than pass around the plane latencies, just grab them from +dev_priv nearer to where they're needed. Do the same for cursor +latencies. + +v2: Add some comments about latency units + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 5b77da33c11b72d703382a93c402544186c7721e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 36 +++++++++++++++++++++--------------- + 1 file changed, 21 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 306f4dc46a6f..2839bdb25b98 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2270,7 +2270,8 @@ static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params, + params->pri_bytes_per_pixel); + } + +-static bool hsw_compute_lp_wm(uint32_t mem_value, struct hsw_wm_maximums *max, ++static bool hsw_compute_lp_wm(struct drm_i915_private *dev_priv, ++ int level, struct hsw_wm_maximums *max, + struct hsw_pipe_wm_parameters *params, + struct hsw_lp_wm_result *result) + { +@@ -2279,10 +2280,14 @@ static bool hsw_compute_lp_wm(uint32_t mem_value, struct hsw_wm_maximums *max, + + for (pipe = PIPE_A; pipe <= PIPE_C; pipe++) { + struct hsw_pipe_wm_parameters *p = ¶ms[pipe]; +- +- pri_val[pipe] = ilk_compute_pri_wm(p, mem_value, true); +- spr_val[pipe] = ilk_compute_spr_wm(p, mem_value); +- cur_val[pipe] = ilk_compute_cur_wm(p, mem_value); ++ /* WM1+ latency values stored in 0.5us units */ ++ uint16_t pri_latency = dev_priv->wm.pri_latency[level] * 5; ++ uint16_t spr_latency = dev_priv->wm.spr_latency[level] * 5; ++ uint16_t cur_latency = dev_priv->wm.cur_latency[level] * 5; ++ ++ pri_val[pipe] = ilk_compute_pri_wm(p, pri_latency, true); ++ spr_val[pipe] = ilk_compute_spr_wm(p, spr_latency); ++ cur_val[pipe] = ilk_compute_cur_wm(p, cur_latency); + fbc_val[pipe] = ilk_compute_fbc_wm(p, pri_val[pipe]); + } + +@@ -2305,14 +2310,18 @@ static bool hsw_compute_lp_wm(uint32_t mem_value, struct hsw_wm_maximums *max, + } + + static uint32_t hsw_compute_wm_pipe(struct drm_i915_private *dev_priv, +- uint32_t mem_value, enum pipe pipe, ++ enum pipe pipe, + struct hsw_pipe_wm_parameters *params) + { + uint32_t pri_val, cur_val, spr_val; ++ /* WM0 latency values stored in 0.1us units */ ++ uint16_t pri_latency = dev_priv->wm.pri_latency[0]; ++ uint16_t spr_latency = dev_priv->wm.spr_latency[0]; ++ uint16_t cur_latency = dev_priv->wm.cur_latency[0]; + +- pri_val = ilk_compute_pri_wm(params, mem_value, false); +- spr_val = ilk_compute_spr_wm(params, mem_value); +- cur_val = ilk_compute_cur_wm(params, mem_value); ++ pri_val = ilk_compute_pri_wm(params, pri_latency, false); ++ spr_val = ilk_compute_spr_wm(params, spr_latency); ++ cur_val = ilk_compute_cur_wm(params, cur_latency); + + WARN(pri_val > 127, + "Primary WM error, mode not supported for pipe %c\n", +@@ -2478,7 +2487,6 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, + + static void hsw_compute_wm_results(struct drm_device *dev, + struct hsw_pipe_wm_parameters *params, +- uint16_t *wm, + struct hsw_wm_maximums *lp_maximums, + struct hsw_wm_values *results) + { +@@ -2489,7 +2497,8 @@ static void hsw_compute_wm_results(struct drm_device *dev, + int level, max_level, wm_lp; + + for (level = 1; level <= 4; level++) +- if (!hsw_compute_lp_wm(wm[level] * 5, lp_maximums, params, ++ if (!hsw_compute_lp_wm(dev_priv, level, ++ lp_maximums, params, + &lp_results[level - 1])) + break; + max_level = level - 1; +@@ -2521,8 +2530,7 @@ static void hsw_compute_wm_results(struct drm_device *dev, + } + + for_each_pipe(pipe) +- results->wm_pipe[pipe] = hsw_compute_wm_pipe(dev_priv, wm[0], +- pipe, ++ results->wm_pipe[pipe] = hsw_compute_wm_pipe(dev_priv, pipe, + ¶ms[pipe]); + + for_each_pipe(pipe) { +@@ -2665,11 +2673,9 @@ static void haswell_update_wm(struct drm_device *dev) + hsw_compute_wm_parameters(dev, params, &lp_max_1_2, &lp_max_5_6); + + hsw_compute_wm_results(dev, params, +- dev_priv->wm.pri_latency, + &lp_max_1_2, &results_1_2); + if (lp_max_1_2.pri != lp_max_5_6.pri) { + hsw_compute_wm_results(dev, params, +- dev_priv->wm.pri_latency, + &lp_max_5_6, &results_5_6); + best_results = hsw_find_best_result(&results_1_2, &results_5_6); + } else { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0586-drm-i915-Print-the-watermark-latencies-during-init.patch b/patches.baytrail/0586-drm-i915-Print-the-watermark-latencies-during-init.patch new file mode 100644 index 000000000000..9e2412fe62ad --- /dev/null +++ b/patches.baytrail/0586-drm-i915-Print-the-watermark-latencies-during-init.patch @@ -0,0 +1,86 @@ +From 3015ca6aea97ff0ddcf6e072a32c4724d4b61825 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Thu, 1 Aug 2013 16:18:52 +0300 +Subject: drm/i915: Print the watermark latencies during init +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Seeing the watermark latency values in dmesg might help sometimes. + +v2: Use DRM_ERROR() when expected latency values are missing + +Note: We might hit the DRM_ERROR added in this patch and apparently +there's not much we can do about that. But I think it'd be interesting +to figure out whether that actually happens in the real world, so I +didn't apply a s/DRM_ERROR/DRM_DEBUG_KMS/ bikeshed while applying. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +[danvet: Add note about new error dmesg output.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 26ec971e302c53b44cc5627ffe209a7d33199e28) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 2839bdb25b98..76bd4de232e1 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2409,6 +2409,39 @@ static void intel_fixup_cur_wm_latency(struct drm_device *dev, uint16_t wm[5]) + wm[3] *= 2; + } + ++static void intel_print_wm_latency(struct drm_device *dev, ++ const char *name, ++ const uint16_t wm[5]) ++{ ++ int level, max_level; ++ ++ /* how many WM levels are we expecting */ ++ if (IS_HASWELL(dev)) ++ max_level = 4; ++ else if (INTEL_INFO(dev)->gen >= 6) ++ max_level = 3; ++ else ++ max_level = 2; ++ ++ for (level = 0; level <= max_level; level++) { ++ unsigned int latency = wm[level]; ++ ++ if (latency == 0) { ++ DRM_ERROR("%s WM%d latency not provided\n", ++ name, level); ++ continue; ++ } ++ ++ /* WM1+ latency values in 0.5us units */ ++ if (level > 0) ++ latency *= 5; ++ ++ DRM_DEBUG_KMS("%s WM%d latency %u (%u.%u usec)\n", ++ name, level, wm[level], ++ latency / 10, latency % 10); ++ } ++} ++ + static void intel_setup_wm_latency(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -2422,6 +2455,10 @@ static void intel_setup_wm_latency(struct drm_device *dev) + + intel_fixup_spr_wm_latency(dev, dev_priv->wm.spr_latency); + intel_fixup_cur_wm_latency(dev, dev_priv->wm.cur_latency); ++ ++ intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency); ++ intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency); ++ intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency); + } + + static void hsw_compute_wm_parameters(struct drm_device *dev, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0587-drm-i915-Disable-specific-watermark-levels-when-late.patch b/patches.baytrail/0587-drm-i915-Disable-specific-watermark-levels-when-late.patch new file mode 100644 index 000000000000..658d7ecf3bf6 --- /dev/null +++ b/patches.baytrail/0587-drm-i915-Disable-specific-watermark-levels-when-late.patch @@ -0,0 +1,53 @@ +From 31c3a7f61f43a4cf229e4f6168c8cc70c6ecfef9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Thu, 1 Aug 2013 16:18:53 +0300 +Subject: drm/i915: Disable specific watermark levels when latency is zero +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Return UINT_MAX for the calculated WM level if the latency is zero. +This will lead to marking the WM level as disabled. + +I'm not sure if latency==0 should mean that we want to disable the +level. But that's the implication I got from the fact that we don't +even enable the watermark code of the SSKDP register is 0. + +v2: Use WARN() to scare people + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 3312ba65caa23cf1210cc578755babc394769843) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 76bd4de232e1..42f541671236 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2131,6 +2131,9 @@ static uint32_t ilk_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel, + { + uint64_t ret; + ++ if (WARN(latency == 0, "Latency value missing\n")) ++ return UINT_MAX; ++ + ret = (uint64_t) pixel_rate * bytes_per_pixel * latency; + ret = DIV_ROUND_UP_ULL(ret, 64 * 10000) + 2; + +@@ -2143,6 +2146,9 @@ static uint32_t ilk_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, + { + uint32_t ret; + ++ if (WARN(latency == 0, "Latency value missing\n")) ++ return UINT_MAX; ++ + ret = (latency * pixel_rate) / (pipe_htotal * 10000); + ret = (ret + 1) * horiz_pixels * bytes_per_pixel; + ret = DIV_ROUND_UP(ret, 64) + 2; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0588-drm-i915-Use-the-watermark-latency-values-from-dev_p.patch b/patches.baytrail/0588-drm-i915-Use-the-watermark-latency-values-from-dev_p.patch new file mode 100644 index 000000000000..e4804cd46049 --- /dev/null +++ b/patches.baytrail/0588-drm-i915-Use-the-watermark-latency-values-from-dev_p.patch @@ -0,0 +1,290 @@ +From 12cd878fcf1ecfd90c34df36a7a69a3037da4577 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Thu, 1 Aug 2013 16:18:54 +0300 +Subject: drm/i915: Use the watermark latency values from dev_priv for + ILK/SNB/IVB too +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Adjust the current ILK/SNB/IVB watermark codepaths to use the +pre-populated latency values from dev_priv instead of reading +them out from the registers every time. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit b0aea5dca064176a626dc2a83727c60ace31ee6d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 9 ------- + drivers/gpu/drm/i915/intel_pm.c | 57 +++++++++++++++++++---------------------- + 2 files changed, 27 insertions(+), 39 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 615d66717016..11800316799f 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -3204,9 +3204,6 @@ + #define MLTR_WM2_SHIFT 8 + /* the unit of memory self-refresh latency time is 0.5us */ + #define ILK_SRLT_MASK 0x3f +-#define ILK_LATENCY(shift) (I915_READ(MLTR_ILK) >> (shift) & ILK_SRLT_MASK) +-#define ILK_READ_WM1_LATENCY() ILK_LATENCY(MLTR_WM1_SHIFT) +-#define ILK_READ_WM2_LATENCY() ILK_LATENCY(MLTR_WM2_SHIFT) + + /* define the fifo size on Ironlake */ + #define ILK_DISPLAY_FIFO 128 +@@ -3253,12 +3250,6 @@ + #define SSKPD_WM2_SHIFT 16 + #define SSKPD_WM3_SHIFT 24 + +-#define SNB_LATENCY(shift) (I915_READ(MCHBAR_MIRROR_BASE_SNB + SSKPD) >> (shift) & SSKPD_WM_MASK) +-#define SNB_READ_WM0_LATENCY() SNB_LATENCY(SSKPD_WM0_SHIFT) +-#define SNB_READ_WM1_LATENCY() SNB_LATENCY(SSKPD_WM1_SHIFT) +-#define SNB_READ_WM2_LATENCY() SNB_LATENCY(SSKPD_WM2_SHIFT) +-#define SNB_READ_WM3_LATENCY() SNB_LATENCY(SSKPD_WM3_SHIFT) +- + /* + * The two pipe frame counter registers are not synchronized, so + * reading a stable value is somewhat tricky. The following code +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 42f541671236..0254e620ba05 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -1680,9 +1680,6 @@ static void i830_update_wm(struct drm_device *dev) + I915_WRITE(FW_BLC, fwater_lo); + } + +-#define ILK_LP0_PLANE_LATENCY 700 +-#define ILK_LP0_CURSOR_LATENCY 1300 +- + /* + * Check the wm result. + * +@@ -1797,9 +1794,9 @@ static void ironlake_update_wm(struct drm_device *dev) + enabled = 0; + if (g4x_compute_wm0(dev, PIPE_A, + &ironlake_display_wm_info, +- ILK_LP0_PLANE_LATENCY, ++ dev_priv->wm.pri_latency[0] * 100, + &ironlake_cursor_wm_info, +- ILK_LP0_CURSOR_LATENCY, ++ dev_priv->wm.cur_latency[0] * 100, + &plane_wm, &cursor_wm)) { + I915_WRITE(WM0_PIPEA_ILK, + (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); +@@ -1811,9 +1808,9 @@ static void ironlake_update_wm(struct drm_device *dev) + + if (g4x_compute_wm0(dev, PIPE_B, + &ironlake_display_wm_info, +- ILK_LP0_PLANE_LATENCY, ++ dev_priv->wm.pri_latency[0] * 100, + &ironlake_cursor_wm_info, +- ILK_LP0_CURSOR_LATENCY, ++ dev_priv->wm.cur_latency[0] * 100, + &plane_wm, &cursor_wm)) { + I915_WRITE(WM0_PIPEB_ILK, + (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); +@@ -1837,7 +1834,7 @@ static void ironlake_update_wm(struct drm_device *dev) + + /* WM1 */ + if (!ironlake_compute_srwm(dev, 1, enabled, +- ILK_READ_WM1_LATENCY() * 500, ++ dev_priv->wm.pri_latency[1] * 500, + &ironlake_display_srwm_info, + &ironlake_cursor_srwm_info, + &fbc_wm, &plane_wm, &cursor_wm)) +@@ -1845,14 +1842,14 @@ static void ironlake_update_wm(struct drm_device *dev) + + I915_WRITE(WM1_LP_ILK, + WM1_LP_SR_EN | +- (ILK_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | ++ (dev_priv->wm.pri_latency[1] << WM1_LP_LATENCY_SHIFT) | + (fbc_wm << WM1_LP_FBC_SHIFT) | + (plane_wm << WM1_LP_SR_SHIFT) | + cursor_wm); + + /* WM2 */ + if (!ironlake_compute_srwm(dev, 2, enabled, +- ILK_READ_WM2_LATENCY() * 500, ++ dev_priv->wm.pri_latency[2] * 500, + &ironlake_display_srwm_info, + &ironlake_cursor_srwm_info, + &fbc_wm, &plane_wm, &cursor_wm)) +@@ -1860,7 +1857,7 @@ static void ironlake_update_wm(struct drm_device *dev) + + I915_WRITE(WM2_LP_ILK, + WM2_LP_EN | +- (ILK_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | ++ (dev_priv->wm.pri_latency[2] << WM1_LP_LATENCY_SHIFT) | + (fbc_wm << WM1_LP_FBC_SHIFT) | + (plane_wm << WM1_LP_SR_SHIFT) | + cursor_wm); +@@ -1874,7 +1871,7 @@ static void ironlake_update_wm(struct drm_device *dev) + static void sandybridge_update_wm(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ ++ int latency = dev_priv->wm.pri_latency[0] * 100; /* In unit 0.1us */ + u32 val; + int fbc_wm, plane_wm, cursor_wm; + unsigned int enabled; +@@ -1929,7 +1926,7 @@ static void sandybridge_update_wm(struct drm_device *dev) + + /* WM1 */ + if (!ironlake_compute_srwm(dev, 1, enabled, +- SNB_READ_WM1_LATENCY() * 500, ++ dev_priv->wm.pri_latency[1] * 500, + &sandybridge_display_srwm_info, + &sandybridge_cursor_srwm_info, + &fbc_wm, &plane_wm, &cursor_wm)) +@@ -1937,14 +1934,14 @@ static void sandybridge_update_wm(struct drm_device *dev) + + I915_WRITE(WM1_LP_ILK, + WM1_LP_SR_EN | +- (SNB_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | ++ (dev_priv->wm.pri_latency[1] << WM1_LP_LATENCY_SHIFT) | + (fbc_wm << WM1_LP_FBC_SHIFT) | + (plane_wm << WM1_LP_SR_SHIFT) | + cursor_wm); + + /* WM2 */ + if (!ironlake_compute_srwm(dev, 2, enabled, +- SNB_READ_WM2_LATENCY() * 500, ++ dev_priv->wm.pri_latency[2] * 500, + &sandybridge_display_srwm_info, + &sandybridge_cursor_srwm_info, + &fbc_wm, &plane_wm, &cursor_wm)) +@@ -1952,14 +1949,14 @@ static void sandybridge_update_wm(struct drm_device *dev) + + I915_WRITE(WM2_LP_ILK, + WM2_LP_EN | +- (SNB_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | ++ (dev_priv->wm.pri_latency[2] << WM1_LP_LATENCY_SHIFT) | + (fbc_wm << WM1_LP_FBC_SHIFT) | + (plane_wm << WM1_LP_SR_SHIFT) | + cursor_wm); + + /* WM3 */ + if (!ironlake_compute_srwm(dev, 3, enabled, +- SNB_READ_WM3_LATENCY() * 500, ++ dev_priv->wm.pri_latency[3] * 500, + &sandybridge_display_srwm_info, + &sandybridge_cursor_srwm_info, + &fbc_wm, &plane_wm, &cursor_wm)) +@@ -1967,7 +1964,7 @@ static void sandybridge_update_wm(struct drm_device *dev) + + I915_WRITE(WM3_LP_ILK, + WM3_LP_EN | +- (SNB_READ_WM3_LATENCY() << WM1_LP_LATENCY_SHIFT) | ++ (dev_priv->wm.pri_latency[3] << WM1_LP_LATENCY_SHIFT) | + (fbc_wm << WM1_LP_FBC_SHIFT) | + (plane_wm << WM1_LP_SR_SHIFT) | + cursor_wm); +@@ -1976,7 +1973,7 @@ static void sandybridge_update_wm(struct drm_device *dev) + static void ivybridge_update_wm(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ ++ int latency = dev_priv->wm.pri_latency[0] * 100; /* In unit 0.1us */ + u32 val; + int fbc_wm, plane_wm, cursor_wm; + int ignore_fbc_wm, ignore_plane_wm, ignore_cursor_wm; +@@ -2046,7 +2043,7 @@ static void ivybridge_update_wm(struct drm_device *dev) + + /* WM1 */ + if (!ironlake_compute_srwm(dev, 1, enabled, +- SNB_READ_WM1_LATENCY() * 500, ++ dev_priv->wm.pri_latency[1] * 500, + &sandybridge_display_srwm_info, + &sandybridge_cursor_srwm_info, + &fbc_wm, &plane_wm, &cursor_wm)) +@@ -2054,14 +2051,14 @@ static void ivybridge_update_wm(struct drm_device *dev) + + I915_WRITE(WM1_LP_ILK, + WM1_LP_SR_EN | +- (SNB_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | ++ (dev_priv->wm.pri_latency[1] << WM1_LP_LATENCY_SHIFT) | + (fbc_wm << WM1_LP_FBC_SHIFT) | + (plane_wm << WM1_LP_SR_SHIFT) | + cursor_wm); + + /* WM2 */ + if (!ironlake_compute_srwm(dev, 2, enabled, +- SNB_READ_WM2_LATENCY() * 500, ++ dev_priv->wm.pri_latency[2] * 500, + &sandybridge_display_srwm_info, + &sandybridge_cursor_srwm_info, + &fbc_wm, &plane_wm, &cursor_wm)) +@@ -2069,19 +2066,19 @@ static void ivybridge_update_wm(struct drm_device *dev) + + I915_WRITE(WM2_LP_ILK, + WM2_LP_EN | +- (SNB_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | ++ (dev_priv->wm.pri_latency[2] << WM1_LP_LATENCY_SHIFT) | + (fbc_wm << WM1_LP_FBC_SHIFT) | + (plane_wm << WM1_LP_SR_SHIFT) | + cursor_wm); + + /* WM3, note we have to correct the cursor latency */ + if (!ironlake_compute_srwm(dev, 3, enabled, +- SNB_READ_WM3_LATENCY() * 500, ++ dev_priv->wm.pri_latency[3] * 500, + &sandybridge_display_srwm_info, + &sandybridge_cursor_srwm_info, + &fbc_wm, &plane_wm, &ignore_cursor_wm) || + !ironlake_compute_srwm(dev, 3, enabled, +- 2 * SNB_READ_WM3_LATENCY() * 500, ++ dev_priv->wm.cur_latency[3] * 500, + &sandybridge_display_srwm_info, + &sandybridge_cursor_srwm_info, + &ignore_fbc_wm, &ignore_plane_wm, &cursor_wm)) +@@ -2089,7 +2086,7 @@ static void ivybridge_update_wm(struct drm_device *dev) + + I915_WRITE(WM3_LP_ILK, + WM3_LP_EN | +- (SNB_READ_WM3_LATENCY() << WM1_LP_LATENCY_SHIFT) | ++ (dev_priv->wm.pri_latency[3] << WM1_LP_LATENCY_SHIFT) | + (fbc_wm << WM1_LP_FBC_SHIFT) | + (plane_wm << WM1_LP_SR_SHIFT) | + cursor_wm); +@@ -2833,7 +2830,7 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, + bool enable, bool scaled) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ ++ int latency = dev_priv->wm.spr_latency[0] * 100; /* In unit 0.1us */ + u32 val; + int sprite_wm, reg; + int ret; +@@ -2873,7 +2870,7 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, + ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, + pixel_size, + &sandybridge_display_srwm_info, +- SNB_READ_WM1_LATENCY() * 500, ++ dev_priv->wm.spr_latency[1] * 500, + &sprite_wm); + if (!ret) { + DRM_DEBUG_KMS("failed to compute sprite lp1 wm on pipe %c\n", +@@ -2889,7 +2886,7 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, + ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, + pixel_size, + &sandybridge_display_srwm_info, +- SNB_READ_WM2_LATENCY() * 500, ++ dev_priv->wm.spr_latency[2] * 500, + &sprite_wm); + if (!ret) { + DRM_DEBUG_KMS("failed to compute sprite lp2 wm on pipe %c\n", +@@ -2901,7 +2898,7 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, + ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, + pixel_size, + &sandybridge_display_srwm_info, +- SNB_READ_WM3_LATENCY() * 500, ++ dev_priv->wm.spr_latency[3] * 500, + &sprite_wm); + if (!ret) { + DRM_DEBUG_KMS("failed to compute sprite lp3 wm on pipe %c\n", +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0589-drm-i915-Add-comments-about-units-of-latency-values.patch b/patches.baytrail/0589-drm-i915-Add-comments-about-units-of-latency-values.patch new file mode 100644 index 000000000000..f0fdb3a00835 --- /dev/null +++ b/patches.baytrail/0589-drm-i915-Add-comments-about-units-of-latency-values.patch @@ -0,0 +1,79 @@ +From e0f086d4869ed927b4eb22ac0bc4e385944e7cf7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Thu, 1 Aug 2013 16:18:55 +0300 +Subject: drm/i915: Add comments about units of latency values +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +All the ILK+ WM compute functions take the latency values in 0.1us +units. Add a few comments to remind people about that. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 37126462a4feadeb3ff08c4b308a28e4db8c83a7) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 0254e620ba05..9b8c90ea81ff 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2123,6 +2123,7 @@ static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev, + return pixel_rate; + } + ++/* latency must be in 0.1us units. */ + static uint32_t ilk_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel, + uint32_t latency) + { +@@ -2137,6 +2138,7 @@ static uint32_t ilk_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel, + return ret; + } + ++/* latency must be in 0.1us units. */ + static uint32_t ilk_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, + uint32_t horiz_pixels, uint8_t bytes_per_pixel, + uint32_t latency) +@@ -2200,7 +2202,10 @@ enum hsw_data_buf_partitioning { + HSW_DATA_BUF_PART_5_6, + }; + +-/* For both WM_PIPE and WM_LP. */ ++/* ++ * For both WM_PIPE and WM_LP. ++ * mem_value must be in 0.1us units. ++ */ + static uint32_t ilk_compute_pri_wm(struct hsw_pipe_wm_parameters *params, + uint32_t mem_value, + bool is_lp) +@@ -2227,7 +2232,10 @@ static uint32_t ilk_compute_pri_wm(struct hsw_pipe_wm_parameters *params, + return min(method1, method2); + } + +-/* For both WM_PIPE and WM_LP. */ ++/* ++ * For both WM_PIPE and WM_LP. ++ * mem_value must be in 0.1us units. ++ */ + static uint32_t ilk_compute_spr_wm(struct hsw_pipe_wm_parameters *params, + uint32_t mem_value) + { +@@ -2247,7 +2255,10 @@ static uint32_t ilk_compute_spr_wm(struct hsw_pipe_wm_parameters *params, + return min(method1, method2); + } + +-/* For both WM_PIPE and WM_LP. */ ++/* ++ * For both WM_PIPE and WM_LP. ++ * mem_value must be in 0.1us units. ++ */ + static uint32_t ilk_compute_cur_wm(struct hsw_pipe_wm_parameters *params, + uint32_t mem_value) + { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0590-drm-i915-eliminate-dead-domain-clearing-on-reset.patch b/patches.baytrail/0590-drm-i915-eliminate-dead-domain-clearing-on-reset.patch new file mode 100644 index 000000000000..e74ed26a00f5 --- /dev/null +++ b/patches.baytrail/0590-drm-i915-eliminate-dead-domain-clearing-on-reset.patch @@ -0,0 +1,49 @@ +From 28811bb29b8e2c215f9ba040f747993046ff9855 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Mon, 5 Aug 2013 09:46:44 -0700 +Subject: drm/i915: eliminate dead domain clearing on reset + +The code itself is no longer accurate without updating once we have +multiple address space since clearing the domains of every object +requires scanning the inactive list for all VMs. + +"This code is dead. Just remove it rather than port it to vma." - Chris +Wilson + +Recommended-by: Chris Wilson +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 637efacf8fcf112a188dd005c816e2b0f39894f0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index bd6eb646d541..d31e15dd173c 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2285,20 +2285,12 @@ void i915_gem_restore_fences(struct drm_device *dev) + void i915_gem_reset(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- struct i915_address_space *vm = &dev_priv->gtt.base; +- struct drm_i915_gem_object *obj; + struct intel_ring_buffer *ring; + int i; + + for_each_ring(ring, dev_priv, i) + i915_gem_reset_ring_lists(dev_priv, ring); + +- /* Move everything out of the GPU domains to ensure we do any +- * necessary invalidation upon reuse. +- */ +- list_for_each_entry(obj, &vm->inactive_list, mm_list) +- obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; +- + i915_gem_restore_fences(dev); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0591-drm-i915-silence-useless-messages-about-DDI-buffer-t.patch b/patches.baytrail/0591-drm-i915-silence-useless-messages-about-DDI-buffer-t.patch new file mode 100644 index 000000000000..ffd2686847d8 --- /dev/null +++ b/patches.baytrail/0591-drm-i915-silence-useless-messages-about-DDI-buffer-t.patch @@ -0,0 +1,53 @@ +From 8e9f9bd7cdd932b4094226fca46bbf7bf21bfc17 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Mon, 5 Aug 2013 17:25:55 -0300 +Subject: drm/i915: silence useless messages about DDI buffer translation + +These messages are not really useful since it's very easy to check +which mode is used for each port: The values programmed are based on +the port type, then assigned to the ddi_translations variable. +Currently we use DP mode for ports A-D and FDI mode for port E. + +Also, when we add the code to enable/disable PC8+, +intel_prepare_ddi_buffers will be called more often and will eat your +dmesg buffers. + +While at it, fix the coding style of the "for" statement above. + +Signed-off-by: Paulo Zanoni +[danvet: Pimp commit message with Paulo's more detailed explanation of +how the ddi translation buffer settings are computed, to answer a +question from Chris.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit f72d19f069f8efaa535aacc719d23d469b0d9f18) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index b361c0862373..b6281d9e4d62 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -94,15 +94,8 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, + hsw_ddi_translations_fdi : + hsw_ddi_translations_dp); + +- DRM_DEBUG_DRIVER("Initializing DDI buffers for port %c in %s mode\n", +- port_name(port), +- use_fdi_mode ? "FDI" : "DP"); +- +- WARN((use_fdi_mode && (port != PORT_E)), +- "Programming port %c in FDI mode, this probably will not work.\n", +- port_name(port)); +- +- for (i=0, reg=DDI_BUF_TRANS(port); i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { ++ for (i = 0, reg = DDI_BUF_TRANS(port); ++ i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { + I915_WRITE(reg, ddi_translations[i]); + reg += 4; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0592-drm-i915-remove-use_fdi_mode-argument-from-intel_pre.patch b/patches.baytrail/0592-drm-i915-remove-use_fdi_mode-argument-from-intel_pre.patch new file mode 100644 index 000000000000..99ff1a3d0487 --- /dev/null +++ b/patches.baytrail/0592-drm-i915-remove-use_fdi_mode-argument-from-intel_pre.patch @@ -0,0 +1,59 @@ +From 9c2921cb2b4222577217ddc2175a8ff80d3b7c54 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Mon, 5 Aug 2013 17:25:56 -0300 +Subject: drm/i915: remove use_fdi_mode argument from intel_prepare_ddi_buffers + +We set the mode based on the port, and we already pass the port as an +argument. + +Signed-off-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit ad8d270c21aa2f57f0cd578b1737f65c44c34b80) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 17 +++++------------ + 1 file changed, 5 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index b6281d9e4d62..b8c096b4a1de 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -84,15 +84,14 @@ static enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) + * in either FDI or DP modes only, as HDMI connections will work with both + * of those + */ +-static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, +- bool use_fdi_mode) ++static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) + { + struct drm_i915_private *dev_priv = dev->dev_private; + u32 reg; + int i; +- const u32 *ddi_translations = ((use_fdi_mode) ? ++ const u32 *ddi_translations = (port == PORT_E) ? + hsw_ddi_translations_fdi : +- hsw_ddi_translations_dp); ++ hsw_ddi_translations_dp; + + for (i = 0, reg = DDI_BUF_TRANS(port); + i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { +@@ -111,14 +110,8 @@ void intel_prepare_ddi(struct drm_device *dev) + if (!HAS_DDI(dev)) + return; + +- for (port = PORT_A; port < PORT_E; port++) +- intel_prepare_ddi_buffers(dev, port, false); +- +- /* DDI E is the suggested one to work in FDI mode, so program is as such +- * by default. It will have to be re-programmed in case a digital DP +- * output will be detected on it +- */ +- intel_prepare_ddi_buffers(dev, PORT_E, true); ++ for (port = PORT_A; port <= PORT_E; port++) ++ intel_prepare_ddi_buffers(dev, port); + } + + static const long hsw_ddi_buf_ctl_values[] = { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0593-drm-i915-Rename-I915_CACHE_MLC_LLC-to-L3_LLC-for-Ivy.patch b/patches.baytrail/0593-drm-i915-Rename-I915_CACHE_MLC_LLC-to-L3_LLC-for-Ivy.patch new file mode 100644 index 000000000000..f5001fd65be5 --- /dev/null +++ b/patches.baytrail/0593-drm-i915-Rename-I915_CACHE_MLC_LLC-to-L3_LLC-for-Ivy.patch @@ -0,0 +1,151 @@ +From 627c36ead437f9760b319a3df8c8cda70cd9d741 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Tue, 6 Aug 2013 13:17:02 +0100 +Subject: drm/i915: Rename I915_CACHE_MLC_LLC to L3_LLC for Ivybridge +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +MLC_LLC was never validated for Sandybridge and was superseded by a new +level of cacheing for the GPU in Ivybridge. Update our names to be +consistent with usage, and in the process stop setting the unwanted bit +on Sandybridge. + +Signed-off-by: Chris Wilson +Reviewed-by: Ville Syrjälä +[danvet: s/BUG/WARN_ON(1) bikeshed.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 350ec881d966453bdcf1d3299071e90da4e507b4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 7 +++++-- + drivers/gpu/drm/i915/i915_gem_context.c | 2 +- + drivers/gpu/drm/i915/i915_gem_gtt.c | 37 ++++++++++++++++++++++++++------- + drivers/gpu/drm/i915/i915_gpu_error.c | 4 ++-- + 4 files changed, 38 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index ec7692cb2726..9ff09a287671 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -449,8 +449,11 @@ struct intel_device_info { + + enum i915_cache_level { + I915_CACHE_NONE = 0, +- I915_CACHE_LLC, +- I915_CACHE_LLC_MLC, /* gen6+, in docs at least! */ ++ I915_CACHE_LLC, /* also used for snoopable memory on non-LLC */ ++ I915_CACHE_L3_LLC, /* gen7+, L3 sits between the domain specifc ++ caches, eg sampler/render caches, and the ++ large Last-Level-Cache. LLC is coherent with ++ the CPU, but L3 is only visible to the GPU. */ + }; + + typedef uint32_t gen6_gtt_pte_t; +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index d1cb28cbc71e..7273a729a039 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -155,7 +155,7 @@ create_hw_context(struct drm_device *dev, + + if (INTEL_INFO(dev)->gen >= 7) { + ret = i915_gem_object_set_cache_level(ctx->obj, +- I915_CACHE_LLC_MLC); ++ I915_CACHE_L3_LLC); + /* Failure shouldn't ever happen this early */ + if (WARN_ON(ret)) + goto err_out; +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index f38cc696be7f..24fb989593f0 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -43,7 +43,7 @@ + #define GEN6_PTE_UNCACHED (1 << 1) + #define HSW_PTE_UNCACHED (0) + #define GEN6_PTE_CACHE_LLC (2 << 1) +-#define GEN6_PTE_CACHE_LLC_MLC (3 << 1) ++#define GEN7_PTE_CACHE_L3_LLC (3 << 1) + #define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) + #define HSW_PTE_ADDR_ENCODE(addr) HSW_GTT_ADDR_ENCODE(addr) + +@@ -56,15 +56,36 @@ + #define HSW_WB_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x3) + #define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb) + +-static gen6_gtt_pte_t gen6_pte_encode(dma_addr_t addr, +- enum i915_cache_level level) ++static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr, ++ enum i915_cache_level level) + { + gen6_gtt_pte_t pte = GEN6_PTE_VALID; + pte |= GEN6_PTE_ADDR_ENCODE(addr); + + switch (level) { +- case I915_CACHE_LLC_MLC: +- pte |= GEN6_PTE_CACHE_LLC_MLC; ++ case I915_CACHE_L3_LLC: ++ case I915_CACHE_LLC: ++ pte |= GEN6_PTE_CACHE_LLC; ++ break; ++ case I915_CACHE_NONE: ++ pte |= GEN6_PTE_UNCACHED; ++ break; ++ default: ++ WARN_ON(1); ++ } ++ ++ return pte; ++} ++ ++static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr, ++ enum i915_cache_level level) ++{ ++ gen6_gtt_pte_t pte = GEN6_PTE_VALID; ++ pte |= GEN6_PTE_ADDR_ENCODE(addr); ++ ++ switch (level) { ++ case I915_CACHE_L3_LLC: ++ pte |= GEN7_PTE_CACHE_L3_LLC; + break; + case I915_CACHE_LLC: + pte |= GEN6_PTE_CACHE_LLC; +@@ -73,7 +94,7 @@ static gen6_gtt_pte_t gen6_pte_encode(dma_addr_t addr, + pte |= GEN6_PTE_UNCACHED; + break; + default: +- BUG(); ++ WARN_ON(1); + } + + return pte; +@@ -890,8 +911,10 @@ int i915_gem_gtt_init(struct drm_device *dev) + gtt->base.pte_encode = hsw_pte_encode; + else if (IS_VALLEYVIEW(dev)) + gtt->base.pte_encode = byt_pte_encode; ++ else if (INTEL_INFO(dev)->gen >= 7) ++ gtt->base.pte_encode = ivb_pte_encode; + else +- gtt->base.pte_encode = gen6_pte_encode; ++ gtt->base.pte_encode = snb_pte_encode; + } + + ret = gtt->gtt_probe(dev, >t->base.total, >t->stolen_size, +diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c +index d970d84da65f..8091485e7e88 100644 +--- a/drivers/gpu/drm/i915/i915_gpu_error.c ++++ b/drivers/gpu/drm/i915/i915_gpu_error.c +@@ -938,8 +938,8 @@ const char *i915_cache_level_str(int type) + { + switch (type) { + case I915_CACHE_NONE: return " uncached"; +- case I915_CACHE_LLC: return " snooped (LLC)"; +- case I915_CACHE_LLC_MLC: return " snooped (LLC+MLC)"; ++ case I915_CACHE_LLC: return " snooped or LLC"; ++ case I915_CACHE_L3_LLC: return " L3+LLC"; + default: return ""; + } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0594-drm-i915-Export-intel_framebuffer_fini.patch b/patches.baytrail/0594-drm-i915-Export-intel_framebuffer_fini.patch new file mode 100644 index 000000000000..1bdd7d6a494b --- /dev/null +++ b/patches.baytrail/0594-drm-i915-Export-intel_framebuffer_fini.patch @@ -0,0 +1,101 @@ +From 05aae3a8db54dfa8c154b6a97ea60e766d806e74 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Tue, 6 Aug 2013 17:43:07 +0100 +Subject: drm/i915: Export intel_framebuffer_fini +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Rather than open-code the teardown of a framebuffer, export the routine +from intel_display.c. This then make intel_fbdev symmetric in its use of +the common intel_framebuffer routines to initialise and clean up the +struct intel_framebuffer. (And new features need only be added in one +location!) + +Signed-off-by: Chris Wilson +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit ddfe15677d9c47f2491e401cd773b45e1aac74bf) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 10 +++++++--- + drivers/gpu/drm/i915/intel_drv.h | 1 + + drivers/gpu/drm/i915/intel_fb.c | 15 +++++---------- + 3 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index bd3591af3395..a5aee8993283 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -9408,13 +9408,17 @@ static void intel_setup_outputs(struct drm_device *dev) + drm_helper_move_panel_connectors_to_head(dev); + } + ++void intel_framebuffer_fini(struct intel_framebuffer *fb) ++{ ++ drm_framebuffer_cleanup(&fb->base); ++ drm_gem_object_unreference_unlocked(&fb->obj->base); ++} ++ + static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) + { + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); + +- drm_framebuffer_cleanup(fb); +- drm_gem_object_unreference_unlocked(&intel_fb->obj->base); +- ++ intel_framebuffer_fini(intel_fb); + kfree(intel_fb); + } + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index ed33976c194b..54e389de9f42 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -720,6 +720,7 @@ extern int intel_framebuffer_init(struct drm_device *dev, + struct intel_framebuffer *ifb, + struct drm_mode_fb_cmd2 *mode_cmd, + struct drm_i915_gem_object *obj); ++extern void intel_framebuffer_fini(struct intel_framebuffer *fb); + extern int intel_fbdev_init(struct drm_device *dev); + extern void intel_fbdev_initial_config(struct drm_device *dev); + extern void intel_fbdev_fini(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c +index f3c97e05b0d8..bc2100007b21 100644 +--- a/drivers/gpu/drm/i915/intel_fb.c ++++ b/drivers/gpu/drm/i915/intel_fb.c +@@ -193,26 +193,21 @@ static struct drm_fb_helper_funcs intel_fb_helper_funcs = { + static void intel_fbdev_destroy(struct drm_device *dev, + struct intel_fbdev *ifbdev) + { +- struct fb_info *info; +- struct intel_framebuffer *ifb = &ifbdev->ifb; +- + if (ifbdev->helper.fbdev) { +- info = ifbdev->helper.fbdev; ++ struct fb_info *info = ifbdev->helper.fbdev; ++ + unregister_framebuffer(info); + iounmap(info->screen_base); + if (info->cmap.len) + fb_dealloc_cmap(&info->cmap); ++ + framebuffer_release(info); + } + + drm_fb_helper_fini(&ifbdev->helper); + +- drm_framebuffer_unregister_private(&ifb->base); +- drm_framebuffer_cleanup(&ifb->base); +- if (ifb->obj) { +- drm_gem_object_unreference_unlocked(&ifb->obj->base); +- ifb->obj = NULL; +- } ++ drm_framebuffer_unregister_private(&ifbdev->ifb.base); ++ intel_framebuffer_fini(&ifbdev->ifb); + } + + int intel_fbdev_init(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0595-drm-i915-Improve-VMA-comments.patch b/patches.baytrail/0595-drm-i915-Improve-VMA-comments.patch new file mode 100644 index 000000000000..1bffe2e4e84c --- /dev/null +++ b/patches.baytrail/0595-drm-i915-Improve-VMA-comments.patch @@ -0,0 +1,34 @@ +From 57cbd5293aac8908748ed96c2fd6b624aeaf3963 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:08 -0700 +Subject: drm/i915: Improve VMA comments + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 0b02e798ffec99b51f2fe931ceb61ca0d22d2a70) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 9ff09a287671..62ec760782f5 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -545,7 +545,12 @@ struct i915_hw_ppgtt { + int (*enable)(struct drm_device *dev); + }; + +-/* To make things as simple as possible (ie. no refcounting), a VMA's lifetime ++/** ++ * A VMA represents a GEM BO that is bound into an address space. Therefore, a ++ * VMA's presence cannot be guaranteed before binding, or after unbinding the ++ * object into/from the address space. ++ * ++ * To make things as simple as possible (ie. no refcounting), a VMA's lifetime + * will always be <= an objects lifetime. So object refcounting should cover us. + */ + struct i915_vma { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0596-drm-gem-create-drm_gem_dumb_destroy.patch b/patches.baytrail/0596-drm-gem-create-drm_gem_dumb_destroy.patch new file mode 100644 index 000000000000..c846b3f54c61 --- /dev/null +++ b/patches.baytrail/0596-drm-gem-create-drm_gem_dumb_destroy.patch @@ -0,0 +1,777 @@ +From 97a39ea0ac420e99b5201704f0df265e191da03e Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 16 Jul 2013 09:12:04 +0200 +Subject: drm/gem: create drm_gem_dumb_destroy + +All the gem based kms drivers really want the same function to +destroy a dumb framebuffer backing storage object. + +So give it to them and roll it out in all drivers. + +This still leaves the option open for kms drivers which don't use GEM +for backing storage, but it does decently simplify matters for gem +drivers. + +Acked-by: Inki Dae +Acked-by: Laurent Pinchart +Cc: Intel Graphics Development +Cc: Ben Skeggs +Reviwed-by: Rob Clark +Cc: Alex Deucher +Acked-by: Patrik Jakobsson +Signed-off-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit 43387b37fa2d0f368142b8fa8c9440da92e5381b) +Signed-off-by: James Ausmus + +Conflicts: + drivers/gpu/drm/exynos/exynos_drm_gem.c + (context changes) + drivers/gpu/drm/rcar-du/rcar_du_drv.c + (we don't have this driver in our tree) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/ast/ast_drv.c | 2 +- + drivers/gpu/drm/ast/ast_drv.h | 3 --- + drivers/gpu/drm/ast/ast_main.c | 7 ------- + drivers/gpu/drm/cirrus/cirrus_drv.c | 2 +- + drivers/gpu/drm/cirrus/cirrus_drv.h | 3 --- + drivers/gpu/drm/cirrus/cirrus_main.c | 7 ------- + drivers/gpu/drm/drm_gem.c | 14 ++++++++++++++ + drivers/gpu/drm/drm_gem_cma_helper.c | 10 ---------- + drivers/gpu/drm/exynos/exynos_drm_drv.c | 2 +- + drivers/gpu/drm/exynos/exynos_drm_gem.c | 22 ---------------------- + drivers/gpu/drm/exynos/exynos_drm_gem.h | 9 --------- + drivers/gpu/drm/gma500/gem.c | 17 ----------------- + drivers/gpu/drm/gma500/psb_drv.c | 2 +- + drivers/gpu/drm/gma500/psb_drv.h | 2 -- + drivers/gpu/drm/i915/i915_drv.c | 2 +- + drivers/gpu/drm/i915/i915_drv.h | 2 -- + drivers/gpu/drm/i915/i915_gem.c | 7 ------- + drivers/gpu/drm/mgag200/mgag200_drv.c | 2 +- + drivers/gpu/drm/mgag200/mgag200_drv.h | 3 --- + drivers/gpu/drm/mgag200/mgag200_main.c | 7 ------- + drivers/gpu/drm/nouveau/nouveau_display.c | 7 ------- + drivers/gpu/drm/nouveau/nouveau_display.h | 2 -- + drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +- + drivers/gpu/drm/omapdrm/omap_drv.c | 2 +- + drivers/gpu/drm/omapdrm/omap_drv.h | 2 -- + drivers/gpu/drm/omapdrm/omap_gem.c | 15 --------------- + drivers/gpu/drm/qxl/qxl_drv.c | 2 +- + drivers/gpu/drm/qxl/qxl_drv.h | 3 --- + drivers/gpu/drm/qxl/qxl_dumb.c | 7 ------- + drivers/gpu/drm/radeon/radeon.h | 3 --- + drivers/gpu/drm/radeon/radeon_drv.c | 5 +---- + drivers/gpu/drm/radeon/radeon_gem.c | 7 ------- + drivers/gpu/drm/shmobile/shmob_drm_drv.c | 2 +- + drivers/gpu/drm/tilcdc/tilcdc_drv.c | 2 +- + drivers/gpu/drm/udl/udl_drv.c | 2 +- + drivers/gpu/drm/udl/udl_drv.h | 2 -- + drivers/gpu/drm/udl/udl_gem.c | 6 ------ + drivers/gpu/host1x/drm/drm.c | 2 +- + drivers/gpu/host1x/drm/gem.c | 6 ------ + drivers/gpu/host1x/drm/gem.h | 2 -- + drivers/staging/imx-drm/imx-drm-core.c | 2 +- + include/drm/drmP.h | 3 +++ + include/drm/drm_gem_cma_helper.h | 8 -------- + 43 files changed, 32 insertions(+), 187 deletions(-) + +diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c +index df0d0a08097a..a144fb044852 100644 +--- a/drivers/gpu/drm/ast/ast_drv.c ++++ b/drivers/gpu/drm/ast/ast_drv.c +@@ -216,7 +216,7 @@ static struct drm_driver driver = { + .gem_free_object = ast_gem_free_object, + .dumb_create = ast_dumb_create, + .dumb_map_offset = ast_dumb_mmap_offset, +- .dumb_destroy = ast_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + + }; + +diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h +index b6b7d70f2832..68e1d324005a 100644 +--- a/drivers/gpu/drm/ast/ast_drv.h ++++ b/drivers/gpu/drm/ast/ast_drv.h +@@ -322,9 +322,6 @@ ast_bo(struct ttm_buffer_object *bo) + extern int ast_dumb_create(struct drm_file *file, + struct drm_device *dev, + struct drm_mode_create_dumb *args); +-extern int ast_dumb_destroy(struct drm_file *file, +- struct drm_device *dev, +- uint32_t handle); + + extern int ast_gem_init_object(struct drm_gem_object *obj); + extern void ast_gem_free_object(struct drm_gem_object *obj); +diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c +index c195dc2abc09..7f6152d374ca 100644 +--- a/drivers/gpu/drm/ast/ast_main.c ++++ b/drivers/gpu/drm/ast/ast_main.c +@@ -449,13 +449,6 @@ int ast_dumb_create(struct drm_file *file, + return 0; + } + +-int ast_dumb_destroy(struct drm_file *file, +- struct drm_device *dev, +- uint32_t handle) +-{ +- return drm_gem_handle_delete(file, handle); +-} +- + int ast_gem_init_object(struct drm_gem_object *obj) + { + BUG(); +diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c +index 8ecb601152ef..d35d99c15f84 100644 +--- a/drivers/gpu/drm/cirrus/cirrus_drv.c ++++ b/drivers/gpu/drm/cirrus/cirrus_drv.c +@@ -102,7 +102,7 @@ static struct drm_driver driver = { + .gem_free_object = cirrus_gem_free_object, + .dumb_create = cirrus_dumb_create, + .dumb_map_offset = cirrus_dumb_mmap_offset, +- .dumb_destroy = cirrus_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + }; + + static struct pci_driver cirrus_pci_driver = { +diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h +index 7ca059596887..33a0f991b0fc 100644 +--- a/drivers/gpu/drm/cirrus/cirrus_drv.h ++++ b/drivers/gpu/drm/cirrus/cirrus_drv.h +@@ -203,9 +203,6 @@ int cirrus_gem_create(struct drm_device *dev, + int cirrus_dumb_create(struct drm_file *file, + struct drm_device *dev, + struct drm_mode_create_dumb *args); +-int cirrus_dumb_destroy(struct drm_file *file, +- struct drm_device *dev, +- uint32_t handle); + + int cirrus_framebuffer_init(struct drm_device *dev, + struct cirrus_framebuffer *gfb, +diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c +index 3a7a0efe3675..f130a533a512 100644 +--- a/drivers/gpu/drm/cirrus/cirrus_main.c ++++ b/drivers/gpu/drm/cirrus/cirrus_main.c +@@ -255,13 +255,6 @@ int cirrus_dumb_create(struct drm_file *file, + return 0; + } + +-int cirrus_dumb_destroy(struct drm_file *file, +- struct drm_device *dev, +- uint32_t handle) +-{ +- return drm_gem_handle_delete(file, handle); +-} +- + int cirrus_gem_init_object(struct drm_gem_object *obj) + { + BUG(); +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index 2688795172f9..ee9ddc856710 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -244,6 +244,20 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle) + EXPORT_SYMBOL(drm_gem_handle_delete); + + /** ++ * drm_gem_dumb_destroy - dumb fb callback helper for gem based drivers ++ * ++ * This implements the ->dumb_destroy kms driver callback for drivers which use ++ * gem to manage their backing storage. ++ */ ++int drm_gem_dumb_destroy(struct drm_file *file, ++ struct drm_device *dev, ++ uint32_t handle) ++{ ++ return drm_gem_handle_delete(file, handle); ++} ++EXPORT_SYMBOL(drm_gem_dumb_destroy); ++ ++/** + * Create a handle for this object. This adds a handle reference + * to the object, which includes a regular reference count. Callers + * will likely want to dereference the object afterwards. +diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c +index 11b616ef9dc2..3ec218376734 100644 +--- a/drivers/gpu/drm/drm_gem_cma_helper.c ++++ b/drivers/gpu/drm/drm_gem_cma_helper.c +@@ -235,16 +235,6 @@ int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma) + } + EXPORT_SYMBOL_GPL(drm_gem_cma_mmap); + +-/* +- * drm_gem_cma_dumb_destroy - (struct drm_driver)->dumb_destroy callback function +- */ +-int drm_gem_cma_dumb_destroy(struct drm_file *file_priv, +- struct drm_device *drm, unsigned int handle) +-{ +- return drm_gem_handle_delete(file_priv, handle); +-} +-EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_destroy); +- + #ifdef CONFIG_DEBUG_FS + void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, struct seq_file *m) + { +diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c +index ba6d995e4375..1ff89aca1fed 100644 +--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c +@@ -276,7 +276,7 @@ static struct drm_driver exynos_drm_driver = { + .gem_vm_ops = &exynos_drm_gem_vm_ops, + .dumb_create = exynos_drm_gem_dumb_create, + .dumb_map_offset = exynos_drm_gem_dumb_map_offset, +- .dumb_destroy = exynos_drm_gem_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .gem_prime_export = exynos_dmabuf_prime_export, +diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c +index 408b71f4c95e..e83930fdf6c7 100644 +--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c +@@ -735,28 +735,6 @@ unlock: + return ret; + } + +-int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv, +- struct drm_device *dev, +- unsigned int handle) +-{ +- int ret; +- +- DRM_DEBUG_KMS("%s\n", __FILE__); +- +- /* +- * obj->refcount and obj->handle_count are decreased and +- * if both them are 0 then exynos_drm_gem_free_object() +- * would be called by callback to release resources. +- */ +- ret = drm_gem_handle_delete(file_priv, handle); +- if (ret < 0) { +- DRM_ERROR("failed to delete drm_gem_handle.\n"); +- return ret; +- } +- +- return 0; +-} +- + int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + { + struct drm_gem_object *obj = vma->vm_private_data; +diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h +index 468766bee450..09555afdfe9c 100644 +--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h ++++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h +@@ -151,15 +151,6 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, + struct drm_device *dev, uint32_t handle, + uint64_t *offset); + +-/* +- * destroy memory region allocated. +- * - a gem handle and physical memory region pointed by a gem object +- * would be released by drm_gem_handle_delete(). +- */ +-int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv, +- struct drm_device *dev, +- unsigned int handle); +- + /* page fault handler and mmap fault address(virtual) to physical memory. */ + int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); + +diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c +index 2f77bea30b11..10ae8c52d06f 100644 +--- a/drivers/gpu/drm/gma500/gem.c ++++ b/drivers/gpu/drm/gma500/gem.c +@@ -162,23 +162,6 @@ int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev, + } + + /** +- * psb_gem_dumb_destroy - destroy a dumb buffer +- * @file: client file +- * @dev: our DRM device +- * @handle: the object handle +- * +- * Destroy a handle that was created via psb_gem_dumb_create, at least +- * we hope it was created that way. i915 seems to assume the caller +- * does the checking but that might be worth review ! FIXME +- */ +-int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, +- uint32_t handle) +-{ +- /* No special work needed, drop the reference and see what falls out */ +- return drm_gem_handle_delete(file, handle); +-} +- +-/** + * psb_gem_fault - pagefault handler for GEM objects + * @vma: the VMA of the GEM object + * @vmf: fault detail +diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c +index bddea5807442..ed06d5ce3757 100644 +--- a/drivers/gpu/drm/gma500/psb_drv.c ++++ b/drivers/gpu/drm/gma500/psb_drv.c +@@ -652,7 +652,7 @@ static struct drm_driver driver = { + .gem_vm_ops = &psb_gem_vm_ops, + .dumb_create = psb_gem_dumb_create, + .dumb_map_offset = psb_gem_dumb_map_gtt, +- .dumb_destroy = psb_gem_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + .fops = &psb_gem_fops, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, +diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h +index 6053b8abcd12..984cacfcbaf2 100644 +--- a/drivers/gpu/drm/gma500/psb_drv.h ++++ b/drivers/gpu/drm/gma500/psb_drv.h +@@ -838,8 +838,6 @@ extern int psb_gem_get_aperture(struct drm_device *dev, void *data, + struct drm_file *file); + extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev, + struct drm_mode_create_dumb *args); +-extern int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, +- uint32_t handle); + extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, + uint32_t handle, uint64_t *offset); + extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 01d63a0435fb..13457e3e9cad 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -1038,7 +1038,7 @@ static struct drm_driver driver = { + + .dumb_create = i915_gem_dumb_create, + .dumb_map_offset = i915_gem_mmap_gtt, +- .dumb_destroy = i915_gem_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + .ioctls = i915_ioctls, + .fops = &i915_driver_fops, + .name = DRIVER_NAME, +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 62ec760782f5..06c31752fcb2 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1775,8 +1775,6 @@ int i915_gem_dumb_create(struct drm_file *file_priv, + struct drm_mode_create_dumb *args); + int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev, + uint32_t handle, uint64_t *offset); +-int i915_gem_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev, +- uint32_t handle); + /** + * Returns true if seq1 is later than seq2. + */ +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index d31e15dd173c..967fe650fa8b 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -245,13 +245,6 @@ i915_gem_dumb_create(struct drm_file *file, + args->size, &args->handle); + } + +-int i915_gem_dumb_destroy(struct drm_file *file, +- struct drm_device *dev, +- uint32_t handle) +-{ +- return drm_gem_handle_delete(file, handle); +-} +- + /** + * Creates a new mm object and returns a handle to it. + */ +diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c +index 122b571ccc7c..bd9196478735 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_drv.c ++++ b/drivers/gpu/drm/mgag200/mgag200_drv.c +@@ -104,7 +104,7 @@ static struct drm_driver driver = { + .gem_free_object = mgag200_gem_free_object, + .dumb_create = mgag200_dumb_create, + .dumb_map_offset = mgag200_dumb_mmap_offset, +- .dumb_destroy = mgag200_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + }; + + static struct pci_driver mgag200_pci_driver = { +diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h +index 988911afcc8b..e61ce34910d6 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_drv.h ++++ b/drivers/gpu/drm/mgag200/mgag200_drv.h +@@ -248,9 +248,6 @@ int mgag200_gem_init_object(struct drm_gem_object *obj); + int mgag200_dumb_create(struct drm_file *file, + struct drm_device *dev, + struct drm_mode_create_dumb *args); +-int mgag200_dumb_destroy(struct drm_file *file, +- struct drm_device *dev, +- uint32_t handle); + void mgag200_gem_free_object(struct drm_gem_object *obj); + int + mgag200_dumb_mmap_offset(struct drm_file *file, +diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c +index 2d56e28d2b21..4529d4dd12c2 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_main.c ++++ b/drivers/gpu/drm/mgag200/mgag200_main.c +@@ -291,13 +291,6 @@ int mgag200_dumb_create(struct drm_file *file, + return 0; + } + +-int mgag200_dumb_destroy(struct drm_file *file, +- struct drm_device *dev, +- uint32_t handle) +-{ +- return drm_gem_handle_delete(file, handle); +-} +- + int mgag200_gem_init_object(struct drm_gem_object *obj) + { + BUG(); +diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c +index 52498de87a3b..05ae27277543 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_display.c ++++ b/drivers/gpu/drm/nouveau/nouveau_display.c +@@ -689,13 +689,6 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, + } + + int +-nouveau_display_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev, +- uint32_t handle) +-{ +- return drm_gem_handle_delete(file_priv, handle); +-} +- +-int + nouveau_display_dumb_map_offset(struct drm_file *file_priv, + struct drm_device *dev, + uint32_t handle, uint64_t *poffset) +diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h +index 1ea3e4734b62..185e74132a6d 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_display.h ++++ b/drivers/gpu/drm/nouveau/nouveau_display.h +@@ -68,8 +68,6 @@ int nouveau_display_dumb_create(struct drm_file *, struct drm_device *, + struct drm_mode_create_dumb *args); + int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *, + u32 handle, u64 *offset); +-int nouveau_display_dumb_destroy(struct drm_file *, struct drm_device *, +- u32 handle); + + void nouveau_hdmi_mode_set(struct drm_encoder *, struct drm_display_mode *); + +diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c +index 383f4e6ea9d1..b77bcb9237e0 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drm.c ++++ b/drivers/gpu/drm/nouveau/nouveau_drm.c +@@ -714,7 +714,7 @@ driver = { + + .dumb_create = nouveau_display_dumb_create, + .dumb_map_offset = nouveau_display_dumb_map_offset, +- .dumb_destroy = nouveau_display_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + + .name = DRIVER_NAME, + .desc = DRIVER_DESC, +diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c +index 826586ffbe83..75886a3bf639 100644 +--- a/drivers/gpu/drm/omapdrm/omap_drv.c ++++ b/drivers/gpu/drm/omapdrm/omap_drv.c +@@ -618,7 +618,7 @@ static struct drm_driver omap_drm_driver = { + .gem_vm_ops = &omap_gem_vm_ops, + .dumb_create = omap_gem_dumb_create, + .dumb_map_offset = omap_gem_dumb_map_offset, +- .dumb_destroy = omap_gem_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + .ioctls = ioctls, + .num_ioctls = DRM_OMAP_NUM_IOCTLS, + .fops = &omapdriver_fops, +diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h +index 215a20dd340c..fd13601ff6fb 100644 +--- a/drivers/gpu/drm/omapdrm/omap_drv.h ++++ b/drivers/gpu/drm/omapdrm/omap_drv.h +@@ -224,8 +224,6 @@ int omap_gem_init_object(struct drm_gem_object *obj); + void *omap_gem_vaddr(struct drm_gem_object *obj); + int omap_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, + uint32_t handle, uint64_t *offset); +-int omap_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, +- uint32_t handle); + int omap_gem_dumb_create(struct drm_file *file, struct drm_device *dev, + struct drm_mode_create_dumb *args); + int omap_gem_mmap(struct file *filp, struct vm_area_struct *vma); +diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c +index f90531fc00c9..b1f19702550f 100644 +--- a/drivers/gpu/drm/omapdrm/omap_gem.c ++++ b/drivers/gpu/drm/omapdrm/omap_gem.c +@@ -629,21 +629,6 @@ int omap_gem_dumb_create(struct drm_file *file, struct drm_device *dev, + } + + /** +- * omap_gem_dumb_destroy - destroy a dumb buffer +- * @file: client file +- * @dev: our DRM device +- * @handle: the object handle +- * +- * Destroy a handle that was created via omap_gem_dumb_create. +- */ +-int omap_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, +- uint32_t handle) +-{ +- /* No special work needed, drop the reference and see what falls out */ +- return drm_gem_handle_delete(file, handle); +-} +- +-/** + * omap_gem_dumb_map - buffer mapping for dumb interface + * @file: our drm client file + * @dev: drm device +diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c +index aa291d8a98a2..60cb159c4f7d 100644 +--- a/drivers/gpu/drm/qxl/qxl_drv.c ++++ b/drivers/gpu/drm/qxl/qxl_drv.c +@@ -99,7 +99,7 @@ static struct drm_driver qxl_driver = { + + .dumb_create = qxl_mode_dumb_create, + .dumb_map_offset = qxl_mode_dumb_mmap, +- .dumb_destroy = qxl_mode_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + #if defined(CONFIG_DEBUG_FS) + .debugfs_init = qxl_debugfs_init, + .debugfs_cleanup = qxl_debugfs_takedown, +diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h +index 43d06ab28a21..089fd42802dd 100644 +--- a/drivers/gpu/drm/qxl/qxl_drv.h ++++ b/drivers/gpu/drm/qxl/qxl_drv.h +@@ -409,9 +409,6 @@ int qxl_bo_kmap(struct qxl_bo *bo, void **ptr); + int qxl_mode_dumb_create(struct drm_file *file_priv, + struct drm_device *dev, + struct drm_mode_create_dumb *args); +-int qxl_mode_dumb_destroy(struct drm_file *file_priv, +- struct drm_device *dev, +- uint32_t handle); + int qxl_mode_dumb_mmap(struct drm_file *filp, + struct drm_device *dev, + uint32_t handle, uint64_t *offset_p); +diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c +index 847c4ee798f7..d34bb4130ff0 100644 +--- a/drivers/gpu/drm/qxl/qxl_dumb.c ++++ b/drivers/gpu/drm/qxl/qxl_dumb.c +@@ -68,13 +68,6 @@ int qxl_mode_dumb_create(struct drm_file *file_priv, + return 0; + } + +-int qxl_mode_dumb_destroy(struct drm_file *file_priv, +- struct drm_device *dev, +- uint32_t handle) +-{ +- return drm_gem_handle_delete(file_priv, handle); +-} +- + int qxl_mode_dumb_mmap(struct drm_file *file_priv, + struct drm_device *dev, + uint32_t handle, uint64_t *offset_p) +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index d4ff48ce1d8b..0fbc44e468da 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -444,9 +444,6 @@ int radeon_mode_dumb_create(struct drm_file *file_priv, + int radeon_mode_dumb_mmap(struct drm_file *filp, + struct drm_device *dev, + uint32_t handle, uint64_t *offset_p); +-int radeon_mode_dumb_destroy(struct drm_file *file_priv, +- struct drm_device *dev, +- uint32_t handle); + + /* + * Semaphores. +diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c +index 094e7e5ea39e..bef72931ea08 100644 +--- a/drivers/gpu/drm/radeon/radeon_drv.c ++++ b/drivers/gpu/drm/radeon/radeon_drv.c +@@ -119,9 +119,6 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, + int radeon_mode_dumb_create(struct drm_file *file_priv, + struct drm_device *dev, + struct drm_mode_create_dumb *args); +-int radeon_mode_dumb_destroy(struct drm_file *file_priv, +- struct drm_device *dev, +- uint32_t handle); + struct sg_table *radeon_gem_prime_get_sg_table(struct drm_gem_object *obj); + struct drm_gem_object *radeon_gem_prime_import_sg_table(struct drm_device *dev, + size_t size, +@@ -414,7 +411,7 @@ static struct drm_driver kms_driver = { + .dma_ioctl = radeon_dma_ioctl_kms, + .dumb_create = radeon_mode_dumb_create, + .dumb_map_offset = radeon_mode_dumb_mmap, +- .dumb_destroy = radeon_mode_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + .fops = &radeon_driver_kms_fops, + + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, +diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c +index aa796031ab65..dce99c8a5835 100644 +--- a/drivers/gpu/drm/radeon/radeon_gem.c ++++ b/drivers/gpu/drm/radeon/radeon_gem.c +@@ -570,13 +570,6 @@ int radeon_mode_dumb_create(struct drm_file *file_priv, + return 0; + } + +-int radeon_mode_dumb_destroy(struct drm_file *file_priv, +- struct drm_device *dev, +- uint32_t handle) +-{ +- return drm_gem_handle_delete(file_priv, handle); +-} +- + #if defined(CONFIG_DEBUG_FS) + static int radeon_debugfs_gem_info(struct seq_file *m, void *data) + { +diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c +index f6e0b5395051..946bd28bf5da 100644 +--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c ++++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c +@@ -285,7 +285,7 @@ static struct drm_driver shmob_drm_driver = { + .gem_vm_ops = &drm_gem_cma_vm_ops, + .dumb_create = drm_gem_cma_dumb_create, + .dumb_map_offset = drm_gem_cma_dumb_map_offset, +- .dumb_destroy = drm_gem_cma_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + .fops = &shmob_drm_fops, + .name = "shmob-drm", + .desc = "Renesas SH Mobile DRM", +diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c +index 2b5461bcd9fb..bba8daf9230c 100644 +--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c ++++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c +@@ -490,7 +490,7 @@ static struct drm_driver tilcdc_driver = { + .gem_vm_ops = &drm_gem_cma_vm_ops, + .dumb_create = drm_gem_cma_dumb_create, + .dumb_map_offset = drm_gem_cma_dumb_map_offset, +- .dumb_destroy = drm_gem_cma_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + #ifdef CONFIG_DEBUG_FS + .debugfs_init = tilcdc_debugfs_init, + .debugfs_cleanup = tilcdc_debugfs_cleanup, +diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c +index c0770dbba74a..bb0af58c769a 100644 +--- a/drivers/gpu/drm/udl/udl_drv.c ++++ b/drivers/gpu/drm/udl/udl_drv.c +@@ -84,7 +84,7 @@ static struct drm_driver driver = { + + .dumb_create = udl_dumb_create, + .dumb_map_offset = udl_gem_mmap, +- .dumb_destroy = udl_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + .fops = &udl_driver_fops, + + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, +diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h +index cc6d90f28c71..56aec9409fa3 100644 +--- a/drivers/gpu/drm/udl/udl_drv.h ++++ b/drivers/gpu/drm/udl/udl_drv.h +@@ -114,8 +114,6 @@ int udl_dumb_create(struct drm_file *file_priv, + struct drm_mode_create_dumb *args); + int udl_gem_mmap(struct drm_file *file_priv, struct drm_device *dev, + uint32_t handle, uint64_t *offset); +-int udl_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev, +- uint32_t handle); + + int udl_gem_init_object(struct drm_gem_object *obj); + void udl_gem_free_object(struct drm_gem_object *gem_obj); +diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c +index 2a4cb2f83b36..b5e3b8038253 100644 +--- a/drivers/gpu/drm/udl/udl_gem.c ++++ b/drivers/gpu/drm/udl/udl_gem.c +@@ -66,12 +66,6 @@ int udl_dumb_create(struct drm_file *file, + args->size, &args->handle); + } + +-int udl_dumb_destroy(struct drm_file *file, struct drm_device *dev, +- uint32_t handle) +-{ +- return drm_gem_handle_delete(file, handle); +-} +- + int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) + { + int ret; +diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c +index 2b561c9118c6..da15a6291bb9 100644 +--- a/drivers/gpu/host1x/drm/drm.c ++++ b/drivers/gpu/host1x/drm/drm.c +@@ -625,7 +625,7 @@ struct drm_driver tegra_drm_driver = { + .gem_vm_ops = &tegra_bo_vm_ops, + .dumb_create = tegra_bo_dumb_create, + .dumb_map_offset = tegra_bo_dumb_map_offset, +- .dumb_destroy = tegra_bo_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + + .ioctls = tegra_drm_ioctls, + .num_ioctls = ARRAY_SIZE(tegra_drm_ioctls), +diff --git a/drivers/gpu/host1x/drm/gem.c b/drivers/gpu/host1x/drm/gem.c +index bc323b3dbe4d..3c35622c9f15 100644 +--- a/drivers/gpu/host1x/drm/gem.c ++++ b/drivers/gpu/host1x/drm/gem.c +@@ -261,9 +261,3 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma) + + return ret; + } +- +-int tegra_bo_dumb_destroy(struct drm_file *file, struct drm_device *drm, +- unsigned int handle) +-{ +- return drm_gem_handle_delete(file, handle); +-} +diff --git a/drivers/gpu/host1x/drm/gem.h b/drivers/gpu/host1x/drm/gem.h +index 34de2b486eb7..2e93b0379da8 100644 +--- a/drivers/gpu/host1x/drm/gem.h ++++ b/drivers/gpu/host1x/drm/gem.h +@@ -49,8 +49,6 @@ int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm, + struct drm_mode_create_dumb *args); + int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm, + uint32_t handle, uint64_t *offset); +-int tegra_bo_dumb_destroy(struct drm_file *file, struct drm_device *drm, +- unsigned int handle); + + int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma); + +diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c +index a532ca568526..a18622570812 100644 +--- a/drivers/staging/imx-drm/imx-drm-core.c ++++ b/drivers/staging/imx-drm/imx-drm-core.c +@@ -801,7 +801,7 @@ static struct drm_driver imx_drm_driver = { + .gem_vm_ops = &drm_gem_cma_vm_ops, + .dumb_create = drm_gem_cma_dumb_create, + .dumb_map_offset = drm_gem_cma_dumb_map_offset, +- .dumb_destroy = drm_gem_cma_dumb_destroy, ++ .dumb_destroy = drm_gem_dumb_destroy, + + .get_vblank_counter = drm_vblank_count, + .enable_vblank = imx_drm_enable_vblank, +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index bf677c0b4cae..9a8ea57e3b94 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1589,6 +1589,9 @@ extern int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page ** + extern struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages); + extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg); + ++int drm_gem_dumb_destroy(struct drm_file *file, ++ struct drm_device *dev, ++ uint32_t handle); + + void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv); + void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv); +diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h +index 63397ced9254..632a6c50fab7 100644 +--- a/include/drm/drm_gem_cma_helper.h ++++ b/include/drm/drm_gem_cma_helper.h +@@ -27,14 +27,6 @@ int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv, + /* set vm_flags and we can change the vm attribute to other one at here. */ + int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma); + +-/* +- * destroy memory region allocated. +- * - a gem handle and physical memory region pointed by a gem object +- * would be released by drm_gem_handle_delete(). +- */ +-int drm_gem_cma_dumb_destroy(struct drm_file *file_priv, +- struct drm_device *drm, unsigned int handle); +- + /* allocate physical memory. */ + struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, + unsigned int size); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0597-drm-mm-add-best_match-flag-to-drm_mm_insert_node.patch b/patches.baytrail/0597-drm-mm-add-best_match-flag-to-drm_mm_insert_node.patch new file mode 100644 index 000000000000..aef83e12e832 --- /dev/null +++ b/patches.baytrail/0597-drm-mm-add-best_match-flag-to-drm_mm_insert_node.patch @@ -0,0 +1,383 @@ +From e14dfda46c77534376ee238386424a17b3986b12 Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Sat, 27 Jul 2013 13:36:27 +0200 +Subject: drm/mm: add "best_match" flag to drm_mm_insert_node() + +Add a "best_match" flag similar to the drm_mm_search_*() helpers so we +can convert TTM to use them in follow up patches. We can also inline the +non-generic helpers and move them into the header to allow compile-time +optimizations. + +To make calls to drm_mm_{search,insert}_node() more readable, this +converts the boolean argument to a flagset. There are pending patches that +add additional flags for top-down allocators and more. + +v2: + - use flag parameter instead of boolean "best_match" + - convert *_search_free() helpers to also use flags argument + +Signed-off-by: David Herrmann +Reviewed-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit 31e5d7c67bd492fd0b2988440e21e31809c7c9af) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_mm.c | 37 ++++++++--------------- + drivers/gpu/drm/drm_vma_manager.c | 4 +-- + drivers/gpu/drm/i915/i915_gem.c | 3 +- + drivers/gpu/drm/i915/i915_gem_stolen.c | 12 +++++--- + drivers/gpu/drm/sis/sis_mm.c | 6 ++-- + drivers/gpu/drm/ttm/ttm_bo_manager.c | 3 +- + drivers/gpu/drm/via/via_mm.c | 4 +-- + include/drm/drm_mm.h | 54 ++++++++++++++++++++++------------ + 8 files changed, 68 insertions(+), 55 deletions(-) + +diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c +index 2f6b06b5a617..83ad98b2737d 100644 +--- a/drivers/gpu/drm/drm_mm.c ++++ b/drivers/gpu/drm/drm_mm.c +@@ -212,12 +212,13 @@ EXPORT_SYMBOL(drm_mm_get_block_generic); + */ + int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node, + unsigned long size, unsigned alignment, +- unsigned long color) ++ unsigned long color, ++ enum drm_mm_search_flags flags) + { + struct drm_mm_node *hole_node; + + hole_node = drm_mm_search_free_generic(mm, size, alignment, +- color, 0); ++ color, flags); + if (!hole_node) + return -ENOSPC; + +@@ -226,13 +227,6 @@ int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node, + } + EXPORT_SYMBOL(drm_mm_insert_node_generic); + +-int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, +- unsigned long size, unsigned alignment) +-{ +- return drm_mm_insert_node_generic(mm, node, size, alignment, 0); +-} +-EXPORT_SYMBOL(drm_mm_insert_node); +- + static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, + struct drm_mm_node *node, + unsigned long size, unsigned alignment, +@@ -313,13 +307,14 @@ EXPORT_SYMBOL(drm_mm_get_block_range_generic); + */ + int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *node, + unsigned long size, unsigned alignment, unsigned long color, +- unsigned long start, unsigned long end) ++ unsigned long start, unsigned long end, ++ enum drm_mm_search_flags flags) + { + struct drm_mm_node *hole_node; + + hole_node = drm_mm_search_free_in_range_generic(mm, + size, alignment, color, +- start, end, 0); ++ start, end, flags); + if (!hole_node) + return -ENOSPC; + +@@ -330,14 +325,6 @@ int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *n + } + EXPORT_SYMBOL(drm_mm_insert_node_in_range_generic); + +-int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node, +- unsigned long size, unsigned alignment, +- unsigned long start, unsigned long end) +-{ +- return drm_mm_insert_node_in_range_generic(mm, node, size, alignment, 0, start, end); +-} +-EXPORT_SYMBOL(drm_mm_insert_node_in_range); +- + /** + * Remove a memory node from the allocator. + */ +@@ -413,7 +400,7 @@ struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm, + unsigned long size, + unsigned alignment, + unsigned long color, +- bool best_match) ++ enum drm_mm_search_flags flags) + { + struct drm_mm_node *entry; + struct drm_mm_node *best; +@@ -436,7 +423,7 @@ struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm, + if (!check_free_hole(adj_start, adj_end, size, alignment)) + continue; + +- if (!best_match) ++ if (!(flags & DRM_MM_SEARCH_BEST)) + return entry; + + if (entry->size < best_size) { +@@ -455,7 +442,7 @@ struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm, + unsigned long color, + unsigned long start, + unsigned long end, +- bool best_match) ++ enum drm_mm_search_flags flags) + { + struct drm_mm_node *entry; + struct drm_mm_node *best; +@@ -483,7 +470,7 @@ struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm, + if (!check_free_hole(adj_start, adj_end, size, alignment)) + continue; + +- if (!best_match) ++ if (!(flags & DRM_MM_SEARCH_BEST)) + return entry; + + if (entry->size < best_size) { +@@ -629,8 +616,8 @@ EXPORT_SYMBOL(drm_mm_scan_add_block); + * corrupted. + * + * When the scan list is empty, the selected memory nodes can be freed. An +- * immediately following drm_mm_search_free with best_match = 0 will then return +- * the just freed block (because its at the top of the free_stack list). ++ * immediately following drm_mm_search_free with !DRM_MM_SEARCH_BEST will then ++ * return the just freed block (because its at the top of the free_stack list). + * + * Returns one if this block should be evicted, zero otherwise. Will always + * return zero when no hole has been found. +diff --git a/drivers/gpu/drm/drm_vma_manager.c b/drivers/gpu/drm/drm_vma_manager.c +index b966cea95f11..3837481d5607 100644 +--- a/drivers/gpu/drm/drm_vma_manager.c ++++ b/drivers/gpu/drm/drm_vma_manager.c +@@ -241,8 +241,8 @@ int drm_vma_offset_add(struct drm_vma_offset_manager *mgr, + goto out_unlock; + } + +- ret = drm_mm_insert_node_generic(&mgr->vm_addr_space_mm, +- &node->vm_node, pages, 0, 0); ++ ret = drm_mm_insert_node(&mgr->vm_addr_space_mm, &node->vm_node, ++ pages, 0, DRM_MM_SEARCH_DEFAULT); + if (ret) + goto out_unlock; + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 967fe650fa8b..deb0a0fcf2b4 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3124,7 +3124,8 @@ search_free: + ret = drm_mm_insert_node_in_range_generic(&dev_priv->gtt.base.mm, + &vma->node, + size, alignment, +- obj->cache_level, 0, gtt_max); ++ obj->cache_level, 0, gtt_max, ++ DRM_MM_SEARCH_DEFAULT); + if (ret) { + ret = i915_gem_evict_something(dev, size, alignment, + obj->cache_level, +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 5531643136f5..03bb991e0267 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -97,10 +97,12 @@ static int i915_setup_compression(struct drm_device *dev, int size) + + /* Try to over-allocate to reduce reallocations and fragmentation */ + compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, +- size <<= 1, 4096, 0); ++ size <<= 1, 4096, ++ DRM_MM_SEARCH_DEFAULT); + if (!compressed_fb) + compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, +- size >>= 1, 4096, 0); ++ size >>= 1, 4096, ++ DRM_MM_SEARCH_DEFAULT); + if (compressed_fb) + compressed_fb = drm_mm_get_block(compressed_fb, size, 4096); + if (!compressed_fb) +@@ -112,7 +114,8 @@ static int i915_setup_compression(struct drm_device *dev, int size) + I915_WRITE(DPFC_CB_BASE, compressed_fb->start); + } else { + compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen, +- 4096, 4096, 0); ++ 4096, 4096, ++ DRM_MM_SEARCH_DEFAULT); + if (compressed_llb) + compressed_llb = drm_mm_get_block(compressed_llb, + 4096, 4096); +@@ -310,7 +313,8 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size) + if (size == 0) + return NULL; + +- stolen = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, 0); ++ stolen = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, ++ DRM_MM_SEARCH_DEFAULT); + if (stolen) + stolen = drm_mm_get_block(stolen, size, 4096); + if (stolen == NULL) +diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c +index 9a43d98e5003..23a234985941 100644 +--- a/drivers/gpu/drm/sis/sis_mm.c ++++ b/drivers/gpu/drm/sis/sis_mm.c +@@ -109,7 +109,8 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file, + if (pool == AGP_TYPE) { + retval = drm_mm_insert_node(&dev_priv->agp_mm, + &item->mm_node, +- mem->size, 0); ++ mem->size, 0, ++ DRM_MM_SEARCH_DEFAULT); + offset = item->mm_node.start; + } else { + #if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) +@@ -121,7 +122,8 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file, + #else + retval = drm_mm_insert_node(&dev_priv->vram_mm, + &item->mm_node, +- mem->size, 0); ++ mem->size, 0, ++ DRM_MM_SEARCH_DEFAULT); + offset = item->mm_node.start; + #endif + } +diff --git a/drivers/gpu/drm/ttm/ttm_bo_manager.c b/drivers/gpu/drm/ttm/ttm_bo_manager.c +index e4367f91472a..e4be29efba6b 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo_manager.c ++++ b/drivers/gpu/drm/ttm/ttm_bo_manager.c +@@ -69,7 +69,8 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, + spin_lock(&rman->lock); + node = drm_mm_search_free_in_range(mm, + mem->num_pages, mem->page_alignment, +- placement->fpfn, lpfn, 1); ++ placement->fpfn, lpfn, ++ DRM_MM_SEARCH_BEST); + if (unlikely(node == NULL)) { + spin_unlock(&rman->lock); + return 0; +diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c +index 0ab93ff09873..7e3ad87c366c 100644 +--- a/drivers/gpu/drm/via/via_mm.c ++++ b/drivers/gpu/drm/via/via_mm.c +@@ -140,11 +140,11 @@ int via_mem_alloc(struct drm_device *dev, void *data, + if (mem->type == VIA_MEM_AGP) + retval = drm_mm_insert_node(&dev_priv->agp_mm, + &item->mm_node, +- tmpSize, 0); ++ tmpSize, 0, DRM_MM_SEARCH_DEFAULT); + else + retval = drm_mm_insert_node(&dev_priv->vram_mm, + &item->mm_node, +- tmpSize, 0); ++ tmpSize, 0, DRM_MM_SEARCH_DEFAULT); + if (retval) + goto fail_alloc; + +diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h +index e3aceb350001..aebbe3d5b280 100644 +--- a/include/drm/drm_mm.h ++++ b/include/drm/drm_mm.h +@@ -41,6 +41,11 @@ + #include + #endif + ++enum drm_mm_search_flags { ++ DRM_MM_SEARCH_DEFAULT = 0, ++ DRM_MM_SEARCH_BEST = 1 << 0, ++}; ++ + struct drm_mm_node { + struct list_head node_list; + struct list_head hole_stack; +@@ -197,28 +202,41 @@ static inline struct drm_mm_node *drm_mm_get_block_atomic_range( + start, end, 1); + } + +-extern int drm_mm_insert_node(struct drm_mm *mm, +- struct drm_mm_node *node, +- unsigned long size, +- unsigned alignment); +-extern int drm_mm_insert_node_in_range(struct drm_mm *mm, +- struct drm_mm_node *node, +- unsigned long size, +- unsigned alignment, +- unsigned long start, +- unsigned long end); + extern int drm_mm_insert_node_generic(struct drm_mm *mm, + struct drm_mm_node *node, + unsigned long size, + unsigned alignment, +- unsigned long color); ++ unsigned long color, ++ enum drm_mm_search_flags flags); ++static inline int drm_mm_insert_node(struct drm_mm *mm, ++ struct drm_mm_node *node, ++ unsigned long size, ++ unsigned alignment, ++ enum drm_mm_search_flags flags) ++{ ++ return drm_mm_insert_node_generic(mm, node, size, alignment, 0, flags); ++} ++ + extern int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, + struct drm_mm_node *node, + unsigned long size, + unsigned alignment, + unsigned long color, + unsigned long start, +- unsigned long end); ++ unsigned long end, ++ enum drm_mm_search_flags flags); ++static inline int drm_mm_insert_node_in_range(struct drm_mm *mm, ++ struct drm_mm_node *node, ++ unsigned long size, ++ unsigned alignment, ++ unsigned long start, ++ unsigned long end, ++ enum drm_mm_search_flags flags) ++{ ++ return drm_mm_insert_node_in_range_generic(mm, node, size, alignment, ++ 0, start, end, flags); ++} ++ + extern void drm_mm_put_block(struct drm_mm_node *cur); + extern void drm_mm_remove_node(struct drm_mm_node *node); + extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new); +@@ -226,7 +244,7 @@ extern struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm, + unsigned long size, + unsigned alignment, + unsigned long color, +- bool best_match); ++ enum drm_mm_search_flags flags); + extern struct drm_mm_node *drm_mm_search_free_in_range_generic( + const struct drm_mm *mm, + unsigned long size, +@@ -234,13 +252,13 @@ extern struct drm_mm_node *drm_mm_search_free_in_range_generic( + unsigned long color, + unsigned long start, + unsigned long end, +- bool best_match); ++ enum drm_mm_search_flags flags); + static inline struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, + unsigned long size, + unsigned alignment, +- bool best_match) ++ enum drm_mm_search_flags flags) + { +- return drm_mm_search_free_generic(mm,size, alignment, 0, best_match); ++ return drm_mm_search_free_generic(mm,size, alignment, 0, flags); + } + static inline struct drm_mm_node *drm_mm_search_free_in_range( + const struct drm_mm *mm, +@@ -248,10 +266,10 @@ static inline struct drm_mm_node *drm_mm_search_free_in_range( + unsigned alignment, + unsigned long start, + unsigned long end, +- bool best_match) ++ enum drm_mm_search_flags flags) + { + return drm_mm_search_free_in_range_generic(mm, size, alignment, 0, +- start, end, best_match); ++ start, end, flags); + } + static inline struct drm_mm_node *drm_mm_search_free_color(const struct drm_mm *mm, + unsigned long size, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0598-drm-const-ify-ioctls-table-v2.patch b/patches.baytrail/0598-drm-const-ify-ioctls-table-v2.patch new file mode 100644 index 000000000000..b860bcabbc06 --- /dev/null +++ b/patches.baytrail/0598-drm-const-ify-ioctls-table-v2.patch @@ -0,0 +1,432 @@ +From f027e2cb678fa555f8356f5a0f0e332afe0894d1 Mon Sep 17 00:00:00 2001 +From: Rob Clark +Date: Fri, 2 Aug 2013 13:27:49 -0400 +Subject: drm: const'ify ioctls table (v2) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Because, there is no reason for it not to be const. + +v1: original +v2: fix compile break in vmwgfx, and couple related cleanups suggested + by Ville Syrjälä + +Signed-off-by: Rob Clark +Reviewed-by: Ville Syrjälä +Reviewed-by: Alex Deucher +Signed-off-by: Dave Airlie +(cherry picked from commit baa7094355a10b432bbccacb925da4bdac861c8d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/exynos/exynos_drm_drv.c | 4 ++-- + drivers/gpu/drm/gma500/psb_drv.c | 2 +- + drivers/gpu/drm/i810/i810_dma.c | 2 +- + drivers/gpu/drm/i810/i810_drv.h | 2 +- + drivers/gpu/drm/i915/i915_dma.c | 2 +- + drivers/gpu/drm/i915/i915_drv.h | 2 +- + drivers/gpu/drm/mga/mga_drv.h | 2 +- + drivers/gpu/drm/mga/mga_state.c | 2 +- + drivers/gpu/drm/nouveau/nouveau_drm.c | 5 ++--- + drivers/gpu/drm/omapdrm/omap_drv.c | 2 +- + drivers/gpu/drm/qxl/qxl_drv.h | 2 +- + drivers/gpu/drm/qxl/qxl_ioctl.c | 2 +- + drivers/gpu/drm/r128/r128_drv.h | 2 +- + drivers/gpu/drm/r128/r128_state.c | 2 +- + drivers/gpu/drm/radeon/radeon_drv.c | 2 +- + drivers/gpu/drm/radeon/radeon_kms.c | 2 +- + drivers/gpu/drm/savage/savage_bci.c | 2 +- + drivers/gpu/drm/savage/savage_drv.h | 2 +- + drivers/gpu/drm/sis/sis_drv.h | 2 +- + drivers/gpu/drm/sis/sis_mm.c | 2 +- + drivers/gpu/drm/via/via_dma.c | 2 +- + drivers/gpu/drm/via/via_drv.h | 2 +- + drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 4 ++-- + drivers/gpu/host1x/drm/drm.c | 2 +- + drivers/staging/imx-drm/imx-drm-core.c | 2 +- + include/drm/drmP.h | 2 +- + 26 files changed, 29 insertions(+), 30 deletions(-) + +diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c +index 1ff89aca1fed..7e4669188c63 100644 +--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c +@@ -218,7 +218,7 @@ static const struct vm_operations_struct exynos_drm_gem_vm_ops = { + .close = drm_gem_vm_close, + }; + +-static struct drm_ioctl_desc exynos_ioctls[] = { ++static const struct drm_ioctl_desc exynos_ioctls[] = { + DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl, + DRM_UNLOCKED | DRM_AUTH), + DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP_OFFSET, +@@ -282,6 +282,7 @@ static struct drm_driver exynos_drm_driver = { + .gem_prime_export = exynos_dmabuf_prime_export, + .gem_prime_import = exynos_dmabuf_prime_import, + .ioctls = exynos_ioctls, ++ .num_ioctls = ARRAY_SIZE(exynos_ioctls), + .fops = &exynos_drm_driver_fops, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, +@@ -295,7 +296,6 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) + DRM_DEBUG_DRIVER("%s\n", __FILE__); + + pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +- exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls); + + return drm_platform_init(&exynos_drm_driver, pdev); + } +diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c +index ed06d5ce3757..d13c2fc848bc 100644 +--- a/drivers/gpu/drm/gma500/psb_drv.c ++++ b/drivers/gpu/drm/gma500/psb_drv.c +@@ -131,7 +131,7 @@ static int psb_gamma_ioctl(struct drm_device *dev, void *data, + static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +-static struct drm_ioctl_desc psb_ioctls[] = { ++static const struct drm_ioctl_desc psb_ioctls[] = { + DRM_IOCTL_DEF_DRV(GMA_ADB, psb_adb_ioctl, DRM_AUTH), + DRM_IOCTL_DEF_DRV(GMA_MODE_OPERATION, psb_mode_operation_ioctl, + DRM_AUTH), +diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c +index 004ecdfe1b55..926ac7d48381 100644 +--- a/drivers/gpu/drm/i810/i810_dma.c ++++ b/drivers/gpu/drm/i810/i810_dma.c +@@ -1241,7 +1241,7 @@ int i810_driver_dma_quiescent(struct drm_device *dev) + return 0; + } + +-struct drm_ioctl_desc i810_ioctls[] = { ++const struct drm_ioctl_desc i810_ioctls[] = { + DRM_IOCTL_DEF_DRV(I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED), +diff --git a/drivers/gpu/drm/i810/i810_drv.h b/drivers/gpu/drm/i810/i810_drv.h +index 6e0acad9e0f5..d4d16eddd651 100644 +--- a/drivers/gpu/drm/i810/i810_drv.h ++++ b/drivers/gpu/drm/i810/i810_drv.h +@@ -125,7 +125,7 @@ extern void i810_driver_preclose(struct drm_device *dev, + extern int i810_driver_device_is_agp(struct drm_device *dev); + + extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +-extern struct drm_ioctl_desc i810_ioctls[]; ++extern const struct drm_ioctl_desc i810_ioctls[]; + extern int i810_max_ioctl; + + #define I810_BASE(reg) ((unsigned long) \ +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index e4e98dfb7f25..0adfe4000871 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1833,7 +1833,7 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) + kfree(file_priv); + } + +-struct drm_ioctl_desc i915_ioctls[] = { ++const struct drm_ioctl_desc i915_ioctls[] = { + DRM_IOCTL_DEF_DRV(I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_FLUSH, i915_flush_ioctl, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_FLIP, i915_flip_bufs, DRM_AUTH), +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 06c31752fcb2..2468d3aec9af 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1595,7 +1595,7 @@ struct drm_i915_file_private { + #define INTEL_RC6p_ENABLE (1<<1) + #define INTEL_RC6pp_ENABLE (1<<2) + +-extern struct drm_ioctl_desc i915_ioctls[]; ++extern const struct drm_ioctl_desc i915_ioctls[]; + extern int i915_max_ioctl; + extern unsigned int i915_fbpercrtc __always_unused; + extern int i915_panel_ignore_lid __read_mostly; +diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h +index 54558a01969a..ca4bc54ea214 100644 +--- a/drivers/gpu/drm/mga/mga_drv.h ++++ b/drivers/gpu/drm/mga/mga_drv.h +@@ -149,7 +149,7 @@ typedef struct drm_mga_private { + unsigned int agp_size; + } drm_mga_private_t; + +-extern struct drm_ioctl_desc mga_ioctls[]; ++extern const struct drm_ioctl_desc mga_ioctls[]; + extern int mga_max_ioctl; + + /* mga_dma.c */ +diff --git a/drivers/gpu/drm/mga/mga_state.c b/drivers/gpu/drm/mga/mga_state.c +index 9c145143ad0f..37cc2fb4eadd 100644 +--- a/drivers/gpu/drm/mga/mga_state.c ++++ b/drivers/gpu/drm/mga/mga_state.c +@@ -1083,7 +1083,7 @@ file_priv) + return 0; + } + +-struct drm_ioctl_desc mga_ioctls[] = { ++const struct drm_ioctl_desc mga_ioctls[] = { + DRM_IOCTL_DEF_DRV(MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(MGA_FLUSH, mga_dma_flush, DRM_AUTH), + DRM_IOCTL_DEF_DRV(MGA_RESET, mga_dma_reset, DRM_AUTH), +diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c +index b77bcb9237e0..421815b1ef93 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drm.c ++++ b/drivers/gpu/drm/nouveau/nouveau_drm.c +@@ -640,7 +640,7 @@ nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv) + nouveau_cli_destroy(cli); + } + +-static struct drm_ioctl_desc ++static const struct drm_ioctl_desc + nouveau_ioctls[] = { + DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_abi16_ioctl_getparam, DRM_UNLOCKED|DRM_AUTH), + DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_abi16_ioctl_setparam, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), +@@ -695,6 +695,7 @@ driver = { + .disable_vblank = nouveau_drm_vblank_disable, + + .ioctls = nouveau_ioctls, ++ .num_ioctls = ARRAY_SIZE(nouveau_ioctls), + .fops = &nouveau_driver_fops, + + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, +@@ -764,8 +765,6 @@ nouveau_drm_pci_driver = { + static int __init + nouveau_drm_init(void) + { +- driver.num_ioctls = ARRAY_SIZE(nouveau_ioctls); +- + if (nouveau_modeset == -1) { + #ifdef CONFIG_VGA_CONSOLE + if (vgacon_text_force()) +diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c +index 75886a3bf639..f69f9f6785e8 100644 +--- a/drivers/gpu/drm/omapdrm/omap_drv.c ++++ b/drivers/gpu/drm/omapdrm/omap_drv.c +@@ -404,7 +404,7 @@ static int ioctl_gem_info(struct drm_device *dev, void *data, + return ret; + } + +-static struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { ++static const struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { + DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param, DRM_UNLOCKED|DRM_AUTH), + DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH), +diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h +index 089fd42802dd..6bdb2689e95e 100644 +--- a/drivers/gpu/drm/qxl/qxl_drv.h ++++ b/drivers/gpu/drm/qxl/qxl_drv.h +@@ -319,7 +319,7 @@ struct qxl_device { + /* forward declaration for QXL_INFO_IO */ + void qxl_io_log(struct qxl_device *qdev, const char *fmt, ...); + +-extern struct drm_ioctl_desc qxl_ioctls[]; ++extern const struct drm_ioctl_desc qxl_ioctls[]; + extern int qxl_max_ioctl; + + int qxl_driver_load(struct drm_device *dev, unsigned long flags); +diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c +index a30f29425c21..faa5b17a9c9e 100644 +--- a/drivers/gpu/drm/qxl/qxl_ioctl.c ++++ b/drivers/gpu/drm/qxl/qxl_ioctl.c +@@ -396,7 +396,7 @@ static int qxl_alloc_surf_ioctl(struct drm_device *dev, void *data, + return ret; + } + +-struct drm_ioctl_desc qxl_ioctls[] = { ++const struct drm_ioctl_desc qxl_ioctls[] = { + DRM_IOCTL_DEF_DRV(QXL_ALLOC, qxl_alloc_ioctl, DRM_AUTH|DRM_UNLOCKED), + + DRM_IOCTL_DEF_DRV(QXL_MAP, qxl_map_ioctl, DRM_AUTH|DRM_UNLOCKED), +diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h +index 930c71b2fb5e..56eb5e3f5439 100644 +--- a/drivers/gpu/drm/r128/r128_drv.h ++++ b/drivers/gpu/drm/r128/r128_drv.h +@@ -131,7 +131,7 @@ typedef struct drm_r128_buf_priv { + drm_r128_freelist_t *list_entry; + } drm_r128_buf_priv_t; + +-extern struct drm_ioctl_desc r128_ioctls[]; ++extern const struct drm_ioctl_desc r128_ioctls[]; + extern int r128_max_ioctl; + + /* r128_cce.c */ +diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c +index 19bb7e6f3d9a..01dd9aef9f0e 100644 +--- a/drivers/gpu/drm/r128/r128_state.c ++++ b/drivers/gpu/drm/r128/r128_state.c +@@ -1643,7 +1643,7 @@ void r128_driver_lastclose(struct drm_device *dev) + r128_do_cleanup_cce(dev); + } + +-struct drm_ioctl_desc r128_ioctls[] = { ++const struct drm_ioctl_desc r128_ioctls[] = { + DRM_IOCTL_DEF_DRV(R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), +diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c +index bef72931ea08..cb84df3114a6 100644 +--- a/drivers/gpu/drm/radeon/radeon_drv.c ++++ b/drivers/gpu/drm/radeon/radeon_drv.c +@@ -110,7 +110,7 @@ void radeon_gem_object_close(struct drm_gem_object *obj, + struct drm_file *file_priv); + extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, + int *vpos, int *hpos); +-extern struct drm_ioctl_desc radeon_ioctls_kms[]; ++extern const struct drm_ioctl_desc radeon_ioctls_kms[]; + extern int radeon_max_kms_ioctl; + int radeon_mmap(struct file *filp, struct vm_area_struct *vma); + int radeon_mode_dumb_mmap(struct drm_file *filp, +diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c +index 7e292d899209..100d10930da5 100644 +--- a/drivers/gpu/drm/radeon/radeon_kms.c ++++ b/drivers/gpu/drm/radeon/radeon_kms.c +@@ -716,7 +716,7 @@ KMS_INVALID_IOCTL(radeon_surface_alloc_kms) + KMS_INVALID_IOCTL(radeon_surface_free_kms) + + +-struct drm_ioctl_desc radeon_ioctls_kms[] = { ++const struct drm_ioctl_desc radeon_ioctls_kms[] = { + DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), +diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c +index b55c1d661147..ce3a7d42ee43 100644 +--- a/drivers/gpu/drm/savage/savage_bci.c ++++ b/drivers/gpu/drm/savage/savage_bci.c +@@ -1085,7 +1085,7 @@ void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) + drm_idlelock_release(&file_priv->master->lock); + } + +-struct drm_ioctl_desc savage_ioctls[] = { ++const struct drm_ioctl_desc savage_ioctls[] = { + DRM_IOCTL_DEF_DRV(SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH), + DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH), +diff --git a/drivers/gpu/drm/savage/savage_drv.h b/drivers/gpu/drm/savage/savage_drv.h +index df2aac6636f7..5f55b21ea22d 100644 +--- a/drivers/gpu/drm/savage/savage_drv.h ++++ b/drivers/gpu/drm/savage/savage_drv.h +@@ -104,7 +104,7 @@ enum savage_family { + S3_LAST + }; + +-extern struct drm_ioctl_desc savage_ioctls[]; ++extern const struct drm_ioctl_desc savage_ioctls[]; + extern int savage_max_ioctl; + + #define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) +diff --git a/drivers/gpu/drm/sis/sis_drv.h b/drivers/gpu/drm/sis/sis_drv.h +index 13b527bb83be..c31c0253054d 100644 +--- a/drivers/gpu/drm/sis/sis_drv.h ++++ b/drivers/gpu/drm/sis/sis_drv.h +@@ -70,7 +70,7 @@ extern void sis_reclaim_buffers_locked(struct drm_device *dev, + struct drm_file *file_priv); + extern void sis_lastclose(struct drm_device *dev); + +-extern struct drm_ioctl_desc sis_ioctls[]; ++extern const struct drm_ioctl_desc sis_ioctls[]; + extern int sis_max_ioctl; + + #endif +diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c +index 23a234985941..01857d836350 100644 +--- a/drivers/gpu/drm/sis/sis_mm.c ++++ b/drivers/gpu/drm/sis/sis_mm.c +@@ -350,7 +350,7 @@ void sis_reclaim_buffers_locked(struct drm_device *dev, + return; + } + +-struct drm_ioctl_desc sis_ioctls[] = { ++const struct drm_ioctl_desc sis_ioctls[] = { + DRM_IOCTL_DEF_DRV(SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH), + DRM_IOCTL_DEF_DRV(SIS_FB_FREE, sis_drm_free, DRM_AUTH), + DRM_IOCTL_DEF_DRV(SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), +diff --git a/drivers/gpu/drm/via/via_dma.c b/drivers/gpu/drm/via/via_dma.c +index 13558f5a2422..652f9b43ec9d 100644 +--- a/drivers/gpu/drm/via/via_dma.c ++++ b/drivers/gpu/drm/via/via_dma.c +@@ -720,7 +720,7 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file * + return ret; + } + +-struct drm_ioctl_desc via_ioctls[] = { ++const struct drm_ioctl_desc via_ioctls[] = { + DRM_IOCTL_DEF_DRV(VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH), + DRM_IOCTL_DEF_DRV(VIA_FREEMEM, via_mem_free, DRM_AUTH), + DRM_IOCTL_DEF_DRV(VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER), +diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h +index 893a65090c36..a811ef2b505f 100644 +--- a/drivers/gpu/drm/via/via_drv.h ++++ b/drivers/gpu/drm/via/via_drv.h +@@ -114,7 +114,7 @@ enum via_family { + #define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg) + #define VIA_WRITE8(reg, val) DRM_WRITE8(VIA_BASE, reg, val) + +-extern struct drm_ioctl_desc via_ioctls[]; ++extern const struct drm_ioctl_desc via_ioctls[]; + extern int via_max_ioctl; + + extern int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv); +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +index 6c44c69a5ba4..46ebf7312dc9 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +@@ -124,7 +124,7 @@ + * Ioctl definitions. + */ + +-static struct drm_ioctl_desc vmw_ioctls[] = { ++static const struct drm_ioctl_desc vmw_ioctls[] = { + VMW_IOCTL_DEF(VMW_GET_PARAM, vmw_getparam_ioctl, + DRM_AUTH | DRM_UNLOCKED), + VMW_IOCTL_DEF(VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, +@@ -792,7 +792,7 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd, + + if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) + && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { +- struct drm_ioctl_desc *ioctl = ++ const struct drm_ioctl_desc *ioctl = + &vmw_ioctls[nr - DRM_COMMAND_BASE]; + + if (unlikely(ioctl->cmd_drv != cmd)) { +diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c +index da15a6291bb9..c114080d0d58 100644 +--- a/drivers/gpu/host1x/drm/drm.c ++++ b/drivers/gpu/host1x/drm/drm.c +@@ -479,7 +479,7 @@ static int tegra_submit(struct drm_device *drm, void *data, + } + #endif + +-static struct drm_ioctl_desc tegra_drm_ioctls[] = { ++static const struct drm_ioctl_desc tegra_drm_ioctls[] = { + #ifdef CONFIG_DRM_TEGRA_STAGING + DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create, DRM_UNLOCKED | DRM_AUTH), + DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap, DRM_UNLOCKED), +diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c +index a18622570812..f2a07af5cd5e 100644 +--- a/drivers/staging/imx-drm/imx-drm-core.c ++++ b/drivers/staging/imx-drm/imx-drm-core.c +@@ -787,7 +787,7 @@ int imx_drm_remove_connector(struct imx_drm_connector *imx_drm_connector) + } + EXPORT_SYMBOL_GPL(imx_drm_remove_connector); + +-static struct drm_ioctl_desc imx_drm_ioctls[] = { ++static const struct drm_ioctl_desc imx_drm_ioctls[] = { + /* none so far */ + }; + +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 9a8ea57e3b94..70de499fa3b7 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -965,7 +965,7 @@ struct drm_driver { + + u32 driver_features; + int dev_priv_size; +- struct drm_ioctl_desc *ioctls; ++ const struct drm_ioctl_desc *ioctls; + int num_ioctls; + const struct file_operations *fops; + union { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0599-drm-i915-pre-alloc-instead-of-drm_mm-search-get_bloc.patch b/patches.baytrail/0599-drm-i915-pre-alloc-instead-of-drm_mm-search-get_bloc.patch new file mode 100644 index 000000000000..387e840248a9 --- /dev/null +++ b/patches.baytrail/0599-drm-i915-pre-alloc-instead-of-drm_mm-search-get_bloc.patch @@ -0,0 +1,176 @@ +From ab3af9e47229f8921603280b54935a0c53823997 Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Sat, 27 Jul 2013 16:21:27 +0200 +Subject: drm/i915: pre-alloc instead of drm_mm search/get_block + +i915 is the last user of the weird search+get_block drm_mm API. Convert it +to an explicit kmalloc()+insert_node(). This drops the last user of the +node-cache in drm_mm. We can remove it now in a follow-up patch. + +v2: + - simplify error path in i915_setup_compression() +v3: + - simplify error path even more + +Cc: Chris Wilson +Acked-by: Daniel Vetter +Signed-off-by: David Herrmann +Signed-off-by: Dave Airlie +(cherry picked from commit 06e78edff18195f8e416e6961fea7d88118a5c63) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_stolen.c | 78 ++++++++++++++++++++-------------- + 1 file changed, 47 insertions(+), 31 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 03bb991e0267..0d0a3b179075 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -94,34 +94,36 @@ static int i915_setup_compression(struct drm_device *dev, int size) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb); ++ int ret; + +- /* Try to over-allocate to reduce reallocations and fragmentation */ +- compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, +- size <<= 1, 4096, +- DRM_MM_SEARCH_DEFAULT); +- if (!compressed_fb) +- compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, +- size >>= 1, 4096, +- DRM_MM_SEARCH_DEFAULT); +- if (compressed_fb) +- compressed_fb = drm_mm_get_block(compressed_fb, size, 4096); ++ compressed_fb = kzalloc(sizeof(*compressed_fb), GFP_KERNEL); + if (!compressed_fb) +- goto err; ++ goto err_llb; ++ ++ /* Try to over-allocate to reduce reallocations and fragmentation */ ++ ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_fb, ++ size <<= 1, 4096, DRM_MM_SEARCH_DEFAULT); ++ if (ret) ++ ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_fb, ++ size >>= 1, 4096, ++ DRM_MM_SEARCH_DEFAULT); ++ if (ret) ++ goto err_llb; + + if (HAS_PCH_SPLIT(dev)) + I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start); + else if (IS_GM45(dev)) { + I915_WRITE(DPFC_CB_BASE, compressed_fb->start); + } else { +- compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen, +- 4096, 4096, +- DRM_MM_SEARCH_DEFAULT); +- if (compressed_llb) +- compressed_llb = drm_mm_get_block(compressed_llb, +- 4096, 4096); ++ compressed_llb = kzalloc(sizeof(*compressed_llb), GFP_KERNEL); + if (!compressed_llb) + goto err_fb; + ++ ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_llb, ++ 4096, 4096, DRM_MM_SEARCH_DEFAULT); ++ if (ret) ++ goto err_fb; ++ + dev_priv->fbc.compressed_llb = compressed_llb; + + I915_WRITE(FBC_CFB_BASE, +@@ -139,8 +141,10 @@ static int i915_setup_compression(struct drm_device *dev, int size) + return 0; + + err_fb: +- drm_mm_put_block(compressed_fb); +-err: ++ kfree(compressed_llb); ++ drm_mm_remove_node(compressed_fb); ++err_llb: ++ kfree(compressed_fb); + pr_info_once("drm: not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size); + return -ENOSPC; + } +@@ -168,11 +172,15 @@ void i915_gem_stolen_cleanup_compression(struct drm_device *dev) + if (dev_priv->fbc.size == 0) + return; + +- if (dev_priv->fbc.compressed_fb) +- drm_mm_put_block(dev_priv->fbc.compressed_fb); ++ if (dev_priv->fbc.compressed_fb) { ++ drm_mm_remove_node(dev_priv->fbc.compressed_fb); ++ kfree(dev_priv->fbc.compressed_fb); ++ } + +- if (dev_priv->fbc.compressed_llb) +- drm_mm_put_block(dev_priv->fbc.compressed_llb); ++ if (dev_priv->fbc.compressed_llb) { ++ drm_mm_remove_node(dev_priv->fbc.compressed_llb); ++ kfree(dev_priv->fbc.compressed_llb); ++ } + + dev_priv->fbc.size = 0; + } +@@ -305,6 +313,7 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size) + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj; + struct drm_mm_node *stolen; ++ int ret; + + if (!drm_mm_initialized(&dev_priv->mm.stolen)) + return NULL; +@@ -313,18 +322,23 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size) + if (size == 0) + return NULL; + +- stolen = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, +- DRM_MM_SEARCH_DEFAULT); +- if (stolen) +- stolen = drm_mm_get_block(stolen, size, 4096); +- if (stolen == NULL) ++ stolen = kzalloc(sizeof(*stolen), GFP_KERNEL); ++ if (!stolen) + return NULL; + ++ ret = drm_mm_insert_node(&dev_priv->mm.stolen, stolen, size, ++ 4096, DRM_MM_SEARCH_DEFAULT); ++ if (ret) { ++ kfree(stolen); ++ return NULL; ++ } ++ + obj = _i915_gem_object_create_stolen(dev, stolen); + if (obj) + return obj; + +- drm_mm_put_block(stolen); ++ drm_mm_remove_node(stolen); ++ kfree(stolen); + return NULL; + } + +@@ -370,7 +384,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + obj = _i915_gem_object_create_stolen(dev, stolen); + if (obj == NULL) { + DRM_DEBUG_KMS("failed to allocate stolen object\n"); +- drm_mm_put_block(stolen); ++ drm_mm_remove_node(stolen); ++ kfree(stolen); + return NULL; + } + +@@ -417,7 +432,8 @@ void + i915_gem_object_release_stolen(struct drm_i915_gem_object *obj) + { + if (obj->stolen) { +- drm_mm_put_block(obj->stolen); ++ drm_mm_remove_node(obj->stolen); ++ kfree(obj->stolen); + obj->stolen = NULL; + } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0600-Re-create-dirty-merge-32c913e.patch b/patches.baytrail/0600-Re-create-dirty-merge-32c913e.patch new file mode 100644 index 000000000000..a998078be976 --- /dev/null +++ b/patches.baytrail/0600-Re-create-dirty-merge-32c913e.patch @@ -0,0 +1,35 @@ +From 38ca57a9cd5d6555f2c1981cd3974203350f2dbc Mon Sep 17 00:00:00 2001 +From: James Ausmus +Date: Thu, 10 Oct 2013 19:05:12 -0700 +Subject: Re-create dirty merge 32c913e + +Fix code up to post-merge state after 32c913e4369ce7bd1d16a9b6983f7b8975c13f5a +("Merge tag 'drm-intel-next-2013-07-26-fixed' of +git://people.freedesktop.org/~danvet/drm-intel into drm-next") + +Signed-off-by: James Ausmus +(cherry picked from + https://chromium.googlesource.com/chromiumos/third_party/kernel-next + chromeos-3.10, 3a0d8e0095892f31c9cdde50b147ea606bb541b7) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_stolen.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 0d0a3b179075..ba4dabca83c2 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -423,7 +423,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + return obj; + + err_out: +- drm_mm_put_block(stolen); ++ drm_mm_remove_node(stolen); ++ kfree(stolen); + drm_gem_object_unreference(&obj->base); + return NULL; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0601-drm-i915-Rework-__i915_gem_shrink.patch b/patches.baytrail/0601-drm-i915-Rework-__i915_gem_shrink.patch new file mode 100644 index 000000000000..b8bc6021d7c9 --- /dev/null +++ b/patches.baytrail/0601-drm-i915-Rework-__i915_gem_shrink.patch @@ -0,0 +1,41 @@ +From df1f9168b19ff78f1e4272c506cb4edbce0916fa Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:01 -0700 +Subject: drm/i915: Rework __i915_gem_shrink + +In order to do this for all VMs, it's convenient to rework the logic a +bit. This should have no functional impact. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 80dcfdbd68b094f21f7ce222fb8039123f5b4cbe) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index deb0a0fcf2b4..6fa05c47ea4b 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -1694,9 +1694,14 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, + } + + list_for_each_entry_safe(obj, next, &vm->inactive_list, mm_list) { +- if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) && +- i915_gem_object_unbind(obj) == 0 && +- i915_gem_object_put_pages(obj) == 0) { ++ ++ if (!i915_gem_object_is_purgeable(obj) && purgeable_only) ++ continue; ++ ++ if (i915_gem_object_unbind(obj)) ++ continue; ++ ++ if (!i915_gem_object_put_pages(obj)) { + count += obj->base.size >> PAGE_SHIFT; + if (count >= target) + return count; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0602-drm-i915-plumb-VM-into-bind-unbind-code.patch b/patches.baytrail/0602-drm-i915-plumb-VM-into-bind-unbind-code.patch new file mode 100644 index 000000000000..04218ac2a8c4 --- /dev/null +++ b/patches.baytrail/0602-drm-i915-plumb-VM-into-bind-unbind-code.patch @@ -0,0 +1,530 @@ +From 663c990c6ca1129872b76a6f7ec8d22ceee8fd81 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:10 -0700 +Subject: drm/i915: plumb VM into bind/unbind code + +As alluded to in several patches, and it will be reiterated later... A +VMA is an abstraction for a GEM BO bound into an address space. +Therefore it stands to reason, that the existing bind, and unbind are +the ones which will be the most impacted. This patch implements this, +and updates all callers which weren't already updated in the series +(because it was too messy). + +This patch represents the bulk of an earlier, larger patch. I've pulled +out a bunch of things by the request of Daniel. The history is preserved +for posterity with the email convention of ">" One big change from the +original patch aside from a bunch of cropping is I've created an +i915_vma_unbind() function. That is because we always have the VMA +anyway, and doing an extra lookup is useful. There is a caveat, we +retain an i915_gem_object_ggtt_unbind, for the global cases which might +not talk in VMAs. + +> drm/i915: plumb VM into object operations +> +> This patch was formerly known as: +> "drm/i915: Create VMAs (part 3) - plumbing" +> +> This patch adds a VM argument, bind/unbind, and the object +> offset/size/color getters/setters. It preserves the old ggtt helper +> functions because things still need, and will continue to need them. +> +> Some code will still need to be ported over after this. +> +> v2: Fix purge to pick an object and unbind all vmas +> This was doable because of the global bound list change. +> +> v3: With the commit to actually pin/unpin pages in place, there is no +> longer a need to check if unbind succeeded before calling put_pages(). +> Make put_pages only BUG() after checking pin count. +> +> v4: Rebased on top of the new hangcheck work by Mika +> plumbed eb_destroy also +> Many checkpatch related fixes +> +> v5: Very large rebase +> +> v6: +> Change BUG_ON to WARN_ON (Daniel) +> Rename vm to ggtt in preallocate stolen, since it is always ggtt when +> dealing with stolen memory. (Daniel) +> list_for_each will short-circuit already (Daniel) +> remove superflous space (Daniel) +> Use per object list of vmas (Daniel) +> Make obj_bound_any() use obj_bound for each vm (Ben) +> s/bind_to_gtt/bind_to_vm/ (Ben) +> +> Fixed up the inactive shrinker. As Daniel noticed the code could +> potentially count the same object multiple times. While it's not +> possible in the current case, since 1 object can only ever be bound into +> 1 address space thus far - we may as well try to get something more +> future proof in place now. With a prep patch before this to switch over +> to using the bound list + inactive check, we're now able to carry that +> forward for every address space an object is bound into. + +Signed-off-by: Ben Widawsky +[danvet: Rebase on top of the loss of "drm/i915: Cleanup more of VMA +in destroy".] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 07fe0b12800d4752d729d4122c01f41f80a5ba5a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 2 +- + drivers/gpu/drm/i915/i915_drv.h | 3 +- + drivers/gpu/drm/i915/i915_gem.c | 134 +++++++++++++++++++---------- + drivers/gpu/drm/i915/i915_gem_evict.c | 4 +- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- + drivers/gpu/drm/i915/i915_gem_tiling.c | 9 +- + drivers/gpu/drm/i915/i915_trace.h | 37 ++++---- + 7 files changed, 120 insertions(+), 71 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 748af58b0cea..d2935b4fd695 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1800,7 +1800,7 @@ i915_drop_caches_set(void *data, u64 val) + if (obj->pin_count) + continue; + +- ret = i915_gem_object_unbind(obj); ++ ret = i915_gem_object_ggtt_unbind(obj); + if (ret) + goto unlock; + } +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 2468d3aec9af..6e8e6950cb8c 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1738,7 +1738,8 @@ int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, + bool map_and_fenceable, + bool nonblocking); + void i915_gem_object_unpin(struct drm_i915_gem_object *obj); +-int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj); ++int __must_check i915_vma_unbind(struct i915_vma *vma); ++int __must_check i915_gem_object_ggtt_unbind(struct drm_i915_gem_object *obj); + int i915_gem_object_put_pages(struct drm_i915_gem_object *obj); + void i915_gem_release_mmap(struct drm_i915_gem_object *obj); + void i915_gem_lastclose(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 6fa05c47ea4b..6f7b1b47d210 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -39,10 +39,12 @@ + + static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); + static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); +-static __must_check int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, +- unsigned alignment, +- bool map_and_fenceable, +- bool nonblocking); ++static __must_check int ++i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, ++ struct i915_address_space *vm, ++ unsigned alignment, ++ bool map_and_fenceable, ++ bool nonblocking); + static int i915_gem_phys_pwrite(struct drm_device *dev, + struct drm_i915_gem_object *obj, + struct drm_i915_gem_pwrite *args, +@@ -1679,7 +1681,6 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, + bool purgeable_only) + { + struct drm_i915_gem_object *obj, *next; +- struct i915_address_space *vm = &dev_priv->gtt.base; + long count = 0; + + list_for_each_entry_safe(obj, next, +@@ -1693,13 +1694,16 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, + } + } + +- list_for_each_entry_safe(obj, next, &vm->inactive_list, mm_list) { ++ list_for_each_entry_safe(obj, next, &dev_priv->mm.bound_list, ++ global_list) { ++ struct i915_vma *vma, *v; + + if (!i915_gem_object_is_purgeable(obj) && purgeable_only) + continue; + +- if (i915_gem_object_unbind(obj)) +- continue; ++ list_for_each_entry_safe(vma, v, &obj->vma_list, vma_link) ++ if (i915_vma_unbind(vma)) ++ break; + + if (!i915_gem_object_put_pages(obj)) { + count += obj->base.size >> PAGE_SHIFT; +@@ -2583,17 +2587,13 @@ static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj) + old_write_domain); + } + +-/** +- * Unbinds an object from the GTT aperture. +- */ +-int +-i915_gem_object_unbind(struct drm_i915_gem_object *obj) ++int i915_vma_unbind(struct i915_vma *vma) + { ++ struct drm_i915_gem_object *obj = vma->obj; + drm_i915_private_t *dev_priv = obj->base.dev->dev_private; +- struct i915_vma *vma; + int ret; + +- if (!i915_gem_obj_ggtt_bound(obj)) ++ if (list_empty(&vma->vma_link)) + return 0; + + if (obj->pin_count) +@@ -2616,7 +2616,7 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) + if (ret) + return ret; + +- trace_i915_gem_object_unbind(obj); ++ trace_i915_vma_unbind(vma); + + if (obj->has_global_gtt_mapping) + i915_gem_gtt_unbind_object(obj); +@@ -2631,7 +2631,6 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) + /* Avoid an unnecessary call to unbind on rebind. */ + obj->map_and_fenceable = true; + +- vma = i915_gem_obj_to_vma(obj, &dev_priv->gtt.base); + list_del(&vma->vma_link); + drm_mm_remove_node(&vma->node); + i915_gem_vma_destroy(vma); +@@ -2646,6 +2645,26 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) + return 0; + } + ++/** ++ * Unbinds an object from the global GTT aperture. ++ */ ++int ++i915_gem_object_ggtt_unbind(struct drm_i915_gem_object *obj) ++{ ++ struct drm_i915_private *dev_priv = obj->base.dev->dev_private; ++ struct i915_address_space *ggtt = &dev_priv->gtt.base; ++ ++ if (!i915_gem_obj_ggtt_bound(obj)); ++ return 0; ++ ++ if (obj->pin_count) ++ return -EBUSY; ++ ++ BUG_ON(obj->pages == NULL); ++ ++ return i915_vma_unbind(i915_gem_obj_to_vma(obj, ggtt)); ++} ++ + int i915_gpu_idle(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; +@@ -3063,18 +3082,18 @@ static void i915_gem_verify_gtt(struct drm_device *dev) + * Finds free space in the GTT aperture and binds the object there. + */ + static int +-i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, +- unsigned alignment, +- bool map_and_fenceable, +- bool nonblocking) ++i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, ++ struct i915_address_space *vm, ++ unsigned alignment, ++ bool map_and_fenceable, ++ bool nonblocking) + { + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; +- struct i915_address_space *vm = &dev_priv->gtt.base; + u32 size, fence_size, fence_alignment, unfenced_alignment; + bool mappable, fenceable; +- size_t gtt_max = map_and_fenceable ? +- dev_priv->gtt.mappable_end : dev_priv->gtt.base.total; ++ size_t gtt_max = ++ map_and_fenceable ? dev_priv->gtt.mappable_end : vm->total; + struct i915_vma *vma; + int ret; + +@@ -3119,15 +3138,18 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + + i915_gem_object_pin_pages(obj); + +- vma = i915_gem_vma_create(obj, &dev_priv->gtt.base); ++ /* FIXME: For now we only ever use 1 VMA per object */ ++ BUG_ON(!i915_is_ggtt(vm)); ++ WARN_ON(!list_empty(&obj->vma_list)); ++ ++ vma = i915_gem_vma_create(obj, vm); + if (IS_ERR(vma)) { + ret = PTR_ERR(vma); + goto err_unpin; + } + + search_free: +- ret = drm_mm_insert_node_in_range_generic(&dev_priv->gtt.base.mm, +- &vma->node, ++ ret = drm_mm_insert_node_in_range_generic(&vm->mm, &vma->node, + size, alignment, + obj->cache_level, 0, gtt_max, + DRM_MM_SEARCH_DEFAULT); +@@ -3153,18 +3175,25 @@ search_free: + + list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); + list_add_tail(&obj->mm_list, &vm->inactive_list); +- list_add(&vma->vma_link, &obj->vma_list); ++ ++ /* Keep GGTT vmas first to make debug easier */ ++ if (i915_is_ggtt(vm)) ++ list_add(&vma->vma_link, &obj->vma_list); ++ else ++ list_add_tail(&vma->vma_link, &obj->vma_list); + + fenceable = ++ i915_is_ggtt(vm) && + i915_gem_obj_ggtt_size(obj) == fence_size && + (i915_gem_obj_ggtt_offset(obj) & (fence_alignment - 1)) == 0; + +- mappable = i915_gem_obj_ggtt_offset(obj) + obj->base.size <= +- dev_priv->gtt.mappable_end; ++ mappable = ++ i915_is_ggtt(vm) && ++ vma->node.start + obj->base.size <= dev_priv->gtt.mappable_end; + + obj->map_and_fenceable = mappable && fenceable; + +- trace_i915_gem_object_bind(obj, map_and_fenceable); ++ trace_i915_vma_bind(vma, map_and_fenceable); + i915_gem_verify_gtt(dev); + return 0; + +@@ -3333,7 +3362,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + + list_for_each_entry(vma, &obj->vma_list, vma_link) { + if (!i915_gem_valid_gtt_space(dev, &vma->node, cache_level)) { +- ret = i915_gem_object_unbind(obj); ++ ret = i915_vma_unbind(vma); + if (ret) + return ret; + +@@ -3641,33 +3670,39 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, + bool map_and_fenceable, + bool nonblocking) + { ++ struct i915_vma *vma; + int ret; + + if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT)) + return -EBUSY; + +- if (i915_gem_obj_ggtt_bound(obj)) { +- if ((alignment && i915_gem_obj_ggtt_offset(obj) & (alignment - 1)) || ++ WARN_ON(map_and_fenceable && !i915_is_ggtt(vm)); ++ ++ vma = i915_gem_obj_to_vma(obj, vm); ++ ++ if (vma) { ++ if ((alignment && ++ vma->node.start & (alignment - 1)) || + (map_and_fenceable && !obj->map_and_fenceable)) { + WARN(obj->pin_count, + "bo is already pinned with incorrect alignment:" + " offset=%lx, req.alignment=%x, req.map_and_fenceable=%d," + " obj->map_and_fenceable=%d\n", +- i915_gem_obj_ggtt_offset(obj), alignment, ++ i915_gem_obj_offset(obj, vm), alignment, + map_and_fenceable, + obj->map_and_fenceable); +- ret = i915_gem_object_unbind(obj); ++ ret = i915_vma_unbind(vma); + if (ret) + return ret; + } + } + +- if (!i915_gem_obj_ggtt_bound(obj)) { ++ if (!i915_gem_obj_bound(obj, vm)) { + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + +- ret = i915_gem_object_bind_to_gtt(obj, alignment, +- map_and_fenceable, +- nonblocking); ++ ret = i915_gem_object_bind_to_vm(obj, vm, alignment, ++ map_and_fenceable, ++ nonblocking); + if (ret) + return ret; + +@@ -3963,6 +3998,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) + struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; ++ struct i915_vma *vma, *next; + + trace_i915_gem_object_destroy(obj); + +@@ -3970,15 +4006,21 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) + i915_gem_detach_phys_object(dev, obj); + + obj->pin_count = 0; +- if (WARN_ON(i915_gem_object_unbind(obj) == -ERESTARTSYS)) { +- bool was_interruptible; ++ /* NB: 0 or 1 elements */ ++ WARN_ON(!list_empty(&obj->vma_list) && ++ !list_is_singular(&obj->vma_list)); ++ list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) { ++ int ret = i915_vma_unbind(vma); ++ if (WARN_ON(ret == -ERESTARTSYS)) { ++ bool was_interruptible; + +- was_interruptible = dev_priv->mm.interruptible; +- dev_priv->mm.interruptible = false; ++ was_interruptible = dev_priv->mm.interruptible; ++ dev_priv->mm.interruptible = false; + +- WARN_ON(i915_gem_object_unbind(obj)); ++ WARN_ON(i915_vma_unbind(vma)); + +- dev_priv->mm.interruptible = was_interruptible; ++ dev_priv->mm.interruptible = was_interruptible; ++ } + } + + /* Stolen objects don't hold a ref, but do hold pin count. Fix that up +diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c +index 33d85a4447a6..9205a4179b7e 100644 +--- a/drivers/gpu/drm/i915/i915_gem_evict.c ++++ b/drivers/gpu/drm/i915/i915_gem_evict.c +@@ -147,7 +147,7 @@ found: + struct drm_i915_gem_object, + exec_list); + if (ret == 0) +- ret = i915_gem_object_unbind(obj); ++ ret = i915_gem_object_ggtt_unbind(obj); + + list_del_init(&obj->exec_list); + drm_gem_object_unreference(&obj->base); +@@ -185,7 +185,7 @@ i915_gem_evict_everything(struct drm_device *dev) + /* Having flushed everything, unbind() should never raise an error */ + list_for_each_entry_safe(obj, next, &vm->inactive_list, mm_list) + if (obj->pin_count == 0) +- WARN_ON(i915_gem_object_unbind(obj)); ++ WARN_ON(i915_gem_object_ggtt_unbind(obj)); + + return 0; + } +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 9939d2ef3ea9..17be2e4bae6b 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -556,7 +556,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, + if ((entry->alignment && + obj_offset & (entry->alignment - 1)) || + (need_mappable && !obj->map_and_fenceable)) +- ret = i915_gem_object_unbind(obj); ++ ret = i915_vma_unbind(i915_gem_obj_to_vma(obj, vm)); + else + ret = i915_gem_execbuffer_reserve_object(obj, ring, vm, need_relocs); + if (ret) +diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c +index 92a8d279ca39..032e9ef9c896 100644 +--- a/drivers/gpu/drm/i915/i915_gem_tiling.c ++++ b/drivers/gpu/drm/i915/i915_gem_tiling.c +@@ -360,17 +360,18 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, + + obj->map_and_fenceable = + !i915_gem_obj_ggtt_bound(obj) || +- (i915_gem_obj_ggtt_offset(obj) + obj->base.size <= dev_priv->gtt.mappable_end && ++ (i915_gem_obj_ggtt_offset(obj) + ++ obj->base.size <= dev_priv->gtt.mappable_end && + i915_gem_object_fence_ok(obj, args->tiling_mode)); + + /* Rebind if we need a change of alignment */ + if (!obj->map_and_fenceable) { +- u32 unfenced_alignment = ++ u32 unfenced_align = + i915_gem_get_gtt_alignment(dev, obj->base.size, + args->tiling_mode, + false); +- if (i915_gem_obj_ggtt_offset(obj) & (unfenced_alignment - 1)) +- ret = i915_gem_object_unbind(obj); ++ if (i915_gem_obj_ggtt_offset(obj) & (unfenced_align - 1)) ++ ret = i915_gem_object_ggtt_unbind(obj); + } + + if (ret == 0) { +diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h +index 2933e2ffeaa4..e2c5ee6f6194 100644 +--- a/drivers/gpu/drm/i915/i915_trace.h ++++ b/drivers/gpu/drm/i915/i915_trace.h +@@ -33,47 +33,52 @@ TRACE_EVENT(i915_gem_object_create, + TP_printk("obj=%p, size=%u", __entry->obj, __entry->size) + ); + +-TRACE_EVENT(i915_gem_object_bind, +- TP_PROTO(struct drm_i915_gem_object *obj, bool mappable), +- TP_ARGS(obj, mappable), ++TRACE_EVENT(i915_vma_bind, ++ TP_PROTO(struct i915_vma *vma, bool mappable), ++ TP_ARGS(vma, mappable), + + TP_STRUCT__entry( + __field(struct drm_i915_gem_object *, obj) ++ __field(struct i915_address_space *, vm) + __field(u32, offset) + __field(u32, size) + __field(bool, mappable) + ), + + TP_fast_assign( +- __entry->obj = obj; +- __entry->offset = i915_gem_obj_ggtt_offset(obj); +- __entry->size = i915_gem_obj_ggtt_size(obj); ++ __entry->obj = vma->obj; ++ __entry->vm = vma->vm; ++ __entry->offset = vma->node.start; ++ __entry->size = vma->node.size; + __entry->mappable = mappable; + ), + +- TP_printk("obj=%p, offset=%08x size=%x%s", ++ TP_printk("obj=%p, offset=%08x size=%x%s vm=%p", + __entry->obj, __entry->offset, __entry->size, +- __entry->mappable ? ", mappable" : "") ++ __entry->mappable ? ", mappable" : "", ++ __entry->vm) + ); + +-TRACE_EVENT(i915_gem_object_unbind, +- TP_PROTO(struct drm_i915_gem_object *obj), +- TP_ARGS(obj), ++TRACE_EVENT(i915_vma_unbind, ++ TP_PROTO(struct i915_vma *vma), ++ TP_ARGS(vma), + + TP_STRUCT__entry( + __field(struct drm_i915_gem_object *, obj) ++ __field(struct i915_address_space *, vm) + __field(u32, offset) + __field(u32, size) + ), + + TP_fast_assign( +- __entry->obj = obj; +- __entry->offset = i915_gem_obj_ggtt_offset(obj); +- __entry->size = i915_gem_obj_ggtt_size(obj); ++ __entry->obj = vma->obj; ++ __entry->vm = vma->vm; ++ __entry->offset = vma->node.start; ++ __entry->size = vma->node.size; + ), + +- TP_printk("obj=%p, offset=%08x size=%x", +- __entry->obj, __entry->offset, __entry->size) ++ TP_printk("obj=%p, offset=%08x size=%x vm=%p", ++ __entry->obj, __entry->offset, __entry->size, __entry->vm) + ); + + TRACE_EVENT(i915_gem_object_change_domain, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0603-drm-i915-Use-new-bind-unbind-in-eviction-code.patch b/patches.baytrail/0603-drm-i915-Use-new-bind-unbind-in-eviction-code.patch new file mode 100644 index 000000000000..630452217e05 --- /dev/null +++ b/patches.baytrail/0603-drm-i915-Use-new-bind-unbind-in-eviction-code.patch @@ -0,0 +1,184 @@ +From 01eecc95b0a5eb792a22b0f533f1099c2eb33fd9 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:11 -0700 +Subject: drm/i915: Use new bind/unbind in eviction code + +Eviction code, like the rest of the converted code needs to be aware of +the address space for which it is evicting (or the everything case, all +addresses). With the updated bind/unbind interfaces of the last patch, +we can now safely move the eviction code over. + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit f6cd1f15d345688cb95cc195aaf8b375f7de8cf6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 4 ++- + drivers/gpu/drm/i915/i915_gem.c | 2 +- + drivers/gpu/drm/i915/i915_gem_evict.c | 53 +++++++++++++++++++---------------- + 3 files changed, 33 insertions(+), 26 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 6e8e6950cb8c..49a2e336a7b5 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1982,7 +1982,9 @@ static inline void i915_gem_chipset_flush(struct drm_device *dev) + + + /* i915_gem_evict.c */ +-int __must_check i915_gem_evict_something(struct drm_device *dev, int min_size, ++int __must_check i915_gem_evict_something(struct drm_device *dev, ++ struct i915_address_space *vm, ++ int min_size, + unsigned alignment, + unsigned cache_level, + bool mappable, +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 6f7b1b47d210..8a21ee7f7903 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3154,7 +3154,7 @@ search_free: + obj->cache_level, 0, gtt_max, + DRM_MM_SEARCH_DEFAULT); + if (ret) { +- ret = i915_gem_evict_something(dev, size, alignment, ++ ret = i915_gem_evict_something(dev, vm, size, alignment, + obj->cache_level, + map_and_fenceable, + nonblocking); +diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c +index 9205a4179b7e..61bf5e20e5e0 100644 +--- a/drivers/gpu/drm/i915/i915_gem_evict.c ++++ b/drivers/gpu/drm/i915/i915_gem_evict.c +@@ -32,26 +32,21 @@ + #include "i915_trace.h" + + static bool +-mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind) ++mark_free(struct i915_vma *vma, struct list_head *unwind) + { +- struct drm_device *dev = obj->base.dev; +- struct drm_i915_private *dev_priv = dev->dev_private; +- struct i915_vma *vma = i915_gem_obj_to_vma(obj, &dev_priv->gtt.base); +- +- if (obj->pin_count) ++ if (vma->obj->pin_count) + return false; + +- list_add(&obj->exec_list, unwind); ++ list_add(&vma->obj->exec_list, unwind); + return drm_mm_scan_add_block(&vma->node); + } + + int +-i915_gem_evict_something(struct drm_device *dev, int min_size, +- unsigned alignment, unsigned cache_level, ++i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm, ++ int min_size, unsigned alignment, unsigned cache_level, + bool mappable, bool nonblocking) + { + drm_i915_private_t *dev_priv = dev->dev_private; +- struct i915_address_space *vm = &dev_priv->gtt.base; + struct list_head eviction_list, unwind_list; + struct i915_vma *vma; + struct drm_i915_gem_object *obj; +@@ -83,16 +78,18 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, + */ + + INIT_LIST_HEAD(&unwind_list); +- if (mappable) ++ if (mappable) { ++ BUG_ON(!i915_is_ggtt(vm)); + drm_mm_init_scan_with_range(&vm->mm, min_size, + alignment, cache_level, 0, + dev_priv->gtt.mappable_end); +- else ++ } else + drm_mm_init_scan(&vm->mm, min_size, alignment, cache_level); + + /* First see if there is a large enough contiguous idle region... */ + list_for_each_entry(obj, &vm->inactive_list, mm_list) { +- if (mark_free(obj, &unwind_list)) ++ struct i915_vma *vma = i915_gem_obj_to_vma(obj, vm); ++ if (mark_free(vma, &unwind_list)) + goto found; + } + +@@ -101,7 +98,8 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, + + /* Now merge in the soon-to-be-expired objects... */ + list_for_each_entry(obj, &vm->active_list, mm_list) { +- if (mark_free(obj, &unwind_list)) ++ struct i915_vma *vma = i915_gem_obj_to_vma(obj, vm); ++ if (mark_free(vma, &unwind_list)) + goto found; + } + +@@ -111,7 +109,7 @@ none: + obj = list_first_entry(&unwind_list, + struct drm_i915_gem_object, + exec_list); +- vma = i915_gem_obj_to_vma(obj, &dev_priv->gtt.base); ++ vma = i915_gem_obj_to_vma(obj, vm); + ret = drm_mm_scan_remove_block(&vma->node); + BUG_ON(ret); + +@@ -132,7 +130,7 @@ found: + obj = list_first_entry(&unwind_list, + struct drm_i915_gem_object, + exec_list); +- vma = i915_gem_obj_to_vma(obj, &dev_priv->gtt.base); ++ vma = i915_gem_obj_to_vma(obj, vm); + if (drm_mm_scan_remove_block(&vma->node)) { + list_move(&obj->exec_list, &eviction_list); + drm_gem_object_reference(&obj->base); +@@ -147,7 +145,7 @@ found: + struct drm_i915_gem_object, + exec_list); + if (ret == 0) +- ret = i915_gem_object_ggtt_unbind(obj); ++ ret = i915_vma_unbind(i915_gem_obj_to_vma(obj, vm)); + + list_del_init(&obj->exec_list); + drm_gem_object_unreference(&obj->base); +@@ -160,13 +158,18 @@ int + i915_gem_evict_everything(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; +- struct i915_address_space *vm = &dev_priv->gtt.base; ++ struct i915_address_space *vm; + struct drm_i915_gem_object *obj, *next; +- bool lists_empty; ++ bool lists_empty = true; + int ret; + +- lists_empty = (list_empty(&vm->inactive_list) && +- list_empty(&vm->active_list)); ++ list_for_each_entry(vm, &dev_priv->vm_list, global_link) { ++ lists_empty = (list_empty(&vm->inactive_list) && ++ list_empty(&vm->active_list)); ++ if (!lists_empty) ++ lists_empty = false; ++ } ++ + if (lists_empty) + return -ENOSPC; + +@@ -183,9 +186,11 @@ i915_gem_evict_everything(struct drm_device *dev) + i915_gem_retire_requests(dev); + + /* Having flushed everything, unbind() should never raise an error */ +- list_for_each_entry_safe(obj, next, &vm->inactive_list, mm_list) +- if (obj->pin_count == 0) +- WARN_ON(i915_gem_object_ggtt_unbind(obj)); ++ list_for_each_entry(vm, &dev_priv->vm_list, global_link) { ++ list_for_each_entry_safe(obj, next, &vm->inactive_list, mm_list) ++ if (obj->pin_count == 0) ++ WARN_ON(i915_vma_unbind(i915_gem_obj_to_vma(obj, vm))); ++ } + + return 0; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0604-drm-i915-turn-bound_ggtt-checks-to-bound_any.patch b/patches.baytrail/0604-drm-i915-turn-bound_ggtt-checks-to-bound_any.patch new file mode 100644 index 000000000000..a2fe920ba308 --- /dev/null +++ b/patches.baytrail/0604-drm-i915-turn-bound_ggtt-checks-to-bound_any.patch @@ -0,0 +1,109 @@ +From 94fe280df819c4414b59832e63584dff43d3e7fc Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:12 -0700 +Subject: drm/i915: turn bound_ggtt checks to bound_any + +In some places, we want to know if an object is bound in any address +space, and not just the global GTT. This often applies when there is a +single global resource (object, pages, etc.) + +function | reason +-------------------------------------------------- +i915_gem_object_is_inactive | global object +i915_gem_object_put_pages | object's pages +915_gem_object_unpin | global object +i915_gem_execbuffer_unreserve_object | temporary until we plumb vma +pread/pwrite | see the note below + +Note: set_to_gtt_domain in pwrite/pread is abused as a wait_rendering +call - but that once only worked if the object is bound. We really +should replace this with a plain wait_rendering call, which would have +the upside that in pread it would be clearer that we actually only +wait for oustanding gpu writes. + +Signed-off-by: Ben Widawsky +[danvet: Explain the set_to_gtt_domain in pwrite/pread and volunteer +Ben to replace those with wait_rendering calls.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 9843877d10700d6b64b615e0e8724fc9f6ff6268) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 12 ++++++------ + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 8a21ee7f7903..9150804dffc0 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -142,7 +142,7 @@ int i915_mutex_lock_interruptible(struct drm_device *dev) + static inline bool + i915_gem_object_is_inactive(struct drm_i915_gem_object *obj) + { +- return i915_gem_obj_ggtt_bound(obj) && !obj->active; ++ return i915_gem_obj_bound_any(obj) && !obj->active; + } + + int +@@ -416,7 +416,7 @@ i915_gem_shmem_pread(struct drm_device *dev, + * anyway again before the next pread happens. */ + if (obj->cache_level == I915_CACHE_NONE) + needs_clflush = 1; +- if (i915_gem_obj_ggtt_bound(obj)) { ++ if (i915_gem_obj_bound_any(obj)) { + ret = i915_gem_object_set_to_gtt_domain(obj, false); + if (ret) + return ret; +@@ -733,7 +733,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev, + * right away and we therefore have to clflush anyway. */ + if (obj->cache_level == I915_CACHE_NONE) + needs_clflush_after = 1; +- if (i915_gem_obj_ggtt_bound(obj)) { ++ if (i915_gem_obj_bound_any(obj)) { + ret = i915_gem_object_set_to_gtt_domain(obj, true); + if (ret) + return ret; +@@ -1660,7 +1660,7 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj) + if (obj->pages_pin_count) + return -EBUSY; + +- BUG_ON(i915_gem_obj_ggtt_bound(obj)); ++ BUG_ON(i915_gem_obj_bound_any(obj)); + + /* ->put_pages might need to allocate memory for the bit17 swizzle + * array, hence protect them from being reaped by removing them from gtt +@@ -3299,7 +3299,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) + int ret; + + /* Not valid to be called on unbound objects. */ +- if (!i915_gem_obj_ggtt_bound(obj)) ++ if (!i915_gem_obj_bound_any(obj)) + return -EINVAL; + + if (obj->base.write_domain == I915_GEM_DOMAIN_GTT) +@@ -3723,7 +3723,7 @@ void + i915_gem_object_unpin(struct drm_i915_gem_object *obj) + { + BUG_ON(obj->pin_count == 0); +- BUG_ON(!i915_gem_obj_ggtt_bound(obj)); ++ BUG_ON(!i915_gem_obj_bound_any(obj)); + + if (--obj->pin_count == 0) + obj->pin_mappable = false; +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 17be2e4bae6b..aa3fa9425cae 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -466,7 +466,7 @@ i915_gem_execbuffer_unreserve_object(struct drm_i915_gem_object *obj) + { + struct drm_i915_gem_exec_object2 *entry; + +- if (!i915_gem_obj_ggtt_bound(obj)) ++ if (!i915_gem_obj_bound_any(obj)) + return; + + entry = obj->exec_entry; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0605-video-hdmi-Introduce-a-generic-hdmi_infoframe-union.patch b/patches.baytrail/0605-video-hdmi-Introduce-a-generic-hdmi_infoframe-union.patch new file mode 100644 index 000000000000..da6f5bfc478d --- /dev/null +++ b/patches.baytrail/0605-video-hdmi-Introduce-a-generic-hdmi_infoframe-union.patch @@ -0,0 +1,117 @@ +From 0e4425f28f2d06748f566f13b086bbf639c00c66 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Tue, 6 Aug 2013 20:32:14 +0100 +Subject: video/hdmi: Introduce a generic hdmi_infoframe union +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +And a way to pack hdmi_infoframe generically. + +Cc: Thierry Reding +Reviewed-by: Ville Syrjälä +Signed-off-by: Damien Lespiau +Acked-by: Dave Airlie +Reviewed-by: Alex Deucher +Signed-off-by: Daniel Vetter +(cherry picked from commit 72b098964d3c3fb030dcac2d4c869c9851a0d17a) +Signed-off-by: Darren Hart +--- + drivers/video/hdmi.c | 43 +++++++++++++++++++++++++++++++++++++++++++ + include/linux/hdmi.h | 17 +++++++++++++++++ + 2 files changed, 60 insertions(+) + +diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c +index 40178338b619..89054d82c0e1 100644 +--- a/drivers/video/hdmi.c ++++ b/drivers/video/hdmi.c +@@ -22,6 +22,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -321,3 +322,45 @@ ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, + return length; + } + EXPORT_SYMBOL(hdmi_vendor_infoframe_pack); ++ ++/** ++ * hdmi_infoframe_pack() - write a HDMI infoframe to binary buffer ++ * @frame: HDMI infoframe ++ * @buffer: destination buffer ++ * @size: size of buffer ++ * ++ * Packs the information contained in the @frame structure into a binary ++ * representation that can be written into the corresponding controller ++ * registers. Also computes the checksum as required by section 5.3.5 of ++ * the HDMI 1.4 specification. ++ * ++ * Returns the number of bytes packed into the binary buffer or a negative ++ * error code on failure. ++ */ ++ssize_t ++hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size) ++{ ++ ssize_t length; ++ ++ switch (frame->any.type) { ++ case HDMI_INFOFRAME_TYPE_AVI: ++ length = hdmi_avi_infoframe_pack(&frame->avi, buffer, size); ++ break; ++ case HDMI_INFOFRAME_TYPE_SPD: ++ length = hdmi_spd_infoframe_pack(&frame->spd, buffer, size); ++ break; ++ case HDMI_INFOFRAME_TYPE_AUDIO: ++ length = hdmi_audio_infoframe_pack(&frame->audio, buffer, size); ++ break; ++ case HDMI_INFOFRAME_TYPE_VENDOR: ++ length = hdmi_vendor_infoframe_pack(&frame->vendor, ++ buffer, size); ++ break; ++ default: ++ WARN(1, "Bad infoframe type %d\n", frame->any.type); ++ length = -EINVAL; ++ } ++ ++ return length; ++} ++EXPORT_SYMBOL(hdmi_infoframe_pack); +diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h +index 3b589440ecfe..0f3f82eadef7 100644 +--- a/include/linux/hdmi.h ++++ b/include/linux/hdmi.h +@@ -23,6 +23,12 @@ enum hdmi_infoframe_type { + #define HDMI_SPD_INFOFRAME_SIZE 25 + #define HDMI_AUDIO_INFOFRAME_SIZE 10 + ++struct hdmi_any_infoframe { ++ enum hdmi_infoframe_type type; ++ unsigned char version; ++ unsigned char length; ++}; ++ + enum hdmi_colorspace { + HDMI_COLORSPACE_RGB, + HDMI_COLORSPACE_YUV422, +@@ -228,4 +234,15 @@ struct hdmi_vendor_infoframe { + ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, + void *buffer, size_t size); + ++union hdmi_infoframe { ++ struct hdmi_any_infoframe any; ++ struct hdmi_avi_infoframe avi; ++ struct hdmi_spd_infoframe spd; ++ struct hdmi_vendor_infoframe vendor; ++ struct hdmi_audio_infoframe audio; ++}; ++ ++ssize_t ++hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size); ++ + #endif /* _DRM_HDMI_H */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0606-video-hdmi-Add-a-macro-to-return-the-size-of-a-full-.patch b/patches.baytrail/0606-video-hdmi-Add-a-macro-to-return-the-size-of-a-full-.patch new file mode 100644 index 000000000000..38302776b933 --- /dev/null +++ b/patches.baytrail/0606-video-hdmi-Add-a-macro-to-return-the-size-of-a-full-.patch @@ -0,0 +1,37 @@ +From cc8238049bdc063a0ce0b6dde68e1e9687107cb4 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Tue, 6 Aug 2013 20:32:15 +0100 +Subject: video/hdmi: Add a macro to return the size of a full infoframe +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Cc: Thierry Reding +Reviewed-by: Ville Syrjälä +Signed-off-by: Damien Lespiau +Acked-by: Dave Airlie +Reviewed-by: Alex Deucher +Signed-off-by: Daniel Vetter +(cherry picked from commit 61177b0e12ba162d5de206914e8703d8eb90ad19) +Signed-off-by: Darren Hart +--- + include/linux/hdmi.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h +index 0f3f82eadef7..bc6743e76e37 100644 +--- a/include/linux/hdmi.h ++++ b/include/linux/hdmi.h +@@ -23,6 +23,9 @@ enum hdmi_infoframe_type { + #define HDMI_SPD_INFOFRAME_SIZE 25 + #define HDMI_AUDIO_INFOFRAME_SIZE 10 + ++#define HDMI_INFOFRAME_SIZE(type) \ ++ (HDMI_INFOFRAME_HEADER_SIZE + HDMI_ ## type ## _INFOFRAME_SIZE) ++ + struct hdmi_any_infoframe { + enum hdmi_infoframe_type type; + unsigned char version; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0607-video-hdmi-Don-t-let-the-user-of-this-API-create-inv.patch b/patches.baytrail/0607-video-hdmi-Don-t-let-the-user-of-this-API-create-inv.patch new file mode 100644 index 000000000000..e0fa2f2315c4 --- /dev/null +++ b/patches.baytrail/0607-video-hdmi-Don-t-let-the-user-of-this-API-create-inv.patch @@ -0,0 +1,66 @@ +From 67d51500875d57f0b9ccef39aafedcaf43a1f33c Mon Sep 17 00:00:00 2001 +From: "Lespiau, Damien" +Date: Mon, 19 Aug 2013 16:58:56 +0100 +Subject: video/hdmi: Don't let the user of this API create invalid infoframes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +To set the active aspect ratio value in the AVI infoframe today, you not +only have to set the active_aspect field, but also the active_info_valid +bit. Out of the 1 user of this API, we had 100% misuse, forgetting the +_valid bit. This was fixed in: + + Author: Damien Lespiau + Date: Tue Aug 6 20:32:17 2013 +0100 + + drm: Don't generate invalid AVI infoframes for CEA modes + +We can do better and derive the _valid bit from the user wanting to set +the active aspect ratio. + +v2: Fix multi-lines comment style (Thierry Reding) + +Signed-off-by: Damien Lespiau +Reviewed-by: Ville Syrjälä +Reviewed-by: Thierry Reding +Signed-off-by: Dave Airlie +(cherry picked from commit a5ad3dcf358475dfc5ccf11e28d3822fc3c8e5fe) +Signed-off-by: Darren Hart +--- + drivers/video/hdmi.c | 6 +++++- + include/linux/hdmi.h | 1 - + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c +index 89054d82c0e1..995daec1ca7b 100644 +--- a/drivers/video/hdmi.c ++++ b/drivers/video/hdmi.c +@@ -96,7 +96,11 @@ ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, + + ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3); + +- if (frame->active_info_valid) ++ /* ++ * Data byte 1, bit 4 has to be set if we provide the active format ++ * aspect ratio ++ */ ++ if (frame->active_aspect & 0xf) + ptr[0] |= BIT(4); + + if (frame->horizontal_bar_valid) +diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h +index bc6743e76e37..931474c60b71 100644 +--- a/include/linux/hdmi.h ++++ b/include/linux/hdmi.h +@@ -109,7 +109,6 @@ struct hdmi_avi_infoframe { + unsigned char version; + unsigned char length; + enum hdmi_colorspace colorspace; +- bool active_info_valid; + bool horizontal_bar_valid; + bool vertical_bar_valid; + enum hdmi_scan_mode scan_mode; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0608-video-hdmi-Derive-the-bar-data-valid-bit-from-the-ba.patch b/patches.baytrail/0608-video-hdmi-Derive-the-bar-data-valid-bit-from-the-ba.patch new file mode 100644 index 000000000000..711d1d0ba012 --- /dev/null +++ b/patches.baytrail/0608-video-hdmi-Derive-the-bar-data-valid-bit-from-the-ba.patch @@ -0,0 +1,62 @@ +From c9b8c9c70dace339ee2f0a67423ebb824f6be71e Mon Sep 17 00:00:00 2001 +From: "Lespiau, Damien" +Date: Mon, 19 Aug 2013 16:58:57 +0100 +Subject: video/hdmi: Derive the bar data valid bit from the bar data fields +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Just like: + + Author: Damien Lespiau + Date: Mon Aug 12 11:53:24 2013 +0100 + + video/hdmi: Don't let the user of this API create invalid infoframes + +But this time for the horizontal/vertical bar data present bits. + +Signed-off-by: Damien Lespiau +Reviewed-by: Ville Syrjälä +Reviewed-by: Thierry Reding +Signed-off-by: Dave Airlie +(cherry picked from commit 974e0701c5251de879624d166890fbd0ee9fc429) +Signed-off-by: Darren Hart +--- + drivers/video/hdmi.c | 5 +++-- + include/linux/hdmi.h | 2 -- + 2 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c +index 995daec1ca7b..060337b393db 100644 +--- a/drivers/video/hdmi.c ++++ b/drivers/video/hdmi.c +@@ -103,10 +103,11 @@ ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, + if (frame->active_aspect & 0xf) + ptr[0] |= BIT(4); + +- if (frame->horizontal_bar_valid) ++ /* Bit 3 and 2 indicate if we transmit horizontal/vertical bar data */ ++ if (frame->top_bar || frame->bottom_bar) + ptr[0] |= BIT(3); + +- if (frame->vertical_bar_valid) ++ if (frame->left_bar || frame->right_bar) + ptr[0] |= BIT(2); + + ptr[1] = ((frame->colorimetry & 0x3) << 6) | +diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h +index 931474c60b71..b98340b82e05 100644 +--- a/include/linux/hdmi.h ++++ b/include/linux/hdmi.h +@@ -109,8 +109,6 @@ struct hdmi_avi_infoframe { + unsigned char version; + unsigned char length; + enum hdmi_colorspace colorspace; +- bool horizontal_bar_valid; +- bool vertical_bar_valid; + enum hdmi_scan_mode scan_mode; + enum hdmi_colorimetry colorimetry; + enum hdmi_picture_aspect picture_aspect; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0609-video-hdmi-Introduce-helpers-for-the-HDMI-vendor-spe.patch b/patches.baytrail/0609-video-hdmi-Introduce-helpers-for-the-HDMI-vendor-spe.patch new file mode 100644 index 000000000000..d359b8fe6c60 --- /dev/null +++ b/patches.baytrail/0609-video-hdmi-Introduce-helpers-for-the-HDMI-vendor-spe.patch @@ -0,0 +1,176 @@ +From 64e96dc8bf364ec5c71bef620b170964fc29173a Mon Sep 17 00:00:00 2001 +From: "Lespiau, Damien" +Date: Mon, 19 Aug 2013 16:58:58 +0100 +Subject: video/hdmi: Introduce helpers for the HDMI vendor specific infoframe +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Provide the same programming model than the other infoframe types. + +The generic _pack() function can't handle those yet as we need to move +the vendor OUI in the generic hdmi_vendor_infoframe structure to know +which kind of vendor infoframe we are dealing with. + +v2: Fix the value of Side-by-side (half), hmdi typo, pack 3D_Ext_Data + (Ville Syrjälä) +v3: Future proof the sending of 3D_Ext_Data (Ville Syrjälä), Fix + multi-lines comment style (Thierry Reding) + +Signed-off-by: Damien Lespiau +Reviewed-by: Ville Syrjälä +Reviewed-by: Thierry Reding +Signed-off-by: Dave Airlie +(cherry picked from commit 7d27becb3532d881378846e72864031977be511a) +Signed-off-by: Darren Hart +--- + drivers/video/hdmi.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + include/linux/hdmi.h | 26 +++++++++++++++ + 2 files changed, 116 insertions(+) + +diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c +index 060337b393db..82c663a8961e 100644 +--- a/drivers/video/hdmi.c ++++ b/drivers/video/hdmi.c +@@ -288,6 +288,96 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, + EXPORT_SYMBOL(hdmi_audio_infoframe_pack); + + /** ++ * hdmi_hdmi_infoframe_init() - initialize an HDMI vendor infoframe ++ * @frame: HDMI vendor infoframe ++ * ++ * Returns 0 on success or a negative error code on failure. ++ */ ++int hdmi_hdmi_infoframe_init(struct hdmi_hdmi_infoframe *frame) ++{ ++ memset(frame, 0, sizeof(*frame)); ++ ++ frame->type = HDMI_INFOFRAME_TYPE_VENDOR; ++ frame->version = 1; ++ ++ /* ++ * 0 is a valid value for s3d_struct, so we use a special "not set" ++ * value ++ */ ++ frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID; ++ ++ return 0; ++} ++EXPORT_SYMBOL(hdmi_hdmi_infoframe_init); ++ ++/** ++ * hdmi_hdmi_infoframe_pack() - write a HDMI vendor infoframe to binary buffer ++ * @frame: HDMI infoframe ++ * @buffer: destination buffer ++ * @size: size of buffer ++ * ++ * Packs the information contained in the @frame structure into a binary ++ * representation that can be written into the corresponding controller ++ * registers. Also computes the checksum as required by section 5.3.5 of ++ * the HDMI 1.4 specification. ++ * ++ * Returns the number of bytes packed into the binary buffer or a negative ++ * error code on failure. ++ */ ++ssize_t hdmi_hdmi_infoframe_pack(struct hdmi_hdmi_infoframe *frame, ++ void *buffer, size_t size) ++{ ++ u8 *ptr = buffer; ++ size_t length; ++ ++ /* empty info frame */ ++ if (frame->vic == 0 && frame->s3d_struct == HDMI_3D_STRUCTURE_INVALID) ++ return -EINVAL; ++ ++ /* only one of those can be supplied */ ++ if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) ++ return -EINVAL; ++ ++ /* for side by side (half) we also need to provide 3D_Ext_Data */ ++ if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) ++ frame->length = 6; ++ else ++ frame->length = 5; ++ ++ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; ++ ++ if (size < length) ++ return -ENOSPC; ++ ++ memset(buffer, 0, size); ++ ++ ptr[0] = frame->type; ++ ptr[1] = frame->version; ++ ptr[2] = frame->length; ++ ptr[3] = 0; /* checksum */ ++ ++ /* HDMI OUI */ ++ ptr[4] = 0x03; ++ ptr[5] = 0x0c; ++ ptr[6] = 0x00; ++ ++ if (frame->vic) { ++ ptr[7] = 0x1 << 5; /* video format */ ++ ptr[8] = frame->vic; ++ } else { ++ ptr[7] = 0x2 << 5; /* video format */ ++ ptr[8] = (frame->s3d_struct & 0xf) << 4; ++ if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) ++ ptr[9] = (frame->s3d_ext_data & 0xf) << 4; ++ } ++ ++ hdmi_infoframe_checksum(buffer, length); ++ ++ return length; ++} ++EXPORT_SYMBOL(hdmi_hdmi_infoframe_pack); ++ ++/** + * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary + * buffer + * @frame: HDMI vendor infoframe +diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h +index b98340b82e05..e733252c2b5d 100644 +--- a/include/linux/hdmi.h ++++ b/include/linux/hdmi.h +@@ -234,11 +234,37 @@ struct hdmi_vendor_infoframe { + ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, + void *buffer, size_t size); + ++enum hdmi_3d_structure { ++ HDMI_3D_STRUCTURE_INVALID = -1, ++ HDMI_3D_STRUCTURE_FRAME_PACKING = 0, ++ HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE, ++ HDMI_3D_STRUCTURE_LINE_ALTERNATIVE, ++ HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL, ++ HDMI_3D_STRUCTURE_L_DEPTH, ++ HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH, ++ HDMI_3D_STRUCTURE_TOP_AND_BOTTOM, ++ HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF = 8, ++}; ++ ++struct hdmi_hdmi_infoframe { ++ enum hdmi_infoframe_type type; ++ unsigned char version; ++ unsigned char length; ++ u8 vic; ++ enum hdmi_3d_structure s3d_struct; ++ unsigned int s3d_ext_data; ++}; ++ ++int hdmi_hdmi_infoframe_init(struct hdmi_hdmi_infoframe *frame); ++ssize_t hdmi_hdmi_infoframe_pack(struct hdmi_hdmi_infoframe *frame, ++ void *buffer, size_t size); ++ + union hdmi_infoframe { + struct hdmi_any_infoframe any; + struct hdmi_avi_infoframe avi; + struct hdmi_spd_infoframe spd; + struct hdmi_vendor_infoframe vendor; ++ struct hdmi_hdmi_infoframe hdmi; + struct hdmi_audio_infoframe audio; + }; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0610-drm-edid-Move-HDMI_IDENTIFIER-to-hdmi.h.patch b/patches.baytrail/0610-drm-edid-Move-HDMI_IDENTIFIER-to-hdmi.h.patch new file mode 100644 index 000000000000..bbee7a7c9df6 --- /dev/null +++ b/patches.baytrail/0610-drm-edid-Move-HDMI_IDENTIFIER-to-hdmi.h.patch @@ -0,0 +1,54 @@ +From 505b8dc01bed63c31636a7eb0b3981ff9d9caf7e Mon Sep 17 00:00:00 2001 +From: "Lespiau, Damien" +Date: Mon, 19 Aug 2013 16:59:00 +0100 +Subject: drm/edid: Move HDMI_IDENTIFIER to hdmi.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We'll need the HDMI OUI for the HDMI vendor infoframe data, so let's +move the DRM one to hdmi.h, might as well use the hdmi header to store +some hdmi defines. + +(Note that, in fact, infoframes are part of the CEA-861 standard, and +only the HDMI vendor specific infoframe is special to HDMI, but +details..) + +Signed-off-by: Damien Lespiau +Reviewed-by: Ville Syrjälä +Reviewed-by: Thierry Reding +Signed-off-by: Dave Airlie +(cherry picked from commit c782d2e73d1e69c863d03945907bc7fbc879a778) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_edid.c | 1 - + include/linux/hdmi.h | 1 + + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 0cb9b5d8e30a..388039be229d 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -2287,7 +2287,6 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, + return closure.modes; + } + +-#define HDMI_IDENTIFIER 0x000C03 + #define AUDIO_BLOCK 0x01 + #define VIDEO_BLOCK 0x02 + #define VENDOR_BLOCK 0x03 +diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h +index e733252c2b5d..37e0cd755284 100644 +--- a/include/linux/hdmi.h ++++ b/include/linux/hdmi.h +@@ -18,6 +18,7 @@ enum hdmi_infoframe_type { + HDMI_INFOFRAME_TYPE_AUDIO = 0x84, + }; + ++#define HDMI_IDENTIFIER 0x000c03 + #define HDMI_INFOFRAME_HEADER_SIZE 4 + #define HDMI_AVI_INFOFRAME_SIZE 13 + #define HDMI_SPD_INFOFRAME_SIZE 25 +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0611-video-hdmi-Hook-the-HDMI-vendor-infoframe-with-the-g.patch b/patches.baytrail/0611-video-hdmi-Hook-the-HDMI-vendor-infoframe-with-the-g.patch new file mode 100644 index 000000000000..837fd87af39a --- /dev/null +++ b/patches.baytrail/0611-video-hdmi-Hook-the-HDMI-vendor-infoframe-with-the-g.patch @@ -0,0 +1,163 @@ +From 487dd947e265f3dcc64edfba87022b7d325f16aa Mon Sep 17 00:00:00 2001 +From: "Lespiau, Damien" +Date: Mon, 19 Aug 2013 16:59:01 +0100 +Subject: video/hdmi: Hook the HDMI vendor infoframe with the generic _pack() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With this last bit, hdmi_infoframe_pack() is now able to pack any +infoframe we support. + +At the same time, because it's impractical to make two commits out of +this, we get rid of the version that encourages the open coding of the +vendor infoframe packing. We can do so because the only user of this API +has been ported in: + + Author: Damien Lespiau + Date: Mon Aug 12 18:08:37 2013 +0100 + + gpu: host1x: Port the HDMI vendor infoframe code the common helpers + +v2: Change oui to be an unsigned int (Ville Syrjälä) + +Signed-off-by: Damien Lespiau +Reviewed-by: Ville Syrjälä +Reviewed-by: Thierry Reding +Signed-off-by: Dave Airlie +(cherry picked from commit af3e95b40720cdf301eb85387c0a3dc4067cc551) +Signed-off-by: James Ausmus + +Conflicts: + drivers/video/hdmi.c + (context changes) +Signed-off-by: Darren Hart +--- + drivers/video/hdmi.c | 46 ++++++++++------------------------------------ + include/linux/hdmi.h | 24 ++++++++++++------------ + 2 files changed, 22 insertions(+), 48 deletions(-) + +diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c +index 82c663a8961e..4d79791e6ebc 100644 +--- a/drivers/video/hdmi.c ++++ b/drivers/video/hdmi.c +@@ -300,6 +300,8 @@ int hdmi_hdmi_infoframe_init(struct hdmi_hdmi_infoframe *frame) + frame->type = HDMI_INFOFRAME_TYPE_VENDOR; + frame->version = 1; + ++ frame->oui = HDMI_IDENTIFIER; ++ + /* + * 0 is a valid value for s3d_struct, so we use a special "not set" + * value +@@ -377,46 +379,18 @@ ssize_t hdmi_hdmi_infoframe_pack(struct hdmi_hdmi_infoframe *frame, + } + EXPORT_SYMBOL(hdmi_hdmi_infoframe_pack); + +-/** +- * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary +- * buffer +- * @frame: HDMI vendor infoframe +- * @buffer: destination buffer +- * @size: size of buffer +- * +- * Packs the information contained in the @frame structure into a binary +- * representation that can be written into the corresponding controller +- * registers. Also computes the checksum as required by section 5.3.5 of +- * the HDMI 1.4 specification. +- * +- * Returns the number of bytes packed into the binary buffer or a negative +- * error code on failure. ++/* ++ * hdmi_vendor_infoframe_pack() - write a vendor infoframe to binary buffer + */ +-ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, +- void *buffer, size_t size) ++static ssize_t hdmi_vendor_infoframe_pack(union hdmi_vendor_infoframe *frame, ++ void *buffer, size_t size) + { +- u8 *ptr = buffer; +- size_t length; +- +- length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; +- +- if (size < length) +- return -ENOSPC; +- +- memset(buffer, 0, length); +- +- ptr[0] = frame->type; +- ptr[1] = frame->version; +- ptr[2] = frame->length; +- ptr[3] = 0; /* checksum */ +- +- memcpy(&ptr[HDMI_INFOFRAME_HEADER_SIZE], frame->data, frame->length); +- +- hdmi_infoframe_checksum(buffer, length); ++ /* we only know about HDMI vendor infoframes */ ++ if (frame->any.oui != HDMI_IDENTIFIER) ++ return -EINVAL; + +- return length; ++ return hdmi_hdmi_infoframe_pack(&frame->hdmi, buffer, size); + } +-EXPORT_SYMBOL(hdmi_vendor_infoframe_pack); + + /** + * hdmi_infoframe_pack() - write a HDMI infoframe to binary buffer +diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h +index 37e0cd755284..e24d850a8ee6 100644 +--- a/include/linux/hdmi.h ++++ b/include/linux/hdmi.h +@@ -225,16 +225,6 @@ int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame); + ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, + void *buffer, size_t size); + +-struct hdmi_vendor_infoframe { +- enum hdmi_infoframe_type type; +- unsigned char version; +- unsigned char length; +- u8 data[27]; +-}; +- +-ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, +- void *buffer, size_t size); +- + enum hdmi_3d_structure { + HDMI_3D_STRUCTURE_INVALID = -1, + HDMI_3D_STRUCTURE_FRAME_PACKING = 0, +@@ -251,6 +241,7 @@ struct hdmi_hdmi_infoframe { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; ++ unsigned int oui; + u8 vic; + enum hdmi_3d_structure s3d_struct; + unsigned int s3d_ext_data; +@@ -260,12 +251,21 @@ int hdmi_hdmi_infoframe_init(struct hdmi_hdmi_infoframe *frame); + ssize_t hdmi_hdmi_infoframe_pack(struct hdmi_hdmi_infoframe *frame, + void *buffer, size_t size); + ++union hdmi_vendor_infoframe { ++ struct { ++ enum hdmi_infoframe_type type; ++ unsigned char version; ++ unsigned char length; ++ unsigned int oui; ++ } any; ++ struct hdmi_hdmi_infoframe hdmi; ++}; ++ + union hdmi_infoframe { + struct hdmi_any_infoframe any; + struct hdmi_avi_infoframe avi; + struct hdmi_spd_infoframe spd; +- struct hdmi_vendor_infoframe vendor; +- struct hdmi_hdmi_infoframe hdmi; ++ union hdmi_vendor_infoframe vendor; + struct hdmi_audio_infoframe audio; + }; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0612-video-hdmi-Use-hdmi_vendor_infoframe-for-the-HDMI-sp.patch b/patches.baytrail/0612-video-hdmi-Use-hdmi_vendor_infoframe-for-the-HDMI-sp.patch new file mode 100644 index 000000000000..a457d3328e74 --- /dev/null +++ b/patches.baytrail/0612-video-hdmi-Use-hdmi_vendor_infoframe-for-the-HDMI-sp.patch @@ -0,0 +1,185 @@ +From bcb29d1b90c9e5781d56e22fbe2e62d825070531 Mon Sep 17 00:00:00 2001 +From: "Lespiau, Damien" +Date: Mon, 19 Aug 2013 16:59:02 +0100 +Subject: video/hdmi: Use hdmi_vendor_infoframe for the HDMI specific infoframe + +We just got rid of the version of hdmi_vendor_infoframe that had a byte +array for anyone to poke at. It's now time to shuffle around the naming +of hdmi_hdmi_infoframe to make hdmi_vendor_infoframe become the HDMI +vendor specific structure. + +Cc: Thierry Reding +Signed-off-by: Damien Lespiau +Reviewed-by: Thierry Reding +Signed-off-by: Dave Airlie +(cherry picked from commit ae84b900b009589a7017a1f8f060edd7de501642) +Signed-off-by: James Ausmus + +Conflicts: + drivers/gpu/host1x/drm/hdmi.c + (context changes) +Signed-off-by: Darren Hart +--- + drivers/gpu/host1x/drm/hdmi.c | 20 ++------------------ + drivers/video/hdmi.c | 25 +++++++++++++------------ + include/linux/hdmi.h | 15 ++++++++------- + 3 files changed, 23 insertions(+), 37 deletions(-) + +diff --git a/drivers/gpu/host1x/drm/hdmi.c b/drivers/gpu/host1x/drm/hdmi.c +index 01097da09f7f..52e3c9641a0f 100644 +--- a/drivers/gpu/host1x/drm/hdmi.c ++++ b/drivers/gpu/host1x/drm/hdmi.c +@@ -551,24 +551,8 @@ static void tegra_hdmi_setup_stereo_infoframe(struct tegra_hdmi *hdmi) + return; + } + +- memset(&frame, 0, sizeof(frame)); +- +- frame.type = HDMI_INFOFRAME_TYPE_VENDOR; +- frame.version = 0x01; +- frame.length = 6; +- +- frame.data[0] = 0x03; /* regid0 */ +- frame.data[1] = 0x0c; /* regid1 */ +- frame.data[2] = 0x00; /* regid2 */ +- frame.data[3] = 0x02 << 5; /* video format */ +- +- /* TODO: 74 MHz limit? */ +- if (1) { +- frame.data[4] = 0x00 << 4; /* 3D structure */ +- } else { +- frame.data[4] = 0x08 << 4; /* 3D structure */ +- frame.data[5] = 0x00 << 4; /* 3D ext. data */ +- } ++ hdmi_vendor_infoframe_init(&frame); ++ frame.s3d_struct = HDMI_3D_STRUCTURE_FRAME_PACKING; + + err = hdmi_vendor_infoframe_pack(&frame, buffer, sizeof(buffer)); + if (err < 0) { +diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c +index 4d79791e6ebc..e22ea8b16a1d 100644 +--- a/drivers/video/hdmi.c ++++ b/drivers/video/hdmi.c +@@ -288,12 +288,12 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, + EXPORT_SYMBOL(hdmi_audio_infoframe_pack); + + /** +- * hdmi_hdmi_infoframe_init() - initialize an HDMI vendor infoframe ++ * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe + * @frame: HDMI vendor infoframe + * + * Returns 0 on success or a negative error code on failure. + */ +-int hdmi_hdmi_infoframe_init(struct hdmi_hdmi_infoframe *frame) ++int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame) + { + memset(frame, 0, sizeof(*frame)); + +@@ -310,10 +310,10 @@ int hdmi_hdmi_infoframe_init(struct hdmi_hdmi_infoframe *frame) + + return 0; + } +-EXPORT_SYMBOL(hdmi_hdmi_infoframe_init); ++EXPORT_SYMBOL(hdmi_vendor_infoframe_init); + + /** +- * hdmi_hdmi_infoframe_pack() - write a HDMI vendor infoframe to binary buffer ++ * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary buffer + * @frame: HDMI infoframe + * @buffer: destination buffer + * @size: size of buffer +@@ -326,7 +326,7 @@ EXPORT_SYMBOL(hdmi_hdmi_infoframe_init); + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +-ssize_t hdmi_hdmi_infoframe_pack(struct hdmi_hdmi_infoframe *frame, ++ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, + void *buffer, size_t size) + { + u8 *ptr = buffer; +@@ -377,19 +377,20 @@ ssize_t hdmi_hdmi_infoframe_pack(struct hdmi_hdmi_infoframe *frame, + + return length; + } +-EXPORT_SYMBOL(hdmi_hdmi_infoframe_pack); ++EXPORT_SYMBOL(hdmi_vendor_infoframe_pack); + + /* +- * hdmi_vendor_infoframe_pack() - write a vendor infoframe to binary buffer ++ * hdmi_vendor_any_infoframe_pack() - write a vendor infoframe to binary buffer + */ +-static ssize_t hdmi_vendor_infoframe_pack(union hdmi_vendor_infoframe *frame, +- void *buffer, size_t size) ++static ssize_t ++hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame, ++ void *buffer, size_t size) + { + /* we only know about HDMI vendor infoframes */ + if (frame->any.oui != HDMI_IDENTIFIER) + return -EINVAL; + +- return hdmi_hdmi_infoframe_pack(&frame->hdmi, buffer, size); ++ return hdmi_vendor_infoframe_pack(&frame->hdmi, buffer, size); + } + + /** +@@ -422,8 +423,8 @@ hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size) + length = hdmi_audio_infoframe_pack(&frame->audio, buffer, size); + break; + case HDMI_INFOFRAME_TYPE_VENDOR: +- length = hdmi_vendor_infoframe_pack(&frame->vendor, +- buffer, size); ++ length = hdmi_vendor_any_infoframe_pack(&frame->vendor, ++ buffer, size); + break; + default: + WARN(1, "Bad infoframe type %d\n", frame->any.type); +diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h +index e24d850a8ee6..d4ae12c7931b 100644 +--- a/include/linux/hdmi.h ++++ b/include/linux/hdmi.h +@@ -237,7 +237,8 @@ enum hdmi_3d_structure { + HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF = 8, + }; + +-struct hdmi_hdmi_infoframe { ++ ++struct hdmi_vendor_infoframe { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; +@@ -247,25 +248,25 @@ struct hdmi_hdmi_infoframe { + unsigned int s3d_ext_data; + }; + +-int hdmi_hdmi_infoframe_init(struct hdmi_hdmi_infoframe *frame); +-ssize_t hdmi_hdmi_infoframe_pack(struct hdmi_hdmi_infoframe *frame, +- void *buffer, size_t size); ++int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame); ++ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, ++ void *buffer, size_t size); + +-union hdmi_vendor_infoframe { ++union hdmi_vendor_any_infoframe { + struct { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; + unsigned int oui; + } any; +- struct hdmi_hdmi_infoframe hdmi; ++ struct hdmi_vendor_infoframe hdmi; + }; + + union hdmi_infoframe { + struct hdmi_any_infoframe any; + struct hdmi_avi_infoframe avi; + struct hdmi_spd_infoframe spd; +- union hdmi_vendor_infoframe vendor; ++ union hdmi_vendor_any_infoframe vendor; + struct hdmi_audio_infoframe audio; + }; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0613-drm-edid-Fix-add_cea_modes-style-issues.patch b/patches.baytrail/0613-drm-edid-Fix-add_cea_modes-style-issues.patch new file mode 100644 index 000000000000..ca7d3fdd7c20 --- /dev/null +++ b/patches.baytrail/0613-drm-edid-Fix-add_cea_modes-style-issues.patch @@ -0,0 +1,66 @@ +From 95438688202ec84a3f666a24fa8a8f3a0400c489 Mon Sep 17 00:00:00 2001 +From: "Lespiau, Damien" +Date: Mon, 19 Aug 2013 16:58:53 +0100 +Subject: drm/edid: Fix add_cea_modes() style issues +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A few styles issues have crept in here, fix them before touching this +code again. + +v2: constify arguments that can be (Ville Syrjälä) +v3: constify, but better (Ville Syrjälä) + +Signed-off-by: Damien Lespiau +Reviewed-by: Ville Syrjälä +Reviewed-by: Thierry Reding +Signed-off-by: Dave Airlie +(cherry picked from commit 13ac3f5593cf0964cdb239864829e57cc6981dac) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_edid.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 388039be229d..8b5b7aee73cb 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -2368,10 +2368,11 @@ EXPORT_SYMBOL(drm_match_cea_mode); + + + static int +-do_cea_modes (struct drm_connector *connector, u8 *db, u8 len) ++do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len) + { + struct drm_device *dev = connector->dev; +- u8 * mode, cea_mode; ++ const u8 *mode; ++ u8 cea_mode; + int modes = 0; + + for (mode = db; mode < db + len; mode++) { +@@ -2428,8 +2429,9 @@ cea_db_offsets(const u8 *cea, int *start, int *end) + static int + add_cea_modes(struct drm_connector *connector, struct edid *edid) + { +- u8 * cea = drm_find_cea_extension(edid); +- u8 * db, dbl; ++ const u8 *cea = drm_find_cea_extension(edid); ++ const u8 *db; ++ u8 dbl; + int modes = 0; + + if (cea && cea_revision(cea) >= 3) { +@@ -2443,7 +2445,7 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid) + dbl = cea_db_payload_len(db); + + if (cea_db_tag(db) == VIDEO_BLOCK) +- modes += do_cea_modes (connector, db+1, dbl); ++ modes += do_cea_modes(connector, db + 1, dbl); + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0614-drm-edid-Parse-the-HDMI-CEA-block-and-look-for-4k-mo.patch b/patches.baytrail/0614-drm-edid-Parse-the-HDMI-CEA-block-and-look-for-4k-mo.patch new file mode 100644 index 000000000000..86dedf0fbb3b --- /dev/null +++ b/patches.baytrail/0614-drm-edid-Parse-the-HDMI-CEA-block-and-look-for-4k-mo.patch @@ -0,0 +1,199 @@ +From af2a7255606a2ff9e909bf24d5c28379b37f313f Mon Sep 17 00:00:00 2001 +From: "Lespiau, Damien" +Date: Mon, 19 Aug 2013 16:58:54 +0100 +Subject: drm/edid: Parse the HDMI CEA block and look for 4k modes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +HDMI 1.4 adds 4 "4k x 2k" modes in the the CEA vendor specific block. + +With this commit, we now parse this block and expose the 4k modes that +we find there. + +v2: Fix the "4096x2160" string (nice catch!), add comments about + do_hdmi_vsdb_modes() arguments and make it clearer that offset is + relative to the end of the required fields of the HDMI VSDB + (Ville Syrjälä) + +v3: Fix 'Unknow' typo (Simon Farnsworth) + +Signed-off-by: Damien Lespiau +Tested-by: Cancan Feng +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67030 +Reviewed-by: Simon Farnsworth +Reviewed-by: Ville Syrjälä +Reviewed-by: Thierry Reding +Signed-off-by: Dave Airlie +(cherry picked from commit 7ebe1963a063daf30f95752c35244c5d49550aa9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_edid.c | 124 +++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 109 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 8b5b7aee73cb..49b5492e6d59 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -934,6 +934,36 @@ static const struct drm_display_mode edid_cea_modes[] = { + .vrefresh = 100, }, + }; + ++/* ++ * HDMI 1.4 4k modes. ++ */ ++static const struct drm_display_mode edid_4k_modes[] = { ++ /* 1 - 3840x2160@30Hz */ ++ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, ++ 3840, 4016, 4104, 4400, 0, ++ 2160, 2168, 2178, 2250, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), ++ .vrefresh = 30, }, ++ /* 2 - 3840x2160@25Hz */ ++ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, ++ 3840, 4896, 4984, 5280, 0, ++ 2160, 2168, 2178, 2250, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), ++ .vrefresh = 25, }, ++ /* 3 - 3840x2160@24Hz */ ++ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, ++ 3840, 5116, 5204, 5500, 0, ++ 2160, 2168, 2178, 2250, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), ++ .vrefresh = 24, }, ++ /* 4 - 4096x2160@24Hz (SMPTE) */ ++ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, ++ 4096, 5116, 5204, 5500, 0, ++ 2160, 2168, 2178, 2250, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), ++ .vrefresh = 24, }, ++}; ++ + /*** DDC fetch and block validation ***/ + + static const u8 edid_header[] = { +@@ -2392,6 +2422,68 @@ do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len) + return modes; + } + ++/* ++ * do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block ++ * @connector: connector corresponding to the HDMI sink ++ * @db: start of the CEA vendor specific block ++ * @len: length of the CEA block payload, ie. one can access up to db[len] ++ * ++ * Parses the HDMI VSDB looking for modes to add to @connector. ++ */ ++static int ++do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len) ++{ ++ struct drm_device *dev = connector->dev; ++ int modes = 0, offset = 0, i; ++ u8 vic_len; ++ ++ if (len < 8) ++ goto out; ++ ++ /* no HDMI_Video_Present */ ++ if (!(db[8] & (1 << 5))) ++ goto out; ++ ++ /* Latency_Fields_Present */ ++ if (db[8] & (1 << 7)) ++ offset += 2; ++ ++ /* I_Latency_Fields_Present */ ++ if (db[8] & (1 << 6)) ++ offset += 2; ++ ++ /* the declared length is not long enough for the 2 first bytes ++ * of additional video format capabilities */ ++ offset += 2; ++ if (len < (8 + offset)) ++ goto out; ++ ++ vic_len = db[8 + offset] >> 5; ++ ++ for (i = 0; i < vic_len && len >= (9 + offset + i); i++) { ++ struct drm_display_mode *newmode; ++ u8 vic; ++ ++ vic = db[9 + offset + i]; ++ ++ vic--; /* VICs start at 1 */ ++ if (vic >= ARRAY_SIZE(edid_4k_modes)) { ++ DRM_ERROR("Unknown HDMI VIC: %d\n", vic); ++ continue; ++ } ++ ++ newmode = drm_mode_duplicate(dev, &edid_4k_modes[vic]); ++ if (!newmode) ++ continue; ++ ++ drm_mode_probed_add(connector, newmode); ++ modes++; ++ } ++ ++out: ++ return modes; ++} ++ + static int + cea_db_payload_len(const u8 *db) + { +@@ -2423,6 +2515,21 @@ cea_db_offsets(const u8 *cea, int *start, int *end) + return 0; + } + ++static bool cea_db_is_hdmi_vsdb(const u8 *db) ++{ ++ int hdmi_id; ++ ++ if (cea_db_tag(db) != VENDOR_BLOCK) ++ return false; ++ ++ if (cea_db_payload_len(db) < 5) ++ return false; ++ ++ hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16); ++ ++ return hdmi_id == HDMI_IDENTIFIER; ++} ++ + #define for_each_cea_db(cea, i, start, end) \ + for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1) + +@@ -2446,6 +2553,8 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid) + + if (cea_db_tag(db) == VIDEO_BLOCK) + modes += do_cea_modes(connector, db + 1, dbl); ++ else if (cea_db_is_hdmi_vsdb(db)) ++ modes += do_hdmi_vsdb_modes(connector, db, dbl); + } + } + +@@ -2498,21 +2607,6 @@ monitor_name(struct detailed_timing *t, void *data) + *(u8 **)data = t->data.other_data.data.str.str; + } + +-static bool cea_db_is_hdmi_vsdb(const u8 *db) +-{ +- int hdmi_id; +- +- if (cea_db_tag(db) != VENDOR_BLOCK) +- return false; +- +- if (cea_db_payload_len(db) < 5) +- return false; +- +- hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16); +- +- return hdmi_id == HDMI_IDENTIFIER; +-} +- + /** + * drm_edid_to_eld - build ELD from EDID + * @connector: connector corresponding to the HDMI/DP sink +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0615-video-hdmi-Rename-HDMI_IDENTIFIER-to-HDMI_IEEE_OUI.patch b/patches.baytrail/0615-video-hdmi-Rename-HDMI_IDENTIFIER-to-HDMI_IEEE_OUI.patch new file mode 100644 index 000000000000..de0464f73576 --- /dev/null +++ b/patches.baytrail/0615-video-hdmi-Rename-HDMI_IDENTIFIER-to-HDMI_IEEE_OUI.patch @@ -0,0 +1,73 @@ +From 49a8ccfeed52f250d9e48f9e9b9c32343835bdcd Mon Sep 17 00:00:00 2001 +From: "Lespiau, Damien" +Date: Mon, 19 Aug 2013 16:59:05 +0100 +Subject: video/hdmi: Rename HDMI_IDENTIFIER to HDMI_IEEE_OUI + +HDMI_IDENTIFIER was felt too generic, rename it to what it is, the IEEE +OUI corresponding to HDMI Licensing, LLC. + +http://standards.ieee.org/develop/regauth/oui/oui.txt + +Cc: Thierry Reding +Signed-off-by: Damien Lespiau +Reviewed-by: Thierry Reding +Signed-off-by: Dave Airlie +(cherry picked from commit 6cb3b7f1c013fd4bea41e16ee557bcb2f1561787) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_edid.c | 2 +- + drivers/video/hdmi.c | 4 ++-- + include/linux/hdmi.h | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 49b5492e6d59..97c6c8c95a95 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -2527,7 +2527,7 @@ static bool cea_db_is_hdmi_vsdb(const u8 *db) + + hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16); + +- return hdmi_id == HDMI_IDENTIFIER; ++ return hdmi_id == HDMI_IEEE_OUI; + } + + #define for_each_cea_db(cea, i, start, end) \ +diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c +index e22ea8b16a1d..7944eaa935f5 100644 +--- a/drivers/video/hdmi.c ++++ b/drivers/video/hdmi.c +@@ -300,7 +300,7 @@ int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame) + frame->type = HDMI_INFOFRAME_TYPE_VENDOR; + frame->version = 1; + +- frame->oui = HDMI_IDENTIFIER; ++ frame->oui = HDMI_IEEE_OUI; + + /* + * 0 is a valid value for s3d_struct, so we use a special "not set" +@@ -387,7 +387,7 @@ hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame, + void *buffer, size_t size) + { + /* we only know about HDMI vendor infoframes */ +- if (frame->any.oui != HDMI_IDENTIFIER) ++ if (frame->any.oui != HDMI_IEEE_OUI) + return -EINVAL; + + return hdmi_vendor_infoframe_pack(&frame->hdmi, buffer, size); +diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h +index d4ae12c7931b..9231be9e90a2 100644 +--- a/include/linux/hdmi.h ++++ b/include/linux/hdmi.h +@@ -18,7 +18,7 @@ enum hdmi_infoframe_type { + HDMI_INFOFRAME_TYPE_AUDIO = 0x84, + }; + +-#define HDMI_IDENTIFIER 0x000c03 ++#define HDMI_IEEE_OUI 0x000c03 + #define HDMI_INFOFRAME_HEADER_SIZE 4 + #define HDMI_AVI_INFOFRAME_SIZE 13 + #define HDMI_SPD_INFOFRAME_SIZE 25 +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0616-drm-i915-hdmi-Change-the-write_infoframe-vfunc-to-ta.patch b/patches.baytrail/0616-drm-i915-hdmi-Change-the-write_infoframe-vfunc-to-ta.patch new file mode 100644 index 000000000000..f3e1864251d0 --- /dev/null +++ b/patches.baytrail/0616-drm-i915-hdmi-Change-the-write_infoframe-vfunc-to-ta.patch @@ -0,0 +1,337 @@ +From de4eccc5978c9b1d3173011e7bb6754ad7ddc9ca Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Tue, 6 Aug 2013 20:32:18 +0100 +Subject: drm/i915/hdmi: Change the write_infoframe vfunc to take a buffer and + a type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +First step in the move to the shared infoframe infrastructure, let's +move the different infoframe helpers and the write_infoframe() vfunc to +a type (enum hdmi_infoframe_type) and a buffer + len instead of using +our struct dip_infoframe. + +v2: constify the infoframe pointer and don't mix signs (Ville Syrjälä) + +Signed-off-by: Damien Lespiau +Signed-off-by: Paulo Zanoni +Signed-off-by: Thierry Reding +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 178f736ab96637bc17bcf00c3b58af0137e880e0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_drv.h | 4 +- + drivers/gpu/drm/i915/intel_hdmi.c | 106 ++++++++++++++++++++------------------ + 2 files changed, 59 insertions(+), 51 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 54e389de9f42..712e29e27c14 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -26,6 +26,7 @@ + #define __INTEL_DRV_H__ + + #include ++#include + #include + #include "i915_drv.h" + #include +@@ -464,7 +465,8 @@ struct intel_hdmi { + enum hdmi_force_audio force_audio; + bool rgb_quant_range_selectable; + void (*write_infoframe)(struct drm_encoder *encoder, +- struct dip_infoframe *frame); ++ enum hdmi_infoframe_type type, ++ const uint8_t *frame, ssize_t len); + void (*set_infoframes)(struct drm_encoder *encoder, + struct drm_display_mode *adjusted_mode); + }; +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 0b3750f11a97..594c103136c4 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -81,74 +82,75 @@ void intel_dip_infoframe_csum(struct dip_infoframe *frame) + frame->checksum = 0x100 - sum; + } + +-static u32 g4x_infoframe_index(struct dip_infoframe *frame) ++static u32 g4x_infoframe_index(enum hdmi_infoframe_type type) + { +- switch (frame->type) { +- case DIP_TYPE_AVI: ++ switch (type) { ++ case HDMI_INFOFRAME_TYPE_AVI: + return VIDEO_DIP_SELECT_AVI; +- case DIP_TYPE_SPD: ++ case HDMI_INFOFRAME_TYPE_SPD: + return VIDEO_DIP_SELECT_SPD; + default: +- DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); ++ DRM_DEBUG_DRIVER("unknown info frame type %d\n", type); + return 0; + } + } + +-static u32 g4x_infoframe_enable(struct dip_infoframe *frame) ++static u32 g4x_infoframe_enable(enum hdmi_infoframe_type type) + { +- switch (frame->type) { +- case DIP_TYPE_AVI: ++ switch (type) { ++ case HDMI_INFOFRAME_TYPE_AVI: + return VIDEO_DIP_ENABLE_AVI; +- case DIP_TYPE_SPD: ++ case HDMI_INFOFRAME_TYPE_SPD: + return VIDEO_DIP_ENABLE_SPD; + default: +- DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); ++ DRM_DEBUG_DRIVER("unknown info frame type %d\n", type); + return 0; + } + } + +-static u32 hsw_infoframe_enable(struct dip_infoframe *frame) ++static u32 hsw_infoframe_enable(enum hdmi_infoframe_type type) + { +- switch (frame->type) { +- case DIP_TYPE_AVI: ++ switch (type) { ++ case HDMI_INFOFRAME_TYPE_AVI: + return VIDEO_DIP_ENABLE_AVI_HSW; +- case DIP_TYPE_SPD: ++ case HDMI_INFOFRAME_TYPE_SPD: + return VIDEO_DIP_ENABLE_SPD_HSW; + default: +- DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); ++ DRM_DEBUG_DRIVER("unknown info frame type %d\n", type); + return 0; + } + } + +-static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, ++static u32 hsw_infoframe_data_reg(enum hdmi_infoframe_type type, + enum transcoder cpu_transcoder) + { +- switch (frame->type) { +- case DIP_TYPE_AVI: ++ switch (type) { ++ case HDMI_INFOFRAME_TYPE_AVI: + return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder); +- case DIP_TYPE_SPD: ++ case HDMI_INFOFRAME_TYPE_SPD: + return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder); + default: +- DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); ++ DRM_DEBUG_DRIVER("unknown info frame type %d\n", type); + return 0; + } + } + + static void g4x_write_infoframe(struct drm_encoder *encoder, +- struct dip_infoframe *frame) ++ enum hdmi_infoframe_type type, ++ const uint8_t *frame, ssize_t len) + { + uint32_t *data = (uint32_t *)frame; + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val = I915_READ(VIDEO_DIP_CTL); +- unsigned i, len = DIP_HEADER_SIZE + frame->len; ++ int i; + + WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); + + val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ +- val |= g4x_infoframe_index(frame); ++ val |= g4x_infoframe_index(type); + +- val &= ~g4x_infoframe_enable(frame); ++ val &= ~g4x_infoframe_enable(type); + + I915_WRITE(VIDEO_DIP_CTL, val); + +@@ -162,7 +164,7 @@ static void g4x_write_infoframe(struct drm_encoder *encoder, + I915_WRITE(VIDEO_DIP_DATA, 0); + mmiowb(); + +- val |= g4x_infoframe_enable(frame); ++ val |= g4x_infoframe_enable(type); + val &= ~VIDEO_DIP_FREQ_MASK; + val |= VIDEO_DIP_FREQ_VSYNC; + +@@ -171,22 +173,22 @@ static void g4x_write_infoframe(struct drm_encoder *encoder, + } + + static void ibx_write_infoframe(struct drm_encoder *encoder, +- struct dip_infoframe *frame) ++ enum hdmi_infoframe_type type, ++ const uint8_t *frame, ssize_t len) + { + uint32_t *data = (uint32_t *)frame; + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); +- int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); +- unsigned i, len = DIP_HEADER_SIZE + frame->len; ++ int i, reg = TVIDEO_DIP_CTL(intel_crtc->pipe); + u32 val = I915_READ(reg); + + WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); + + val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ +- val |= g4x_infoframe_index(frame); ++ val |= g4x_infoframe_index(type); + +- val &= ~g4x_infoframe_enable(frame); ++ val &= ~g4x_infoframe_enable(type); + + I915_WRITE(reg, val); + +@@ -200,7 +202,7 @@ static void ibx_write_infoframe(struct drm_encoder *encoder, + I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0); + mmiowb(); + +- val |= g4x_infoframe_enable(frame); ++ val |= g4x_infoframe_enable(type); + val &= ~VIDEO_DIP_FREQ_MASK; + val |= VIDEO_DIP_FREQ_VSYNC; + +@@ -209,25 +211,25 @@ static void ibx_write_infoframe(struct drm_encoder *encoder, + } + + static void cpt_write_infoframe(struct drm_encoder *encoder, +- struct dip_infoframe *frame) ++ enum hdmi_infoframe_type type, ++ const uint8_t *frame, ssize_t len) + { + uint32_t *data = (uint32_t *)frame; + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); +- int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); +- unsigned i, len = DIP_HEADER_SIZE + frame->len; ++ int i, reg = TVIDEO_DIP_CTL(intel_crtc->pipe); + u32 val = I915_READ(reg); + + WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); + + val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ +- val |= g4x_infoframe_index(frame); ++ val |= g4x_infoframe_index(type); + + /* The DIP control register spec says that we need to update the AVI + * infoframe without clearing its enable bit */ +- if (frame->type != DIP_TYPE_AVI) +- val &= ~g4x_infoframe_enable(frame); ++ if (type != HDMI_INFOFRAME_TYPE_AVI) ++ val &= ~g4x_infoframe_enable(type); + + I915_WRITE(reg, val); + +@@ -241,7 +243,7 @@ static void cpt_write_infoframe(struct drm_encoder *encoder, + I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0); + mmiowb(); + +- val |= g4x_infoframe_enable(frame); ++ val |= g4x_infoframe_enable(type); + val &= ~VIDEO_DIP_FREQ_MASK; + val |= VIDEO_DIP_FREQ_VSYNC; + +@@ -250,22 +252,22 @@ static void cpt_write_infoframe(struct drm_encoder *encoder, + } + + static void vlv_write_infoframe(struct drm_encoder *encoder, +- struct dip_infoframe *frame) ++ enum hdmi_infoframe_type type, ++ const uint8_t *frame, ssize_t len) + { + uint32_t *data = (uint32_t *)frame; + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); +- int reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe); +- unsigned i, len = DIP_HEADER_SIZE + frame->len; ++ int i, reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe); + u32 val = I915_READ(reg); + + WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); + + val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ +- val |= g4x_infoframe_index(frame); ++ val |= g4x_infoframe_index(type); + +- val &= ~g4x_infoframe_enable(frame); ++ val &= ~g4x_infoframe_enable(type); + + I915_WRITE(reg, val); + +@@ -279,7 +281,7 @@ static void vlv_write_infoframe(struct drm_encoder *encoder, + I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), 0); + mmiowb(); + +- val |= g4x_infoframe_enable(frame); ++ val |= g4x_infoframe_enable(type); + val &= ~VIDEO_DIP_FREQ_MASK; + val |= VIDEO_DIP_FREQ_VSYNC; + +@@ -288,21 +290,24 @@ static void vlv_write_infoframe(struct drm_encoder *encoder, + } + + static void hsw_write_infoframe(struct drm_encoder *encoder, +- struct dip_infoframe *frame) ++ enum hdmi_infoframe_type type, ++ const uint8_t *frame, ssize_t len) + { + uint32_t *data = (uint32_t *)frame; + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); + u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config.cpu_transcoder); +- u32 data_reg = hsw_infoframe_data_reg(frame, intel_crtc->config.cpu_transcoder); +- unsigned int i, len = DIP_HEADER_SIZE + frame->len; ++ u32 data_reg; ++ int i; + u32 val = I915_READ(ctl_reg); + ++ data_reg = hsw_infoframe_data_reg(type, ++ intel_crtc->config.cpu_transcoder); + if (data_reg == 0) + return; + +- val &= ~hsw_infoframe_enable(frame); ++ val &= ~hsw_infoframe_enable(type); + I915_WRITE(ctl_reg, val); + + mmiowb(); +@@ -315,7 +320,7 @@ static void hsw_write_infoframe(struct drm_encoder *encoder, + I915_WRITE(data_reg + i, 0); + mmiowb(); + +- val |= hsw_infoframe_enable(frame); ++ val |= hsw_infoframe_enable(type); + I915_WRITE(ctl_reg, val); + POSTING_READ(ctl_reg); + } +@@ -326,7 +331,8 @@ static void intel_set_infoframe(struct drm_encoder *encoder, + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); + + intel_dip_infoframe_csum(frame); +- intel_hdmi->write_infoframe(encoder, frame); ++ intel_hdmi->write_infoframe(encoder, frame->type, (uint8_t *)frame, ++ DIP_HEADER_SIZE + frame->len); + } + + static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0617-drm-i915-hdmi-Port-the-infoframe-code-to-the-common-.patch b/patches.baytrail/0617-drm-i915-hdmi-Port-the-infoframe-code-to-the-common-.patch new file mode 100644 index 000000000000..1f784f4a329c --- /dev/null +++ b/patches.baytrail/0617-drm-i915-hdmi-Port-the-infoframe-code-to-the-common-.patch @@ -0,0 +1,147 @@ +From f039cc6278d031d4ee9a7aead0d48469b5bc99fd Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Tue, 6 Aug 2013 20:32:19 +0100 +Subject: drm/i915/hdmi: Port the infoframe code to the common hdmi helpers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Let's use the drivers/video/hmdi.c and drm infoframe helpers to build +our infoframes. + +v2: Simplify the logic to compute the buffer size. We can just take the +maximum infoframe size rounded to 32, which happens to be what the +hardware let us write anyway. + +v3: Remove unnecessary memset() (Ville Syrjälä) + +Signed-off-by: Damien Lespiau +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 5adaea799c1c2c00a1ffe995255af25717029b65) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_hdmi.c | 82 +++++++++++++++++++++++++++------------ + 1 file changed, 58 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 594c103136c4..118715389651 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -325,14 +325,43 @@ static void hsw_write_infoframe(struct drm_encoder *encoder, + POSTING_READ(ctl_reg); + } + ++/* ++ * The data we write to the DIP data buffer registers is 1 byte bigger than the ++ * HDMI infoframe size because of an ECC/reserved byte at position 3 (starting ++ * at 0). It's also a byte used by DisplayPort so the same DIP registers can be ++ * used for both technologies. ++ * ++ * DW0: Reserved/ECC/DP | HB2 | HB1 | HB0 ++ * DW1: DB3 | DB2 | DB1 | DB0 ++ * DW2: DB7 | DB6 | DB5 | DB4 ++ * DW3: ... ++ * ++ * (HB is Header Byte, DB is Data Byte) ++ * ++ * The hdmi pack() functions don't know about that hardware specific hole so we ++ * trick them by giving an offset into the buffer and moving back the header ++ * bytes by one. ++ */ + static void intel_set_infoframe(struct drm_encoder *encoder, +- struct dip_infoframe *frame) ++ union hdmi_infoframe *frame) + { + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); ++ uint8_t buffer[VIDEO_DIP_DATA_SIZE]; ++ ssize_t len; + +- intel_dip_infoframe_csum(frame); +- intel_hdmi->write_infoframe(encoder, frame->type, (uint8_t *)frame, +- DIP_HEADER_SIZE + frame->len); ++ /* see comment above for the reason for this offset */ ++ len = hdmi_infoframe_pack(frame, buffer + 1, sizeof(buffer) - 1); ++ if (len < 0) ++ return; ++ ++ /* Insert the 'hole' (see big comment above) at position 3 */ ++ buffer[0] = buffer[1]; ++ buffer[1] = buffer[2]; ++ buffer[2] = buffer[3]; ++ buffer[3] = 0; ++ len++; ++ ++ intel_hdmi->write_infoframe(encoder, frame->any.type, buffer, len); + } + + static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, +@@ -340,40 +369,45 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, + { + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); +- struct dip_infoframe avi_if = { +- .type = DIP_TYPE_AVI, +- .ver = DIP_VERSION_AVI, +- .len = DIP_LEN_AVI, +- }; ++ union hdmi_infoframe frame; ++ int ret; ++ ++ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, ++ adjusted_mode); ++ if (ret < 0) { ++ DRM_ERROR("couldn't fill AVI infoframe\n"); ++ return; ++ } + + if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) +- avi_if.body.avi.YQ_CN_PR |= DIP_AVI_PR_2; ++ frame.avi.pixel_repeat = 1; + + if (intel_hdmi->rgb_quant_range_selectable) { + if (intel_crtc->config.limited_color_range) +- avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED; ++ frame.avi.quantization_range = ++ HDMI_QUANTIZATION_RANGE_LIMITED; + else +- avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL; ++ frame.avi.quantization_range = ++ HDMI_QUANTIZATION_RANGE_FULL; + } + +- avi_if.body.avi.VIC = drm_match_cea_mode(adjusted_mode); +- +- intel_set_infoframe(encoder, &avi_if); ++ intel_set_infoframe(encoder, &frame); + } + + static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder) + { +- struct dip_infoframe spd_if; ++ union hdmi_infoframe frame; ++ int ret; ++ ++ ret = hdmi_spd_infoframe_init(&frame.spd, "Intel", "Integrated gfx"); ++ if (ret < 0) { ++ DRM_ERROR("couldn't fill SPD infoframe\n"); ++ return; ++ } + +- memset(&spd_if, 0, sizeof(spd_if)); +- spd_if.type = DIP_TYPE_SPD; +- spd_if.ver = DIP_VERSION_SPD; +- spd_if.len = DIP_LEN_SPD; +- strcpy(spd_if.body.spd.vn, "Intel"); +- strcpy(spd_if.body.spd.pd, "Integrated gfx"); +- spd_if.body.spd.sdi = DIP_SPD_PC; ++ frame.spd.sdi = HDMI_SPD_SDI_PC; + +- intel_set_infoframe(encoder, &spd_if); ++ intel_set_infoframe(encoder, &frame); + } + + static void g4x_set_infoframes(struct drm_encoder *encoder, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0618-drm-i915-sdvo-Port-the-infoframe-code-to-the-shared-.patch b/patches.baytrail/0618-drm-i915-sdvo-Port-the-infoframe-code-to-the-shared-.patch new file mode 100644 index 000000000000..b6b918e2ac9f --- /dev/null +++ b/patches.baytrail/0618-drm-i915-sdvo-Port-the-infoframe-code-to-the-shared-.patch @@ -0,0 +1,77 @@ +From 946cb86257b3e587b6f60de2684a7425c92122c9 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Tue, 6 Aug 2013 20:32:20 +0100 +Subject: drm/i915/sdvo: Port the infoframe code to the shared infrastructure +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Ville Syrjälä +Signed-off-by: Damien Lespiau +Signed-off-by: Paulo Zanoni +Signed-off-by: Thierry Reding +Signed-off-by: Daniel Vetter +(cherry picked from commit 15dcd3502160a46acf11e5cb5e80e9d90a6f9f60) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sdvo.c | 38 ++++++++++++++++++++------------------ + 1 file changed, 20 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 47423f31f82b..02f220b4e4a1 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -963,30 +963,32 @@ static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, + static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, + const struct drm_display_mode *adjusted_mode) + { +- struct dip_infoframe avi_if = { +- .type = DIP_TYPE_AVI, +- .ver = DIP_VERSION_AVI, +- .len = DIP_LEN_AVI, +- }; +- uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; +- struct intel_crtc *intel_crtc = to_intel_crtc(intel_sdvo->base.base.crtc); ++ uint8_t sdvo_data[HDMI_INFOFRAME_SIZE(AVI)]; ++ struct drm_crtc *crtc = intel_sdvo->base.base.crtc; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ union hdmi_infoframe frame; ++ int ret; ++ ssize_t len; ++ ++ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, ++ adjusted_mode); ++ if (ret < 0) { ++ DRM_ERROR("couldn't fill AVI infoframe\n"); ++ return false; ++ } + + if (intel_sdvo->rgb_quant_range_selectable) { + if (intel_crtc->config.limited_color_range) +- avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED; ++ frame.avi.quantization_range = ++ HDMI_QUANTIZATION_RANGE_LIMITED; + else +- avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL; ++ frame.avi.quantization_range = ++ HDMI_QUANTIZATION_RANGE_FULL; + } + +- avi_if.body.avi.VIC = drm_match_cea_mode(adjusted_mode); +- +- intel_dip_infoframe_csum(&avi_if); +- +- /* sdvo spec says that the ecc is handled by the hw, and it looks like +- * we must not send the ecc field, either. */ +- memcpy(sdvo_data, &avi_if, 3); +- sdvo_data[3] = avi_if.checksum; +- memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); ++ len = hdmi_infoframe_pack(&frame, sdvo_data, sizeof(sdvo_data)); ++ if (len < 0) ++ return false; + + return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, + SDVO_HBUF_TX_VSYNC, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0619-drm-i915-Remove-the-now-obsolete-infoframe-definitio.patch b/patches.baytrail/0619-drm-i915-Remove-the-now-obsolete-infoframe-definitio.patch new file mode 100644 index 000000000000..98fecd43150a --- /dev/null +++ b/patches.baytrail/0619-drm-i915-Remove-the-now-obsolete-infoframe-definitio.patch @@ -0,0 +1,129 @@ +From aefa93abf9e54139f90f784acc3264e4a94ad836 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Tue, 6 Aug 2013 20:32:21 +0100 +Subject: drm/i915: Remove the now obsolete infoframe definitions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +All the HDMI infoframe code has been ported to use video/hdmi.c, so it's +time to say bye bye to this code. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit c5022bb9ff2a606839ede18ccf268444d3f99729) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_drv.h | 61 --------------------------------------- + drivers/gpu/drm/i915/intel_hdmi.c | 15 ---------- + 2 files changed, 76 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 712e29e27c14..7df662bab280 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -395,66 +395,6 @@ struct cxsr_latency { + #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) + #define to_intel_plane(x) container_of(x, struct intel_plane, base) + +-#define DIP_HEADER_SIZE 5 +- +-#define DIP_TYPE_AVI 0x82 +-#define DIP_VERSION_AVI 0x2 +-#define DIP_LEN_AVI 13 +-#define DIP_AVI_PR_1 0 +-#define DIP_AVI_PR_2 1 +-#define DIP_AVI_RGB_QUANT_RANGE_DEFAULT (0 << 2) +-#define DIP_AVI_RGB_QUANT_RANGE_LIMITED (1 << 2) +-#define DIP_AVI_RGB_QUANT_RANGE_FULL (2 << 2) +- +-#define DIP_TYPE_SPD 0x83 +-#define DIP_VERSION_SPD 0x1 +-#define DIP_LEN_SPD 25 +-#define DIP_SPD_UNKNOWN 0 +-#define DIP_SPD_DSTB 0x1 +-#define DIP_SPD_DVDP 0x2 +-#define DIP_SPD_DVHS 0x3 +-#define DIP_SPD_HDDVR 0x4 +-#define DIP_SPD_DVC 0x5 +-#define DIP_SPD_DSC 0x6 +-#define DIP_SPD_VCD 0x7 +-#define DIP_SPD_GAME 0x8 +-#define DIP_SPD_PC 0x9 +-#define DIP_SPD_BD 0xa +-#define DIP_SPD_SCD 0xb +- +-struct dip_infoframe { +- uint8_t type; /* HB0 */ +- uint8_t ver; /* HB1 */ +- uint8_t len; /* HB2 - body len, not including checksum */ +- uint8_t ecc; /* Header ECC */ +- uint8_t checksum; /* PB0 */ +- union { +- struct { +- /* PB1 - Y 6:5, A 4:4, B 3:2, S 1:0 */ +- uint8_t Y_A_B_S; +- /* PB2 - C 7:6, M 5:4, R 3:0 */ +- uint8_t C_M_R; +- /* PB3 - ITC 7:7, EC 6:4, Q 3:2, SC 1:0 */ +- uint8_t ITC_EC_Q_SC; +- /* PB4 - VIC 6:0 */ +- uint8_t VIC; +- /* PB5 - YQ 7:6, CN 5:4, PR 3:0 */ +- uint8_t YQ_CN_PR; +- /* PB6 to PB13 */ +- uint16_t top_bar_end; +- uint16_t bottom_bar_start; +- uint16_t left_bar_end; +- uint16_t right_bar_start; +- } __attribute__ ((packed)) avi; +- struct { +- uint8_t vn[8]; +- uint8_t pd[16]; +- uint8_t sdi; +- } __attribute__ ((packed)) spd; +- uint8_t payload[27]; +- } __attribute__ ((packed)) body; +-} __attribute__((packed)); +- + struct intel_hdmi { + u32 hdmi_reg; + int ddc_bus; +@@ -568,7 +508,6 @@ extern void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, + extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder); + extern bool intel_hdmi_compute_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config); +-extern void intel_dip_infoframe_csum(struct dip_infoframe *avi_if); + extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, + bool is_sdvob); + extern void intel_dvo_init(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 118715389651..ba742b8e16dc 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -67,21 +67,6 @@ static struct intel_hdmi *intel_attached_hdmi(struct drm_connector *connector) + return enc_to_intel_hdmi(&intel_attached_encoder(connector)->base); + } + +-void intel_dip_infoframe_csum(struct dip_infoframe *frame) +-{ +- uint8_t *data = (uint8_t *)frame; +- uint8_t sum = 0; +- unsigned i; +- +- frame->checksum = 0; +- frame->ecc = 0; +- +- for (i = 0; i < frame->len + DIP_HEADER_SIZE; i++) +- sum += data[i]; +- +- frame->checksum = 0x100 - sum; +-} +- + static u32 g4x_infoframe_index(enum hdmi_infoframe_type type) + { + switch (type) { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0620-drm-Handle-the-DBLCLK-flag-in-the-common-infoframe-h.patch b/patches.baytrail/0620-drm-Handle-the-DBLCLK-flag-in-the-common-infoframe-h.patch new file mode 100644 index 000000000000..c83b8300da24 --- /dev/null +++ b/patches.baytrail/0620-drm-Handle-the-DBLCLK-flag-in-the-common-infoframe-h.patch @@ -0,0 +1,51 @@ +From 6c5054eea7ccaa2e1f33ae0ac26061e4f8766d32 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Tue, 6 Aug 2013 20:32:22 +0100 +Subject: drm: Handle the DBLCLK flag in the common infoframe helper +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Suggested-by: Ville Syrjälä +Signed-off-by: Damien Lespiau +Acked-by: Dave Airlie +Reviewed-by: Alex Deucher +Signed-off-by: Daniel Vetter +(cherry picked from commit bf02db99384929a12eff0cf1205b4547e41e881b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_edid.c | 3 +++ + drivers/gpu/drm/i915/intel_hdmi.c | 3 --- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 97c6c8c95a95..9d4d21f46a8a 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -3123,6 +3123,9 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, + if (err < 0) + return err; + ++ if (mode->flags & DRM_MODE_FLAG_DBLCLK) ++ frame->pixel_repeat = 1; ++ + frame->video_code = drm_match_cea_mode(mode); + if (!frame->video_code) + return 0; +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index ba742b8e16dc..0a4a81447a03 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -364,9 +364,6 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, + return; + } + +- if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) +- frame.avi.pixel_repeat = 1; +- + if (intel_hdmi->rgb_quant_range_selectable) { + if (intel_crtc->config.limited_color_range) + frame.avi.quantization_range = +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0621-drm-i915-hmdi-Rename-set_infoframe-to-write_infofram.patch b/patches.baytrail/0621-drm-i915-hmdi-Rename-set_infoframe-to-write_infofram.patch new file mode 100644 index 000000000000..93f424aabb99 --- /dev/null +++ b/patches.baytrail/0621-drm-i915-hmdi-Rename-set_infoframe-to-write_infofram.patch @@ -0,0 +1,59 @@ +From 4440d555afb8b86124f45d58dca776671953be16 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Tue, 6 Aug 2013 20:32:24 +0100 +Subject: drm/i915/hmdi: Rename set_infoframe() to write_infoframe() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +set_frame() wraps the write_frame() vfunc. Be consistent and name the +wrapping function like the vfunc being called. + +It's doubly confusing as we also have a set_infoframes() vfunc and +set_infoframe() doesn't wrap it. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 9198ee5b9048418849ad96fe37eaff8cd56aaf43) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_hdmi.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index 0a4a81447a03..dd4fa35e0a85 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -327,8 +327,8 @@ static void hsw_write_infoframe(struct drm_encoder *encoder, + * trick them by giving an offset into the buffer and moving back the header + * bytes by one. + */ +-static void intel_set_infoframe(struct drm_encoder *encoder, +- union hdmi_infoframe *frame) ++static void intel_write_infoframe(struct drm_encoder *encoder, ++ union hdmi_infoframe *frame) + { + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); + uint8_t buffer[VIDEO_DIP_DATA_SIZE]; +@@ -373,7 +373,7 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, + HDMI_QUANTIZATION_RANGE_FULL; + } + +- intel_set_infoframe(encoder, &frame); ++ intel_write_infoframe(encoder, &frame); + } + + static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder) +@@ -389,7 +389,7 @@ static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder) + + frame.spd.sdi = HDMI_SPD_SDI_PC; + +- intel_set_infoframe(encoder, &frame); ++ intel_write_infoframe(encoder, &frame); + } + + static void g4x_set_infoframes(struct drm_encoder *encoder, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0622-drm-i915-Use-enabled-instead-of-enable-consistently-.patch b/patches.baytrail/0622-drm-i915-Use-enabled-instead-of-enable-consistently-.patch new file mode 100644 index 000000000000..627c8beab16b --- /dev/null +++ b/patches.baytrail/0622-drm-i915-Use-enabled-instead-of-enable-consistently-.patch @@ -0,0 +1,63 @@ +From 519adbb6b119ef0b4a2c3de448c5c703ba2326e6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 6 Aug 2013 22:24:00 +0300 +Subject: drm/i915: Use 'enabled' instead of 'enable' consistently in sprite WM + code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Let's be consistent and always call our variables 'enabled' insted of +the occasional 'enable'. + +Signed-off-by: Ville Syrjälä +[danvet: Spelling fix in the commit message, spotted by Chris.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 39db4a4d7f9b2809141e5bc0e06f7a5b7daeb356) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 9b8c90ea81ff..fe0c2af4031b 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2838,7 +2838,7 @@ sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane, + + static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, + uint32_t sprite_width, int pixel_size, +- bool enable, bool scaled) ++ bool enabled, bool scaled) + { + struct drm_i915_private *dev_priv = dev->dev_private; + int latency = dev_priv->wm.spr_latency[0] * 100; /* In unit 0.1us */ +@@ -2846,7 +2846,7 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, + int sprite_wm, reg; + int ret; + +- if (!enable) ++ if (!enabled) + return; + + switch (pipe) { +@@ -2961,13 +2961,13 @@ void intel_update_watermarks(struct drm_device *dev) + + void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, + uint32_t sprite_width, int pixel_size, +- bool enable, bool scaled) ++ bool enabled, bool scaled) + { + struct drm_i915_private *dev_priv = dev->dev_private; + + if (dev_priv->display.update_sprite_wm) + dev_priv->display.update_sprite_wm(dev, pipe, sprite_width, +- pixel_size, enable, scaled); ++ pixel_size, enabled, scaled); + } + + static struct drm_i915_gem_object * +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0623-drm-i915-Split-watermark-level-computation-from-the-.patch b/patches.baytrail/0623-drm-i915-Split-watermark-level-computation-from-the-.patch new file mode 100644 index 000000000000..2d120507734b --- /dev/null +++ b/patches.baytrail/0623-drm-i915-Split-watermark-level-computation-from-the-.patch @@ -0,0 +1,105 @@ +From faa184f6d173ef8f7f96efc11b478b64e49d2775 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 6 Aug 2013 22:24:02 +0300 +Subject: drm/i915: Split watermark level computation from the code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Refactor the watermarks computation for one level to a separate +function. This function will now set the ->enable flag to true, +even if the watermark level wasn't actually checked yet. In the +future we will delay the checking so we must consider all unchecked +watermarks as possibly valid. + +v2: Preserve comment about latency units + +Signed-off-by: Ville Syrjälä +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 6f5ddd170453ff44aed1b6efe53ff872295ef538) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 51 +++++++++++++++++++++++++++-------------- + 1 file changed, 34 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index fe0c2af4031b..0d9f56fced55 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2284,31 +2284,45 @@ static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params, + params->pri_bytes_per_pixel); + } + ++static void ilk_compute_wm_level(struct drm_i915_private *dev_priv, ++ int level, ++ struct hsw_pipe_wm_parameters *p, ++ struct hsw_lp_wm_result *result) ++{ ++ uint16_t pri_latency = dev_priv->wm.pri_latency[level]; ++ uint16_t spr_latency = dev_priv->wm.spr_latency[level]; ++ uint16_t cur_latency = dev_priv->wm.cur_latency[level]; ++ ++ /* WM1+ latency values stored in 0.5us units */ ++ if (level > 0) { ++ pri_latency *= 5; ++ spr_latency *= 5; ++ cur_latency *= 5; ++ } ++ ++ result->pri_val = ilk_compute_pri_wm(p, pri_latency, level); ++ result->spr_val = ilk_compute_spr_wm(p, spr_latency); ++ result->cur_val = ilk_compute_cur_wm(p, cur_latency); ++ result->fbc_val = ilk_compute_fbc_wm(p, result->pri_val); ++ result->enable = true; ++} ++ + static bool hsw_compute_lp_wm(struct drm_i915_private *dev_priv, + int level, struct hsw_wm_maximums *max, + struct hsw_pipe_wm_parameters *params, + struct hsw_lp_wm_result *result) + { + enum pipe pipe; +- uint32_t pri_val[3], spr_val[3], cur_val[3], fbc_val[3]; +- +- for (pipe = PIPE_A; pipe <= PIPE_C; pipe++) { +- struct hsw_pipe_wm_parameters *p = ¶ms[pipe]; +- /* WM1+ latency values stored in 0.5us units */ +- uint16_t pri_latency = dev_priv->wm.pri_latency[level] * 5; +- uint16_t spr_latency = dev_priv->wm.spr_latency[level] * 5; +- uint16_t cur_latency = dev_priv->wm.cur_latency[level] * 5; ++ struct hsw_lp_wm_result res[3]; + +- pri_val[pipe] = ilk_compute_pri_wm(p, pri_latency, true); +- spr_val[pipe] = ilk_compute_spr_wm(p, spr_latency); +- cur_val[pipe] = ilk_compute_cur_wm(p, cur_latency); +- fbc_val[pipe] = ilk_compute_fbc_wm(p, pri_val[pipe]); +- } ++ for (pipe = PIPE_A; pipe <= PIPE_C; pipe++) ++ ilk_compute_wm_level(dev_priv, level, ¶ms[pipe], &res[pipe]); + +- result->pri_val = max3(pri_val[0], pri_val[1], pri_val[2]); +- result->spr_val = max3(spr_val[0], spr_val[1], spr_val[2]); +- result->cur_val = max3(cur_val[0], cur_val[1], cur_val[2]); +- result->fbc_val = max3(fbc_val[0], fbc_val[1], fbc_val[2]); ++ result->pri_val = max3(res[0].pri_val, res[1].pri_val, res[2].pri_val); ++ result->spr_val = max3(res[0].spr_val, res[1].spr_val, res[2].spr_val); ++ result->cur_val = max3(res[0].cur_val, res[1].cur_val, res[2].cur_val); ++ result->fbc_val = max3(res[0].fbc_val, res[1].fbc_val, res[2].fbc_val); ++ result->enable = true; + + if (result->fbc_val > max->fbc) { + result->fbc_enable = false; +@@ -2317,6 +2331,9 @@ static bool hsw_compute_lp_wm(struct drm_i915_private *dev_priv, + result->fbc_enable = true; + } + ++ if (!result->enable) ++ return false; ++ + result->enable = result->pri_val <= max->pri && + result->spr_val <= max->spr && + result->cur_val <= max->cur; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0624-drm-i915-Kill-fbc_enable-from-hsw_lp_wm_results.patch b/patches.baytrail/0624-drm-i915-Kill-fbc_enable-from-hsw_lp_wm_results.patch new file mode 100644 index 000000000000..224ae1e945d1 --- /dev/null +++ b/patches.baytrail/0624-drm-i915-Kill-fbc_enable-from-hsw_lp_wm_results.patch @@ -0,0 +1,63 @@ +From 1d07fa059a6628eefd9ad57261cd1d67237385ab Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 6 Aug 2013 22:24:03 +0300 +Subject: drm/i915: Kill fbc_enable from hsw_lp_wm_results +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We don't need to store the FBC WM enabled status in each watermark +level. We anyway have to reduce it down to a single boolean, so just +delay checking the FBC WM limit until we're computing the final +value. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 71fff20ff1bb790f4defe0c880e028581ffab420) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 12 ++---------- + 1 file changed, 2 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 0d9f56fced55..58426cff7d09 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2182,7 +2182,6 @@ struct hsw_wm_maximums { + + struct hsw_lp_wm_result { + bool enable; +- bool fbc_enable; + uint32_t pri_val; + uint32_t spr_val; + uint32_t cur_val; +@@ -2324,13 +2323,6 @@ static bool hsw_compute_lp_wm(struct drm_i915_private *dev_priv, + result->fbc_val = max3(res[0].fbc_val, res[1].fbc_val, res[2].fbc_val); + result->enable = true; + +- if (result->fbc_val > max->fbc) { +- result->fbc_enable = false; +- result->fbc_val = 0; +- } else { +- result->fbc_enable = true; +- } +- + if (!result->enable) + return false; + +@@ -2575,9 +2567,9 @@ static void hsw_compute_wm_results(struct drm_device *dev, + * a WM level. */ + results->enable_fbc_wm = true; + for (level = 1; level <= max_level; level++) { +- if (!lp_results[level - 1].fbc_enable) { ++ if (!lp_results[level - 1].fbc_val > lp_maximums->fbc) { + results->enable_fbc_wm = false; +- break; ++ lp_results[level - 1].fbc_val = 0; + } + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0625-drm-i915-Rename-hsw_data_buf_partitioning-to-intel_d.patch b/patches.baytrail/0625-drm-i915-Rename-hsw_data_buf_partitioning-to-intel_d.patch new file mode 100644 index 000000000000..50e6cbdf325c --- /dev/null +++ b/patches.baytrail/0625-drm-i915-Rename-hsw_data_buf_partitioning-to-intel_d.patch @@ -0,0 +1,107 @@ +From 9a91345c3be8376e216cc551473d7b61d84c1fd8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 6 Aug 2013 22:24:04 +0300 +Subject: drm/i915: Rename hsw_data_buf_partitioning to intel_ddb_partitioning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We're going to use the 1/2 vs. 5/6 split option already on IVB so the +HSW name is not proper. Just give it an intel_ prefix and move it to +i915_drv.h so that we can use it there later. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 77c122bcc448439af7f5fcb2542406b45b606c51) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 5 +++++ + drivers/gpu/drm/i915/intel_pm.c | 17 ++++++----------- + 2 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 49a2e336a7b5..1a3dc5317eec 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1055,6 +1055,11 @@ struct intel_vbt_data { + struct child_device_config *child_dev; + }; + ++enum intel_ddb_partitioning { ++ INTEL_DDB_PART_1_2, ++ INTEL_DDB_PART_5_6, /* IVB+ */ ++}; ++ + typedef struct drm_i915_private { + struct drm_device *dev; + struct kmem_cache *slab; +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 58426cff7d09..a5a995948fa9 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2196,11 +2196,6 @@ struct hsw_wm_values { + bool enable_fbc_wm; + }; + +-enum hsw_data_buf_partitioning { +- HSW_DATA_BUF_PART_1_2, +- HSW_DATA_BUF_PART_5_6, +-}; +- + /* + * For both WM_PIPE and WM_LP. + * mem_value must be in 0.1us units. +@@ -2631,11 +2626,11 @@ static struct hsw_wm_values *hsw_find_best_result(struct hsw_wm_values *r1, + */ + static void hsw_write_wm_values(struct drm_i915_private *dev_priv, + struct hsw_wm_values *results, +- enum hsw_data_buf_partitioning partitioning) ++ enum intel_ddb_partitioning partitioning) + { + struct hsw_wm_values previous; + uint32_t val; +- enum hsw_data_buf_partitioning prev_partitioning; ++ enum intel_ddb_partitioning prev_partitioning; + bool prev_enable_fbc_wm; + + previous.wm_pipe[0] = I915_READ(WM0_PIPEA_ILK); +@@ -2652,7 +2647,7 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv, + previous.wm_linetime[2] = I915_READ(PIPE_WM_LINETIME(PIPE_C)); + + prev_partitioning = (I915_READ(WM_MISC) & WM_MISC_DATA_PARTITION_5_6) ? +- HSW_DATA_BUF_PART_5_6 : HSW_DATA_BUF_PART_1_2; ++ INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2; + + prev_enable_fbc_wm = !(I915_READ(DISP_ARB_CTL) & DISP_FBC_WM_DIS); + +@@ -2691,7 +2686,7 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv, + + if (prev_partitioning != partitioning) { + val = I915_READ(WM_MISC); +- if (partitioning == HSW_DATA_BUF_PART_1_2) ++ if (partitioning == INTEL_DDB_PART_1_2) + val &= ~WM_MISC_DATA_PARTITION_5_6; + else + val |= WM_MISC_DATA_PARTITION_5_6; +@@ -2728,7 +2723,7 @@ static void haswell_update_wm(struct drm_device *dev) + struct hsw_wm_maximums lp_max_1_2, lp_max_5_6; + struct hsw_pipe_wm_parameters params[3]; + struct hsw_wm_values results_1_2, results_5_6, *best_results; +- enum hsw_data_buf_partitioning partitioning; ++ enum intel_ddb_partitioning partitioning; + + hsw_compute_wm_parameters(dev, params, &lp_max_1_2, &lp_max_5_6); + +@@ -2743,7 +2738,7 @@ static void haswell_update_wm(struct drm_device *dev) + } + + partitioning = (best_results == &results_1_2) ? +- HSW_DATA_BUF_PART_1_2 : HSW_DATA_BUF_PART_5_6; ++ INTEL_DDB_PART_1_2 : INTEL_DDB_PART_5_6; + + hsw_write_wm_values(dev_priv, best_results, partitioning); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0626-drm-i915-Silence-a-sparse-warning.patch b/patches.baytrail/0626-drm-i915-Silence-a-sparse-warning.patch new file mode 100644 index 000000000000..bcd63b3dc9d7 --- /dev/null +++ b/patches.baytrail/0626-drm-i915-Silence-a-sparse-warning.patch @@ -0,0 +1,35 @@ +From 30a09d0bbb2c2121b6b2e87baef2a9cf1196793c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 7 Aug 2013 15:11:52 +0300 +Subject: drm/i915: Silence a sparse warning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +drivers/gpu/drm/i915/i915_debugfs.c:2136:3: warning: symbol +'i915_debugfs_files' was not declared. Should it be static? + +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 2b4bd0e0658b98341a899d9550169ffa26c32e39) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index d2935b4fd695..5d52a23d5662 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -2130,7 +2130,7 @@ static struct drm_info_list i915_debugfs_list[] = { + }; + #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) + +-struct i915_debugfs_files { ++static struct i915_debugfs_files { + const char *name; + const struct file_operations *fops; + } i915_debugfs_files[] = { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0627-drm-i915-Fix-up-map-and-fenceable-for-VMA.patch b/patches.baytrail/0627-drm-i915-Fix-up-map-and-fenceable-for-VMA.patch new file mode 100644 index 000000000000..e69d5d53ce44 --- /dev/null +++ b/patches.baytrail/0627-drm-i915-Fix-up-map-and-fenceable-for-VMA.patch @@ -0,0 +1,57 @@ +From e99986d3008081d1762081aba8583fa4cad8cd38 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:13 -0700 +Subject: drm/i915: Fix up map and fenceable for VMA + +formerly: "drm/i915: Create VMAs (part 3.5) - map and fenceable +tracking" + +The map_and_fenceable tracking is per object. GTT mapping, and fences +only apply to global GTT. As such, object operations which are not +performed on the global GTT should not effect mappable or fenceable +characteristics. + +Functionally, this commit could very well be squashed in to a previous +patch which updated object operations to take a VM argument. This +commit is split out because it's a bit tricky (or at least it was for +me). + +Signed-off-by: Ben Widawsky +[danvet: Drop the bogus hunk in i915_vma_unbind as discussed with +Ben.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 5cacaac77cfc1130a2d8bf60addb5c6c9c878214) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 9150804dffc0..103815bedba4 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2629,7 +2629,8 @@ int i915_vma_unbind(struct i915_vma *vma) + + list_del(&obj->mm_list); + /* Avoid an unnecessary call to unbind on rebind. */ +- obj->map_and_fenceable = true; ++ if (i915_is_ggtt(vma->vm)) ++ obj->map_and_fenceable = true; + + list_del(&vma->vma_link); + drm_mm_remove_node(&vma->node); +@@ -3191,7 +3192,9 @@ search_free: + i915_is_ggtt(vm) && + vma->node.start + obj->base.size <= dev_priv->gtt.mappable_end; + +- obj->map_and_fenceable = mappable && fenceable; ++ /* Map and fenceable only changes if the VM is the global GGTT */ ++ if (i915_is_ggtt(vm)) ++ obj->map_and_fenceable = mappable && fenceable; + + trace_i915_vma_bind(vma, map_and_fenceable); + i915_gem_verify_gtt(dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0628-drm-i915-mm_list-is-per-VMA.patch b/patches.baytrail/0628-drm-i915-mm_list-is-per-VMA.patch new file mode 100644 index 000000000000..4052863840dc --- /dev/null +++ b/patches.baytrail/0628-drm-i915-mm_list-is-per-VMA.patch @@ -0,0 +1,453 @@ +From 0869c7f57d79bdfd26ecf5847a254bed58413173 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:14 -0700 +Subject: drm/i915: mm_list is per VMA + +formerly: "drm/i915: Create VMAs (part 5) - move mm_list" + +The mm_list is used for the active/inactive LRUs. Since those LRUs are +per address space, the link should be per VMx . + +Because we'll only ever have 1 VMA before this point, it's not incorrect +to defer this change until this point in the patch series, and doing it +here makes the change much easier to understand. + +Shamelessly manipulated out of Daniel: +"active/inactive stuff is used by eviction when we run out of address +space, so needs to be per-vma and per-address space. Bound/unbound otoh +is used by the shrinker which only cares about the amount of memory used +and not one bit about in which address space this memory is all used in. +Of course to actual kick out an object we need to unbind it from every +address space, but for that we have the per-object list of vmas." + +v2: only bump GGTT LRU in i915_gem_object_set_to_gtt_domain (Chris) + +v3: Moved earlier in the series + +v4: Add dropped message from v3 + +Signed-off-by: Ben Widawsky +[danvet: Frob patch to apply and use vma->node.size directly as +discused with Ben. Also drop a needles BUG_ON before move_to_inactive, +the function itself has the same check.] +[danvet 2nd: Rebase on top of the lost "drm/i915: Cleanup more of VMA +in destroy", specifically unlink the vma from the mm_list in +vma_unbind (to keep it symmetric with bind_to_vm) instead of +vma_destroy.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit ca191b1313e733e47a9fb37c26b44aa6cdd9b1b1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 54 +++++++++++++++++++----------- + drivers/gpu/drm/i915/i915_drv.h | 5 +-- + drivers/gpu/drm/i915/i915_gem.c | 28 +++++++++------- + drivers/gpu/drm/i915/i915_gem_context.c | 3 ++ + drivers/gpu/drm/i915/i915_gem_evict.c | 14 ++++---- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 ++ + drivers/gpu/drm/i915/i915_gem_stolen.c | 2 +- + drivers/gpu/drm/i915/i915_gpu_error.c | 37 +++++++++++--------- + 8 files changed, 86 insertions(+), 59 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 5d52a23d5662..a1f4c91fb112 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -149,7 +149,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) + struct drm_device *dev = node->minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct i915_address_space *vm = &dev_priv->gtt.base; +- struct drm_i915_gem_object *obj; ++ struct i915_vma *vma; + size_t total_obj_size, total_gtt_size; + int count, ret; + +@@ -157,6 +157,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) + if (ret) + return ret; + ++ /* FIXME: the user of this interface might want more than just GGTT */ + switch (list) { + case ACTIVE_LIST: + seq_puts(m, "Active:\n"); +@@ -172,12 +173,12 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) + } + + total_obj_size = total_gtt_size = count = 0; +- list_for_each_entry(obj, head, mm_list) { +- seq_puts(m, " "); +- describe_obj(m, obj); +- seq_putc(m, '\n'); +- total_obj_size += obj->base.size; +- total_gtt_size += i915_gem_obj_ggtt_size(obj); ++ list_for_each_entry(vma, head, mm_list) { ++ seq_printf(m, " "); ++ describe_obj(m, vma->obj); ++ seq_printf(m, "\n"); ++ total_obj_size += vma->obj->base.size; ++ total_gtt_size += vma->node.size; + count++; + } + mutex_unlock(&dev->struct_mutex); +@@ -224,7 +225,18 @@ static int per_file_stats(int id, void *ptr, void *data) + return 0; + } + +-static int i915_gem_object_info(struct seq_file *m, void *data) ++#define count_vmas(list, member) do { \ ++ list_for_each_entry(vma, list, member) { \ ++ size += i915_gem_obj_ggtt_size(vma->obj); \ ++ ++count; \ ++ if (vma->obj->map_and_fenceable) { \ ++ mappable_size += i915_gem_obj_ggtt_size(vma->obj); \ ++ ++mappable_count; \ ++ } \ ++ } \ ++} while (0) ++ ++static int i915_gem_object_info(struct seq_file *m, void* data) + { + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; +@@ -234,6 +246,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data) + struct drm_i915_gem_object *obj; + struct i915_address_space *vm = &dev_priv->gtt.base; + struct drm_file *file; ++ struct i915_vma *vma; + int ret; + + ret = mutex_lock_interruptible(&dev->struct_mutex); +@@ -250,12 +263,12 @@ static int i915_gem_object_info(struct seq_file *m, void *data) + count, mappable_count, size, mappable_size); + + size = count = mappable_size = mappable_count = 0; +- count_objects(&vm->active_list, mm_list); ++ count_vmas(&vm->active_list, mm_list); + seq_printf(m, " %u [%u] active objects, %zu [%zu] bytes\n", + count, mappable_count, size, mappable_size); + + size = count = mappable_size = mappable_count = 0; +- count_objects(&vm->inactive_list, mm_list); ++ count_vmas(&vm->inactive_list, mm_list); + seq_printf(m, " %u [%u] inactive objects, %zu [%zu] bytes\n", + count, mappable_count, size, mappable_size); + +@@ -1774,7 +1787,8 @@ i915_drop_caches_set(void *data, u64 val) + struct drm_device *dev = data; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj, *next; +- struct i915_address_space *vm = &dev_priv->gtt.base; ++ struct i915_address_space *vm; ++ struct i915_vma *vma, *x; + int ret; + + DRM_DEBUG_DRIVER("Dropping caches: 0x%08llx\n", val); +@@ -1795,14 +1809,16 @@ i915_drop_caches_set(void *data, u64 val) + i915_gem_retire_requests(dev); + + if (val & DROP_BOUND) { +- list_for_each_entry_safe(obj, next, &vm->inactive_list, +- mm_list) { +- if (obj->pin_count) +- continue; +- +- ret = i915_gem_object_ggtt_unbind(obj); +- if (ret) +- goto unlock; ++ list_for_each_entry(vm, &dev_priv->vm_list, global_link) { ++ list_for_each_entry_safe(vma, x, &vm->inactive_list, ++ mm_list) { ++ if (vma->obj->pin_count) ++ continue; ++ ++ ret = i915_vma_unbind(vma); ++ if (ret) ++ goto unlock; ++ } + } + } + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 1a3dc5317eec..cd5d4f591e2d 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -558,6 +558,9 @@ struct i915_vma { + struct drm_i915_gem_object *obj; + struct i915_address_space *vm; + ++ /** This object's place on the active/inactive lists */ ++ struct list_head mm_list; ++ + struct list_head vma_link; /* Link in the object's VMA list */ + }; + +@@ -1299,9 +1302,7 @@ struct drm_i915_gem_object { + struct drm_mm_node *stolen; + struct list_head global_list; + +- /** This object's place on the active/inactive lists */ + struct list_head ring_list; +- struct list_head mm_list; + /** This object's place in the batchbuffer or on the eviction list */ + struct list_head exec_list; + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 103815bedba4..093781a28080 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -1873,7 +1873,6 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, + { + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct i915_address_space *vm = &dev_priv->gtt.base; + u32 seqno = intel_ring_get_seqno(ring); + + BUG_ON(ring == NULL); +@@ -1889,8 +1888,6 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, + obj->active = 1; + } + +- /* Move from whatever list we were on to the tail of execution. */ +- list_move_tail(&obj->mm_list, &vm->active_list); + list_move_tail(&obj->ring_list, &ring->active_list); + + obj->last_read_seqno = seqno; +@@ -1912,14 +1909,14 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, + static void + i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) + { +- struct drm_device *dev = obj->base.dev; +- struct drm_i915_private *dev_priv = dev->dev_private; +- struct i915_address_space *vm = &dev_priv->gtt.base; ++ struct drm_i915_private *dev_priv = obj->base.dev->dev_private; ++ struct i915_address_space *ggtt_vm = &dev_priv->gtt.base; ++ struct i915_vma *vma = i915_gem_obj_to_vma(obj, ggtt_vm); + + BUG_ON(obj->base.write_domain & ~I915_GEM_GPU_DOMAINS); + BUG_ON(!obj->active); + +- list_move_tail(&obj->mm_list, &vm->inactive_list); ++ list_move_tail(&vma->mm_list, &ggtt_vm->inactive_list); + + list_del_init(&obj->ring_list); + obj->ring = NULL; +@@ -2627,7 +2624,7 @@ int i915_vma_unbind(struct i915_vma *vma) + i915_gem_gtt_finish_object(obj); + i915_gem_object_unpin_pages(obj); + +- list_del(&obj->mm_list); ++ list_del(&vma->mm_list); + /* Avoid an unnecessary call to unbind on rebind. */ + if (i915_is_ggtt(vma->vm)) + obj->map_and_fenceable = true; +@@ -3175,7 +3172,7 @@ search_free: + goto err_remove_node; + + list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); +- list_add_tail(&obj->mm_list, &vm->inactive_list); ++ list_add_tail(&vma->mm_list, &vm->inactive_list); + + /* Keep GGTT vmas first to make debug easier */ + if (i915_is_ggtt(vm)) +@@ -3340,9 +3337,14 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) + old_write_domain); + + /* And bump the LRU for this access */ +- if (i915_gem_object_is_inactive(obj)) +- list_move_tail(&obj->mm_list, +- &dev_priv->gtt.base.inactive_list); ++ if (i915_gem_object_is_inactive(obj)) { ++ struct i915_vma *vma = i915_gem_obj_to_vma(obj, ++ &dev_priv->gtt.base); ++ if (vma) ++ list_move_tail(&vma->mm_list, ++ &dev_priv->gtt.base.inactive_list); ++ ++ } + + return 0; + } +@@ -3915,7 +3917,6 @@ unlock: + void i915_gem_object_init(struct drm_i915_gem_object *obj, + const struct drm_i915_gem_object_ops *ops) + { +- INIT_LIST_HEAD(&obj->mm_list); + INIT_LIST_HEAD(&obj->global_list); + INIT_LIST_HEAD(&obj->ring_list); + INIT_LIST_HEAD(&obj->exec_list); +@@ -4057,6 +4058,7 @@ struct i915_vma *i915_gem_vma_create(struct drm_i915_gem_object *obj, + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&vma->vma_link); ++ INIT_LIST_HEAD(&vma->mm_list); + vma->vm = vm; + vma->obj = obj; + +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index 7273a729a039..403309c2a7d6 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -436,7 +436,10 @@ static int do_switch(struct i915_hw_context *to) + * MI_SET_CONTEXT instead of when the next seqno has completed. + */ + if (from != NULL) { ++ struct drm_i915_private *dev_priv = from->obj->base.dev->dev_private; ++ struct i915_address_space *ggtt = &dev_priv->gtt.base; + from->obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION; ++ list_move_tail(&i915_gem_obj_to_vma(from->obj, ggtt)->mm_list, &ggtt->active_list); + i915_gem_object_move_to_active(from->obj, ring); + /* As long as MI_SET_CONTEXT is serializing, ie. it flushes the + * whole damn pipeline, we don't need to explicitly mark the +diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c +index 61bf5e20e5e0..425939b7d343 100644 +--- a/drivers/gpu/drm/i915/i915_gem_evict.c ++++ b/drivers/gpu/drm/i915/i915_gem_evict.c +@@ -87,8 +87,7 @@ i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm, + drm_mm_init_scan(&vm->mm, min_size, alignment, cache_level); + + /* First see if there is a large enough contiguous idle region... */ +- list_for_each_entry(obj, &vm->inactive_list, mm_list) { +- struct i915_vma *vma = i915_gem_obj_to_vma(obj, vm); ++ list_for_each_entry(vma, &vm->inactive_list, mm_list) { + if (mark_free(vma, &unwind_list)) + goto found; + } +@@ -97,8 +96,7 @@ i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm, + goto none; + + /* Now merge in the soon-to-be-expired objects... */ +- list_for_each_entry(obj, &vm->active_list, mm_list) { +- struct i915_vma *vma = i915_gem_obj_to_vma(obj, vm); ++ list_for_each_entry(vma, &vm->active_list, mm_list) { + if (mark_free(vma, &unwind_list)) + goto found; + } +@@ -159,7 +157,7 @@ i915_gem_evict_everything(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; + struct i915_address_space *vm; +- struct drm_i915_gem_object *obj, *next; ++ struct i915_vma *vma, *next; + bool lists_empty = true; + int ret; + +@@ -187,9 +185,9 @@ i915_gem_evict_everything(struct drm_device *dev) + + /* Having flushed everything, unbind() should never raise an error */ + list_for_each_entry(vm, &dev_priv->vm_list, global_link) { +- list_for_each_entry_safe(obj, next, &vm->inactive_list, mm_list) +- if (obj->pin_count == 0) +- WARN_ON(i915_vma_unbind(i915_gem_obj_to_vma(obj, vm))); ++ list_for_each_entry_safe(vma, next, &vm->inactive_list, mm_list) ++ if (vma->obj->pin_count == 0) ++ WARN_ON(i915_vma_unbind(vma)); + } + + return 0; +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index aa3fa9425cae..8ccc29ac9629 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -801,6 +801,8 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects, + obj->base.read_domains = obj->base.pending_read_domains; + obj->fenced_gpu_access = obj->pending_fenced_gpu_access; + ++ /* FIXME: This lookup gets fixed later <-- danvet */ ++ list_move_tail(&i915_gem_obj_to_vma(obj, vm)->mm_list, &vm->active_list); + i915_gem_object_move_to_active(obj, ring); + if (obj->base.write_domain) { + obj->dirty = 1; +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index ba4dabca83c2..8912f489f53a 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -418,7 +418,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + obj->has_global_gtt_mapping = 1; + + list_add_tail(&obj->global_list, &dev_priv->mm.bound_list); +- list_add_tail(&obj->mm_list, &ggtt->inactive_list); ++ list_add_tail(&vma->mm_list, &ggtt->inactive_list); + + return obj; + +diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c +index 8091485e7e88..fad48b2bb870 100644 +--- a/drivers/gpu/drm/i915/i915_gpu_error.c ++++ b/drivers/gpu/drm/i915/i915_gpu_error.c +@@ -556,11 +556,11 @@ static void capture_bo(struct drm_i915_error_buffer *err, + static u32 capture_active_bo(struct drm_i915_error_buffer *err, + int count, struct list_head *head) + { +- struct drm_i915_gem_object *obj; ++ struct i915_vma *vma; + int i = 0; + +- list_for_each_entry(obj, head, mm_list) { +- capture_bo(err++, obj); ++ list_for_each_entry(vma, head, mm_list) { ++ capture_bo(err++, vma->obj); + if (++i == count) + break; + } +@@ -622,7 +622,8 @@ static struct drm_i915_error_object * + i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, + struct intel_ring_buffer *ring) + { +- struct i915_address_space *vm = &dev_priv->gtt.base; ++ struct i915_address_space *vm; ++ struct i915_vma *vma; + struct drm_i915_gem_object *obj; + u32 seqno; + +@@ -642,20 +643,23 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, + } + + seqno = ring->get_seqno(ring, false); +- list_for_each_entry(obj, &vm->active_list, mm_list) { +- if (obj->ring != ring) +- continue; ++ list_for_each_entry(vm, &dev_priv->vm_list, global_link) { ++ list_for_each_entry(vma, &vm->active_list, mm_list) { ++ obj = vma->obj; ++ if (obj->ring != ring) ++ continue; + +- if (i915_seqno_passed(seqno, obj->last_read_seqno)) +- continue; ++ if (i915_seqno_passed(seqno, obj->last_read_seqno)) ++ continue; + +- if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0) +- continue; ++ if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0) ++ continue; + +- /* We need to copy these to an anonymous buffer as the simplest +- * method to avoid being overwritten by userspace. +- */ +- return i915_error_object_create(dev_priv, obj); ++ /* We need to copy these to an anonymous buffer as the simplest ++ * method to avoid being overwritten by userspace. ++ */ ++ return i915_error_object_create(dev_priv, obj); ++ } + } + + return NULL; +@@ -775,11 +779,12 @@ static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv, + struct drm_i915_error_state *error) + { + struct i915_address_space *vm = &dev_priv->gtt.base; ++ struct i915_vma *vma; + struct drm_i915_gem_object *obj; + int i; + + i = 0; +- list_for_each_entry(obj, &vm->active_list, mm_list) ++ list_for_each_entry(vma, &vm->active_list, mm_list) + i++; + error->active_bo_count = i; + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0629-drm-i915-Update-error-capture-for-VMs.patch b/patches.baytrail/0629-drm-i915-Update-error-capture-for-VMs.patch new file mode 100644 index 000000000000..c0177494e55b --- /dev/null +++ b/patches.baytrail/0629-drm-i915-Update-error-capture-for-VMs.patch @@ -0,0 +1,163 @@ +From 902bf4191131a3dcc66c457b027115a5886c322c Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:15 -0700 +Subject: drm/i915: Update error capture for VMs + +formerly: "drm/i915: Create VMAs (part 4) - Error capture" + +Since the active/inactive lists are per VM, we need to modify the error +capture code to be aware of this, and also extend it to capture the +buffers from all the VMs. For now all the code assumes only 1 VM, but it +will become more generic over the next few patches. + +NOTE: If the number of VMs in a real world system grows significantly +we'll have to focus on only capturing the guilty VM, or else it's likely +there won't be enough space for error capture. + +v2: Squashed in the "part 6" which had dependencies on the mm_list +change. Since I've moved the mm_list change to an earlier point in the +series, we were able to accomplish it here and now. + +v3: Rebased over new error capture + +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 95f5301dd880da2dea2c9a9c29750064536d426a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 4 +- + drivers/gpu/drm/i915/i915_gpu_error.c | 76 ++++++++++++++++++++++++----------- + 2 files changed, 55 insertions(+), 25 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index cd5d4f591e2d..62d85e2fb90d 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -323,8 +323,8 @@ struct drm_i915_error_state { + u32 purgeable:1; + s32 ring:4; + u32 cache_level:2; +- } *active_bo, *pinned_bo; +- u32 active_bo_count, pinned_bo_count; ++ } **active_bo, **pinned_bo; ++ u32 *active_bo_count, *pinned_bo_count; + struct intel_overlay_error_state *overlay; + struct intel_display_error_state *display; + }; +diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c +index fad48b2bb870..60393cb9a7c7 100644 +--- a/drivers/gpu/drm/i915/i915_gpu_error.c ++++ b/drivers/gpu/drm/i915/i915_gpu_error.c +@@ -304,13 +304,13 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, + + if (error->active_bo) + print_error_buffers(m, "Active", +- error->active_bo, +- error->active_bo_count); ++ error->active_bo[0], ++ error->active_bo_count[0]); + + if (error->pinned_bo) + print_error_buffers(m, "Pinned", +- error->pinned_bo, +- error->pinned_bo_count); ++ error->pinned_bo[0], ++ error->pinned_bo_count[0]); + + for (i = 0; i < ARRAY_SIZE(error->ring); i++) { + struct drm_i915_error_object *obj; +@@ -775,42 +775,72 @@ static void i915_gem_record_rings(struct drm_device *dev, + } + } + +-static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv, +- struct drm_i915_error_state *error) ++/* FIXME: Since pin count/bound list is global, we duplicate what we capture per ++ * VM. ++ */ ++static void i915_gem_capture_vm(struct drm_i915_private *dev_priv, ++ struct drm_i915_error_state *error, ++ struct i915_address_space *vm, ++ const int ndx) + { +- struct i915_address_space *vm = &dev_priv->gtt.base; +- struct i915_vma *vma; ++ struct drm_i915_error_buffer *active_bo = NULL, *pinned_bo = NULL; + struct drm_i915_gem_object *obj; ++ struct i915_vma *vma; + int i; + + i = 0; + list_for_each_entry(vma, &vm->active_list, mm_list) + i++; +- error->active_bo_count = i; ++ error->active_bo_count[ndx] = i; + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) + if (obj->pin_count) + i++; +- error->pinned_bo_count = i - error->active_bo_count; ++ error->pinned_bo_count[ndx] = i - error->active_bo_count[ndx]; + + if (i) { +- error->active_bo = kmalloc(sizeof(*error->active_bo)*i, +- GFP_ATOMIC); +- if (error->active_bo) +- error->pinned_bo = +- error->active_bo + error->active_bo_count; ++ active_bo = kmalloc(sizeof(*active_bo)*i, GFP_ATOMIC); ++ if (active_bo) ++ pinned_bo = active_bo + error->active_bo_count[ndx]; + } + +- if (error->active_bo) +- error->active_bo_count = +- capture_active_bo(error->active_bo, +- error->active_bo_count, ++ if (active_bo) ++ error->active_bo_count[ndx] = ++ capture_active_bo(active_bo, ++ error->active_bo_count[ndx], + &vm->active_list); + +- if (error->pinned_bo) +- error->pinned_bo_count = +- capture_pinned_bo(error->pinned_bo, +- error->pinned_bo_count, ++ if (pinned_bo) ++ error->pinned_bo_count[ndx] = ++ capture_pinned_bo(pinned_bo, ++ error->pinned_bo_count[ndx], + &dev_priv->mm.bound_list); ++ error->active_bo[ndx] = active_bo; ++ error->pinned_bo[ndx] = pinned_bo; ++} ++ ++static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv, ++ struct drm_i915_error_state *error) ++{ ++ struct i915_address_space *vm; ++ int cnt = 0, i = 0; ++ ++ list_for_each_entry(vm, &dev_priv->vm_list, global_link) ++ cnt++; ++ ++ if (WARN(cnt > 1, "Multiple VMs not yet supported\n")) ++ cnt = 1; ++ ++ vm = &dev_priv->gtt.base; ++ ++ error->active_bo = kcalloc(cnt, sizeof(*error->active_bo), GFP_ATOMIC); ++ error->pinned_bo = kcalloc(cnt, sizeof(*error->pinned_bo), GFP_ATOMIC); ++ error->active_bo_count = kcalloc(cnt, sizeof(*error->active_bo_count), ++ GFP_ATOMIC); ++ error->pinned_bo_count = kcalloc(cnt, sizeof(*error->pinned_bo_count), ++ GFP_ATOMIC); ++ ++ list_for_each_entry(vm, &dev_priv->vm_list, global_link) ++ i915_gem_capture_vm(dev_priv, error, vm, i++); + } + + /** +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0630-drm-i915-Add-vma-to-list-at-creation.patch b/patches.baytrail/0630-drm-i915-Add-vma-to-list-at-creation.patch new file mode 100644 index 000000000000..9407806e8189 --- /dev/null +++ b/patches.baytrail/0630-drm-i915-Add-vma-to-list-at-creation.patch @@ -0,0 +1,83 @@ +From a80026de891d226283f110661672af760bfffb58 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 31 Jul 2013 17:00:16 -0700 +Subject: drm/i915: Add vma to list at creation + +With the current code there shouldn't be a distinction - however with an +upcoming change we intend to allocate a vma much earlier, before it's +actually bound anywhere. + +To do this we have to check node allocation as well for the _bound() +check. + +Signed-off-by: Ben Widawsky +[danvet: move list_del(&vma->vma_link) from vma_unbind to vma_destroy, +again fallout from the loss of "rm/i915: Cleanup more of VMA in +destroy".] +Signed-off-by: Daniel Vetter + +fixup for drm/i915: Add vma to list at creation + +(cherry picked from commit 8b9c2b9411dd55617442f8151fb6fb2849c72f7e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 093781a28080..f7ab763d6d76 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2629,7 +2629,6 @@ int i915_vma_unbind(struct i915_vma *vma) + if (i915_is_ggtt(vma->vm)) + obj->map_and_fenceable = true; + +- list_del(&vma->vma_link); + drm_mm_remove_node(&vma->node); + i915_gem_vma_destroy(vma); + +@@ -3174,12 +3173,6 @@ search_free: + list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); + list_add_tail(&vma->mm_list, &vm->inactive_list); + +- /* Keep GGTT vmas first to make debug easier */ +- if (i915_is_ggtt(vm)) +- list_add(&vma->vma_link, &obj->vma_list); +- else +- list_add_tail(&vma->vma_link, &obj->vma_list); +- + fenceable = + i915_is_ggtt(vm) && + i915_gem_obj_ggtt_size(obj) == fence_size && +@@ -4062,12 +4055,19 @@ struct i915_vma *i915_gem_vma_create(struct drm_i915_gem_object *obj, + vma->vm = vm; + vma->obj = obj; + ++ /* Keep GGTT vmas first to make debug easier */ ++ if (i915_is_ggtt(vm)) ++ list_add(&vma->vma_link, &obj->vma_list); ++ else ++ list_add_tail(&vma->vma_link, &obj->vma_list); ++ + return vma; + } + + void i915_gem_vma_destroy(struct i915_vma *vma) + { + WARN_ON(vma->node.allocated); ++ list_del(&vma->vma_link); + kfree(vma); + } + +@@ -4755,7 +4755,7 @@ bool i915_gem_obj_bound(struct drm_i915_gem_object *o, + struct i915_vma *vma; + + list_for_each_entry(vma, &o->vma_list, vma_link) +- if (vma->vm == vm) ++ if (vma->vm == vm && drm_mm_node_allocated(&vma->node)) + return true; + + return false; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0631-drm-i915-Pull-watermark-level-validity-check-out.patch b/patches.baytrail/0631-drm-i915-Pull-watermark-level-validity-check-out.patch new file mode 100644 index 000000000000..4a972909fd62 --- /dev/null +++ b/patches.baytrail/0631-drm-i915-Pull-watermark-level-validity-check-out.patch @@ -0,0 +1,101 @@ +From 46999a5faf8aaa5ea1dcaa81f7cb8b9799780a2f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 7 Aug 2013 13:24:47 +0300 +Subject: drm/i915: Pull watermark level validity check out +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Refactor the code a bit to split the watermark level validity check into +a separate function. + +Also add hack there that allows us to use it even for LP0 watermarks. +ATM we don't pre-compute/check the LP0 watermarks, so we just have to +clamp them to the maximum and hope things work out. + +v2: Add some debug prints when we exceed max WM0 + Kill pointless ret = false' assignment. + Include the check for the already disabled 'result' which + got shuffled around when the patchs got reorderd + +Signed-off-by: Ville Syrjälä +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit a9786a119d2cd0f43d5554bddda71a5fd6ee39ff) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 51 +++++++++++++++++++++++++++++++++++------ + 1 file changed, 44 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index a5a995948fa9..1dd8f30e5427 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2278,6 +2278,49 @@ static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params, + params->pri_bytes_per_pixel); + } + ++static bool ilk_check_wm(int level, ++ const struct hsw_wm_maximums *max, ++ struct hsw_lp_wm_result *result) ++{ ++ bool ret; ++ ++ /* already determined to be invalid? */ ++ if (!result->enable) ++ return false; ++ ++ result->enable = result->pri_val <= max->pri && ++ result->spr_val <= max->spr && ++ result->cur_val <= max->cur; ++ ++ ret = result->enable; ++ ++ /* ++ * HACK until we can pre-compute everything, ++ * and thus fail gracefully if LP0 watermarks ++ * are exceeded... ++ */ ++ if (level == 0 && !result->enable) { ++ if (result->pri_val > max->pri) ++ DRM_DEBUG_KMS("Primary WM%d too large %u (max %u)\n", ++ level, result->pri_val, max->pri); ++ if (result->spr_val > max->spr) ++ DRM_DEBUG_KMS("Sprite WM%d too large %u (max %u)\n", ++ level, result->spr_val, max->spr); ++ if (result->cur_val > max->cur) ++ DRM_DEBUG_KMS("Cursor WM%d too large %u (max %u)\n", ++ level, result->cur_val, max->cur); ++ ++ result->pri_val = min_t(uint32_t, result->pri_val, max->pri); ++ result->spr_val = min_t(uint32_t, result->spr_val, max->spr); ++ result->cur_val = min_t(uint32_t, result->cur_val, max->cur); ++ result->enable = true; ++ } ++ ++ DRM_DEBUG_KMS("WM%d: %sabled\n", level, result->enable ? "en" : "dis"); ++ ++ return ret; ++} ++ + static void ilk_compute_wm_level(struct drm_i915_private *dev_priv, + int level, + struct hsw_pipe_wm_parameters *p, +@@ -2318,13 +2361,7 @@ static bool hsw_compute_lp_wm(struct drm_i915_private *dev_priv, + result->fbc_val = max3(res[0].fbc_val, res[1].fbc_val, res[2].fbc_val); + result->enable = true; + +- if (!result->enable) +- return false; +- +- result->enable = result->pri_val <= max->pri && +- result->spr_val <= max->spr && +- result->cur_val <= max->cur; +- return result->enable; ++ return ilk_check_wm(level, max, result); + } + + static uint32_t hsw_compute_wm_pipe(struct drm_i915_private *dev_priv, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0632-drm-i915-Rename-hsw_lp_wm_result-to-intel_wm_level.patch b/patches.baytrail/0632-drm-i915-Rename-hsw_lp_wm_result-to-intel_wm_level.patch new file mode 100644 index 000000000000..735d2a5deee6 --- /dev/null +++ b/patches.baytrail/0632-drm-i915-Rename-hsw_lp_wm_result-to-intel_wm_level.patch @@ -0,0 +1,111 @@ +From 3b49ab5a553f5befcacc07e7f929829daa15fdfb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 6 Aug 2013 22:24:05 +0300 +Subject: drm/i915: Rename hsw_lp_wm_result to intel_wm_level +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Let's call hsw_lp_wm_result intel_wm_level from now on and move it to +i915_drv.h for later use. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 1fd527cc34ed44efa4f59c01ad920479f728b707) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 8 ++++++++ + drivers/gpu/drm/i915/intel_pm.c | 20 ++++++-------------- + 2 files changed, 14 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 62d85e2fb90d..3a435fede3c4 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1063,6 +1063,14 @@ enum intel_ddb_partitioning { + INTEL_DDB_PART_5_6, /* IVB+ */ + }; + ++struct intel_wm_level { ++ bool enable; ++ uint32_t pri_val; ++ uint32_t spr_val; ++ uint32_t cur_val; ++ uint32_t fbc_val; ++}; ++ + typedef struct drm_i915_private { + struct drm_device *dev; + struct kmem_cache *slab; +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 1dd8f30e5427..d10d4c717b4a 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2180,14 +2180,6 @@ struct hsw_wm_maximums { + uint16_t fbc; + }; + +-struct hsw_lp_wm_result { +- bool enable; +- uint32_t pri_val; +- uint32_t spr_val; +- uint32_t cur_val; +- uint32_t fbc_val; +-}; +- + struct hsw_wm_values { + uint32_t wm_pipe[3]; + uint32_t wm_lp[3]; +@@ -2280,7 +2272,7 @@ static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params, + + static bool ilk_check_wm(int level, + const struct hsw_wm_maximums *max, +- struct hsw_lp_wm_result *result) ++ struct intel_wm_level *result) + { + bool ret; + +@@ -2324,7 +2316,7 @@ static bool ilk_check_wm(int level, + static void ilk_compute_wm_level(struct drm_i915_private *dev_priv, + int level, + struct hsw_pipe_wm_parameters *p, +- struct hsw_lp_wm_result *result) ++ struct intel_wm_level *result) + { + uint16_t pri_latency = dev_priv->wm.pri_latency[level]; + uint16_t spr_latency = dev_priv->wm.spr_latency[level]; +@@ -2347,10 +2339,10 @@ static void ilk_compute_wm_level(struct drm_i915_private *dev_priv, + static bool hsw_compute_lp_wm(struct drm_i915_private *dev_priv, + int level, struct hsw_wm_maximums *max, + struct hsw_pipe_wm_parameters *params, +- struct hsw_lp_wm_result *result) ++ struct intel_wm_level *result) + { + enum pipe pipe; +- struct hsw_lp_wm_result res[3]; ++ struct intel_wm_level res[3]; + + for (pipe = PIPE_A; pipe <= PIPE_C; pipe++) + ilk_compute_wm_level(dev_priv, level, ¶ms[pipe], &res[pipe]); +@@ -2584,7 +2576,7 @@ static void hsw_compute_wm_results(struct drm_device *dev, + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; +- struct hsw_lp_wm_result lp_results[4] = {}; ++ struct intel_wm_level lp_results[4] = {}; + enum pipe pipe; + int level, max_level, wm_lp; + +@@ -2607,7 +2599,7 @@ static void hsw_compute_wm_results(struct drm_device *dev, + + memset(results, 0, sizeof(*results)); + for (wm_lp = 1; wm_lp <= 3; wm_lp++) { +- const struct hsw_lp_wm_result *r; ++ const struct intel_wm_level *r; + + level = (max_level == 4 && wm_lp > 1) ? wm_lp + 1 : wm_lp; + if (level > max_level) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0633-drm-i915-Calculate-max-watermark-levels-for-ILK.patch b/patches.baytrail/0633-drm-i915-Calculate-max-watermark-levels-for-ILK.patch new file mode 100644 index 000000000000..ed3cbb95c414 --- /dev/null +++ b/patches.baytrail/0633-drm-i915-Calculate-max-watermark-levels-for-ILK.patch @@ -0,0 +1,165 @@ +From de594f8178a74406d1b7947e8adeb574821c7925 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 7 Aug 2013 13:28:19 +0300 +Subject: drm/i915: Calculate max watermark levels for ILK+ +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are quite a few variables we need to take into account to +determine the maximum watermark levels, so it feels a bit cleaner +to calculate those rather than just have a bunch of what look like +magic numbers. + +v2: s/pipes_active/num_pipes_active + s/othwewise/otherwise + +Reviewed-by: Chris Wilson +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 158ae64f820939473012dacfc0ae1ec782b45b60) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 119 ++++++++++++++++++++++++++++++++++++---- + 1 file changed, 107 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index d10d4c717b4a..5daa32a4e864 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2270,6 +2270,104 @@ static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params, + params->pri_bytes_per_pixel); + } + ++static unsigned int ilk_display_fifo_size(const struct drm_device *dev) ++{ ++ if (INTEL_INFO(dev)->gen >= 7) ++ return 768; ++ else ++ return 512; ++} ++ ++/* Calculate the maximum primary/sprite plane watermark */ ++static unsigned int ilk_plane_wm_max(const struct drm_device *dev, ++ int level, ++ unsigned int num_pipes_active, ++ bool sprite_enabled, ++ enum intel_ddb_partitioning ddb_partitioning, ++ bool is_sprite) ++{ ++ unsigned int fifo_size = ilk_display_fifo_size(dev); ++ unsigned int max; ++ ++ /* if sprites aren't enabled, sprites get nothing */ ++ if (is_sprite && !sprite_enabled) ++ return 0; ++ ++ /* HSW allows LP1+ watermarks even with multiple pipes */ ++ if (level == 0 || num_pipes_active > 1) { ++ fifo_size /= INTEL_INFO(dev)->num_pipes; ++ ++ /* ++ * For some reason the non self refresh ++ * FIFO size is only half of the self ++ * refresh FIFO size on ILK/SNB. ++ */ ++ if (INTEL_INFO(dev)->gen <= 6) ++ fifo_size /= 2; ++ } ++ ++ if (sprite_enabled) { ++ /* level 0 is always calculated with 1:1 split */ ++ if (level > 0 && ddb_partitioning == INTEL_DDB_PART_5_6) { ++ if (is_sprite) ++ fifo_size *= 5; ++ fifo_size /= 6; ++ } else { ++ fifo_size /= 2; ++ } ++ } ++ ++ /* clamp to max that the registers can hold */ ++ if (INTEL_INFO(dev)->gen >= 7) ++ /* IVB/HSW primary/sprite plane watermarks */ ++ max = level == 0 ? 127 : 1023; ++ else if (!is_sprite) ++ /* ILK/SNB primary plane watermarks */ ++ max = level == 0 ? 127 : 511; ++ else ++ /* ILK/SNB sprite plane watermarks */ ++ max = level == 0 ? 63 : 255; ++ ++ return min(fifo_size, max); ++} ++ ++/* Calculate the maximum cursor plane watermark */ ++static unsigned int ilk_cursor_wm_max(const struct drm_device *dev, ++ int level, unsigned int num_pipes_active) ++{ ++ /* HSW LP1+ watermarks w/ multiple pipes */ ++ if (level > 0 && num_pipes_active > 1) ++ return 64; ++ ++ /* otherwise just report max that registers can hold */ ++ if (INTEL_INFO(dev)->gen >= 7) ++ return level == 0 ? 63 : 255; ++ else ++ return level == 0 ? 31 : 63; ++} ++ ++/* Calculate the maximum FBC watermark */ ++static unsigned int ilk_fbc_wm_max(void) ++{ ++ /* max that registers can hold */ ++ return 15; ++} ++ ++static void ilk_wm_max(struct drm_device *dev, ++ int level, ++ unsigned int num_pipes_active, ++ bool sprite_enabled, ++ enum intel_ddb_partitioning ddb_partitioning, ++ struct hsw_wm_maximums *max) ++{ ++ max->pri = ilk_plane_wm_max(dev, level, num_pipes_active, ++ sprite_enabled, ddb_partitioning, false); ++ max->spr = ilk_plane_wm_max(dev, level, num_pipes_active, ++ sprite_enabled, ddb_partitioning, true); ++ max->cur = ilk_cursor_wm_max(dev, level, num_pipes_active); ++ max->fbc = ilk_fbc_wm_max(); ++} ++ + static bool ilk_check_wm(int level, + const struct hsw_wm_maximums *max, + struct intel_wm_level *result) +@@ -2555,18 +2653,15 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, + sprites_enabled++; + } + +- if (pipes_active > 1) { +- lp_max_1_2->pri = lp_max_5_6->pri = sprites_enabled ? 128 : 256; +- lp_max_1_2->spr = lp_max_5_6->spr = 128; +- lp_max_1_2->cur = lp_max_5_6->cur = 64; +- } else { +- lp_max_1_2->pri = sprites_enabled ? 384 : 768; +- lp_max_5_6->pri = sprites_enabled ? 128 : 768; +- lp_max_1_2->spr = 384; +- lp_max_5_6->spr = 640; +- lp_max_1_2->cur = lp_max_5_6->cur = 255; +- } +- lp_max_1_2->fbc = lp_max_5_6->fbc = 15; ++ ilk_wm_max(dev, 1, pipes_active, sprites_enabled, ++ INTEL_DDB_PART_1_2, lp_max_1_2); ++ ++ /* 5/6 split only in single pipe config on IVB+ */ ++ if (INTEL_INFO(dev)->gen >= 7 && pipes_active <= 1) ++ ilk_wm_max(dev, 1, pipes_active, sprites_enabled, ++ INTEL_DDB_PART_5_6, lp_max_5_6); ++ else ++ *lp_max_5_6 = *lp_max_1_2; + } + + static void hsw_compute_wm_results(struct drm_device *dev, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0634-drm-i915-Pull-some-watermarks-state-into-a-separate-.patch b/patches.baytrail/0634-drm-i915-Pull-some-watermarks-state-into-a-separate-.patch new file mode 100644 index 000000000000..48515f5ffe55 --- /dev/null +++ b/patches.baytrail/0634-drm-i915-Pull-some-watermarks-state-into-a-separate-.patch @@ -0,0 +1,158 @@ +From 597fa348a3b9cfd91e27b6dde4ac40ea4a01fde7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 7 Aug 2013 13:29:12 +0300 +Subject: drm/i915: Pull some watermarks state into a separate structure +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is a bunch of global state that needs to be considered when +checking watermarks for validity. Move most of that to a new +structure intel_wm_config, to avoid having to pass around so +many variables. + +One notable thing left out is the DDB partitioning information, +since we often anyway need to check the same watermarks against +both 1/2 and 5/6 DDB partitioning layouts. + +v2: s/pipes_active/num_pipes_active + +Reviewed-by: Chris Wilson +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 240264f49edbe02eb96b472ae1c518cc413f9d01) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 48 +++++++++++++++++++++-------------------- + 1 file changed, 25 insertions(+), 23 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 5daa32a4e864..9d087be556ff 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2188,6 +2188,14 @@ struct hsw_wm_values { + bool enable_fbc_wm; + }; + ++/* used in computing the new watermarks state */ ++struct intel_wm_config { ++ unsigned int num_pipes_active; ++ bool sprites_enabled; ++ bool sprites_scaled; ++ bool fbc_wm_enabled; ++}; ++ + /* + * For both WM_PIPE and WM_LP. + * mem_value must be in 0.1us units. +@@ -2281,8 +2289,7 @@ static unsigned int ilk_display_fifo_size(const struct drm_device *dev) + /* Calculate the maximum primary/sprite plane watermark */ + static unsigned int ilk_plane_wm_max(const struct drm_device *dev, + int level, +- unsigned int num_pipes_active, +- bool sprite_enabled, ++ const struct intel_wm_config *config, + enum intel_ddb_partitioning ddb_partitioning, + bool is_sprite) + { +@@ -2290,11 +2297,11 @@ static unsigned int ilk_plane_wm_max(const struct drm_device *dev, + unsigned int max; + + /* if sprites aren't enabled, sprites get nothing */ +- if (is_sprite && !sprite_enabled) ++ if (is_sprite && !config->sprites_enabled) + return 0; + + /* HSW allows LP1+ watermarks even with multiple pipes */ +- if (level == 0 || num_pipes_active > 1) { ++ if (level == 0 || config->num_pipes_active > 1) { + fifo_size /= INTEL_INFO(dev)->num_pipes; + + /* +@@ -2306,7 +2313,7 @@ static unsigned int ilk_plane_wm_max(const struct drm_device *dev, + fifo_size /= 2; + } + +- if (sprite_enabled) { ++ if (config->sprites_enabled) { + /* level 0 is always calculated with 1:1 split */ + if (level > 0 && ddb_partitioning == INTEL_DDB_PART_5_6) { + if (is_sprite) +@@ -2333,10 +2340,11 @@ static unsigned int ilk_plane_wm_max(const struct drm_device *dev, + + /* Calculate the maximum cursor plane watermark */ + static unsigned int ilk_cursor_wm_max(const struct drm_device *dev, +- int level, unsigned int num_pipes_active) ++ int level, ++ const struct intel_wm_config *config) + { + /* HSW LP1+ watermarks w/ multiple pipes */ +- if (level > 0 && num_pipes_active > 1) ++ if (level > 0 && config->num_pipes_active > 1) + return 64; + + /* otherwise just report max that registers can hold */ +@@ -2355,16 +2363,13 @@ static unsigned int ilk_fbc_wm_max(void) + + static void ilk_wm_max(struct drm_device *dev, + int level, +- unsigned int num_pipes_active, +- bool sprite_enabled, ++ const struct intel_wm_config *config, + enum intel_ddb_partitioning ddb_partitioning, + struct hsw_wm_maximums *max) + { +- max->pri = ilk_plane_wm_max(dev, level, num_pipes_active, +- sprite_enabled, ddb_partitioning, false); +- max->spr = ilk_plane_wm_max(dev, level, num_pipes_active, +- sprite_enabled, ddb_partitioning, true); +- max->cur = ilk_cursor_wm_max(dev, level, num_pipes_active); ++ max->pri = ilk_plane_wm_max(dev, level, config, ddb_partitioning, false); ++ max->spr = ilk_plane_wm_max(dev, level, config, ddb_partitioning, true); ++ max->cur = ilk_cursor_wm_max(dev, level, config); + max->fbc = ilk_fbc_wm_max(); + } + +@@ -2614,7 +2619,7 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, + struct drm_crtc *crtc; + struct drm_plane *plane; + enum pipe pipe; +- int pipes_active = 0, sprites_enabled = 0; ++ struct intel_wm_config config = {}; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +@@ -2627,7 +2632,7 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, + if (!p->active) + continue; + +- pipes_active++; ++ config.num_pipes_active++; + + p->pipe_htotal = intel_crtc->config.adjusted_mode.htotal; + p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc); +@@ -2649,17 +2654,14 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, + p->spr_bytes_per_pixel = intel_plane->wm.bytes_per_pixel; + p->spr_horiz_pixels = intel_plane->wm.horiz_pixels; + +- if (p->sprite_enabled) +- sprites_enabled++; ++ config.sprites_enabled |= p->sprite_enabled; + } + +- ilk_wm_max(dev, 1, pipes_active, sprites_enabled, +- INTEL_DDB_PART_1_2, lp_max_1_2); ++ ilk_wm_max(dev, 1, &config, INTEL_DDB_PART_1_2, lp_max_1_2); + + /* 5/6 split only in single pipe config on IVB+ */ +- if (INTEL_INFO(dev)->gen >= 7 && pipes_active <= 1) +- ilk_wm_max(dev, 1, pipes_active, sprites_enabled, +- INTEL_DDB_PART_5_6, lp_max_5_6); ++ if (INTEL_INFO(dev)->gen >= 7 && config.num_pipes_active <= 1) ++ ilk_wm_max(dev, 1, &config, INTEL_DDB_PART_5_6, lp_max_5_6); + else + *lp_max_5_6 = *lp_max_1_2; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0635-drm-i915-Split-plane-watermark-parameters-into-a-sep.patch b/patches.baytrail/0635-drm-i915-Split-plane-watermark-parameters-into-a-sep.patch new file mode 100644 index 000000000000..154fef1efa93 --- /dev/null +++ b/patches.baytrail/0635-drm-i915-Split-plane-watermark-parameters-into-a-sep.patch @@ -0,0 +1,198 @@ +From d3f4fbc6a1e2c82b0ff410f3c2484e379a358735 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 7 Aug 2013 13:29:50 +0300 +Subject: drm/i915: Split plane watermark parameters into a separate struct +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Give a name to the plane watermark related data we have currently +stored under intel_plane->wm. + +We also observe that this data is more or less the same that we have +in the hsw_pipe_wm_parameters structure, so use it there as well. + +v2: Make pahole happier + +Reviewed-by: Chris Wilson +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit c35426d2bc25b242ee2a9a7a1d62634be1e86bb0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_drv.h | 14 +++++----- + drivers/gpu/drm/i915/intel_pm.c | 57 +++++++++++++++++++--------------------- + 2 files changed, 35 insertions(+), 36 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 7df662bab280..3ea8e5fe4407 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -331,6 +331,13 @@ struct intel_crtc { + bool pch_fifo_underrun_disabled; + }; + ++struct intel_plane_wm_parameters { ++ uint32_t horiz_pixels; ++ uint8_t bytes_per_pixel; ++ bool enabled; ++ bool scaled; ++}; ++ + struct intel_plane { + struct drm_plane base; + int plane; +@@ -349,12 +356,7 @@ struct intel_plane { + * as the other pieces of the struct may not reflect the values we want + * for the watermark calculations. Currently only Haswell uses this. + */ +- struct { +- bool enabled; +- bool scaled; +- uint8_t bytes_per_pixel; +- uint32_t horiz_pixels; +- } wm; ++ struct intel_plane_wm_parameters wm; + + void (*update_plane)(struct drm_plane *plane, + struct drm_framebuffer *fb, +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 9d087be556ff..af030e815f79 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2162,15 +2162,11 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels, + + struct hsw_pipe_wm_parameters { + bool active; +- bool sprite_enabled; +- uint8_t pri_bytes_per_pixel; +- uint8_t spr_bytes_per_pixel; +- uint8_t cur_bytes_per_pixel; +- uint32_t pri_horiz_pixels; +- uint32_t spr_horiz_pixels; +- uint32_t cur_horiz_pixels; + uint32_t pipe_htotal; + uint32_t pixel_rate; ++ struct intel_plane_wm_parameters pri; ++ struct intel_plane_wm_parameters spr; ++ struct intel_plane_wm_parameters cur; + }; + + struct hsw_wm_maximums { +@@ -2206,12 +2202,11 @@ static uint32_t ilk_compute_pri_wm(struct hsw_pipe_wm_parameters *params, + { + uint32_t method1, method2; + +- /* TODO: for now, assume the primary plane is always enabled. */ +- if (!params->active) ++ if (!params->active || !params->pri.enabled) + return 0; + + method1 = ilk_wm_method1(params->pixel_rate, +- params->pri_bytes_per_pixel, ++ params->pri.bytes_per_pixel, + mem_value); + + if (!is_lp) +@@ -2219,8 +2214,8 @@ static uint32_t ilk_compute_pri_wm(struct hsw_pipe_wm_parameters *params, + + method2 = ilk_wm_method2(params->pixel_rate, + params->pipe_htotal, +- params->pri_horiz_pixels, +- params->pri_bytes_per_pixel, ++ params->pri.horiz_pixels, ++ params->pri.bytes_per_pixel, + mem_value); + + return min(method1, method2); +@@ -2235,16 +2230,16 @@ static uint32_t ilk_compute_spr_wm(struct hsw_pipe_wm_parameters *params, + { + uint32_t method1, method2; + +- if (!params->active || !params->sprite_enabled) ++ if (!params->active || !params->spr.enabled) + return 0; + + method1 = ilk_wm_method1(params->pixel_rate, +- params->spr_bytes_per_pixel, ++ params->spr.bytes_per_pixel, + mem_value); + method2 = ilk_wm_method2(params->pixel_rate, + params->pipe_htotal, +- params->spr_horiz_pixels, +- params->spr_bytes_per_pixel, ++ params->spr.horiz_pixels, ++ params->spr.bytes_per_pixel, + mem_value); + return min(method1, method2); + } +@@ -2256,13 +2251,13 @@ static uint32_t ilk_compute_spr_wm(struct hsw_pipe_wm_parameters *params, + static uint32_t ilk_compute_cur_wm(struct hsw_pipe_wm_parameters *params, + uint32_t mem_value) + { +- if (!params->active) ++ if (!params->active || !params->cur.enabled) + return 0; + + return ilk_wm_method2(params->pixel_rate, + params->pipe_htotal, +- params->cur_horiz_pixels, +- params->cur_bytes_per_pixel, ++ params->cur.horiz_pixels, ++ params->cur.bytes_per_pixel, + mem_value); + } + +@@ -2270,12 +2265,12 @@ static uint32_t ilk_compute_cur_wm(struct hsw_pipe_wm_parameters *params, + static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params, + uint32_t pri_val) + { +- if (!params->active) ++ if (!params->active || !params->pri.enabled) + return 0; + + return ilk_wm_fbc(pri_val, +- params->pri_horiz_pixels, +- params->pri_bytes_per_pixel); ++ params->pri.horiz_pixels, ++ params->pri.bytes_per_pixel); + } + + static unsigned int ilk_display_fifo_size(const struct drm_device *dev) +@@ -2636,11 +2631,14 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, + + p->pipe_htotal = intel_crtc->config.adjusted_mode.htotal; + p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc); +- p->pri_bytes_per_pixel = crtc->fb->bits_per_pixel / 8; +- p->cur_bytes_per_pixel = 4; +- p->pri_horiz_pixels = ++ p->pri.bytes_per_pixel = crtc->fb->bits_per_pixel / 8; ++ p->cur.bytes_per_pixel = 4; ++ p->pri.horiz_pixels = + intel_crtc->config.requested_mode.hdisplay; +- p->cur_horiz_pixels = 64; ++ p->cur.horiz_pixels = 64; ++ /* TODO: for now, assume primary and cursor planes are always enabled. */ ++ p->pri.enabled = true; ++ p->cur.enabled = true; + } + + list_for_each_entry(plane, &dev->mode_config.plane_list, head) { +@@ -2650,11 +2648,10 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, + pipe = intel_plane->pipe; + p = ¶ms[pipe]; + +- p->sprite_enabled = intel_plane->wm.enabled; +- p->spr_bytes_per_pixel = intel_plane->wm.bytes_per_pixel; +- p->spr_horiz_pixels = intel_plane->wm.horiz_pixels; ++ p->spr = intel_plane->wm; + +- config.sprites_enabled |= p->sprite_enabled; ++ config.sprites_enabled |= p->spr.enabled; ++ config.sprites_scaled |= p->spr.scaled; + } + + ilk_wm_max(dev, 1, &config, INTEL_DDB_PART_1_2, lp_max_1_2); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0636-drm-i915-Pass-crtc-to-our-update-disable_plane-hooks.patch b/patches.baytrail/0636-drm-i915-Pass-crtc-to-our-update-disable_plane-hooks.patch new file mode 100644 index 000000000000..3c6b4c4dd93c --- /dev/null +++ b/patches.baytrail/0636-drm-i915-Pass-crtc-to-our-update-disable_plane-hooks.patch @@ -0,0 +1,129 @@ +From 1cd47328d11a8251ba3f835299d8ffff49975c5b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 6 Aug 2013 22:24:09 +0300 +Subject: drm/i915: Pass crtc to our update/disable_plane hooks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We're going to want to know which CRTC we're dealing with, so pass it +down to the update/disable_plane hooks. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit b39d53f624d50d1588933e0ab17f19a5f2da5d94) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_drv.h | 4 +++- + drivers/gpu/drm/i915/intel_sprite.c | 21 ++++++++++++--------- + 2 files changed, 15 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 3ea8e5fe4407..da394f354453 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -359,13 +359,15 @@ struct intel_plane { + struct intel_plane_wm_parameters wm; + + void (*update_plane)(struct drm_plane *plane, ++ struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t x, uint32_t y, + uint32_t src_w, uint32_t src_h); +- void (*disable_plane)(struct drm_plane *plane); ++ void (*disable_plane)(struct drm_plane *plane, ++ struct drm_crtc *crtc); + int (*update_colorkey)(struct drm_plane *plane, + struct drm_intel_sprite_colorkey *key); + void (*get_colorkey)(struct drm_plane *plane, +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index 5a36afb6ea03..d4e0592e3389 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -38,7 +38,8 @@ + #include "i915_drv.h" + + static void +-vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb, ++vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, ++ struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t x, uint32_t y, +@@ -140,7 +141,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb, + } + + static void +-vlv_disable_plane(struct drm_plane *dplane) ++vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) + { + struct drm_device *dev = dplane->dev; + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -207,7 +208,8 @@ vlv_get_colorkey(struct drm_plane *dplane, + } + + static void +-ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, ++ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, ++ struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t x, uint32_t y, +@@ -320,7 +322,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, + } + + static void +-ivb_disable_plane(struct drm_plane *plane) ++ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) + { + struct drm_device *dev = plane->dev; + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -400,7 +402,8 @@ ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) + } + + static void +-ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, ++ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, ++ struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t x, uint32_t y, +@@ -488,7 +491,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, + } + + static void +-ilk_disable_plane(struct drm_plane *plane) ++ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) + { + struct drm_device *dev = plane->dev; + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -823,11 +826,11 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + intel_enable_primary(crtc); + + if (visible) +- intel_plane->update_plane(plane, fb, obj, ++ intel_plane->update_plane(plane, crtc, fb, obj, + crtc_x, crtc_y, crtc_w, crtc_h, + src_x, src_y, src_w, src_h); + else +- intel_plane->disable_plane(plane); ++ intel_plane->disable_plane(plane, crtc); + + if (disable_primary) + intel_disable_primary(crtc); +@@ -862,7 +865,7 @@ intel_disable_plane(struct drm_plane *plane) + + if (plane->crtc) + intel_enable_primary(plane->crtc); +- intel_plane->disable_plane(plane); ++ intel_plane->disable_plane(plane, plane->crtc); + + if (!intel_plane->obj) + goto out; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0637-drm-i915-Don-t-try-to-disable-plane-if-it-s-already-.patch b/patches.baytrail/0637-drm-i915-Don-t-try-to-disable-plane-if-it-s-already-.patch new file mode 100644 index 000000000000..3eb0e7088517 --- /dev/null +++ b/patches.baytrail/0637-drm-i915-Don-t-try-to-disable-plane-if-it-s-already-.patch @@ -0,0 +1,47 @@ +From 01a08550189848bcad9464822a2737ea3b9ce325 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 7 Aug 2013 13:30:23 +0300 +Subject: drm/i915: Don't try to disable plane if it's already disabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Check plane->fb in intel_disable_plane() to determine if the plane +is already disabled. + +If the plane has an fb, then it must also have a crtc, so we can drop +the plane->crtc check and just call intel_enable_primary() directly. + +v2: WARN and bail if the plane doesn't have a crtc when it should + +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 88a94a58a07267d979cc168c3e511b99f4164951) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sprite.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index d4e0592e3389..0a174d7e5854 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -863,8 +863,13 @@ intel_disable_plane(struct drm_plane *plane) + struct intel_plane *intel_plane = to_intel_plane(plane); + int ret = 0; + +- if (plane->crtc) +- intel_enable_primary(plane->crtc); ++ if (!plane->fb) ++ return 0; ++ ++ if (WARN_ON(!plane->crtc)) ++ return -EINVAL; ++ ++ intel_enable_primary(plane->crtc); + intel_plane->disable_plane(plane, plane->crtc); + + if (!intel_plane->obj) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0638-drm-i915-Pass-plane-and-crtc-to-intel_update_sprite_.patch b/patches.baytrail/0638-drm-i915-Pass-plane-and-crtc-to-intel_update_sprite_.patch new file mode 100644 index 000000000000..670d7116f046 --- /dev/null +++ b/patches.baytrail/0638-drm-i915-Pass-plane-and-crtc-to-intel_update_sprite_.patch @@ -0,0 +1,169 @@ +From dd4fa098eccdeff148695ac550df7507cbdd44d6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 6 Aug 2013 22:24:11 +0300 +Subject: drm/i915: Pass plane and crtc to intel_update_sprite_watermarks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We're going to want to know the crtc in the watermark code to avoid +doing more work than we have to. We should also pass the plane we're +disabling so that we know where to stick our watermark parameters +without having to go look the plane up. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit adf3d35e4aced032f0449c6d69b0a90fea14692f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 3 ++- + drivers/gpu/drm/i915/intel_drv.h | 3 ++- + drivers/gpu/drm/i915/intel_pm.c | 34 ++++++++++++++++------------------ + drivers/gpu/drm/i915/intel_sprite.c | 8 ++++---- + 4 files changed, 24 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 3a435fede3c4..7863c8ac867c 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -359,7 +359,8 @@ struct drm_i915_display_funcs { + struct dpll *match_clock, + struct dpll *best_clock); + void (*update_wm)(struct drm_device *dev); +- void (*update_sprite_wm)(struct drm_device *dev, int pipe, ++ void (*update_sprite_wm)(struct drm_plane *plane, ++ struct drm_crtc *crtc, + uint32_t sprite_width, int pixel_size, + bool enable, bool scaled); + void (*modeset_global_resources)(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index da394f354453..caf8b8dfe17a 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -716,7 +716,8 @@ extern void intel_ddi_init(struct drm_device *dev, enum port port); + + /* For use by IVB LP watermark workaround in intel_sprite.c */ + extern void intel_update_watermarks(struct drm_device *dev); +-extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, ++extern void intel_update_sprite_watermarks(struct drm_plane *plane, ++ struct drm_crtc *crtc, + uint32_t sprite_width, int pixel_size, + bool enabled, bool scaled); + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index af030e815f79..96234c6d982d 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2866,25 +2866,19 @@ static void haswell_update_wm(struct drm_device *dev) + hsw_write_wm_values(dev_priv, best_results, partitioning); + } + +-static void haswell_update_sprite_wm(struct drm_device *dev, int pipe, ++static void haswell_update_sprite_wm(struct drm_plane *plane, ++ struct drm_crtc *crtc, + uint32_t sprite_width, int pixel_size, + bool enabled, bool scaled) + { +- struct drm_plane *plane; +- +- list_for_each_entry(plane, &dev->mode_config.plane_list, head) { +- struct intel_plane *intel_plane = to_intel_plane(plane); ++ struct intel_plane *intel_plane = to_intel_plane(plane); + +- if (intel_plane->pipe == pipe) { +- intel_plane->wm.enabled = enabled; +- intel_plane->wm.scaled = scaled; +- intel_plane->wm.horiz_pixels = sprite_width; +- intel_plane->wm.bytes_per_pixel = pixel_size; +- break; +- } +- } ++ intel_plane->wm.enabled = enabled; ++ intel_plane->wm.scaled = scaled; ++ intel_plane->wm.horiz_pixels = sprite_width; ++ intel_plane->wm.bytes_per_pixel = pixel_size; + +- haswell_update_wm(dev); ++ haswell_update_wm(plane->dev); + } + + static bool +@@ -2963,11 +2957,14 @@ sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane, + return *sprite_wm > 0x3ff ? false : true; + } + +-static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, ++static void sandybridge_update_sprite_wm(struct drm_plane *plane, ++ struct drm_crtc *crtc, + uint32_t sprite_width, int pixel_size, + bool enabled, bool scaled) + { ++ struct drm_device *dev = plane->dev; + struct drm_i915_private *dev_priv = dev->dev_private; ++ int pipe = to_intel_plane(plane)->pipe; + int latency = dev_priv->wm.spr_latency[0] * 100; /* In unit 0.1us */ + u32 val; + int sprite_wm, reg; +@@ -3086,14 +3083,15 @@ void intel_update_watermarks(struct drm_device *dev) + dev_priv->display.update_wm(dev); + } + +-void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, ++void intel_update_sprite_watermarks(struct drm_plane *plane, ++ struct drm_crtc *crtc, + uint32_t sprite_width, int pixel_size, + bool enabled, bool scaled) + { +- struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_i915_private *dev_priv = plane->dev->dev_private; + + if (dev_priv->display.update_sprite_wm) +- dev_priv->display.update_sprite_wm(dev, pipe, sprite_width, ++ dev_priv->display.update_sprite_wm(plane, crtc, sprite_width, + pixel_size, enabled, scaled); + } + +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index 0a174d7e5854..05742f7d7006 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -109,7 +109,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, + + sprctl |= SP_ENABLE; + +- intel_update_sprite_watermarks(dev, pipe, src_w, pixel_size, true, ++ intel_update_sprite_watermarks(dplane, crtc, src_w, pixel_size, true, + src_w != crtc_w || src_h != crtc_h); + + /* Sizes are 0 based */ +@@ -265,7 +265,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + if (IS_HASWELL(dev)) + sprctl |= SPRITE_PIPE_CSC_ENABLE; + +- intel_update_sprite_watermarks(dev, pipe, src_w, pixel_size, true, ++ intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true, + src_w != crtc_w || src_h != crtc_h); + + /* Sizes are 0 based */ +@@ -340,7 +340,7 @@ ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) + + dev_priv->sprite_scaling_enabled &= ~(1 << pipe); + +- intel_update_sprite_watermarks(dev, pipe, 0, 0, false, false); ++ intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false); + + /* potentially re-enable LP watermarks */ + if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) +@@ -455,7 +455,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ + dvscntr |= DVS_ENABLE; + +- intel_update_sprite_watermarks(dev, pipe, src_w, pixel_size, true, ++ intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true, + src_w != crtc_w || src_h != crtc_h); + + /* Sizes are 0 based */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0639-drm-i915-Always-call-intel_update_sprite_watermarks-.patch b/patches.baytrail/0639-drm-i915-Always-call-intel_update_sprite_watermarks-.patch new file mode 100644 index 000000000000..b7d87071bdd7 --- /dev/null +++ b/patches.baytrail/0639-drm-i915-Always-call-intel_update_sprite_watermarks-.patch @@ -0,0 +1,46 @@ +From 09276fb9b6f222f6b47a216e0f2bb4676ea921f9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 6 Aug 2013 22:24:12 +0300 +Subject: drm/i915: Always call intel_update_sprite_watermarks() when disabling + a plane +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +ILK and VLV codepaths didn't update sprite watermarks when disabling a +sprite. Make them do that. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit a95fd8cae06dadf4a3eb88c9c130e86c5b0c1723) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sprite.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index 05742f7d7006..78b621cdd108 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -154,6 +154,8 @@ vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) + /* Activate double buffered register update */ + I915_MODIFY_DISPBASE(SPSURF(pipe, plane), 0); + POSTING_READ(SPSURF(pipe, plane)); ++ ++ intel_update_sprite_watermarks(dplane, crtc, 0, 0, false, false); + } + + static int +@@ -504,6 +506,8 @@ ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) + /* Flush double buffered register updates */ + I915_MODIFY_DISPBASE(DVSSURF(pipe), 0); + POSTING_READ(DVSSURF(pipe)); ++ ++ intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false); + } + + static void +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0640-drm-i915-List-objects-allocated-from-stolen-memory-i.patch b/patches.baytrail/0640-drm-i915-List-objects-allocated-from-stolen-memory-i.patch new file mode 100644 index 000000000000..24579f7411e4 --- /dev/null +++ b/patches.baytrail/0640-drm-i915-List-objects-allocated-from-stolen-memory-i.patch @@ -0,0 +1,107 @@ +From b9bcc1d5c871705fc6a6f2a68424946f32cc5117 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 7 Aug 2013 18:30:54 +0100 +Subject: drm/i915: List objects allocated from stolen memory in debugfs + +I was curious as to what objects were currently allocated from stolen +memory, and so exported it from debugfs. + +Signed-off-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 6d2b888569d366beb4be72cacfde41adee2c25e1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 63 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 63 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index a1f4c91fb112..1a87cc9fd899 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + #include "intel_drv.h" + #include "intel_ringbuffer.h" +@@ -188,6 +189,67 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) + return 0; + } + ++static int obj_rank_by_stolen(void *priv, ++ struct list_head *A, struct list_head *B) ++{ ++ struct drm_i915_gem_object *a = ++ container_of(A, struct drm_i915_gem_object, exec_list); ++ struct drm_i915_gem_object *b = ++ container_of(B, struct drm_i915_gem_object, exec_list); ++ ++ return a->stolen->start - b->stolen->start; ++} ++ ++static int i915_gem_stolen_list_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_i915_gem_object *obj; ++ size_t total_obj_size, total_gtt_size; ++ LIST_HEAD(stolen); ++ int count, ret; ++ ++ ret = mutex_lock_interruptible(&dev->struct_mutex); ++ if (ret) ++ return ret; ++ ++ total_obj_size = total_gtt_size = count = 0; ++ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { ++ if (obj->stolen == NULL) ++ continue; ++ ++ list_add(&obj->exec_list, &stolen); ++ ++ total_obj_size += obj->base.size; ++ total_gtt_size += i915_gem_obj_ggtt_size(obj); ++ count++; ++ } ++ list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) { ++ if (obj->stolen == NULL) ++ continue; ++ ++ list_add(&obj->exec_list, &stolen); ++ ++ total_obj_size += obj->base.size; ++ count++; ++ } ++ list_sort(NULL, &stolen, obj_rank_by_stolen); ++ seq_puts(m, "Stolen:\n"); ++ while (!list_empty(&stolen)) { ++ obj = list_first_entry(&stolen, typeof(*obj), exec_list); ++ seq_puts(m, " "); ++ describe_obj(m, obj); ++ seq_putc(m, '\n'); ++ list_del_init(&obj->exec_list); ++ } ++ mutex_unlock(&dev->struct_mutex); ++ ++ seq_printf(m, "Total %d objects, %zu bytes, %zu GTT size\n", ++ count, total_obj_size, total_gtt_size); ++ return 0; ++} ++ + #define count_objects(list, member) do { \ + list_for_each_entry(obj, list, member) { \ + size += i915_gem_obj_ggtt_size(obj); \ +@@ -2114,6 +2176,7 @@ static struct drm_info_list i915_debugfs_list[] = { + {"i915_gem_pinned", i915_gem_gtt_info, 0, (void *) PINNED_LIST}, + {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, + {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, ++ {"i915_gem_stolen", i915_gem_stolen_list_info }, + {"i915_gem_pageflip", i915_gem_pageflip_info, 0}, + {"i915_gem_request", i915_gem_request_info, 0}, + {"i915_gem_seqno", i915_gem_seqno_info, 0}, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0641-drm-i915-Remove-stale-prototypes.patch b/patches.baytrail/0641-drm-i915-Remove-stale-prototypes.patch new file mode 100644 index 000000000000..9a9243e225b4 --- /dev/null +++ b/patches.baytrail/0641-drm-i915-Remove-stale-prototypes.patch @@ -0,0 +1,74 @@ +From 4e26423e203774a1791ee523143d516fdfab7d5f Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Thu, 8 Aug 2013 22:28:53 +0100 +Subject: drm/i915: Remove stale prototypes + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit a2367166fb200528d6fd43859e917e80ee034e16) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 8 -------- + drivers/gpu/drm/i915/intel_drv.h | 2 -- + 2 files changed, 10 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 7863c8ac867c..db5492382d7c 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1677,7 +1677,6 @@ extern void intel_pm_init(struct drm_device *dev); + extern void intel_uncore_sanitize(struct drm_device *dev); + extern void intel_uncore_early_sanitize(struct drm_device *dev); + extern void intel_uncore_init(struct drm_device *dev); +-extern void intel_uncore_reset(struct drm_device *dev); + extern void intel_uncore_clear_errors(struct drm_device *dev); + extern void intel_uncore_check_errors(struct drm_device *dev); + +@@ -1843,9 +1842,6 @@ static inline bool i915_terminally_wedged(struct i915_gpu_error *error) + + void i915_gem_reset(struct drm_device *dev); + void i915_gem_clflush_object(struct drm_i915_gem_object *obj); +-int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, +- uint32_t read_domains, +- uint32_t write_domain); + int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); + int __must_check i915_gem_init(struct drm_device *dev); + int __must_check i915_gem_init_hw(struct drm_device *dev); +@@ -2034,8 +2030,6 @@ void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj); + void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj); + + /* i915_gem_debug.c */ +-void i915_gem_dump_object(struct drm_i915_gem_object *obj, int len, +- const char *where, uint32_t mark); + #if WATCH_LISTS + int i915_verify_lists(struct drm_device *dev); + #else +@@ -2043,8 +2037,6 @@ int i915_verify_lists(struct drm_device *dev); + #endif + void i915_gem_object_check_coherency(struct drm_i915_gem_object *obj, + int handle); +-void i915_gem_dump_object(struct drm_i915_gem_object *obj, int len, +- const char *where, uint32_t mark); + + /* i915_debugfs.c */ + int i915_debugfs_init(struct drm_minor *minor); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index caf8b8dfe17a..d516c63fc94d 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -649,12 +649,10 @@ extern bool intel_get_load_detect_pipe(struct drm_connector *connector, + extern void intel_release_load_detect_pipe(struct drm_connector *connector, + struct intel_load_detect_pipe *old); + +-extern void intelfb_restore(void); + extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, + u16 blue, int regno); + extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, + u16 *blue, int regno); +-extern void intel_enable_clock_gating(struct drm_device *dev); + + extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, + struct drm_i915_gem_object *obj, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0642-drm-i915-Remove-i915_gem_object_check_coherency.patch b/patches.baytrail/0642-drm-i915-Remove-i915_gem_object_check_coherency.patch new file mode 100644 index 000000000000..147eeaab75ac --- /dev/null +++ b/patches.baytrail/0642-drm-i915-Remove-i915_gem_object_check_coherency.patch @@ -0,0 +1,125 @@ +From 80212281be26f4b8cd9941dca6a0526a177a9b0a Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Thu, 8 Aug 2013 22:28:54 +0100 +Subject: drm/i915: Remove i915_gem_object_check_coherency() + +This code was dead since: + + commit 432e58edc9de1d9c3d6a7b444b3c455b8f209a7d + Author: Chris Wilson + Date: Thu Nov 25 19:32:06 2010 +0000 + + drm/i915: Avoid allocation for execbuffer object list + +so just put it to rest for good. + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit ac44bfac5b591c5f9b28b43f8e8ed08e9abf7f95) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 3 -- + drivers/gpu/drm/i915/i915_gem_debug.c | 69 ----------------------------------- + 2 files changed, 72 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index db5492382d7c..0be923ef08c6 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -201,7 +201,6 @@ struct intel_ddi_plls { + #define DRIVER_MINOR 6 + #define DRIVER_PATCHLEVEL 0 + +-#define WATCH_COHERENCY 0 + #define WATCH_LISTS 0 + #define WATCH_GTT 0 + +@@ -2035,8 +2034,6 @@ int i915_verify_lists(struct drm_device *dev); + #else + #define i915_verify_lists(dev) 0 + #endif +-void i915_gem_object_check_coherency(struct drm_i915_gem_object *obj, +- int handle); + + /* i915_debugfs.c */ + int i915_debugfs_init(struct drm_minor *minor); +diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c +index bf945a39fbb1..bcdbafc6c985 100644 +--- a/drivers/gpu/drm/i915/i915_gem_debug.c ++++ b/drivers/gpu/drm/i915/i915_gem_debug.c +@@ -116,72 +116,3 @@ i915_verify_lists(struct drm_device *dev) + return warned = err; + } + #endif /* WATCH_INACTIVE */ +- +-#if WATCH_COHERENCY +-void +-i915_gem_object_check_coherency(struct drm_i915_gem_object *obj, int handle) +-{ +- struct drm_device *dev = obj->base.dev; +- int page; +- uint32_t *gtt_mapping; +- uint32_t *backing_map = NULL; +- int bad_count = 0; +- +- DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %zdkb):\n", +- __func__, obj, obj->gtt_offset, handle, +- obj->size / 1024); +- +- gtt_mapping = ioremap(dev_priv->mm.gtt_base_addr + obj->gtt_offset, +- obj->base.size); +- if (gtt_mapping == NULL) { +- DRM_ERROR("failed to map GTT space\n"); +- return; +- } +- +- for (page = 0; page < obj->size / PAGE_SIZE; page++) { +- int i; +- +- backing_map = kmap_atomic(obj->pages[page]); +- +- if (backing_map == NULL) { +- DRM_ERROR("failed to map backing page\n"); +- goto out; +- } +- +- for (i = 0; i < PAGE_SIZE / 4; i++) { +- uint32_t cpuval = backing_map[i]; +- uint32_t gttval = readl(gtt_mapping + +- page * 1024 + i); +- +- if (cpuval != gttval) { +- DRM_INFO("incoherent CPU vs GPU at 0x%08x: " +- "0x%08x vs 0x%08x\n", +- (int)(obj->gtt_offset + +- page * PAGE_SIZE + i * 4), +- cpuval, gttval); +- if (bad_count++ >= 8) { +- DRM_INFO("...\n"); +- goto out; +- } +- } +- } +- kunmap_atomic(backing_map); +- backing_map = NULL; +- } +- +- out: +- if (backing_map != NULL) +- kunmap_atomic(backing_map); +- iounmap(gtt_mapping); +- +- /* give syslog time to catch up */ +- msleep(1); +- +- /* Directly flush the object, since we just loaded values with the CPU +- * from the backing pages and we don't want to disturb the cache +- * management that we're trying to observe. +- */ +- +- i915_gem_clflush_object(obj); +-} +-#endif +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0643-drm-i915-Fix-endif-comment.patch b/patches.baytrail/0643-drm-i915-Fix-endif-comment.patch new file mode 100644 index 000000000000..d9341e1c9c54 --- /dev/null +++ b/patches.baytrail/0643-drm-i915-Fix-endif-comment.patch @@ -0,0 +1,28 @@ +From fe0f62608afa936f281a6b73366e5b90c8404916 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Thu, 8 Aug 2013 22:28:55 +0100 +Subject: drm/i915: Fix #endif comment + +Did you say OCD? + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit c55651b39a1fad0a6f07692971249eb54febfd73) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_debug.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c +index bcdbafc6c985..775d506b3208 100644 +--- a/drivers/gpu/drm/i915/i915_gem_debug.c ++++ b/drivers/gpu/drm/i915/i915_gem_debug.c +@@ -115,4 +115,4 @@ i915_verify_lists(struct drm_device *dev) + + return warned = err; + } +-#endif /* WATCH_INACTIVE */ ++#endif /* WATCH_LIST */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0644-drm-i915-Make-i915_hangcheck_elapsed-static.patch b/patches.baytrail/0644-drm-i915-Make-i915_hangcheck_elapsed-static.patch new file mode 100644 index 000000000000..4e156b8c1603 --- /dev/null +++ b/patches.baytrail/0644-drm-i915-Make-i915_hangcheck_elapsed-static.patch @@ -0,0 +1,42 @@ +From 67de679e26d2e85b2507dc41a7d292063b1697e2 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Thu, 8 Aug 2013 22:28:56 +0100 +Subject: drm/i915: Make i915_hangcheck_elapsed() static + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit a658b5d20de78435a971f26d56a765fb40f88e16) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 1 - + drivers/gpu/drm/i915/i915_irq.c | 2 +- + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 0be923ef08c6..6141253c8fda 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1665,7 +1665,6 @@ extern void intel_console_resume(struct work_struct *work); + + /* i915_irq.c */ + void i915_queue_hangcheck(struct drm_device *dev); +-void i915_hangcheck_elapsed(unsigned long data); + void i915_handle_error(struct drm_device *dev, bool wedged); + + extern void intel_irq_init(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 97f60282d397..076091e92eea 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1915,7 +1915,7 @@ ring_stuck(struct intel_ring_buffer *ring, u32 acthd) + * we kick the ring. If we see no progress on three subsequent calls + * we assume chip is wedged and try to fix it by resetting the chip. + */ +-void i915_hangcheck_elapsed(unsigned long data) ++static void i915_hangcheck_elapsed(unsigned long data) + { + struct drm_device *dev = (struct drm_device *)data; + drm_i915_private_t *dev_priv = dev->dev_private; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0645-drm-i915-Make-intel_encoder_dpms-static.patch b/patches.baytrail/0645-drm-i915-Make-intel_encoder_dpms-static.patch new file mode 100644 index 000000000000..aa45dadaada9 --- /dev/null +++ b/patches.baytrail/0645-drm-i915-Make-intel_encoder_dpms-static.patch @@ -0,0 +1,48 @@ +From 41b90a64e68e108407854ee96fae00f3fb36dd69 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Thu, 8 Aug 2013 22:28:57 +0100 +Subject: drm/i915: Make intel_encoder_dpms() static + +And also fix a small typo in the intel_encoder_dpms() comment. + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 9237329d83b04cfc7d9fc4608e9db84f32280dc4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 4 ++-- + drivers/gpu/drm/i915/intel_drv.h | 1 - + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index a5aee8993283..109a995150f9 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3889,10 +3889,10 @@ void intel_encoder_destroy(struct drm_encoder *encoder) + kfree(intel_encoder); + } + +-/* Simple dpms helper for encodres with just one connector, no cloning and only ++/* Simple dpms helper for encoders with just one connector, no cloning and only + * one kind of off state. It clamps all !ON modes to fully OFF and changes the + * state of the entire output pipe. */ +-void intel_encoder_dpms(struct intel_encoder *encoder, int mode) ++static void intel_encoder_dpms(struct intel_encoder *encoder, int mode) + { + if (mode == DRM_MODE_DPMS_ON) { + encoder->connectors_active = true; +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index d516c63fc94d..09c919658735 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -583,7 +583,6 @@ extern void intel_crtc_restore_mode(struct drm_crtc *crtc); + extern void intel_crtc_load_lut(struct drm_crtc *crtc); + extern void intel_crtc_update_dpms(struct drm_crtc *crtc); + extern void intel_encoder_destroy(struct drm_encoder *encoder); +-extern void intel_encoder_dpms(struct intel_encoder *encoder, int mode); + extern void intel_connector_dpms(struct drm_connector *, int mode); + extern bool intel_connector_get_hw_state(struct intel_connector *connector); + extern void intel_modeset_check_state(struct drm_device *dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0646-drm-i915-Remove-intel_modeset_disable.patch b/patches.baytrail/0646-drm-i915-Remove-intel_modeset_disable.patch new file mode 100644 index 000000000000..d190dd9809c0 --- /dev/null +++ b/patches.baytrail/0646-drm-i915-Remove-intel_modeset_disable.patch @@ -0,0 +1,52 @@ +From 6887dd8d7e46a2128312a07b5234dafa8fda7699 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Thu, 8 Aug 2013 22:28:58 +0100 +Subject: drm/i915: Remove intel_modeset_disable() + +Caught by the dead code police! + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 1414f6c0497acc9ca73f492d1cf2a2b87bed950b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 10 ---------- + drivers/gpu/drm/i915/intel_drv.h | 1 - + 2 files changed, 11 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 109a995150f9..e22728959c7b 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3871,16 +3871,6 @@ static void intel_crtc_disable(struct drm_crtc *crtc) + } + } + +-void intel_modeset_disable(struct drm_device *dev) +-{ +- struct drm_crtc *crtc; +- +- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { +- if (crtc->enabled) +- intel_crtc_disable(crtc); +- } +-} +- + void intel_encoder_destroy(struct drm_encoder *encoder) + { + struct intel_encoder *intel_encoder = to_intel_encoder(encoder); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 09c919658735..a70a0d04a0e5 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -578,7 +578,6 @@ struct intel_set_config { + + extern int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, + int x, int y, struct drm_framebuffer *old_fb); +-extern void intel_modeset_disable(struct drm_device *dev); + extern void intel_crtc_restore_mode(struct drm_crtc *crtc); + extern void intel_crtc_load_lut(struct drm_crtc *crtc); + extern void intel_crtc_update_dpms(struct drm_crtc *crtc); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0647-drm-i915-Make-intel_set_mode-static.patch b/patches.baytrail/0647-drm-i915-Make-intel_set_mode-static.patch new file mode 100644 index 000000000000..c3364a9f9b9c --- /dev/null +++ b/patches.baytrail/0647-drm-i915-Make-intel_set_mode-static.patch @@ -0,0 +1,58 @@ +From fb66b215d891d72b13330f7abae5aff71650a532 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Thu, 8 Aug 2013 22:28:59 +0100 +Subject: drm/i915: Make intel_set_mode() static + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit e7457a9a333a95e51dd77515eea326a181f968bc) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 10 +++++++--- + drivers/gpu/drm/i915/intel_drv.h | 2 -- + 2 files changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index e22728959c7b..77f8ff1a4284 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -50,6 +50,10 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, + static void ironlake_crtc_clock_get(struct intel_crtc *crtc, + struct intel_crtc_config *pipe_config); + ++static int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, ++ int x, int y, struct drm_framebuffer *old_fb); ++ ++ + typedef struct { + int min, max; + } intel_range_t; +@@ -8738,9 +8742,9 @@ out: + return ret; + } + +-int intel_set_mode(struct drm_crtc *crtc, +- struct drm_display_mode *mode, +- int x, int y, struct drm_framebuffer *fb) ++static int intel_set_mode(struct drm_crtc *crtc, ++ struct drm_display_mode *mode, ++ int x, int y, struct drm_framebuffer *fb) + { + int ret; + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index a70a0d04a0e5..01455aa8b8bb 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -576,8 +576,6 @@ struct intel_set_config { + bool mode_changed; + }; + +-extern int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, +- int x, int y, struct drm_framebuffer *old_fb); + extern void intel_crtc_restore_mode(struct drm_crtc *crtc); + extern void intel_crtc_load_lut(struct drm_crtc *crtc); + extern void intel_crtc_update_dpms(struct drm_crtc *crtc); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0648-drm-i915-unbreak-i915_gem_object_ggtt_unbind.patch b/patches.baytrail/0648-drm-i915-unbreak-i915_gem_object_ggtt_unbind.patch new file mode 100644 index 000000000000..76fa708feace --- /dev/null +++ b/patches.baytrail/0648-drm-i915-unbreak-i915_gem_object_ggtt_unbind.patch @@ -0,0 +1,41 @@ +From 594af4885f16dd82028d68adfa59af208d1395ee Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 9 Aug 2013 12:44:11 +0300 +Subject: drm/i915: unbreak i915_gem_object_ggtt_unbind() + +There is an extra semi-colon here so we just leak and never unbind +anything. + +This regression has been introduced in + +commit 07fe0b12800d4752d729d4122c01f41f80a5ba5a +Author: Ben Widawsky +Date: Wed Jul 31 17:00:10 2013 -0700 + + drm/i915: plumb VM into bind/unbind code + +Cc: Ben Widawsky +Signed-off-by: Dan Carpenter +Signed-off-by: Daniel Vetter +(cherry picked from commit 58e73e15708856540056050ae0798c322e43af18) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index f7ab763d6d76..498ef8a7bbc7 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2651,7 +2651,7 @@ i915_gem_object_ggtt_unbind(struct drm_i915_gem_object *obj) + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct i915_address_space *ggtt = &dev_priv->gtt.base; + +- if (!i915_gem_obj_ggtt_bound(obj)); ++ if (!i915_gem_obj_ggtt_bound(obj)) + return 0; + + if (obj->pin_count) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0649-drm-i915-fix-a-limit-check-in-hsw_compute_wm_results.patch b/patches.baytrail/0649-drm-i915-fix-a-limit-check-in-hsw_compute_wm_results.patch new file mode 100644 index 000000000000..dc0a3387cec4 --- /dev/null +++ b/patches.baytrail/0649-drm-i915-fix-a-limit-check-in-hsw_compute_wm_results.patch @@ -0,0 +1,44 @@ +From 8abb0f7511ce40ed1296dbb583f2163357f1624f Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 9 Aug 2013 13:07:31 +0300 +Subject: drm/i915: fix a limit check in hsw_compute_wm_results() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The '!' here was not intended. Since '!' has higher precedence than +compare, it means the check is never true. + +This regression was introduced in + +commit 71fff20ff1bb790f4defe0c880e028581ffab420 +Author: Ville Syrjälä +Date: Tue Aug 6 22:24:03 2013 +0300 + + drm/i915: Kill fbc_enable from hsw_lp_wm_results + +Signed-off-by: Dan Carpenter +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 16e54061ecc81df66e80ce96b3f91ae56065ed9e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 96234c6d982d..0f5eb217c707 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2685,7 +2685,7 @@ static void hsw_compute_wm_results(struct drm_device *dev, + * a WM level. */ + results->enable_fbc_wm = true; + for (level = 1; level <= max_level; level++) { +- if (!lp_results[level - 1].fbc_val > lp_maximums->fbc) { ++ if (lp_results[level - 1].fbc_val > lp_maximums->fbc) { + results->enable_fbc_wm = false; + lp_results[level - 1].fbc_val = 0; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0650-drm-i915-expose-HDMI-connectors-on-port-C-on-BYT.patch b/patches.baytrail/0650-drm-i915-expose-HDMI-connectors-on-port-C-on-BYT.patch new file mode 100644 index 000000000000..9075ab374547 --- /dev/null +++ b/patches.baytrail/0650-drm-i915-expose-HDMI-connectors-on-port-C-on-BYT.patch @@ -0,0 +1,44 @@ +From ced60c747ad2e5997adfbf2ce9a763b0ef36004c Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Fri, 9 Aug 2013 09:34:35 -0700 +Subject: drm/i915: expose HDMI connectors on port C on BYT + +Ryan noticed that on his board, HDMI was wired up to port C but not +exposed by the kernel, which had only expected DP on that port. Fix +that up by enumerating both ports if possible. + +Tested-by: "Matsumura, Ryan" +Acked-by: Chris Wilson +Signed-off-by: Jesse Barnes +[danvet: Fix up the whitespace fail. Tsk.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 6f6005a52b79c2b2e3d58d8ab63791c378ebf82c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 77f8ff1a4284..ee85aeab5667 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -9341,8 +9341,13 @@ static void intel_setup_outputs(struct drm_device *dev) + intel_dp_init(dev, PCH_DP_D, PORT_D); + } else if (IS_VALLEYVIEW(dev)) { + /* Check for built-in panel first. Shares lanes with HDMI on SDVOC */ +- if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED) +- intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, PORT_C); ++ if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED) { ++ intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC, ++ PORT_C); ++ if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED) ++ intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, ++ PORT_C); ++ } + + if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED) { + intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIB, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0651-drm-i915-Fix-FB-WM-for-HSW.patch b/patches.baytrail/0651-drm-i915-Fix-FB-WM-for-HSW.patch new file mode 100644 index 000000000000..7959bb80f528 --- /dev/null +++ b/patches.baytrail/0651-drm-i915-Fix-FB-WM-for-HSW.patch @@ -0,0 +1,45 @@ +From bb7e32d588b7a57137b805adba274d7c845ee138 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 9 Aug 2013 18:02:09 +0300 +Subject: drm/i915: Fix FB WM for HSW +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Due to a misplaced memset(), we never actually enabled the FBC WM on HSW. +Move the memset() to happen a bit earlier, so that it won't clobber +results->enable_fbc_wm. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 5c536613d8ebda3da0448550d0a997651a6048e2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 0f5eb217c707..4800bab89df1 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -2681,6 +2681,8 @@ static void hsw_compute_wm_results(struct drm_device *dev, + break; + max_level = level - 1; + ++ memset(results, 0, sizeof(*results)); ++ + /* The spec says it is preferred to disable FBC WMs instead of disabling + * a WM level. */ + results->enable_fbc_wm = true; +@@ -2691,7 +2693,6 @@ static void hsw_compute_wm_results(struct drm_device *dev, + } + } + +- memset(results, 0, sizeof(*results)); + for (wm_lp = 1; wm_lp <= 3; wm_lp++) { + const struct intel_wm_level *r; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0652-drm-i915-Update-rules-for-reading-cache-lines-throug.patch b/patches.baytrail/0652-drm-i915-Update-rules-for-reading-cache-lines-throug.patch new file mode 100644 index 000000000000..84d1103a1245 --- /dev/null +++ b/patches.baytrail/0652-drm-i915-Update-rules-for-reading-cache-lines-throug.patch @@ -0,0 +1,96 @@ +From 3b20739e9d8e9b0341710449bb63a7090b7c8729 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Thu, 8 Aug 2013 14:41:03 +0100 +Subject: drm/i915: Update rules for reading cache lines through the LLC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The LLC is a fun device. The cache is a distinct functional block within +the SA that arbitrates access from both the CPU and GPU cores. As such +all writes to memory land first in the LLC before further action is +taken. For example, an uncached write from either the CPU or GPU will +then proceed to memory and evict the cacheline from the LLC. This means that +a read from the LLC always returns the correct information even if the PTE +bit in the GPU differs from the PAT bit in the CPU. For the older +snooping architecture on non-LLC, the fundamental principle still holds +except that some coordination is required between the CPU and GPU to +explicitly perform the snooping (which is handled by our request +tracking). + +The upshot of this is that we know that we can issue a read from either +LLC devices or snoopable memory and trust the contents of the cache - +i.e. we can forgo a clflush before a read in these circumstances. +Writing to memory from the CPU is a little more tricky as we have to +consider that the scanout does not read from the CPU cache at all, but +from main memory. So we have to currently treat all requests to write to +uncached memory as having to be flushed to main memory for coherency +with all consumers. + +Signed-off-by: Chris Wilson +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit c76ce038e31a2b30bc3dd816f0aefaf685097a0a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 498ef8a7bbc7..50200b5e501b 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -62,6 +62,12 @@ static long i915_gem_purge(struct drm_i915_private *dev_priv, long target); + static void i915_gem_shrink_all(struct drm_i915_private *dev_priv); + static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); + ++static bool cpu_cache_is_coherent(struct drm_device *dev, ++ enum i915_cache_level level) ++{ ++ return HAS_LLC(dev) || level != I915_CACHE_NONE; ++} ++ + static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj) + { + if (obj->tiling_mode) +@@ -414,8 +420,7 @@ i915_gem_shmem_pread(struct drm_device *dev, + * read domain and manually flush cachelines (if required). This + * optimizes for the case when the gpu will dirty the data + * anyway again before the next pread happens. */ +- if (obj->cache_level == I915_CACHE_NONE) +- needs_clflush = 1; ++ needs_clflush = !cpu_cache_is_coherent(dev, obj->cache_level); + if (i915_gem_obj_bound_any(obj)) { + ret = i915_gem_object_set_to_gtt_domain(obj, false); + if (ret) +@@ -739,11 +744,11 @@ i915_gem_shmem_pwrite(struct drm_device *dev, + return ret; + } + } +- /* Same trick applies for invalidate partially written cachelines before +- * writing. */ +- if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU) +- && obj->cache_level == I915_CACHE_NONE) +- needs_clflush_before = 1; ++ /* Same trick applies to invalidate partially written cachelines read ++ * before writing. */ ++ if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) ++ needs_clflush_before = ++ !cpu_cache_is_coherent(dev, obj->cache_level); + + ret = i915_gem_object_get_pages(obj); + if (ret) +@@ -3585,7 +3590,8 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) + + /* Flush the CPU cache if it's still invalid. */ + if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) { +- i915_gem_clflush_object(obj); ++ if (!cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) ++ i915_gem_clflush_object(obj); + + obj->base.read_domains |= I915_GEM_DOMAIN_CPU; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0653-drm-i915-Track-when-an-object-is-pinned-for-use-by-t.patch b/patches.baytrail/0653-drm-i915-Track-when-an-object-is-pinned-for-use-by-t.patch new file mode 100644 index 000000000000..c790e05a93d5 --- /dev/null +++ b/patches.baytrail/0653-drm-i915-Track-when-an-object-is-pinned-for-use-by-t.patch @@ -0,0 +1,180 @@ +From 45b9d676a89b2f6c778f8ba0cc54e5a24925c613 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Fri, 9 Aug 2013 12:25:09 +0100 +Subject: drm/i915: Track when an object is pinned for use by the display + engine +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The display engine has unique coherency rules such that it requires +special handling to ensure that all writes to cursors, scanouts and +sprites are clflushed. This patch introduces the infrastructure to +simply track when an object is being accessed by the display engine. + +v2: Explain the is_pin_display() magic as the sources for obj->pin_count +and their individual rules is not obvious. (Ville) + +Signed-off-by: Chris Wilson +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit cc98b413c197c4c6a62b1e469e9d05e613571af5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 2 ++ + drivers/gpu/drm/i915/i915_drv.h | 2 ++ + drivers/gpu/drm/i915/i915_gem.c | 36 ++++++++++++++++++++++++++++++++++-- + drivers/gpu/drm/i915/intel_display.c | 8 ++++---- + 4 files changed, 42 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 1a87cc9fd899..eb87865c20d4 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -117,6 +117,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) + seq_printf(m, " (name: %d)", obj->base.name); + if (obj->pin_count) + seq_printf(m, " (pinned x %d)", obj->pin_count); ++ if (obj->pin_display) ++ seq_printf(m, " (display)"); + if (obj->fence_reg != I915_FENCE_REG_NONE) + seq_printf(m, " (fence: %d)", obj->fence_reg); + list_for_each_entry(vma, &obj->vma_list, vma_link) { +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 6141253c8fda..cbb35a09ad7d 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1377,6 +1377,7 @@ struct drm_i915_gem_object { + */ + unsigned int fault_mappable:1; + unsigned int pin_mappable:1; ++ unsigned int pin_display:1; + + /* + * Is the GPU currently using a fence to access this buffer, +@@ -1866,6 +1867,7 @@ int __must_check + i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, + u32 alignment, + struct intel_ring_buffer *pipelined); ++void i915_gem_object_unpin_from_display_plane(struct drm_i915_gem_object *obj); + int i915_gem_attach_phys_object(struct drm_device *dev, + struct drm_i915_gem_object *obj, + int id, +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 50200b5e501b..46f007cd7f87 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3489,6 +3489,22 @@ unlock: + return ret; + } + ++static bool is_pin_display(struct drm_i915_gem_object *obj) ++{ ++ /* There are 3 sources that pin objects: ++ * 1. The display engine (scanouts, sprites, cursors); ++ * 2. Reservations for execbuffer; ++ * 3. The user. ++ * ++ * We can ignore reservations as we hold the struct_mutex and ++ * are only called outside of the reservation path. The user ++ * can only increment pin_count once, and so if after ++ * subtracting the potential reference by the user, any pin_count ++ * remains, it must be due to another use by the display engine. ++ */ ++ return obj->pin_count - !!obj->user_pin_count; ++} ++ + /* + * Prepare buffer for display plane (scanout, cursors, etc). + * Can be called from an uninterruptible phase (modesetting) and allows +@@ -3508,6 +3524,11 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, + return ret; + } + ++ /* Mark the pin_display early so that we account for the ++ * display coherency whilst setting up the cache domains. ++ */ ++ obj->pin_display = true; ++ + /* The display engine is not coherent with the LLC cache on gen6. As + * a result, we make sure that the pinning that is about to occur is + * done with uncached PTEs. This is lowest common denominator for all +@@ -3519,7 +3540,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, + */ + ret = i915_gem_object_set_cache_level(obj, I915_CACHE_NONE); + if (ret) +- return ret; ++ goto err_unpin_display; + + /* As the user may map the buffer once pinned in the display plane + * (e.g. libkms for the bootup splash), we have to ensure that we +@@ -3527,7 +3548,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, + */ + ret = i915_gem_obj_ggtt_pin(obj, alignment, true, false); + if (ret) +- return ret; ++ goto err_unpin_display; + + i915_gem_object_flush_cpu_write_domain(obj); + +@@ -3545,6 +3566,17 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, + old_write_domain); + + return 0; ++ ++err_unpin_display: ++ obj->pin_display = is_pin_display(obj); ++ return ret; ++} ++ ++void ++i915_gem_object_unpin_from_display_plane(struct drm_i915_gem_object *obj) ++{ ++ i915_gem_object_unpin(obj); ++ obj->pin_display = is_pin_display(obj); + } + + int +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index ee85aeab5667..65bc851f5f91 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1877,7 +1877,7 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, + return 0; + + err_unpin: +- i915_gem_object_unpin(obj); ++ i915_gem_object_unpin_from_display_plane(obj); + err_interruptible: + dev_priv->mm.interruptible = true; + return ret; +@@ -1886,7 +1886,7 @@ err_interruptible: + void intel_unpin_fb_obj(struct drm_i915_gem_object *obj) + { + i915_gem_object_unpin_fence(obj); +- i915_gem_object_unpin(obj); ++ i915_gem_object_unpin_from_display_plane(obj); + } + + /* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel +@@ -6763,7 +6763,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, + if (intel_crtc->cursor_bo != obj) + i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); + } else +- i915_gem_object_unpin(intel_crtc->cursor_bo); ++ i915_gem_object_unpin_from_display_plane(intel_crtc->cursor_bo); + drm_gem_object_unreference(&intel_crtc->cursor_bo->base); + } + +@@ -6778,7 +6778,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, + + return 0; + fail_unpin: +- i915_gem_object_unpin(obj); ++ i915_gem_object_unpin_from_display_plane(obj); + fail_locked: + mutex_unlock(&dev->struct_mutex); + fail: +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0654-drm-i915-Update-rules-for-writing-through-the-LLC-wi.patch b/patches.baytrail/0654-drm-i915-Update-rules-for-writing-through-the-LLC-wi.patch new file mode 100644 index 000000000000..cd1848e4c3ce --- /dev/null +++ b/patches.baytrail/0654-drm-i915-Update-rules-for-writing-through-the-LLC-wi.patch @@ -0,0 +1,265 @@ +From 52ae6dfe428aa66fb70c6771ec325f7c64a2ea91 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Fri, 9 Aug 2013 12:26:45 +0100 +Subject: drm/i915: Update rules for writing through the LLC with the cpu +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +As mentioned in the previous commit, reads and writes from both the CPU +and GPU go through the LLC. This gives us coherency between the CPU and +GPU irrespective of the attribute settings either device sets. We can +use to avoid having to clflush even uncached memory. + +Except for the scanout. + +The scanout resides within another functional block that does not use +the LLC but reads directly from main memory. So in order to maintain +coherency with the scanout, writes to uncached memory must be flushed. +In order to optimize writes elsewhere, we start tracking whether an +framebuffer is attached to an object. + +v2: Use pin_display tracking rather than fb_count (to ensure we flush +cursors as well etc) and only force the clflush along explicit writes to +the scanout paths (i.e. pin_to_display_plane and pwrite into scanout). + +v3: Force the flush after hitting the slowpath in pwrite, as after +dropping the lock the object's cache domain may be invalidated. (Ville) + +Based on a patch by Ville Syrjälä. + +Signed-off-by: Chris Wilson +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 2c22569bba8af6c2976d5f9479fe54a53a39966b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 +- + drivers/gpu/drm/i915/i915_gem.c | 58 ++++++++++++++++-------------- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- + drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- + 4 files changed, 35 insertions(+), 29 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index cbb35a09ad7d..d25f9f712b6f 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1840,7 +1840,7 @@ static inline bool i915_terminally_wedged(struct i915_gpu_error *error) + } + + void i915_gem_reset(struct drm_device *dev); +-void i915_gem_clflush_object(struct drm_i915_gem_object *obj); ++void i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force); + int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); + int __must_check i915_gem_init(struct drm_device *dev); + int __must_check i915_gem_init_hw(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 46f007cd7f87..ce4a8c4e42ac 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -38,7 +38,8 @@ + #include + + static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); +-static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); ++static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj, ++ bool force); + static __must_check int + i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, + struct i915_address_space *vm, +@@ -68,6 +69,14 @@ static bool cpu_cache_is_coherent(struct drm_device *dev, + return HAS_LLC(dev) || level != I915_CACHE_NONE; + } + ++static bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj) ++{ ++ if (!cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) ++ return true; ++ ++ return obj->pin_display; ++} ++ + static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj) + { + if (obj->tiling_mode) +@@ -736,8 +745,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev, + * write domain and manually flush cachelines (if required). This + * optimizes for the case when the gpu will use the data + * right away and we therefore have to clflush anyway. */ +- if (obj->cache_level == I915_CACHE_NONE) +- needs_clflush_after = 1; ++ needs_clflush_after = cpu_write_needs_clflush(obj); + if (i915_gem_obj_bound_any(obj)) { + ret = i915_gem_object_set_to_gtt_domain(obj, true); + if (ret) +@@ -827,7 +835,7 @@ out: + */ + if (!needs_clflush_after && + obj->base.write_domain != I915_GEM_DOMAIN_CPU) { +- i915_gem_clflush_object(obj); ++ i915_gem_clflush_object(obj, obj->pin_display); + i915_gem_chipset_flush(dev); + } + } +@@ -905,9 +913,9 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, + goto out; + } + +- if (obj->cache_level == I915_CACHE_NONE && +- obj->tiling_mode == I915_TILING_NONE && +- obj->base.write_domain != I915_GEM_DOMAIN_CPU) { ++ if (obj->tiling_mode == I915_TILING_NONE && ++ obj->base.write_domain != I915_GEM_DOMAIN_CPU && ++ cpu_write_needs_clflush(obj)) { + ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file); + /* Note that the gtt paths might fail with non-page-backed user + * pointers (e.g. gtt mappings when moving data between +@@ -1256,8 +1264,8 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, + } + + /* Pinned buffers may be scanout, so flush the cache */ +- if (obj->pin_count) +- i915_gem_object_flush_cpu_write_domain(obj); ++ if (obj->pin_display) ++ i915_gem_object_flush_cpu_write_domain(obj, true); + + drm_gem_object_unreference(&obj->base); + unlock: +@@ -1627,7 +1635,7 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) + * hope for the best. + */ + WARN_ON(ret != -EIO); +- i915_gem_clflush_object(obj); ++ i915_gem_clflush_object(obj, true); + obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU; + } + +@@ -3205,7 +3213,8 @@ err_unpin: + } + + void +-i915_gem_clflush_object(struct drm_i915_gem_object *obj) ++i915_gem_clflush_object(struct drm_i915_gem_object *obj, ++ bool force) + { + /* If we don't have a page list set up, then we're not pinned + * to GPU, and we can ignore the cache flush because it'll happen +@@ -3229,7 +3238,7 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj) + * snooping behaviour occurs naturally as the result of our domain + * tracking. + */ +- if (obj->cache_level != I915_CACHE_NONE) ++ if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) + return; + + trace_i915_gem_object_clflush(obj); +@@ -3266,14 +3275,15 @@ i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj) + + /** Flushes the CPU write domain for the object if it's dirty. */ + static void +-i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj) ++i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj, ++ bool force) + { + uint32_t old_write_domain; + + if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) + return; + +- i915_gem_clflush_object(obj); ++ i915_gem_clflush_object(obj, force); + i915_gem_chipset_flush(obj->base.dev); + old_write_domain = obj->base.write_domain; + obj->base.write_domain = 0; +@@ -3307,7 +3317,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) + if (ret) + return ret; + +- i915_gem_object_flush_cpu_write_domain(obj); ++ i915_gem_object_flush_cpu_write_domain(obj, false); + + /* Serialise direct access to this object with the barriers for + * coherent writes from the GPU, by effectively invalidating the +@@ -3397,7 +3407,11 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + obj, cache_level); + } + +- if (cache_level == I915_CACHE_NONE) { ++ list_for_each_entry(vma, &obj->vma_list, vma_link) ++ vma->node.color = cache_level; ++ obj->cache_level = cache_level; ++ ++ if (cpu_write_needs_clflush(obj)) { + u32 old_read_domains, old_write_domain; + + /* If we're coming from LLC cached, then we haven't +@@ -3420,9 +3434,6 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + old_write_domain); + } + +- list_for_each_entry(vma, &obj->vma_list, vma_link) +- vma->node.color = cache_level; +- obj->cache_level = cache_level; + i915_gem_verify_gtt(dev); + return 0; + } +@@ -3550,7 +3561,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, + if (ret) + goto err_unpin_display; + +- i915_gem_object_flush_cpu_write_domain(obj); ++ i915_gem_object_flush_cpu_write_domain(obj, true); + + old_write_domain = obj->base.write_domain; + old_read_domains = obj->base.read_domains; +@@ -3622,8 +3633,7 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) + + /* Flush the CPU cache if it's still invalid. */ + if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) { +- if (!cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) +- i915_gem_clflush_object(obj); ++ i915_gem_clflush_object(obj, false); + + obj->base.read_domains |= I915_GEM_DOMAIN_CPU; + } +@@ -3805,10 +3815,6 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, + obj->user_pin_count++; + obj->pin_filp = file; + +- /* XXX - flush the CPU caches for pinned objects +- * as the X server doesn't manage domains yet +- */ +- i915_gem_object_flush_cpu_write_domain(obj); + args->offset = i915_gem_obj_ggtt_offset(obj); + out: + drm_gem_object_unreference(&obj->base); +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 8ccc29ac9629..e999578a021c 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -716,7 +716,7 @@ i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, + return ret; + + if (obj->base.write_domain & I915_GEM_DOMAIN_CPU) +- i915_gem_clflush_object(obj); ++ i915_gem_clflush_object(obj, false); + + flush_domains |= obj->base.write_domain; + } +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index 24fb989593f0..c9420c280cf0 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -487,7 +487,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) + dev_priv->gtt.base.total / PAGE_SIZE); + + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { +- i915_gem_clflush_object(obj); ++ i915_gem_clflush_object(obj, obj->pin_display); + i915_gem_gtt_bind_object(obj, obj->cache_level); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0655-drm-i915-Allow-the-GPU-to-cache-stolen-memory.patch b/patches.baytrail/0655-drm-i915-Allow-the-GPU-to-cache-stolen-memory.patch new file mode 100644 index 000000000000..98653844afec --- /dev/null +++ b/patches.baytrail/0655-drm-i915-Allow-the-GPU-to-cache-stolen-memory.patch @@ -0,0 +1,43 @@ +From bb6729beb868d5d75aac9998fc3fa8e4f32aa337 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Thu, 8 Aug 2013 14:41:06 +0100 +Subject: drm/i915: Allow the GPU to cache stolen memory +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +As a corollary to reviewing the interaction between LLC and our cache +domains, the GPU PTE bits are independent of the CPU PAT bits. As such +we can set the cache level on stolen memory based on how we wish the GPU +to cache accesses to it. So we are free to set the same default cache +levels as for normal bo, i.e. enable LLC cacheing by default where +appropriate. + +Signed-off-by: Chris Wilson +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit d46f1c3f1372e3a72fab97c60480aa4a1084387f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_stolen.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 8912f489f53a..8b03327f74b9 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -296,9 +296,8 @@ _i915_gem_object_create_stolen(struct drm_device *dev, + i915_gem_object_pin_pages(obj); + obj->stolen = stolen; + +- obj->base.write_domain = I915_GEM_DOMAIN_GTT; +- obj->base.read_domains = I915_GEM_DOMAIN_GTT; +- obj->cache_level = I915_CACHE_NONE; ++ obj->base.read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT; ++ obj->cache_level = HAS_LLC(dev) ? I915_CACHE_LLC : I915_CACHE_NONE; + + return obj; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0656-drm-kill-dev-context_wait.patch b/patches.baytrail/0656-drm-kill-dev-context_wait.patch new file mode 100644 index 000000000000..abd9465fba33 --- /dev/null +++ b/patches.baytrail/0656-drm-kill-dev-context_wait.patch @@ -0,0 +1,57 @@ +From 94034b5c8b3b11fae675984f2a23795a8bebd9ad Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 10 Jul 2013 14:11:36 +0200 +Subject: drm: kill dev->context_wait + +No one ever waits on this waitqueue, so the wake_up call is wasted. +Remove it all. + +Signed-off-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit 3dadef6c96c8aa6e67f83b30504256a0605ee4d6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_context.c | 1 - + drivers/gpu/drm/drm_fops.c | 1 - + include/drm/drmP.h | 1 - + 3 files changed, 3 deletions(-) + +diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c +index 725968d38976..06dd419f6dfe 100644 +--- a/drivers/gpu/drm/drm_context.c ++++ b/drivers/gpu/drm/drm_context.c +@@ -261,7 +261,6 @@ static int drm_context_switch_complete(struct drm_device *dev, + when the kernel holds the lock, release + that lock here. */ + clear_bit(0, &dev->context_flag); +- wake_up(&dev->context_wait); + + return 0; + } +diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c +index 429e07d0b0f1..23857605a987 100644 +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -81,7 +81,6 @@ static int drm_setup(struct drm_device * dev) + dev->last_context = 0; + dev->last_switch = 0; + dev->last_checked = 0; +- init_waitqueue_head(&dev->context_wait); + dev->if_version = 0; + + dev->ctx_start = 0; +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 70de499fa3b7..45ab45426cdb 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1132,7 +1132,6 @@ struct drm_device { + __volatile__ long context_flag; /**< Context swapping flag */ + __volatile__ long interrupt_flag; /**< Interruption handler flag */ + __volatile__ long dma_flag; /**< DMA dispatch flag */ +- wait_queue_head_t context_wait; /**< Processes waiting on ctx switch */ + int last_checked; /**< Last context checked for DMA */ + int last_context; /**< Last current context */ + unsigned long last_switch; /**< jiffies at last context switch */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0657-drm-remove-dev-last_switch.patch b/patches.baytrail/0657-drm-remove-dev-last_switch.patch new file mode 100644 index 000000000000..9071ffde337e --- /dev/null +++ b/patches.baytrail/0657-drm-remove-dev-last_switch.patch @@ -0,0 +1,57 @@ +From 9b650bcf3ced86b0c94fabd20741a0997412de04 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 10 Jul 2013 14:11:37 +0200 +Subject: drm: remove dev->last_switch + +Only ever assigned in the context code for real, with no readers +anywhere. Remove it. + +Signed-off-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit a17800c70129d5976a52c42f04a16a0f1d9df4b2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_context.c | 1 - + drivers/gpu/drm/drm_fops.c | 1 - + include/drm/drmP.h | 1 - + 3 files changed, 3 deletions(-) + +diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c +index 06dd419f6dfe..2857fa2f9191 100644 +--- a/drivers/gpu/drm/drm_context.c ++++ b/drivers/gpu/drm/drm_context.c +@@ -251,7 +251,6 @@ static int drm_context_switch_complete(struct drm_device *dev, + struct drm_file *file_priv, int new) + { + dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ +- dev->last_switch = jiffies; + + if (!_DRM_LOCK_IS_HELD(file_priv->master->lock.hw_lock->lock)) { + DRM_ERROR("Lock isn't held after context switch\n"); +diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c +index 23857605a987..68d0be794d5d 100644 +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -79,7 +79,6 @@ static int drm_setup(struct drm_device * dev) + dev->interrupt_flag = 0; + dev->dma_flag = 0; + dev->last_context = 0; +- dev->last_switch = 0; + dev->last_checked = 0; + dev->if_version = 0; + +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 45ab45426cdb..9aa0445edb1f 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1134,7 +1134,6 @@ struct drm_device { + __volatile__ long dma_flag; /**< DMA dispatch flag */ + int last_checked; /**< Last context checked for DMA */ + int last_context; /**< Last current context */ +- unsigned long last_switch; /**< jiffies at last context switch */ + /*@} */ + + struct work_struct work; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0658-drm-kill-dev-interrupt_flag-and-dev-dma_flag.patch b/patches.baytrail/0658-drm-kill-dev-interrupt_flag-and-dev-dma_flag.patch new file mode 100644 index 000000000000..e8815b5cd4f3 --- /dev/null +++ b/patches.baytrail/0658-drm-kill-dev-interrupt_flag-and-dev-dma_flag.patch @@ -0,0 +1,45 @@ +From 3313d28301f1fbe0d4726b54c4c356124cdd3631 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 10 Jul 2013 14:11:38 +0200 +Subject: drm: kill dev->interrupt_flag and dev->dma_flag + +Completely unused, so just remove them. + +Signed-off-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit c78d7531031cb6d163e7450bda563c267beef777) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_fops.c | 2 -- + include/drm/drmP.h | 2 -- + 2 files changed, 4 deletions(-) + +diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c +index 68d0be794d5d..2f3b6fcaec0b 100644 +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -76,8 +76,6 @@ static int drm_setup(struct drm_device * dev) + dev->sigdata.lock = NULL; + + dev->context_flag = 0; +- dev->interrupt_flag = 0; +- dev->dma_flag = 0; + dev->last_context = 0; + dev->last_checked = 0; + dev->if_version = 0; +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 9aa0445edb1f..bc802174f3e5 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1130,8 +1130,6 @@ struct drm_device { + /*@{ */ + int irq_enabled; /**< True if irq handler is enabled */ + __volatile__ long context_flag; /**< Context swapping flag */ +- __volatile__ long interrupt_flag; /**< Interruption handler flag */ +- __volatile__ long dma_flag; /**< DMA dispatch flag */ + int last_checked; /**< Last context checked for DMA */ + int last_context; /**< Last current context */ + /*@} */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0659-drm-kill-dev-ctx_start-and-dev-lck_start.patch b/patches.baytrail/0659-drm-kill-dev-ctx_start-and-dev-lck_start.patch new file mode 100644 index 000000000000..3f38180f391b --- /dev/null +++ b/patches.baytrail/0659-drm-kill-dev-ctx_start-and-dev-lck_start.patch @@ -0,0 +1,46 @@ +From b0f54798edd95f9d1ed472bd5496ac424dce6ff4 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 10 Jul 2013 14:11:39 +0200 +Subject: drm: kill dev->ctx_start and dev->lck_start + +Again completely unused, so just remove it. + +Signed-off-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit c7e00b6d6a08772fac43b0fcea7fb48e6a1fe390) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_fops.c | 3 --- + include/drm/drmP.h | 2 -- + 2 files changed, 5 deletions(-) + +diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c +index 2f3b6fcaec0b..cdda3951ff03 100644 +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -80,9 +80,6 @@ static int drm_setup(struct drm_device * dev) + dev->last_checked = 0; + dev->if_version = 0; + +- dev->ctx_start = 0; +- dev->lck_start = 0; +- + dev->buf_async = NULL; + init_waitqueue_head(&dev->buf_readers); + init_waitqueue_head(&dev->buf_writers); +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index bc802174f3e5..952478cd3ec3 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1169,8 +1169,6 @@ struct drm_device { + spinlock_t event_lock; + + /*@} */ +- cycles_t ctx_start; +- cycles_t lck_start; + + struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */ + wait_queue_head_t buf_readers; /**< Processes waiting to read */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0660-drm-kill-dev-buf_readers-and-dev-buf_writers.patch b/patches.baytrail/0660-drm-kill-dev-buf_readers-and-dev-buf_writers.patch new file mode 100644 index 000000000000..e0810f960133 --- /dev/null +++ b/patches.baytrail/0660-drm-kill-dev-buf_readers-and-dev-buf_writers.patch @@ -0,0 +1,45 @@ +From 1e9073ae96ede82e475d14bc90023b1a0055ee94 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 10 Jul 2013 14:11:41 +0200 +Subject: drm: kill dev->buf_readers and dev->buf_writers + +Again totally unused, so just remove them. + +Signed-off-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit 494f38e4e0c5ffca110e361cd3391f25313b52c7) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_fops.c | 2 -- + include/drm/drmP.h | 2 -- + 2 files changed, 4 deletions(-) + +diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c +index cdda3951ff03..2f86ccb86dfc 100644 +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -81,8 +81,6 @@ static int drm_setup(struct drm_device * dev) + dev->if_version = 0; + + dev->buf_async = NULL; +- init_waitqueue_head(&dev->buf_readers); +- init_waitqueue_head(&dev->buf_writers); + + DRM_DEBUG("\n"); + +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 952478cd3ec3..a47fec92c6ca 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1171,8 +1171,6 @@ struct drm_device { + /*@} */ + + struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */ +- wait_queue_head_t buf_readers; /**< Processes waiting to read */ +- wait_queue_head_t buf_writers; /**< Processes waiting to ctx switch */ + + struct drm_agp_head *agp; /**< AGP data */ + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0661-drm-rip-out-dev-last_checked.patch b/patches.baytrail/0661-drm-rip-out-dev-last_checked.patch new file mode 100644 index 000000000000..6145522f3fc5 --- /dev/null +++ b/patches.baytrail/0661-drm-rip-out-dev-last_checked.patch @@ -0,0 +1,43 @@ +From b3382b844bdb6a30e466f30cc1bb09770aa5a33d Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 10 Jul 2013 17:51:10 +0200 +Subject: drm: rip out dev->last_checked + +Only ever re-cleared in drm_setup, otherwise completely unused. + +Signed-off-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit 23367ff49065505e4a255dba2117f654ca26063f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_fops.c | 1 - + include/drm/drmP.h | 1 - + 2 files changed, 2 deletions(-) + +diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c +index 2f86ccb86dfc..8b3eac08b48d 100644 +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -77,7 +77,6 @@ static int drm_setup(struct drm_device * dev) + + dev->context_flag = 0; + dev->last_context = 0; +- dev->last_checked = 0; + dev->if_version = 0; + + dev->buf_async = NULL; +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index a47fec92c6ca..f8ad91bc0f94 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1130,7 +1130,6 @@ struct drm_device { + /*@{ */ + int irq_enabled; /**< True if irq handler is enabled */ + __volatile__ long context_flag; /**< Context swapping flag */ +- int last_checked; /**< Last context checked for DMA */ + int last_context; /**< Last current context */ + /*@} */ + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0662-drm-remove-FASYNC-support.patch b/patches.baytrail/0662-drm-remove-FASYNC-support.patch new file mode 100644 index 000000000000..241e4871b370 --- /dev/null +++ b/patches.baytrail/0662-drm-remove-FASYNC-support.patch @@ -0,0 +1,444 @@ +From 6da1d503e7426a88139cb8f6e8b6fb1a412a036a Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 8 Aug 2013 15:41:23 +0200 +Subject: drm: remove FASYNC support + +So I've stumbled over drm_fasync and wondered what it does. Digging +that up is quite a story. + +First I've had to read up on what this does and ended up being rather +bewildered why peopled loved signals so much back in the days that +they've created SIGIO just for that ... + +Then I wondered how this ever works, and what that strange "No-op." +comment right above it should mean. After all calling the core fasync +helper is pretty obviously not a noop. After reading through the +kernels FASYNC implementation I've noticed that signals are only sent +out to the processes attached with FASYNC by calling kill_fasync. + +No merged drm driver has ever done that. + +After more digging I've found out that the only driver that ever used +this is the so called GAMMA driver. I've frankly never heard of such a +gpu brand ever before. Now FASYNC seems to not have been the only bad +thing with that driver, since Dave Airlie removed it from the drm +driver with prejudice: + +commit 1430163b4bbf7b00367ea1066c1c5fe85dbeefed +Author: Dave Airlie +Date: Sun Aug 29 12:04:35 2004 +0000 + + Drop GAMMA DRM from a great height ... + +Long story short, the drm fasync support seems to be doing absolutely +nothing. And the only user of it was never merged into the upstream +kernel. And we don't need any fops->fasync callback since the fcntl +implementation in the kernel already implements the noop case +correctly. + +So stop this particular cargo-cult and rip it all out. + +v2: Kill drm_fasync assignments in rcar (newly added) and imx drivers +(somehow I've missed that one in staging). Also drop the reference in +the drm DocBook. ARM compile-fail reported by Rob Clark. + +v3: Move the removal of dev->buf_asnyc assignment in drm_setup to this +patch here. + +v4: Actually git add ... tsk. + +Cc: Dave Airlie +Cc: Laurent Pinchart +Cc: Rob Clark +Acked-by: Laurent Pinchart +Signed-off-by: Daniel Vetter +Reviewed-by: David Herrmann +Signed-off-by: Dave Airlie +(cherry picked from commit b0e898ac555e96e7863a5ee95d70f3625f1db5e2) +Signed-off-by: James Ausmus + +Conflicts: + drivers/gpu/drm/rcar-du/rcar_du_drv.c + (driver not in this tree) +Signed-off-by: Darren Hart +--- + Documentation/DocBook/drm.tmpl | 1 - + drivers/gpu/drm/ast/ast_drv.c | 1 - + drivers/gpu/drm/cirrus/cirrus_drv.c | 1 - + drivers/gpu/drm/drm_fops.c | 14 -------------- + drivers/gpu/drm/gma500/psb_drv.c | 1 - + drivers/gpu/drm/i810/i810_dma.c | 1 - + drivers/gpu/drm/i810/i810_drv.c | 1 - + drivers/gpu/drm/i915/i915_drv.c | 1 - + drivers/gpu/drm/mga/mga_drv.c | 1 - + drivers/gpu/drm/mgag200/mgag200_drv.c | 1 - + drivers/gpu/drm/nouveau/nouveau_drm.c | 1 - + drivers/gpu/drm/omapdrm/omap_drv.c | 1 - + drivers/gpu/drm/qxl/qxl_drv.c | 1 - + drivers/gpu/drm/r128/r128_drv.c | 1 - + drivers/gpu/drm/radeon/radeon_drv.c | 2 -- + drivers/gpu/drm/savage/savage_drv.c | 1 - + drivers/gpu/drm/shmobile/shmob_drm_drv.c | 1 - + drivers/gpu/drm/sis/sis_drv.c | 1 - + drivers/gpu/drm/tdfx/tdfx_drv.c | 1 - + drivers/gpu/drm/tilcdc/tilcdc_drv.c | 1 - + drivers/gpu/drm/udl/udl_drv.c | 1 - + drivers/gpu/drm/via/via_drv.c | 1 - + drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 1 - + drivers/gpu/host1x/drm/drm.c | 1 - + drivers/staging/imx-drm/imx-drm-core.c | 1 - + include/drm/drmP.h | 3 --- + 26 files changed, 42 deletions(-) + +diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl +index ba664d7c5a89..da1e28263002 100644 +--- a/Documentation/DocBook/drm.tmpl ++++ b/Documentation/DocBook/drm.tmpl +@@ -2339,7 +2339,6 @@ void (*postclose) (struct drm_device *, struct drm_file *); + + .poll = drm_poll, + .read = drm_read, +- .fasync = drm_fasync, + .llseek = no_llseek, + + +diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c +index a144fb044852..60f1ce3998c3 100644 +--- a/drivers/gpu/drm/ast/ast_drv.c ++++ b/drivers/gpu/drm/ast/ast_drv.c +@@ -190,7 +190,6 @@ static const struct file_operations ast_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = ast_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + #ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, + #endif +diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c +index d35d99c15f84..dd9c908ab3fc 100644 +--- a/drivers/gpu/drm/cirrus/cirrus_drv.c ++++ b/drivers/gpu/drm/cirrus/cirrus_drv.c +@@ -85,7 +85,6 @@ static const struct file_operations cirrus_driver_fops = { + #ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, + #endif +- .fasync = drm_fasync, + }; + static struct drm_driver driver = { + .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_USE_MTRR, +diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c +index 8b3eac08b48d..88e80c37f568 100644 +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -79,8 +79,6 @@ static int drm_setup(struct drm_device * dev) + dev->last_context = 0; + dev->if_version = 0; + +- dev->buf_async = NULL; +- + DRM_DEBUG("\n"); + + /* +@@ -363,18 +361,6 @@ static int drm_open_helper(struct inode *inode, struct file *filp, + return ret; + } + +-/** No-op. */ +-int drm_fasync(int fd, struct file *filp, int on) +-{ +- struct drm_file *priv = filp->private_data; +- struct drm_device *dev = priv->minor->dev; +- +- DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, +- (long)old_encode_dev(priv->minor->device)); +- return fasync_helper(fd, filp, on, &dev->buf_async); +-} +-EXPORT_SYMBOL(drm_fasync); +- + static void drm_master_release(struct drm_device *dev, struct file *filp) + { + struct drm_file *file_priv = filp->private_data; +diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c +index d13c2fc848bc..99b5293972c6 100644 +--- a/drivers/gpu/drm/gma500/psb_drv.c ++++ b/drivers/gpu/drm/gma500/psb_drv.c +@@ -622,7 +622,6 @@ static const struct file_operations psb_gem_fops = { + .unlocked_ioctl = psb_unlocked_ioctl, + .mmap = drm_gem_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + .read = drm_read, + }; + +diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c +index 926ac7d48381..7f8b7a469ff8 100644 +--- a/drivers/gpu/drm/i810/i810_dma.c ++++ b/drivers/gpu/drm/i810/i810_dma.c +@@ -113,7 +113,6 @@ static const struct file_operations i810_buffer_fops = { + .release = drm_release, + .unlocked_ioctl = drm_ioctl, + .mmap = i810_mmap_buffers, +- .fasync = drm_fasync, + #ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, + #endif +diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c +index 2e91fc3580b4..d85c05b4877d 100644 +--- a/drivers/gpu/drm/i810/i810_drv.c ++++ b/drivers/gpu/drm/i810/i810_drv.c +@@ -49,7 +49,6 @@ static const struct file_operations i810_driver_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + #ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, + #endif +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 13457e3e9cad..9411a745adaf 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -994,7 +994,6 @@ static const struct file_operations i915_driver_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = drm_gem_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + .read = drm_read, + #ifdef CONFIG_COMPAT + .compat_ioctl = i915_compat_ioctl, +diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c +index 17d0a637e4fb..fe71e1e44e48 100644 +--- a/drivers/gpu/drm/mga/mga_drv.c ++++ b/drivers/gpu/drm/mga/mga_drv.c +@@ -50,7 +50,6 @@ static const struct file_operations mga_driver_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + #ifdef CONFIG_COMPAT + .compat_ioctl = mga_compat_ioctl, + #endif +diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c +index bd9196478735..b570127ae3b2 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_drv.c ++++ b/drivers/gpu/drm/mgag200/mgag200_drv.c +@@ -81,7 +81,6 @@ static const struct file_operations mgag200_driver_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = mgag200_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + #ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, + #endif +diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c +index 421815b1ef93..375ccf75fd73 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drm.c ++++ b/drivers/gpu/drm/nouveau/nouveau_drm.c +@@ -664,7 +664,6 @@ nouveau_driver_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = nouveau_ttm_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + .read = drm_read, + #if defined(CONFIG_COMPAT) + .compat_ioctl = nouveau_compat_ioctl, +diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c +index f69f9f6785e8..04b94dc38e2c 100644 +--- a/drivers/gpu/drm/omapdrm/omap_drv.c ++++ b/drivers/gpu/drm/omapdrm/omap_drv.c +@@ -583,7 +583,6 @@ static const struct file_operations omapdriver_fops = { + .release = drm_release, + .mmap = omap_gem_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + .read = drm_read, + .llseek = noop_llseek, + }; +diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c +index 60cb159c4f7d..c0302c5a397c 100644 +--- a/drivers/gpu/drm/qxl/qxl_drv.c ++++ b/drivers/gpu/drm/qxl/qxl_drv.c +@@ -86,7 +86,6 @@ static const struct file_operations qxl_fops = { + .release = drm_release, + .unlocked_ioctl = drm_ioctl, + .poll = drm_poll, +- .fasync = drm_fasync, + .mmap = qxl_mmap, + }; + +diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c +index 472c38fe123f..c2338cbc56ad 100644 +--- a/drivers/gpu/drm/r128/r128_drv.c ++++ b/drivers/gpu/drm/r128/r128_drv.c +@@ -48,7 +48,6 @@ static const struct file_operations r128_driver_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + #ifdef CONFIG_COMPAT + .compat_ioctl = r128_compat_ioctl, + #endif +diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c +index cb84df3114a6..3c5f6420319e 100644 +--- a/drivers/gpu/drm/radeon/radeon_drv.c ++++ b/drivers/gpu/drm/radeon/radeon_drv.c +@@ -259,7 +259,6 @@ static const struct file_operations radeon_driver_old_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + .read = drm_read, + #ifdef CONFIG_COMPAT + .compat_ioctl = radeon_compat_ioctl, +@@ -368,7 +367,6 @@ static const struct file_operations radeon_driver_kms_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = radeon_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + .read = drm_read, + #ifdef CONFIG_COMPAT + .compat_ioctl = radeon_kms_compat_ioctl, +diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c +index 71b2081e7835..9135c8bd6fbc 100644 +--- a/drivers/gpu/drm/savage/savage_drv.c ++++ b/drivers/gpu/drm/savage/savage_drv.c +@@ -42,7 +42,6 @@ static const struct file_operations savage_driver_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + #ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, + #endif +diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c +index 946bd28bf5da..6ae63613cfe1 100644 +--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c ++++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c +@@ -267,7 +267,6 @@ static const struct file_operations shmob_drm_fops = { + #endif + .poll = drm_poll, + .read = drm_read, +- .fasync = drm_fasync, + .llseek = no_llseek, + .mmap = drm_gem_cma_mmap, + }; +diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c +index 5a5325e6b759..b88b2d302105 100644 +--- a/drivers/gpu/drm/sis/sis_drv.c ++++ b/drivers/gpu/drm/sis/sis_drv.c +@@ -72,7 +72,6 @@ static const struct file_operations sis_driver_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + #ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, + #endif +diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c +index ddfa743459d0..951ec13e4e5c 100644 +--- a/drivers/gpu/drm/tdfx/tdfx_drv.c ++++ b/drivers/gpu/drm/tdfx/tdfx_drv.c +@@ -48,7 +48,6 @@ static const struct file_operations tdfx_driver_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + #ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, + #endif +diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c +index bba8daf9230c..cf4f0237a053 100644 +--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c ++++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c +@@ -468,7 +468,6 @@ static const struct file_operations fops = { + #endif + .poll = drm_poll, + .read = drm_read, +- .fasync = drm_fasync, + .llseek = no_llseek, + .mmap = drm_gem_cma_mmap, + }; +diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c +index bb0af58c769a..7650dc0d78ce 100644 +--- a/drivers/gpu/drm/udl/udl_drv.c ++++ b/drivers/gpu/drm/udl/udl_drv.c +@@ -65,7 +65,6 @@ static const struct file_operations udl_driver_fops = { + .read = drm_read, + .unlocked_ioctl = drm_ioctl, + .release = drm_release, +- .fasync = drm_fasync, + #ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, + #endif +diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c +index f4ae20327941..448799968a06 100644 +--- a/drivers/gpu/drm/via/via_drv.c ++++ b/drivers/gpu/drm/via/via_drv.c +@@ -64,7 +64,6 @@ static const struct file_operations via_driver_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + #ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, + #endif +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +index 46ebf7312dc9..6993713588e3 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +@@ -1129,7 +1129,6 @@ static const struct file_operations vmwgfx_driver_fops = { + .mmap = vmw_mmap, + .poll = vmw_fops_poll, + .read = vmw_fops_read, +- .fasync = drm_fasync, + #if defined(CONFIG_COMPAT) + .compat_ioctl = drm_compat_ioctl, + #endif +diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c +index c114080d0d58..26dc190fd4fe 100644 +--- a/drivers/gpu/host1x/drm/drm.c ++++ b/drivers/gpu/host1x/drm/drm.c +@@ -500,7 +500,6 @@ static const struct file_operations tegra_drm_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = tegra_drm_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + .read = drm_read, + #ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, +diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c +index f2a07af5cd5e..33eb04e79dfe 100644 +--- a/drivers/staging/imx-drm/imx-drm-core.c ++++ b/drivers/staging/imx-drm/imx-drm-core.c +@@ -207,7 +207,6 @@ static const struct file_operations imx_drm_driver_fops = { + .unlocked_ioctl = drm_ioctl, + .mmap = drm_gem_cma_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + .read = drm_read, + .llseek = noop_llseek, + }; +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index f8ad91bc0f94..7c1570d815aa 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1169,8 +1169,6 @@ struct drm_device { + + /*@} */ + +- struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */ +- + struct drm_agp_head *agp; /**< AGP data */ + + struct device *dev; /**< Device structure */ +@@ -1306,7 +1304,6 @@ extern int drm_lastclose(struct drm_device *dev); + extern struct mutex drm_global_mutex; + extern int drm_open(struct inode *inode, struct file *filp); + extern int drm_stub_open(struct inode *inode, struct file *filp); +-extern int drm_fasync(int fd, struct file *filp, int on); + extern ssize_t drm_read(struct file *filp, char __user *buffer, + size_t count, loff_t *offset); + extern int drm_release(struct inode *inode, struct file *filp); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0663-drm-use-common-drm_gem_dmabuf_release-in-i915-exynos.patch b/patches.baytrail/0663-drm-use-common-drm_gem_dmabuf_release-in-i915-exynos.patch new file mode 100644 index 000000000000..5b0c349bae40 --- /dev/null +++ b/patches.baytrail/0663-drm-use-common-drm_gem_dmabuf_release-in-i915-exynos.patch @@ -0,0 +1,139 @@ +From 36de0db4d8b9b47670a0fea0cd232d2adca312c0 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 15 Aug 2013 00:02:30 +0200 +Subject: drm: use common drm_gem_dmabuf_release in i915/exynos drivers + +Note that this is slightly tricky since both drivers store their +native objects in dma_buf->priv. But both also embed the base +drm_gem_object at the first position, so the implicit cast is ok. + +To use the release helper we need to export it, too. + +Cc: Inki Dae +Cc: Intel Graphics Development +Signed-off-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit c1d6798d20eed38b842eee01813ca6c48630d563) +Signed-off-by: James Ausmus + +Conflicts: + drivers/gpu/drm/exynos/exynos_drm_dmabuf.c + (context changes) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_prime.c | 3 ++- + drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 25 +------------------------ + drivers/gpu/drm/i915/i915_gem_dmabuf.c | 13 +------------ + include/drm/drmP.h | 1 + + 4 files changed, 5 insertions(+), 37 deletions(-) + +diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c +index 5b7b9110254b..330df93ad2d2 100644 +--- a/drivers/gpu/drm/drm_prime.c ++++ b/drivers/gpu/drm/drm_prime.c +@@ -89,7 +89,7 @@ static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, + kfree(sgt); + } + +-static void drm_gem_dmabuf_release(struct dma_buf *dma_buf) ++void drm_gem_dmabuf_release(struct dma_buf *dma_buf) + { + struct drm_gem_object *obj = dma_buf->priv; + +@@ -99,6 +99,7 @@ static void drm_gem_dmabuf_release(struct dma_buf *dma_buf) + drm_gem_object_unreference_unlocked(obj); + } + } ++EXPORT_SYMBOL(drm_gem_dmabuf_release); + + static void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf) + { +diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +index ff7f2a886a34..ec722e228c82 100644 +--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +@@ -129,29 +129,6 @@ static void exynos_gem_unmap_dma_buf(struct dma_buf_attachment *attach, + /* Nothing to do. */ + } + +-static void exynos_dmabuf_release(struct dma_buf *dmabuf) +-{ +- struct exynos_drm_gem_obj *exynos_gem_obj = dmabuf->priv; +- +- DRM_DEBUG_PRIME("%s\n", __FILE__); +- +- /* +- * exynos_dmabuf_release() call means that file object's +- * f_count is 0 and it calls drm_gem_object_handle_unreference() +- * to drop the references that these values had been increased +- * at drm_prime_handle_to_fd() +- */ +- if (exynos_gem_obj->base.export_dma_buf == dmabuf) { +- exynos_gem_obj->base.export_dma_buf = NULL; +- +- /* +- * drop this gem object refcount to release allocated buffer +- * and resources. +- */ +- drm_gem_object_unreference_unlocked(&exynos_gem_obj->base); +- } +-} +- + static void *exynos_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, + unsigned long page_num) + { +@@ -197,7 +174,7 @@ static struct dma_buf_ops exynos_dmabuf_ops = { + .kunmap = exynos_gem_dmabuf_kunmap, + .kunmap_atomic = exynos_gem_dmabuf_kunmap_atomic, + .mmap = exynos_gem_dmabuf_mmap, +- .release = exynos_dmabuf_release, ++ .release = drm_gem_dmabuf_release, + }; + + struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev, +diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c +index 6ed7275d0900..f7e1682ddb8b 100644 +--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c ++++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c +@@ -98,17 +98,6 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, + mutex_unlock(&obj->base.dev->struct_mutex); + } + +-static void i915_gem_dmabuf_release(struct dma_buf *dma_buf) +-{ +- struct drm_i915_gem_object *obj = dma_buf->priv; +- +- if (obj->base.export_dma_buf == dma_buf) { +- /* drop the reference on the export fd holds */ +- obj->base.export_dma_buf = NULL; +- drm_gem_object_unreference_unlocked(&obj->base); +- } +-} +- + static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf) + { + struct drm_i915_gem_object *obj = dma_buf->priv; +@@ -219,7 +208,7 @@ static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size + static const struct dma_buf_ops i915_dmabuf_ops = { + .map_dma_buf = i915_gem_map_dma_buf, + .unmap_dma_buf = i915_gem_unmap_dma_buf, +- .release = i915_gem_dmabuf_release, ++ .release = drm_gem_dmabuf_release, + .kmap = i915_gem_dmabuf_kmap, + .kmap_atomic = i915_gem_dmabuf_kmap_atomic, + .kunmap = i915_gem_dmabuf_kunmap, +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 7c1570d815aa..0c4bad10e928 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1566,6 +1566,7 @@ extern struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, + struct dma_buf *dma_buf); + extern int drm_gem_prime_fd_to_handle(struct drm_device *dev, + struct drm_file *file_priv, int prime_fd, uint32_t *handle); ++extern void drm_gem_dmabuf_release(struct dma_buf *dma_buf); + + extern int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0664-drm-Update-drm_addmap-and-drm_mmap-to-use-PAT-WC-ins.patch b/patches.baytrail/0664-drm-Update-drm_addmap-and-drm_mmap-to-use-PAT-WC-ins.patch new file mode 100644 index 000000000000..7bd850a7340a --- /dev/null +++ b/patches.baytrail/0664-drm-Update-drm_addmap-and-drm_mmap-to-use-PAT-WC-ins.patch @@ -0,0 +1,127 @@ +From c538b99d426c9871a35edb9dafeb1cf9b5918003 Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Mon, 13 May 2013 23:58:42 +0000 +Subject: drm: Update drm_addmap and drm_mmap to use PAT WC instead of MTRRs + +Previously, DRM_FRAME_BUFFER mappings, as well as DRM_REGISTERS +mappings with DRM_WRITE_COMBINING set, resulted in an unconditional +MTRR being added but the actual mappings being created as UC-. + +Now these mappings have the MTRR added only if needed, but they will +be mapped with pgprot_writecombine. + +The non-WC DRM_REGISTERS case now uses pgprot_noncached instead of +hardcoding the bit twiddling. + +The DRM_AGP case is unchanged for now. + +[airlied: fix ppc build] +Reviewed-by: Daniel Vetter +Signed-off-by: Andy Lutomirski +Signed-off-by: Dave Airlie + +(cherry picked from commit ff47eaf24d01b5753e4964b10c606e0d711b143e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_bufs.c | 17 +++++++++-------- + drivers/gpu/drm/drm_vm.c | 25 ++++++++++++------------- + 2 files changed, 21 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c +index 0128147265f3..0190fce20078 100644 +--- a/drivers/gpu/drm/drm_bufs.c ++++ b/drivers/gpu/drm/drm_bufs.c +@@ -210,12 +210,16 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, + if (drm_core_has_MTRR(dev)) { + if (map->type == _DRM_FRAME_BUFFER || + (map->flags & _DRM_WRITE_COMBINING)) { +- map->mtrr = mtrr_add(map->offset, map->size, +- MTRR_TYPE_WRCOMB, 1); ++ map->mtrr = ++ arch_phys_wc_add(map->offset, map->size); + } + } + if (map->type == _DRM_REGISTERS) { +- map->handle = ioremap(map->offset, map->size); ++ if (map->flags & _DRM_WRITE_COMBINING) ++ map->handle = ioremap_wc(map->offset, ++ map->size); ++ else ++ map->handle = ioremap(map->offset, map->size); + if (!map->handle) { + kfree(map); + return -ENOMEM; +@@ -451,11 +455,8 @@ int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map) + iounmap(map->handle); + /* FALLTHROUGH */ + case _DRM_FRAME_BUFFER: +- if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { +- int retcode; +- retcode = mtrr_del(map->mtrr, map->offset, map->size); +- DRM_DEBUG("mtrr_del=%d\n", retcode); +- } ++ if (drm_core_has_MTRR(dev)) ++ arch_phys_wc_del(map->mtrr); + break; + case _DRM_SHM: + vfree(map->handle); +diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c +index 1d4f7c9fe661..43e7825d3717 100644 +--- a/drivers/gpu/drm/drm_vm.c ++++ b/drivers/gpu/drm/drm_vm.c +@@ -43,18 +43,22 @@ + static void drm_vm_open(struct vm_area_struct *vma); + static void drm_vm_close(struct vm_area_struct *vma); + +-static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) ++static pgprot_t drm_io_prot(struct drm_local_map *map, ++ struct vm_area_struct *vma) + { + pgprot_t tmp = vm_get_page_prot(vma->vm_flags); + + #if defined(__i386__) || defined(__x86_64__) +- if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) { +- pgprot_val(tmp) |= _PAGE_PCD; +- pgprot_val(tmp) &= ~_PAGE_PWT; ++ if (map->type != _DRM_AGP) { ++ if (map->type == _DRM_FRAME_BUFFER || ++ map->flags & _DRM_WRITE_COMBINING) ++ tmp = pgprot_writecombine(tmp); ++ else ++ tmp = pgprot_noncached(tmp); + } + #elif defined(__powerpc__) + pgprot_val(tmp) |= _PAGE_NO_CACHE; +- if (map_type == _DRM_REGISTERS) ++ if (map->type == _DRM_REGISTERS) + pgprot_val(tmp) |= _PAGE_GUARDED; + #elif defined(__ia64__) + if (efi_range_is_wc(vma->vm_start, vma->vm_end - +@@ -250,13 +254,8 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) + switch (map->type) { + case _DRM_REGISTERS: + case _DRM_FRAME_BUFFER: +- if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { +- int retcode; +- retcode = mtrr_del(map->mtrr, +- map->offset, +- map->size); +- DRM_DEBUG("mtrr_del = %d\n", retcode); +- } ++ if (drm_core_has_MTRR(dev)) ++ arch_phys_wc_del(map->mtrr); + iounmap(map->handle); + break; + case _DRM_SHM: +@@ -618,7 +617,7 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) + case _DRM_REGISTERS: + offset = drm_core_get_reg_ofs(dev); + vma->vm_flags |= VM_IO; /* not in core dump */ +- vma->vm_page_prot = drm_io_prot(map->type, vma); ++ vma->vm_page_prot = drm_io_prot(map, vma); + if (io_remap_pfn_range(vma, vma->vm_start, + (map->offset + offset) >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0665-drm-agpgart-Use-pgprot_writecombine-for-AGP-maps-and.patch b/patches.baytrail/0665-drm-agpgart-Use-pgprot_writecombine-for-AGP-maps-and.patch new file mode 100644 index 000000000000..b8504029c7b8 --- /dev/null +++ b/patches.baytrail/0665-drm-agpgart-Use-pgprot_writecombine-for-AGP-maps-and.patch @@ -0,0 +1,124 @@ +From 0befbca168c6420ed27682d74ca4768fd15b0128 Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Mon, 13 May 2013 23:58:43 +0000 +Subject: drm, agpgart: Use pgprot_writecombine for AGP maps and make the MTRR + optional + +I'm not sure I understand the intent of the previous behavior. mmap +on /dev/agpgart and DRM_AGP maps had no cache flags set, so they +would be fully cacheable. But the DRM code (most of the time) would +add a write-combining MTRR that would change the effective memory +type to WC. + +The new behavior just requests WC explicitly for all AGP maps. + +If there is any code out there that expects cacheable access to the +AGP aperture (because the drm driver doesn't request an MTRR or +because it's using /dev/agpgart directly), then it will now end up +with a UC or WC mapping, depending on the architecture and PAT +availability. But cacheable access to the aperture seems like it's +asking for trouble, because, AIUI, the aperture is an alias of RAM. + +Reviewed-by: Daniel Vetter +Signed-off-by: Andy Lutomirski +Signed-off-by: Dave Airlie +(cherry picked from commit f435046d38af631920b299455db9e95dfc06d055) +Signed-off-by: Darren Hart +--- + drivers/char/agp/frontend.c | 8 +++++--- + drivers/gpu/drm/drm_pci.c | 8 ++++---- + drivers/gpu/drm/drm_stub.c | 10 ++-------- + drivers/gpu/drm/drm_vm.c | 11 ++++------- + 4 files changed, 15 insertions(+), 22 deletions(-) + +diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c +index 2e044338753c..1b192395a90c 100644 +--- a/drivers/char/agp/frontend.c ++++ b/drivers/char/agp/frontend.c +@@ -603,7 +603,8 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) + vma->vm_ops = kerninfo.vm_ops; + } else if (io_remap_pfn_range(vma, vma->vm_start, + (kerninfo.aper_base + offset) >> PAGE_SHIFT, +- size, vma->vm_page_prot)) { ++ size, ++ pgprot_writecombine(vma->vm_page_prot))) { + goto out_again; + } + mutex_unlock(&(agp_fe.agp_mutex)); +@@ -618,8 +619,9 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) + if (kerninfo.vm_ops) { + vma->vm_ops = kerninfo.vm_ops; + } else if (io_remap_pfn_range(vma, vma->vm_start, +- kerninfo.aper_base >> PAGE_SHIFT, +- size, vma->vm_page_prot)) { ++ kerninfo.aper_base >> PAGE_SHIFT, ++ size, ++ pgprot_writecombine(vma->vm_page_prot))) { + goto out_again; + } + mutex_unlock(&(agp_fe.agp_mutex)); +diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c +index 14194b6ef644..80c0b2b29801 100644 +--- a/drivers/gpu/drm/drm_pci.c ++++ b/drivers/gpu/drm/drm_pci.c +@@ -278,10 +278,10 @@ static int drm_pci_agp_init(struct drm_device *dev) + } + if (drm_core_has_MTRR(dev)) { + if (dev->agp) +- dev->agp->agp_mtrr = +- mtrr_add(dev->agp->agp_info.aper_base, +- dev->agp->agp_info.aper_size * +- 1024 * 1024, MTRR_TYPE_WRCOMB, 1); ++ dev->agp->agp_mtrr = arch_phys_wc_add( ++ dev->agp->agp_info.aper_base, ++ dev->agp->agp_info.aper_size * ++ 1024 * 1024); + } + } + return 0; +diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c +index 16f3ec579b3b..577786ce9fbc 100644 +--- a/drivers/gpu/drm/drm_stub.c ++++ b/drivers/gpu/drm/drm_stub.c +@@ -451,14 +451,8 @@ void drm_put_dev(struct drm_device *dev) + + drm_lastclose(dev); + +- if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && +- dev->agp && dev->agp->agp_mtrr >= 0) { +- int retval; +- retval = mtrr_del(dev->agp->agp_mtrr, +- dev->agp->agp_info.aper_base, +- dev->agp->agp_info.aper_size * 1024 * 1024); +- DRM_DEBUG("mtrr_del=%d\n", retval); +- } ++ if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && dev->agp) ++ arch_phys_wc_del(dev->agp->agp_mtrr); + + if (dev->driver->unload) + dev->driver->unload(dev); +diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c +index 43e7825d3717..1575694ccaca 100644 +--- a/drivers/gpu/drm/drm_vm.c ++++ b/drivers/gpu/drm/drm_vm.c +@@ -49,13 +49,10 @@ static pgprot_t drm_io_prot(struct drm_local_map *map, + pgprot_t tmp = vm_get_page_prot(vma->vm_flags); + + #if defined(__i386__) || defined(__x86_64__) +- if (map->type != _DRM_AGP) { +- if (map->type == _DRM_FRAME_BUFFER || +- map->flags & _DRM_WRITE_COMBINING) +- tmp = pgprot_writecombine(tmp); +- else +- tmp = pgprot_noncached(tmp); +- } ++ if (map->type == _DRM_REGISTERS && !(map->flags & _DRM_WRITE_COMBINING)) ++ tmp = pgprot_noncached(tmp); ++ else ++ tmp = pgprot_writecombine(tmp); + #elif defined(__powerpc__) + pgprot_val(tmp) |= _PAGE_NO_CACHE; + if (map->type == _DRM_REGISTERS) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0666-drm-agp-move-AGP-cleanup-paths-to-drm_agpsupport.c.patch b/patches.baytrail/0666-drm-agp-move-AGP-cleanup-paths-to-drm_agpsupport.c.patch new file mode 100644 index 000000000000..19d208a8072c --- /dev/null +++ b/patches.baytrail/0666-drm-agp-move-AGP-cleanup-paths-to-drm_agpsupport.c.patch @@ -0,0 +1,193 @@ +From 01442c7bcb90339b0abab3caffce62909f3aab2d Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Sat, 27 Jul 2013 16:37:00 +0200 +Subject: drm/agp: move AGP cleanup paths to drm_agpsupport.c + +Introduce two new helpers, drm_agp_clear() and drm_agp_destroy() which +clear all AGP mappings and destroy the AGP head. This allows to reduce the +AGP code in core DRM and move it all to drm_agpsupport.c. + +Signed-off-by: David Herrmann +Signed-off-by: Dave Airlie +(cherry picked from commit 28ec711cd427f8b61f73712a43b8100ba8ca933b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_agpsupport.c | 51 ++++++++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/drm_drv.c | 21 +---------------- + drivers/gpu/drm/drm_pci.c | 12 ++++++++++ + drivers/gpu/drm/drm_stub.c | 9 ++----- + include/drm/drmP.h | 3 +++ + 5 files changed, 69 insertions(+), 27 deletions(-) + +diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c +index 3d8fed179797..e301d653d97e 100644 +--- a/drivers/gpu/drm/drm_agpsupport.c ++++ b/drivers/gpu/drm/drm_agpsupport.c +@@ -424,6 +424,57 @@ struct drm_agp_head *drm_agp_init(struct drm_device *dev) + } + + /** ++ * drm_agp_clear - Clear AGP resource list ++ * @dev: DRM device ++ * ++ * Iterate over all AGP resources and remove them. But keep the AGP head ++ * intact so it can still be used. It is safe to call this if AGP is disabled or ++ * was already removed. ++ * ++ * If DRIVER_MODESET is active, nothing is done to protect the modesetting ++ * resources from getting destroyed. Drivers are responsible of cleaning them up ++ * during device shutdown. ++ */ ++void drm_agp_clear(struct drm_device *dev) ++{ ++ struct drm_agp_mem *entry, *tempe; ++ ++ if (!drm_core_has_AGP(dev) || !dev->agp) ++ return; ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return; ++ ++ list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) { ++ if (entry->bound) ++ drm_unbind_agp(entry->memory); ++ drm_free_agp(entry->memory, entry->pages); ++ kfree(entry); ++ } ++ INIT_LIST_HEAD(&dev->agp->memory); ++ ++ if (dev->agp->acquired) ++ drm_agp_release(dev); ++ ++ dev->agp->acquired = 0; ++ dev->agp->enabled = 0; ++} ++ ++/** ++ * drm_agp_destroy - Destroy AGP head ++ * @dev: DRM device ++ * ++ * Destroy resources that were previously allocated via drm_agp_initp. Caller ++ * must ensure to clean up all AGP resources before calling this. See ++ * drm_agp_clear(). ++ * ++ * Call this to destroy AGP heads allocated via drm_agp_init(). ++ */ ++void drm_agp_destroy(struct drm_agp_head *agp) ++{ ++ kfree(agp); ++} ++ ++/** + * Binds a collection of pages into AGP memory at the given offset, returning + * the AGP memory structure containing them. + * +diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c +index 2ab782cb38a2..2994cd7513e9 100644 +--- a/drivers/gpu/drm/drm_drv.c ++++ b/drivers/gpu/drm/drm_drv.c +@@ -194,27 +194,8 @@ int drm_lastclose(struct drm_device * dev) + + mutex_lock(&dev->struct_mutex); + +- /* Clear AGP information */ +- if (drm_core_has_AGP(dev) && dev->agp && +- !drm_core_check_feature(dev, DRIVER_MODESET)) { +- struct drm_agp_mem *entry, *tempe; +- +- /* Remove AGP resources, but leave dev->agp +- intact until drv_cleanup is called. */ +- list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) { +- if (entry->bound) +- drm_unbind_agp(entry->memory); +- drm_free_agp(entry->memory, entry->pages); +- kfree(entry); +- } +- INIT_LIST_HEAD(&dev->agp->memory); +- +- if (dev->agp->acquired) +- drm_agp_release(dev); ++ drm_agp_clear(dev); + +- dev->agp->acquired = 0; +- dev->agp->enabled = 0; +- } + if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg && + !drm_core_check_feature(dev, DRIVER_MODESET)) { + drm_sg_cleanup(dev->sg); +diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c +index 80c0b2b29801..382e5bd699c6 100644 +--- a/drivers/gpu/drm/drm_pci.c ++++ b/drivers/gpu/drm/drm_pci.c +@@ -287,6 +287,17 @@ static int drm_pci_agp_init(struct drm_device *dev) + return 0; + } + ++static void drm_pci_agp_destroy(struct drm_device *dev) ++{ ++ if (drm_core_has_AGP(dev) && dev->agp) { ++ if (drm_core_has_MTRR(dev)) ++ arch_phys_wc_del(dev->agp->agp_mtrr); ++ drm_agp_clear(dev); ++ drm_agp_destroy(dev->agp); ++ dev->agp = NULL; ++ } ++} ++ + static struct drm_bus drm_pci_bus = { + .bus_type = DRIVER_BUS_PCI, + .get_irq = drm_pci_get_irq, +@@ -295,6 +306,7 @@ static struct drm_bus drm_pci_bus = { + .set_unique = drm_pci_set_unique, + .irq_by_busid = drm_pci_irq_by_busid, + .agp_init = drm_pci_agp_init, ++ .agp_destroy = drm_pci_agp_destroy, + }; + + /** +diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c +index 577786ce9fbc..31442a45dae0 100644 +--- a/drivers/gpu/drm/drm_stub.c ++++ b/drivers/gpu/drm/drm_stub.c +@@ -451,16 +451,11 @@ void drm_put_dev(struct drm_device *dev) + + drm_lastclose(dev); + +- if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && dev->agp) +- arch_phys_wc_del(dev->agp->agp_mtrr); +- + if (dev->driver->unload) + dev->driver->unload(dev); + +- if (drm_core_has_AGP(dev) && dev->agp) { +- kfree(dev->agp); +- dev->agp = NULL; +- } ++ if (dev->driver->bus->agp_destroy) ++ dev->driver->bus->agp_destroy(dev); + + drm_vblank_cleanup(dev); + +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 0c4bad10e928..bcaf5575c79c 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -739,6 +739,7 @@ struct drm_bus { + int (*irq_by_busid)(struct drm_device *dev, struct drm_irq_busid *p); + /* hooks that are for PCI */ + int (*agp_init)(struct drm_device *dev); ++ void (*agp_destroy)(struct drm_device *dev); + + }; + +@@ -1482,6 +1483,8 @@ extern int drm_modeset_ctl(struct drm_device *dev, void *data, + + /* AGP/GART support (drm_agpsupport.h) */ + extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); ++extern void drm_agp_destroy(struct drm_agp_head *agp); ++extern void drm_agp_clear(struct drm_device *dev); + extern int drm_agp_acquire(struct drm_device *dev); + extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0667-drm-ast-cirrus-mgag200-nouveau-savage-vmwgfx-Remove-.patch b/patches.baytrail/0667-drm-ast-cirrus-mgag200-nouveau-savage-vmwgfx-Remove-.patch new file mode 100644 index 000000000000..7688ca7be63c --- /dev/null +++ b/patches.baytrail/0667-drm-ast-cirrus-mgag200-nouveau-savage-vmwgfx-Remove-.patch @@ -0,0 +1,336 @@ +From 8b57825903c47ff203da91e9b36dcd94d669f5df Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Mon, 13 May 2013 23:58:41 +0000 +Subject: drm (ast, cirrus, mgag200, nouveau, savage, vmwgfx): Remove + drm_mtrr_{add, del} + +This replaces drm_mtrr_{add,del} with arch_phys_wc_{add,del}. The +interface is simplified (because the base and size parameters to +drm_mtrr_del never did anything), and it no longer adds MTRRs on +systems that don't need them. + +Reviewed-by: Daniel Vetter +Signed-off-by: Andy Lutomirski +Signed-off-by: Dave Airlie +(cherry picked from commit 247d36d75128ba1f63702e0e6185d9a7a23ee5cb) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/ast/ast_ttm.c | 13 +++-------- + drivers/gpu/drm/cirrus/cirrus_ttm.c | 15 ++++-------- + drivers/gpu/drm/mgag200/mgag200_ttm.c | 14 ++++-------- + drivers/gpu/drm/nouveau/nouveau_ttm.c | 13 ++++------- + drivers/gpu/drm/savage/savage_bci.c | 43 ++++++++++++----------------------- + drivers/gpu/drm/savage/savage_drv.h | 5 +--- + drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 10 ++++---- + include/drm/drmP.h | 29 ----------------------- + 8 files changed, 35 insertions(+), 107 deletions(-) + +diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c +index d5902e21d4a3..18acdf40c97c 100644 +--- a/drivers/gpu/drm/ast/ast_ttm.c ++++ b/drivers/gpu/drm/ast/ast_ttm.c +@@ -271,26 +271,19 @@ int ast_mm_init(struct ast_private *ast) + return ret; + } + +- ast->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0), +- pci_resource_len(dev->pdev, 0), +- DRM_MTRR_WC); ++ ast->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0), ++ pci_resource_len(dev->pdev, 0)); + + return 0; + } + + void ast_mm_fini(struct ast_private *ast) + { +- struct drm_device *dev = ast->dev; + ttm_bo_device_release(&ast->ttm.bdev); + + ast_ttm_global_release(ast); + +- if (ast->fb_mtrr >= 0) { +- drm_mtrr_del(ast->fb_mtrr, +- pci_resource_start(dev->pdev, 0), +- pci_resource_len(dev->pdev, 0), DRM_MTRR_WC); +- ast->fb_mtrr = -1; +- } ++ arch_phys_wc_del(ast->fb_mtrr); + } + + void ast_ttm_placement(struct ast_bo *bo, int domain) +diff --git a/drivers/gpu/drm/cirrus/cirrus_ttm.c b/drivers/gpu/drm/cirrus/cirrus_ttm.c +index c18faff82651..2c62eb44d377 100644 +--- a/drivers/gpu/drm/cirrus/cirrus_ttm.c ++++ b/drivers/gpu/drm/cirrus/cirrus_ttm.c +@@ -271,9 +271,8 @@ int cirrus_mm_init(struct cirrus_device *cirrus) + return ret; + } + +- cirrus->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0), +- pci_resource_len(dev->pdev, 0), +- DRM_MTRR_WC); ++ cirrus->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0), ++ pci_resource_len(dev->pdev, 0)); + + cirrus->mm_inited = true; + return 0; +@@ -281,8 +280,6 @@ int cirrus_mm_init(struct cirrus_device *cirrus) + + void cirrus_mm_fini(struct cirrus_device *cirrus) + { +- struct drm_device *dev = cirrus->dev; +- + if (!cirrus->mm_inited) + return; + +@@ -290,12 +287,8 @@ void cirrus_mm_fini(struct cirrus_device *cirrus) + + cirrus_ttm_global_release(cirrus); + +- if (cirrus->fb_mtrr >= 0) { +- drm_mtrr_del(cirrus->fb_mtrr, +- pci_resource_start(dev->pdev, 0), +- pci_resource_len(dev->pdev, 0), DRM_MTRR_WC); +- cirrus->fb_mtrr = -1; +- } ++ arch_phys_wc_del(cirrus->fb_mtrr); ++ cirrus->fb_mtrr = 0; + } + + void cirrus_ttm_placement(struct cirrus_bo *bo, int domain) +diff --git a/drivers/gpu/drm/mgag200/mgag200_ttm.c b/drivers/gpu/drm/mgag200/mgag200_ttm.c +index d2cb32f3c05b..6be84f047882 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_ttm.c ++++ b/drivers/gpu/drm/mgag200/mgag200_ttm.c +@@ -270,26 +270,20 @@ int mgag200_mm_init(struct mga_device *mdev) + return ret; + } + +- mdev->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0), +- pci_resource_len(dev->pdev, 0), +- DRM_MTRR_WC); ++ mdev->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0), ++ pci_resource_len(dev->pdev, 0)); + + return 0; + } + + void mgag200_mm_fini(struct mga_device *mdev) + { +- struct drm_device *dev = mdev->dev; + ttm_bo_device_release(&mdev->ttm.bdev); + + mgag200_ttm_global_release(mdev); + +- if (mdev->fb_mtrr >= 0) { +- drm_mtrr_del(mdev->fb_mtrr, +- pci_resource_start(dev->pdev, 0), +- pci_resource_len(dev->pdev, 0), DRM_MTRR_WC); +- mdev->fb_mtrr = -1; +- } ++ arch_phys_wc_del(mdev->fb_mtrr); ++ mdev->fb_mtrr = 0; + } + + void mgag200_ttm_placement(struct mgag200_bo *bo, int domain) +diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c +index f19a15a3bc03..3da985eb38cc 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c ++++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c +@@ -396,9 +396,8 @@ nouveau_ttm_init(struct nouveau_drm *drm) + return ret; + } + +- drm->ttm.mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1), +- pci_resource_len(dev->pdev, 1), +- DRM_MTRR_WC); ++ drm->ttm.mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 1), ++ pci_resource_len(dev->pdev, 1)); + + /* GART init */ + if (drm->agp.stat != ENABLED) { +@@ -433,10 +432,6 @@ nouveau_ttm_fini(struct nouveau_drm *drm) + + nouveau_ttm_global_release(drm); + +- if (drm->ttm.mtrr >= 0) { +- drm_mtrr_del(drm->ttm.mtrr, +- pci_resource_start(drm->dev->pdev, 1), +- pci_resource_len(drm->dev->pdev, 1), DRM_MTRR_WC); +- drm->ttm.mtrr = -1; +- } ++ arch_phys_wc_del(drm->ttm.mtrr); ++ drm->ttm.mtrr = 0; + } +diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c +index ce3a7d42ee43..b17d0710871a 100644 +--- a/drivers/gpu/drm/savage/savage_bci.c ++++ b/drivers/gpu/drm/savage/savage_bci.c +@@ -570,9 +570,6 @@ int savage_driver_firstopen(struct drm_device *dev) + unsigned int fb_rsrc, aper_rsrc; + int ret = 0; + +- dev_priv->mtrr[0].handle = -1; +- dev_priv->mtrr[1].handle = -1; +- dev_priv->mtrr[2].handle = -1; + if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { + fb_rsrc = 0; + fb_base = pci_resource_start(dev->pdev, 0); +@@ -584,21 +581,14 @@ int savage_driver_firstopen(struct drm_device *dev) + if (pci_resource_len(dev->pdev, 0) == 0x08000000) { + /* Don't make MMIO write-cobining! We need 3 + * MTRRs. */ +- dev_priv->mtrr[0].base = fb_base; +- dev_priv->mtrr[0].size = 0x01000000; +- dev_priv->mtrr[0].handle = +- drm_mtrr_add(dev_priv->mtrr[0].base, +- dev_priv->mtrr[0].size, DRM_MTRR_WC); +- dev_priv->mtrr[1].base = fb_base + 0x02000000; +- dev_priv->mtrr[1].size = 0x02000000; +- dev_priv->mtrr[1].handle = +- drm_mtrr_add(dev_priv->mtrr[1].base, +- dev_priv->mtrr[1].size, DRM_MTRR_WC); +- dev_priv->mtrr[2].base = fb_base + 0x04000000; +- dev_priv->mtrr[2].size = 0x04000000; +- dev_priv->mtrr[2].handle = +- drm_mtrr_add(dev_priv->mtrr[2].base, +- dev_priv->mtrr[2].size, DRM_MTRR_WC); ++ dev_priv->mtrr_handles[0] = ++ arch_phys_wc_add(fb_base, 0x01000000); ++ dev_priv->mtrr_handles[1] = ++ arch_phys_wc_add(fb_base + 0x02000000, ++ 0x02000000); ++ dev_priv->mtrr_handles[2] = ++ arch_phys_wc_add(fb_base + 0x04000000, ++ 0x04000000); + } else { + DRM_ERROR("strange pci_resource_len %08llx\n", + (unsigned long long) +@@ -616,11 +606,9 @@ int savage_driver_firstopen(struct drm_device *dev) + if (pci_resource_len(dev->pdev, 1) == 0x08000000) { + /* Can use one MTRR to cover both fb and + * aperture. */ +- dev_priv->mtrr[0].base = fb_base; +- dev_priv->mtrr[0].size = 0x08000000; +- dev_priv->mtrr[0].handle = +- drm_mtrr_add(dev_priv->mtrr[0].base, +- dev_priv->mtrr[0].size, DRM_MTRR_WC); ++ dev_priv->mtrr_handles[0] = ++ arch_phys_wc_add(fb_base, ++ 0x08000000); + } else { + DRM_ERROR("strange pci_resource_len %08llx\n", + (unsigned long long) +@@ -660,11 +648,10 @@ void savage_driver_lastclose(struct drm_device *dev) + drm_savage_private_t *dev_priv = dev->dev_private; + int i; + +- for (i = 0; i < 3; ++i) +- if (dev_priv->mtrr[i].handle >= 0) +- drm_mtrr_del(dev_priv->mtrr[i].handle, +- dev_priv->mtrr[i].base, +- dev_priv->mtrr[i].size, DRM_MTRR_WC); ++ for (i = 0; i < 3; ++i) { ++ arch_phys_wc_del(dev_priv->mtrr_handles[i]); ++ dev_priv->mtrr_handles[i] = 0; ++ } + } + + int savage_driver_unload(struct drm_device *dev) +diff --git a/drivers/gpu/drm/savage/savage_drv.h b/drivers/gpu/drm/savage/savage_drv.h +index 5f55b21ea22d..335f8fcf1041 100644 +--- a/drivers/gpu/drm/savage/savage_drv.h ++++ b/drivers/gpu/drm/savage/savage_drv.h +@@ -160,10 +160,7 @@ typedef struct drm_savage_private { + drm_local_map_t *cmd_dma; + drm_local_map_t fake_dma; + +- struct { +- int handle; +- unsigned long base, size; +- } mtrr[3]; ++ int mtrr_handles[3]; + + /* BCI and status-related stuff */ + volatile uint32_t *status_ptr, *bci_ptr; +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +index 6993713588e3..a2990b8a9e5e 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +@@ -565,8 +565,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) + dev_priv->has_gmr = false; + } + +- dev_priv->mmio_mtrr = drm_mtrr_add(dev_priv->mmio_start, +- dev_priv->mmio_size, DRM_MTRR_WC); ++ dev_priv->mmio_mtrr = arch_phys_wc_add(dev_priv->mmio_start, ++ dev_priv->mmio_size); + + dev_priv->mmio_virt = ioremap_wc(dev_priv->mmio_start, + dev_priv->mmio_size); +@@ -664,8 +664,7 @@ out_no_device: + out_err4: + iounmap(dev_priv->mmio_virt); + out_err3: +- drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, +- dev_priv->mmio_size, DRM_MTRR_WC); ++ arch_phys_wc_del(dev_priv->mmio_mtrr); + if (dev_priv->has_gmr) + (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); + (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); +@@ -709,8 +708,7 @@ static int vmw_driver_unload(struct drm_device *dev) + + ttm_object_device_release(&dev_priv->tdev); + iounmap(dev_priv->mmio_virt); +- drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, +- dev_priv->mmio_size, DRM_MTRR_WC); ++ arch_phys_wc_del(dev_priv->mmio_mtrr); + if (dev_priv->has_gmr) + (void)ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); + (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index bcaf5575c79c..dcd590728e9b 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1239,37 +1239,8 @@ static inline int drm_core_has_MTRR(struct drm_device *dev) + { + return drm_core_check_feature(dev, DRIVER_USE_MTRR); + } +- +-#define DRM_MTRR_WC MTRR_TYPE_WRCOMB +- +-static inline int drm_mtrr_add(unsigned long offset, unsigned long size, +- unsigned int flags) +-{ +- return mtrr_add(offset, size, flags, 1); +-} +- +-static inline int drm_mtrr_del(int handle, unsigned long offset, +- unsigned long size, unsigned int flags) +-{ +- return mtrr_del(handle, offset, size); +-} +- + #else + #define drm_core_has_MTRR(dev) (0) +- +-#define DRM_MTRR_WC 0 +- +-static inline int drm_mtrr_add(unsigned long offset, unsigned long size, +- unsigned int flags) +-{ +- return 0; +-} +- +-static inline int drm_mtrr_del(int handle, unsigned long offset, +- unsigned long size, unsigned int flags) +-{ +- return 0; +-} + #endif + + static inline void drm_device_set_unplugged(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0668-drm-Remove-mtrr_add-and-mtrr_del-fallback-hack-for-n.patch b/patches.baytrail/0668-drm-Remove-mtrr_add-and-mtrr_del-fallback-hack-for-n.patch new file mode 100644 index 000000000000..bf6cd97219c4 --- /dev/null +++ b/patches.baytrail/0668-drm-Remove-mtrr_add-and-mtrr_del-fallback-hack-for-n.patch @@ -0,0 +1,69 @@ +From dfcf59ef1f50a127b41c653648d96aa8c8154e48 Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Mon, 13 May 2013 23:58:47 +0000 +Subject: drm: Remove mtrr_add and mtrr_del fallback hack for non-MTRR systems + +There are no users left in drivers/gpu. + +Reviewed-by: Daniel Vetter +Signed-off-by: Andy Lutomirski +Signed-off-by: Dave Airlie +(cherry picked from commit 03dae7c567d24c49e826a033df45802ac9d1d6c8) +Signed-off-by: Darren Hart +--- + include/drm/drmP.h | 5 +---- + include/drm/drm_os_linux.h | 16 ---------------- + 2 files changed, 1 insertion(+), 20 deletions(-) + +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index dcd590728e9b..78dc6a19a427 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -55,16 +55,13 @@ + #include + #include + #include ++#include + #include + #if defined(__alpha__) || defined(__powerpc__) + #include /* For pte_wrprotect */ + #endif +-#include + #include + #include +-#ifdef CONFIG_MTRR +-#include +-#endif + #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) + #include + #include +diff --git a/include/drm/drm_os_linux.h b/include/drm/drm_os_linux.h +index 675ddf4b441f..815fafc6b4ad 100644 +--- a/include/drm/drm_os_linux.h ++++ b/include/drm/drm_os_linux.h +@@ -65,22 +65,6 @@ struct no_agp_kern { + #define DRM_AGP_KERN struct no_agp_kern + #endif + +-#if !(__OS_HAS_MTRR) +-static __inline__ int mtrr_add(unsigned long base, unsigned long size, +- unsigned int type, char increment) +-{ +- return -ENODEV; +-} +- +-static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size) +-{ +- return -ENODEV; +-} +- +-#define MTRR_TYPE_WRCOMB 1 +- +-#endif +- + /** Other copying of data to kernel space */ + #define DRM_COPY_FROM_USER(arg1, arg2, arg3) \ + copy_from_user(arg1, arg2, arg3) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0669-drm-provide-agp-dummies-for-CONFIG_AGP-n.patch b/patches.baytrail/0669-drm-provide-agp-dummies-for-CONFIG_AGP-n.patch new file mode 100644 index 000000000000..a9c70b61ceec --- /dev/null +++ b/patches.baytrail/0669-drm-provide-agp-dummies-for-CONFIG_AGP-n.patch @@ -0,0 +1,318 @@ +From 6eaeb90874d8c28265c6cb2c5984928098a416c9 Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Thu, 8 Aug 2013 22:19:12 +0200 +Subject: drm: provide agp dummies for CONFIG_AGP=n + +We currently rely on gcc dead-code elimination so the drm_agp_* helpers +are not called if drm_core_has_AGP() is false. That's ugly as hell so +provide "static inline" dummies for the case that AGP is disabled. + +Fixes a build-regression introduced by: + + commit 28ec711cd427f8b61f73712a43b8100ba8ca933b + Author: David Herrmann + Date: Sat Jul 27 16:37:00 2013 +0200 + + drm/agp: move AGP cleanup paths to drm_agpsupport.c + +v2: switch #ifdef -> #if (spotted by Stephen) + +Cc: Laurent Pinchart +Cc: Daniel Vetter +Tested-by: Stephen Warren +Signed-off-by: David Herrmann +Signed-off-by: Dave Airlie +(cherry picked from commit 00fd78e5279aec3aa504307ff2db892d3efb555d) +Signed-off-by: Darren Hart +--- + include/drm/drmP.h | 49 +---------- + include/drm/drm_agpsupport.h | 194 +++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 196 insertions(+), 47 deletions(-) + create mode 100644 include/drm/drm_agpsupport.h + +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 78dc6a19a427..39e12a6356f9 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -62,10 +62,8 @@ + #endif + #include + #include +-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) + #include + #include +-#endif + #include + #include + #include +@@ -1221,16 +1219,6 @@ static inline int drm_dev_to_irq(struct drm_device *dev) + return dev->driver->bus->get_irq(dev); + } + +- +-#if __OS_HAS_AGP +-static inline int drm_core_has_AGP(struct drm_device *dev) +-{ +- return drm_core_check_feature(dev, DRIVER_USE_AGP); +-} +-#else +-#define drm_core_has_AGP(dev) (0) +-#endif +- + #if __OS_HAS_MTRR + static inline int drm_core_has_MTRR(struct drm_device *dev) + { +@@ -1286,14 +1274,6 @@ extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); + + /* Memory management support (drm_memory.h) */ + #include +-extern void drm_free_agp(DRM_AGP_MEM * handle, int pages); +-extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start); +-extern DRM_AGP_MEM *drm_agp_bind_pages(struct drm_device *dev, +- struct page **pages, +- unsigned long num_pages, +- uint32_t gtt_offset, +- uint32_t type); +-extern int drm_unbind_agp(DRM_AGP_MEM * handle); + + /* Misc. IOCTL support (drm_ioctl.h) */ + extern int drm_irq_by_busid(struct drm_device *dev, void *data, +@@ -1450,33 +1430,8 @@ extern int drm_modeset_ctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + + /* AGP/GART support (drm_agpsupport.h) */ +-extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); +-extern void drm_agp_destroy(struct drm_agp_head *agp); +-extern void drm_agp_clear(struct drm_device *dev); +-extern int drm_agp_acquire(struct drm_device *dev); +-extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, +- struct drm_file *file_priv); +-extern int drm_agp_release(struct drm_device *dev); +-extern int drm_agp_release_ioctl(struct drm_device *dev, void *data, +- struct drm_file *file_priv); +-extern int drm_agp_enable(struct drm_device *dev, struct drm_agp_mode mode); +-extern int drm_agp_enable_ioctl(struct drm_device *dev, void *data, +- struct drm_file *file_priv); +-extern int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info); +-extern int drm_agp_info_ioctl(struct drm_device *dev, void *data, +- struct drm_file *file_priv); +-extern int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request); +-extern int drm_agp_alloc_ioctl(struct drm_device *dev, void *data, +- struct drm_file *file_priv); +-extern int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request); +-extern int drm_agp_free_ioctl(struct drm_device *dev, void *data, +- struct drm_file *file_priv); +-extern int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request); +-extern int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, +- struct drm_file *file_priv); +-extern int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request); +-extern int drm_agp_bind_ioctl(struct drm_device *dev, void *data, +- struct drm_file *file_priv); ++ ++#include + + /* Stub support (drm_stub.h) */ + extern int drm_setmaster_ioctl(struct drm_device *dev, void *data, +diff --git a/include/drm/drm_agpsupport.h b/include/drm/drm_agpsupport.h +new file mode 100644 +index 000000000000..a184eeee9c96 +--- /dev/null ++++ b/include/drm/drm_agpsupport.h +@@ -0,0 +1,194 @@ ++#ifndef _DRM_AGPSUPPORT_H_ ++#define _DRM_AGPSUPPORT_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if __OS_HAS_AGP ++ ++void drm_free_agp(DRM_AGP_MEM * handle, int pages); ++int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start); ++int drm_unbind_agp(DRM_AGP_MEM * handle); ++DRM_AGP_MEM *drm_agp_bind_pages(struct drm_device *dev, ++ struct page **pages, ++ unsigned long num_pages, ++ uint32_t gtt_offset, ++ uint32_t type); ++ ++struct drm_agp_head *drm_agp_init(struct drm_device *dev); ++void drm_agp_destroy(struct drm_agp_head *agp); ++void drm_agp_clear(struct drm_device *dev); ++int drm_agp_acquire(struct drm_device *dev); ++int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++int drm_agp_release(struct drm_device *dev); ++int drm_agp_release_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++int drm_agp_enable(struct drm_device *dev, struct drm_agp_mode mode); ++int drm_agp_enable_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info); ++int drm_agp_info_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request); ++int drm_agp_alloc_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request); ++int drm_agp_free_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request); ++int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request); ++int drm_agp_bind_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++ ++static inline int drm_core_has_AGP(struct drm_device *dev) ++{ ++ return drm_core_check_feature(dev, DRIVER_USE_AGP); ++} ++ ++#else /* __OS_HAS_AGP */ ++ ++static inline void drm_free_agp(DRM_AGP_MEM * handle, int pages) ++{ ++} ++ ++static inline int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_unbind_agp(DRM_AGP_MEM * handle) ++{ ++ return -ENODEV; ++} ++ ++static inline DRM_AGP_MEM *drm_agp_bind_pages(struct drm_device *dev, ++ struct page **pages, ++ unsigned long num_pages, ++ uint32_t gtt_offset, ++ uint32_t type) ++{ ++ return NULL; ++} ++ ++static inline struct drm_agp_head *drm_agp_init(struct drm_device *dev) ++{ ++ return NULL; ++} ++ ++static inline void drm_agp_destroy(struct drm_agp_head *agp) ++{ ++} ++ ++static inline void drm_agp_clear(struct drm_device *dev) ++{ ++} ++ ++static inline int drm_agp_acquire(struct drm_device *dev) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_release(struct drm_device *dev) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_release_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_enable(struct drm_device *dev, ++ struct drm_agp_mode mode) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_enable_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_info(struct drm_device *dev, ++ struct drm_agp_info *info) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_info_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_alloc(struct drm_device *dev, ++ struct drm_agp_buffer *request) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_alloc_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_free(struct drm_device *dev, ++ struct drm_agp_buffer *request) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_free_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_unbind(struct drm_device *dev, ++ struct drm_agp_binding *request) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_bind(struct drm_device *dev, ++ struct drm_agp_binding *request) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_agp_bind_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return -ENODEV; ++} ++ ++static inline int drm_core_has_AGP(struct drm_device *dev) ++{ ++ return 0; ++} ++ ++#endif /* __OS_HAS_AGP */ ++ ++#endif /* _DRM_AGPSUPPORT_H_ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0670-drm-rip-out-drm_core_has_MTRR-checks.patch b/patches.baytrail/0670-drm-rip-out-drm_core_has_MTRR-checks.patch new file mode 100644 index 000000000000..0d5b3a002504 --- /dev/null +++ b/patches.baytrail/0670-drm-rip-out-drm_core_has_MTRR-checks.patch @@ -0,0 +1,391 @@ +From b74cfabd1583f180802014ce2fb94acf37f21a95 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 8 Aug 2013 15:41:27 +0200 +Subject: drm: rip out drm_core_has_MTRR checks + +The new arch_phys_wc_add/del functions do the right thing both with +and without MTRR support in the kernel. So we can drop these +additional checks. + +David Herrmann suggest to also kill the DRIVER_USE_MTRR flag since +it's now unused, which spurred me to do a bit a better audit of the +affected drivers. David helped a lot in that. Quoting our mail +discussion: + +On Wed, Jul 10, 2013 at 5:41 PM, David Herrmann wrote: +> On Wed, Jul 10, 2013 at 5:22 PM, Daniel Vetter wrote: +>> On Wed, Jul 10, 2013 at 3:51 PM, David Herrmann wrote: +>>>> -#if __OS_HAS_MTRR +>>>> -static inline int drm_core_has_MTRR(struct drm_device *dev) +>>>> -{ +>>>> - return drm_core_check_feature(dev, DRIVER_USE_MTRR); +>>>> -} +>>>> -#else +>>>> -#define drm_core_has_MTRR(dev) (0) +>>>> -#endif +>>>> - +>>> +>>> That was the last user of DRIVER_USE_MTRR (apart from drivers setting +>>> it in .driver_features). Any reason to keep it around? +>> +>> Yeah, I guess we could rip things out. Which will also force me to +>> properly audit drivers for the eventual behaviour change this could +>> entail (in case there's an x86 driver which did not ask for an mtrr, +>> but iirc there isn't). +> +> david@david-mb ~/dev/kernel/linux $ for i in drivers/gpu/drm/* ; do if +> test -d "$i" ; then if ! grep -q USE_MTRR -r $i ; then echo $i ; fi ; +> fi ; done +> drivers/gpu/drm/exynos +> drivers/gpu/drm/gma500 +> drivers/gpu/drm/i2c +> drivers/gpu/drm/nouveau +> drivers/gpu/drm/omapdrm +> drivers/gpu/drm/qxl +> drivers/gpu/drm/rcar-du +> drivers/gpu/drm/shmobile +> drivers/gpu/drm/tilcdc +> drivers/gpu/drm/ttm +> drivers/gpu/drm/udl +> drivers/gpu/drm/vmwgfx +> david@david-mb ~/dev/kernel/linux $ +> +> So for x86 gma500,nouveau,qxl,udl,vmwgfx don't set DRIVER_USE_MTRR. +> But I cannot tell whether they break if we call arch_phys_wc_add/del, +> anyway. At least nouveau seemed to work here, but it doesn't use AGP +> or drm_bufs, I guess. + +Cool, thanks a lot for stitching together the list of drivers to look +at. So for real KMS drivers it's the drives responsibility to add an +mtrr if it needs one. nouvea, radeon, mgag200, i915 and vmwgfx do that +already. Somehow the savage driver also ends up doing that, I have no +idea why. + +Note that gma500 as a pure KMS driver doesn't need MTRR setup since +the platforms that it supports all support PAT. So no MTRRs needed to +get wc iomappings. + +The mtrr support in the drm core is all for legacy mappings of garts, +framebuffers and registers. All legacy drivers set the USE_MTRR flag, +so we're good there. + +All in all I think we can really just ditch this + +/endquote + +v2: Also kill DRIVER_USE_MTRR as suggested by David Herrmann + +v3: Rebase on top of David Herrmann's agp setup/cleanup changes. + +Cc: David Herrmann +Cc: Andy Lutomirski +Signed-off-by: Daniel Vetter +Acked-by: Andy Lutomirski +Reviewed-by: David Herrmann +Signed-off-by: Dave Airlie +(cherry picked from commit 281856477cdaba70032af502ee7192fe7aa54f69) +Signed-off-by: James Ausmus + +Conflicts: + drivers/gpu/drm/radeon/radeon_drv.c + (context changes) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/ast/ast_drv.c | 2 +- + drivers/gpu/drm/cirrus/cirrus_drv.c | 2 +- + drivers/gpu/drm/drm_bufs.c | 13 +++++-------- + drivers/gpu/drm/drm_pci.c | 14 ++++++-------- + drivers/gpu/drm/drm_vm.c | 3 +-- + drivers/gpu/drm/i810/i810_drv.c | 2 +- + drivers/gpu/drm/i915/i915_drv.c | 2 +- + drivers/gpu/drm/mga/mga_drv.c | 2 +- + drivers/gpu/drm/mgag200/mgag200_drv.c | 2 +- + drivers/gpu/drm/r128/r128_drv.c | 2 +- + drivers/gpu/drm/radeon/radeon_drv.c | 4 ++-- + drivers/gpu/drm/savage/savage_drv.c | 2 +- + drivers/gpu/drm/sis/sis_drv.c | 2 +- + drivers/gpu/drm/tdfx/tdfx_drv.c | 1 - + drivers/gpu/drm/via/via_drv.c | 2 +- + include/drm/drmP.h | 11 ----------- + 16 files changed, 24 insertions(+), 42 deletions(-) + +diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c +index 60f1ce3998c3..32e270dc714e 100644 +--- a/drivers/gpu/drm/ast/ast_drv.c ++++ b/drivers/gpu/drm/ast/ast_drv.c +@@ -197,7 +197,7 @@ static const struct file_operations ast_fops = { + }; + + static struct drm_driver driver = { +- .driver_features = DRIVER_USE_MTRR | DRIVER_MODESET | DRIVER_GEM, ++ .driver_features = DRIVER_MODESET | DRIVER_GEM, + .dev_priv_size = 0, + + .load = ast_driver_load, +diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c +index dd9c908ab3fc..138364d91782 100644 +--- a/drivers/gpu/drm/cirrus/cirrus_drv.c ++++ b/drivers/gpu/drm/cirrus/cirrus_drv.c +@@ -87,7 +87,7 @@ static const struct file_operations cirrus_driver_fops = { + #endif + }; + static struct drm_driver driver = { +- .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_USE_MTRR, ++ .driver_features = DRIVER_MODESET | DRIVER_GEM, + .load = cirrus_driver_load, + .unload = cirrus_driver_unload, + .fops = &cirrus_driver_fops, +diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c +index 0190fce20078..7b7b93ed0fef 100644 +--- a/drivers/gpu/drm/drm_bufs.c ++++ b/drivers/gpu/drm/drm_bufs.c +@@ -207,12 +207,10 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, + return 0; + } + +- if (drm_core_has_MTRR(dev)) { +- if (map->type == _DRM_FRAME_BUFFER || +- (map->flags & _DRM_WRITE_COMBINING)) { +- map->mtrr = +- arch_phys_wc_add(map->offset, map->size); +- } ++ if (map->type == _DRM_FRAME_BUFFER || ++ (map->flags & _DRM_WRITE_COMBINING)) { ++ map->mtrr = ++ arch_phys_wc_add(map->offset, map->size); + } + if (map->type == _DRM_REGISTERS) { + if (map->flags & _DRM_WRITE_COMBINING) +@@ -455,8 +453,7 @@ int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map) + iounmap(map->handle); + /* FALLTHROUGH */ + case _DRM_FRAME_BUFFER: +- if (drm_core_has_MTRR(dev)) +- arch_phys_wc_del(map->mtrr); ++ arch_phys_wc_del(map->mtrr); + break; + case _DRM_SHM: + vfree(map->handle); +diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c +index 382e5bd699c6..83fb3dba1b25 100644 +--- a/drivers/gpu/drm/drm_pci.c ++++ b/drivers/gpu/drm/drm_pci.c +@@ -276,12 +276,11 @@ static int drm_pci_agp_init(struct drm_device *dev) + DRM_ERROR("Cannot initialize the agpgart module.\n"); + return -EINVAL; + } +- if (drm_core_has_MTRR(dev)) { +- if (dev->agp) +- dev->agp->agp_mtrr = arch_phys_wc_add( +- dev->agp->agp_info.aper_base, +- dev->agp->agp_info.aper_size * +- 1024 * 1024); ++ if (dev->agp) { ++ dev->agp->agp_mtrr = arch_phys_wc_add( ++ dev->agp->agp_info.aper_base, ++ dev->agp->agp_info.aper_size * ++ 1024 * 1024); + } + } + return 0; +@@ -290,8 +289,7 @@ static int drm_pci_agp_init(struct drm_device *dev) + static void drm_pci_agp_destroy(struct drm_device *dev) + { + if (drm_core_has_AGP(dev) && dev->agp) { +- if (drm_core_has_MTRR(dev)) +- arch_phys_wc_del(dev->agp->agp_mtrr); ++ arch_phys_wc_del(dev->agp->agp_mtrr); + drm_agp_clear(dev); + drm_agp_destroy(dev->agp); + dev->agp = NULL; +diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c +index 1575694ccaca..f8bc9fdd3575 100644 +--- a/drivers/gpu/drm/drm_vm.c ++++ b/drivers/gpu/drm/drm_vm.c +@@ -251,8 +251,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) + switch (map->type) { + case _DRM_REGISTERS: + case _DRM_FRAME_BUFFER: +- if (drm_core_has_MTRR(dev)) +- arch_phys_wc_del(map->mtrr); ++ arch_phys_wc_del(map->mtrr); + iounmap(map->handle); + break; + case _DRM_SHM: +diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c +index d85c05b4877d..d8180d22cedd 100644 +--- a/drivers/gpu/drm/i810/i810_drv.c ++++ b/drivers/gpu/drm/i810/i810_drv.c +@@ -57,7 +57,7 @@ static const struct file_operations i810_driver_fops = { + + static struct drm_driver driver = { + .driver_features = +- DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | ++ DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | + DRIVER_HAVE_DMA, + .dev_priv_size = sizeof(drm_i810_buf_priv_t), + .load = i810_driver_load, +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 9411a745adaf..eec47bd00353 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -1006,7 +1006,7 @@ static struct drm_driver driver = { + * deal with them for Intel hardware. + */ + .driver_features = +- DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ ++ DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | + DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME, + .load = i915_driver_load, + .unload = i915_driver_unload, +diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c +index fe71e1e44e48..6b1a87c8aac5 100644 +--- a/drivers/gpu/drm/mga/mga_drv.c ++++ b/drivers/gpu/drm/mga/mga_drv.c +@@ -58,7 +58,7 @@ static const struct file_operations mga_driver_fops = { + + static struct drm_driver driver = { + .driver_features = +- DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | ++ DRIVER_USE_AGP | DRIVER_PCI_DMA | + DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, + .dev_priv_size = sizeof(drm_mga_buf_priv_t), + .load = mga_driver_load, +diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c +index b570127ae3b2..fcce7b2f8011 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_drv.c ++++ b/drivers/gpu/drm/mgag200/mgag200_drv.c +@@ -88,7 +88,7 @@ static const struct file_operations mgag200_driver_fops = { + }; + + static struct drm_driver driver = { +- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_USE_MTRR, ++ .driver_features = DRIVER_GEM | DRIVER_MODESET, + .load = mgag200_driver_load, + .unload = mgag200_driver_unload, + .fops = &mgag200_driver_fops, +diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c +index c2338cbc56ad..5bd307cd8da1 100644 +--- a/drivers/gpu/drm/r128/r128_drv.c ++++ b/drivers/gpu/drm/r128/r128_drv.c +@@ -56,7 +56,7 @@ static const struct file_operations r128_driver_fops = { + + static struct drm_driver driver = { + .driver_features = +- DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | ++ DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | + DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, + .dev_priv_size = sizeof(drm_r128_buf_priv_t), + .load = r128_driver_load, +diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c +index 3c5f6420319e..6d26fb2c0a83 100644 +--- a/drivers/gpu/drm/radeon/radeon_drv.c ++++ b/drivers/gpu/drm/radeon/radeon_drv.c +@@ -268,7 +268,7 @@ static const struct file_operations radeon_driver_old_fops = { + + static struct drm_driver driver_old = { + .driver_features = +- DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | ++ DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | + DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED, + .dev_priv_size = sizeof(drm_radeon_buf_priv_t), + .load = radeon_driver_load, +@@ -375,7 +375,7 @@ static const struct file_operations radeon_driver_kms_fops = { + + static struct drm_driver kms_driver = { + .driver_features = +- DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | ++ DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | + DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_GEM | + DRIVER_PRIME, + .dev_priv_size = 0, +diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c +index 9135c8bd6fbc..3c030216e888 100644 +--- a/drivers/gpu/drm/savage/savage_drv.c ++++ b/drivers/gpu/drm/savage/savage_drv.c +@@ -50,7 +50,7 @@ static const struct file_operations savage_driver_fops = { + + static struct drm_driver driver = { + .driver_features = +- DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA, ++ DRIVER_USE_AGP | DRIVER_HAVE_DMA | DRIVER_PCI_DMA, + .dev_priv_size = sizeof(drm_savage_buf_priv_t), + .load = savage_driver_load, + .firstopen = savage_driver_firstopen, +diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c +index b88b2d302105..4383b74a3aa4 100644 +--- a/drivers/gpu/drm/sis/sis_drv.c ++++ b/drivers/gpu/drm/sis/sis_drv.c +@@ -102,7 +102,7 @@ void sis_driver_postclose(struct drm_device *dev, struct drm_file *file) + } + + static struct drm_driver driver = { +- .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, ++ .driver_features = DRIVER_USE_AGP, + .load = sis_driver_load, + .unload = sis_driver_unload, + .open = sis_driver_open, +diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c +index 951ec13e4e5c..3492ca5c46d3 100644 +--- a/drivers/gpu/drm/tdfx/tdfx_drv.c ++++ b/drivers/gpu/drm/tdfx/tdfx_drv.c +@@ -55,7 +55,6 @@ static const struct file_operations tdfx_driver_fops = { + }; + + static struct drm_driver driver = { +- .driver_features = DRIVER_USE_MTRR, + .fops = &tdfx_driver_fops, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, +diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c +index 448799968a06..92684a9b7e34 100644 +--- a/drivers/gpu/drm/via/via_drv.c ++++ b/drivers/gpu/drm/via/via_drv.c +@@ -72,7 +72,7 @@ static const struct file_operations via_driver_fops = { + + static struct drm_driver driver = { + .driver_features = +- DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | ++ DRIVER_USE_AGP | DRIVER_HAVE_IRQ | + DRIVER_IRQ_SHARED, + .load = via_driver_load, + .unload = via_driver_unload, +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 39e12a6356f9..f65eaddd4844 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -74,7 +74,6 @@ + #include + + #define __OS_HAS_AGP (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE))) +-#define __OS_HAS_MTRR (defined(CONFIG_MTRR)) + + struct module; + +@@ -139,7 +138,6 @@ int drm_err(const char *func, const char *format, ...); + /* driver capabilities and requirements mask */ + #define DRIVER_USE_AGP 0x1 + #define DRIVER_REQUIRE_AGP 0x2 +-#define DRIVER_USE_MTRR 0x4 + #define DRIVER_PCI_DMA 0x8 + #define DRIVER_SG 0x10 + #define DRIVER_HAVE_DMA 0x20 +@@ -1219,15 +1217,6 @@ static inline int drm_dev_to_irq(struct drm_device *dev) + return dev->driver->bus->get_irq(dev); + } + +-#if __OS_HAS_MTRR +-static inline int drm_core_has_MTRR(struct drm_device *dev) +-{ +- return drm_core_check_feature(dev, DRIVER_USE_MTRR); +-} +-#else +-#define drm_core_has_MTRR(dev) (0) +-#endif +- + static inline void drm_device_set_unplugged(struct drm_device *dev) + { + smp_wmb(); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0671-drm-i915-Only-do-a-chipset-flush-after-a-clflush.patch b/patches.baytrail/0671-drm-i915-Only-do-a-chipset-flush-after-a-clflush.patch new file mode 100644 index 000000000000..76b57024cab3 --- /dev/null +++ b/patches.baytrail/0671-drm-i915-Only-do-a-chipset-flush-after-a-clflush.patch @@ -0,0 +1,136 @@ +From d61196c0ca69ba7a0f374b32c53b7b07c6c6cdba Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Thu, 8 Aug 2013 14:41:09 +0100 +Subject: drm/i915: Only do a chipset flush after a clflush +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Now that we skip clflushes more often, return a boolean indicating +whether the clflush was actually performed, and only if it was do the +chipset flush. (Though on most of the architectures where the clflush will +be skipped, the chipset flush is a no-op!) + +Signed-off-by: Chris Wilson +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 000433b67e46771a7c08f78574943855a98c53ec) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 +- + drivers/gpu/drm/i915/i915_gem.c | 20 +++++++++++--------- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 5 +++-- + 3 files changed, 15 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index d25f9f712b6f..cccd6084b236 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1840,7 +1840,7 @@ static inline bool i915_terminally_wedged(struct i915_gpu_error *error) + } + + void i915_gem_reset(struct drm_device *dev); +-void i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force); ++bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force); + int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); + int __must_check i915_gem_init(struct drm_device *dev); + int __must_check i915_gem_init_hw(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index ce4a8c4e42ac..f7f3cba75b57 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -835,8 +835,8 @@ out: + */ + if (!needs_clflush_after && + obj->base.write_domain != I915_GEM_DOMAIN_CPU) { +- i915_gem_clflush_object(obj, obj->pin_display); +- i915_gem_chipset_flush(dev); ++ if (i915_gem_clflush_object(obj, obj->pin_display)) ++ i915_gem_chipset_flush(dev); + } + } + +@@ -3212,7 +3212,7 @@ err_unpin: + return ret; + } + +-void ++bool + i915_gem_clflush_object(struct drm_i915_gem_object *obj, + bool force) + { +@@ -3221,14 +3221,14 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj, + * again at bind time. + */ + if (obj->pages == NULL) +- return; ++ return false; + + /* + * Stolen memory is always coherent with the GPU as it is explicitly + * marked as wc by the system, or the system is cache-coherent. + */ + if (obj->stolen) +- return; ++ return false; + + /* If the GPU is snooping the contents of the CPU cache, + * we do not need to manually clear the CPU cache lines. However, +@@ -3239,11 +3239,12 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj, + * tracking. + */ + if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) +- return; ++ return false; + + trace_i915_gem_object_clflush(obj); +- + drm_clflush_sg(obj->pages); ++ ++ return true; + } + + /** Flushes the GTT write domain for the object if it's dirty. */ +@@ -3283,8 +3284,9 @@ i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj, + if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) + return; + +- i915_gem_clflush_object(obj, force); +- i915_gem_chipset_flush(obj->base.dev); ++ if (i915_gem_clflush_object(obj, force)) ++ i915_gem_chipset_flush(obj->base.dev); ++ + old_write_domain = obj->base.write_domain; + obj->base.write_domain = 0; + +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index e999578a021c..7dcf78cf6781 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -708,6 +708,7 @@ i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, + { + struct drm_i915_gem_object *obj; + uint32_t flush_domains = 0; ++ bool flush_chipset = false; + int ret; + + list_for_each_entry(obj, objects, exec_list) { +@@ -716,12 +717,12 @@ i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, + return ret; + + if (obj->base.write_domain & I915_GEM_DOMAIN_CPU) +- i915_gem_clflush_object(obj, false); ++ flush_chipset |= i915_gem_clflush_object(obj, false); + + flush_domains |= obj->base.write_domain; + } + +- if (flush_domains & I915_GEM_DOMAIN_CPU) ++ if (flush_chipset) + i915_gem_chipset_flush(ring->dev); + + if (flush_domains & I915_GEM_DOMAIN_GTT) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0672-drm-i915-WARN_ON-failed-map_and_fenceable.patch b/patches.baytrail/0672-drm-i915-WARN_ON-failed-map_and_fenceable.patch new file mode 100644 index 000000000000..b12631514ace --- /dev/null +++ b/patches.baytrail/0672-drm-i915-WARN_ON-failed-map_and_fenceable.patch @@ -0,0 +1,35 @@ +From 53dda2c1621a455ee5622e6beb24f1f821ce7eb6 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Fri, 9 Aug 2013 22:12:12 -0700 +Subject: drm/i915: WARN_ON failed map_and_fenceable + +I just noticed in our code we don't really check the assertion, and +given some of the code I am changing in this area, I feel a WARN is very +nice to have. + +Signed-off-by: Ben Widawsky +[danvet: s/&/&&/ to fix typo on the check.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 7ace7ef2f5d20632240196fa3e5d5c74cf2c1508) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index f7f3cba75b57..b6f01ef1d174 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3199,6 +3199,8 @@ search_free: + if (i915_is_ggtt(vm)) + obj->map_and_fenceable = mappable && fenceable; + ++ WARN_ON(map_and_fenceable && !obj->map_and_fenceable); ++ + trace_i915_vma_bind(vma, map_and_fenceable); + i915_gem_verify_gtt(dev); + return 0; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0673-i915-Fix-SDVO-potentially-turning-off-randomly.patch b/patches.baytrail/0673-i915-Fix-SDVO-potentially-turning-off-randomly.patch new file mode 100644 index 000000000000..03f177ac5455 --- /dev/null +++ b/patches.baytrail/0673-i915-Fix-SDVO-potentially-turning-off-randomly.patch @@ -0,0 +1,36 @@ +From 1a089b1bf0b130982ed7edad12ec360280ef78c2 Mon Sep 17 00:00:00 2001 +From: Guillaume Clement +Date: Sat, 10 Aug 2013 21:57:57 +0200 +Subject: i915: Fix SDVO potentially turning off randomly + +Some Poulsbo cards seem to incorrectly report +SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED instead of +SDVO_CMD_STATUS_PENDING, which causes the display to be turned off. + +This could also happen to i915. + +Signed-off-by: Guillaume Clement +Signed-off-by: Daniel Vetter +(cherry picked from commit 1ad87e72b54cf3b698c002f0a31ac34d6b407f0b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sdvo.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 02f220b4e4a1..317e058fb3cf 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -538,7 +538,8 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, + &status)) + goto log_fail; + +- while (status == SDVO_CMD_STATUS_PENDING && --retry) { ++ while ((status == SDVO_CMD_STATUS_PENDING || ++ status == SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED) && --retry) { + if (retry < 10) + msleep(15); + else +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0674-drm-i915-remove-unused-leftover-variable-irq_receive.patch b/patches.baytrail/0674-drm-i915-remove-unused-leftover-variable-irq_receive.patch new file mode 100644 index 000000000000..ce32d0652440 --- /dev/null +++ b/patches.baytrail/0674-drm-i915-remove-unused-leftover-variable-irq_receive.patch @@ -0,0 +1,44 @@ +From 00f4d77457e9f6a74d6ef733bbaecd86c79b0642 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Sun, 11 Aug 2013 12:44:26 +0300 +Subject: drm/i915: remove unused leftover variable irq_received + +It's been there since i8xx_irq_handler() was added in +commit c2798b19bac2538393fc932bfbe59807a4734b3e +Author: Chris Wilson +Date: Sun Apr 22 21:13:57 2012 +0100 + + drm/i915: i8xx interrupt handler + +Signed-off-by: Jani Nikula +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit c8b5018b22bc03941fbc6dcf7bea5e8344a8f3da) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 076091e92eea..96430a360b89 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2449,7 +2449,6 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) + u16 iir, new_iir; + u32 pipe_stats[2]; + unsigned long irqflags; +- int irq_received; + int pipe; + u16 flip_mask = + I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | +@@ -2483,7 +2482,6 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) + DRM_DEBUG_DRIVER("pipe %c underrun\n", + pipe_name(pipe)); + I915_WRITE(reg, pipe_stats[pipe]); +- irq_received = 1; + } + } + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0675-drm-i915-give-more-distinctive-names-to-ring-hangche.patch b/patches.baytrail/0675-drm-i915-give-more-distinctive-names-to-ring-hangche.patch new file mode 100644 index 000000000000..a4ac24077f1d --- /dev/null +++ b/patches.baytrail/0675-drm-i915-give-more-distinctive-names-to-ring-hangche.patch @@ -0,0 +1,121 @@ +From ef643f5bc7a26658f51a4be1eb29d27ec05c1a31 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Sun, 11 Aug 2013 12:44:01 +0300 +Subject: drm/i915: give more distinctive names to ring hangcheck action enums + +The short lowercase names are bound to collide. The default warnings +don't even warn about shadowing. + +Signed-off-by: Jani Nikula +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit f2f4d82faf85d2e53a2ba00a831a9f7f80b7e6e7) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 2 +- + drivers/gpu/drm/i915/i915_irq.c | 22 +++++++++++----------- + drivers/gpu/drm/i915/intel_ringbuffer.h | 7 ++++++- + 3 files changed, 18 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index b6f01ef1d174..66136cd88ed5 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2201,7 +2201,7 @@ static void i915_set_reset_status(struct intel_ring_buffer *ring, + offset = i915_gem_obj_offset(request->batch_obj, + request_to_vm(request)); + +- if (ring->hangcheck.action != wait && ++ if (ring->hangcheck.action != HANGCHECK_WAIT && + i915_request_guilty(request, acthd, &inside)) { + DRM_ERROR("%s hung %s bo (0x%lx ctx %d) at 0x%x\n", + ring->name, +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 96430a360b89..096d50142c11 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1872,10 +1872,10 @@ ring_stuck(struct intel_ring_buffer *ring, u32 acthd) + u32 tmp; + + if (ring->hangcheck.acthd != acthd) +- return active; ++ return HANGCHECK_ACTIVE; + + if (IS_GEN2(dev)) +- return hung; ++ return HANGCHECK_HUNG; + + /* Is the chip hanging on a WAIT_FOR_EVENT? + * If so we can simply poke the RB_WAIT bit +@@ -1887,24 +1887,24 @@ ring_stuck(struct intel_ring_buffer *ring, u32 acthd) + DRM_ERROR("Kicking stuck wait on %s\n", + ring->name); + I915_WRITE_CTL(ring, tmp); +- return kick; ++ return HANGCHECK_KICK; + } + + if (INTEL_INFO(dev)->gen >= 6 && tmp & RING_WAIT_SEMAPHORE) { + switch (semaphore_passed(ring)) { + default: +- return hung; ++ return HANGCHECK_HUNG; + case 1: + DRM_ERROR("Kicking stuck semaphore on %s\n", + ring->name); + I915_WRITE_CTL(ring, tmp); +- return kick; ++ return HANGCHECK_KICK; + case 0: +- return wait; ++ return HANGCHECK_WAIT; + } + } + +- return hung; ++ return HANGCHECK_HUNG; + } + + /** +@@ -1972,16 +1972,16 @@ static void i915_hangcheck_elapsed(unsigned long data) + acthd); + + switch (ring->hangcheck.action) { +- case wait: ++ case HANGCHECK_WAIT: + score = 0; + break; +- case active: ++ case HANGCHECK_ACTIVE: + score = BUSY; + break; +- case kick: ++ case HANGCHECK_KICK: + score = KICK; + break; +- case hung: ++ case HANGCHECK_HUNG: + score = HUNG; + stuck[i] = true; + break; +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index 6e38256d41e1..5e6be842d225 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -37,7 +37,12 @@ struct intel_hw_status_page { + #define I915_READ_SYNC_0(ring) I915_READ(RING_SYNC_0((ring)->mmio_base)) + #define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base)) + +-enum intel_ring_hangcheck_action { wait, active, kick, hung }; ++enum intel_ring_hangcheck_action { ++ HANGCHECK_WAIT, ++ HANGCHECK_ACTIVE, ++ HANGCHECK_KICK, ++ HANGCHECK_HUNG, ++}; + + struct intel_ring_hangcheck { + bool deadlock; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0676-drm-i915-drop-unnecessary-local-variable-to-suppress.patch b/patches.baytrail/0676-drm-i915-drop-unnecessary-local-variable-to-suppress.patch new file mode 100644 index 000000000000..0f456f226316 --- /dev/null +++ b/patches.baytrail/0676-drm-i915-drop-unnecessary-local-variable-to-suppress.patch @@ -0,0 +1,66 @@ +From 946ff50b24654a2a633cb5566248a7f0620d6924 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Sun, 11 Aug 2013 12:44:02 +0300 +Subject: drm/i915: drop unnecessary local variable to suppress build warning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Although I could not reproduce this (different compiler version, +perhaps), reportedly we get: + +drivers/gpu/drm/i915/i915_irq.c:1943:27: warning: ‘score’ may be used +uninitialized in this function [-Wuninitialized] + +Drop the 'score' variable altogether as it's not really needed. + +Reported-by: Kees Cook +Signed-off-by: Jani Nikula +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit ea04cb31d506ac3f4fc3cefb1c50eb4f35ab37fd) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 096d50142c11..36cf7073690e 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1951,8 +1951,6 @@ static void i915_hangcheck_elapsed(unsigned long data) + } else + busy = false; + } else { +- int score; +- + /* We always increment the hangcheck score + * if the ring is busy and still processing + * the same request, so that no single request +@@ -1973,20 +1971,18 @@ static void i915_hangcheck_elapsed(unsigned long data) + + switch (ring->hangcheck.action) { + case HANGCHECK_WAIT: +- score = 0; + break; + case HANGCHECK_ACTIVE: +- score = BUSY; ++ ring->hangcheck.score += BUSY; + break; + case HANGCHECK_KICK: +- score = KICK; ++ ring->hangcheck.score += KICK; + break; + case HANGCHECK_HUNG: +- score = HUNG; ++ ring->hangcheck.score += HUNG; + stuck[i] = true; + break; + } +- ring->hangcheck.score += score; + } + } else { + /* Gradually reduce the count so that we catch DoS +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0677-drm-i915-reserve-I915_CACHING_DISPLAY-and-document-c.patch b/patches.baytrail/0677-drm-i915-reserve-I915_CACHING_DISPLAY-and-document-c.patch new file mode 100644 index 000000000000..705d96ed4355 --- /dev/null +++ b/patches.baytrail/0677-drm-i915-reserve-I915_CACHING_DISPLAY-and-document-c.patch @@ -0,0 +1,66 @@ +From 2a102a6ca28b062eddb36b035afd83cf0e3e54e2 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sat, 10 Aug 2013 14:51:11 +0200 +Subject: drm/i915: reserve I915_CACHING_DISPLAY and document cache modes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Resolve the catch-22 of igt needing a stable number and patches first +needing testcases by reserving the interface number up-front. + +v2: Improve the spelling a bit. + +v3: More spelling fail spotted by Chris. + +Requested-by: Chris Wilson +Cc: Chris Wilson +Cc: Ville Syrjälä +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 35c7ab421a13f8327e3fd627c6ebafb1c13b2e55) +Signed-off-by: Darren Hart +--- + include/uapi/drm/i915_drm.h | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h +index a1a7b6bd60d8..0bb3e5524382 100644 +--- a/include/uapi/drm/i915_drm.h ++++ b/include/uapi/drm/i915_drm.h +@@ -768,8 +768,32 @@ struct drm_i915_gem_busy { + __u32 busy; + }; + ++/** ++ * I915_CACHING_NONE ++ * ++ * GPU access is not coherent with cpu caches. Default for machines without an ++ * LLC. ++ */ + #define I915_CACHING_NONE 0 ++/** ++ * I915_CACHING_CACHED ++ * ++ * GPU access is coherent with cpu caches and furthermore the data is cached in ++ * last-level caches shared between cpu cores and the gpu GT. Default on ++ * machines with HAS_LLC. ++ */ + #define I915_CACHING_CACHED 1 ++/** ++ * I915_CACHING_DISPLAY ++ * ++ * Special GPU caching mode which is coherent with the scanout engines. ++ * Transparently falls back to I915_CACHING_NONE on platforms where no special ++ * cache mode (like write-through or gfdt flushing) is available. The kernel ++ * automatically sets this mode when using a buffer as a scanout target. ++ * Userspace can manually set this mode to avoid a costly stall and clflush in ++ * the hotpath of drawing the first frame. ++ */ ++#define I915_CACHING_DISPLAY 2 + + struct drm_i915_gem_caching { + /** +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0678-drm-i915-Use-Write-Through-cacheing-for-the-display-.patch b/patches.baytrail/0678-drm-i915-Use-Write-Through-cacheing-for-the-display-.patch new file mode 100644 index 000000000000..590ee1d749d0 --- /dev/null +++ b/patches.baytrail/0678-drm-i915-Use-Write-Through-cacheing-for-the-display-.patch @@ -0,0 +1,159 @@ +From 1411160277c96987c6e78f079b509ec01dd7daed Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Thu, 8 Aug 2013 14:41:10 +0100 +Subject: drm/i915: Use Write-Through cacheing for the display plane on Iris +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Haswell GT3e has the unique feature of supporting Write-Through cacheing +of objects within the eLLC/LLC. The purpose of this is to enable the display +plane to remain coherent whilst objects lie resident in the eLLC/LLC - so +that we, in theory, get the best of both worlds, perfect display and fast +access. + +However, we still need to be careful as the CPU does not see the WT when +accessing the cache. In particular, this means that we need to flush the +cache lines after writing to an object through the CPU, and on +transitioning from a cached state to WT. + +v2: Actually do the clflush on transition to WT, nagging by Ville. +v3: Flush the CPU cache after writes into WT objects. +v4: Rease onto LLC updates and report WT as "uncached" for +get_cache_level_ioctl to remain symmetric with set_cache_level_ioctl. + +Signed-off-by: Chris Wilson +Cc: Ville Syrjälä +Cc: Kenneth Graunke +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 651d794fae9b79237aae1c97f8a9d9f3817bd31d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 3 +++ + drivers/gpu/drm/i915/i915_drv.h | 4 +++- + drivers/gpu/drm/i915/i915_gem.c | 14 ++++++++++++-- + drivers/gpu/drm/i915/i915_gem_gtt.c | 11 ++++++++++- + include/uapi/drm/i915_drm.h | 1 + + 5 files changed, 29 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 0adfe4000871..45c262b9cb40 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -976,6 +976,9 @@ static int i915_getparam(struct drm_device *dev, void *data, + case I915_PARAM_HAS_LLC: + value = HAS_LLC(dev); + break; ++ case I915_PARAM_HAS_WT: ++ value = HAS_WT(dev); ++ break; + case I915_PARAM_HAS_ALIASING_PPGTT: + value = dev_priv->mm.aliasing_ppgtt ? 1 : 0; + break; +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index cccd6084b236..dcae809eafe8 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -454,6 +454,7 @@ enum i915_cache_level { + caches, eg sampler/render caches, and the + large Last-Level-Cache. LLC is coherent with + the CPU, but L3 is only visible to the GPU. */ ++ I915_CACHE_WT, /* hsw:gt3e WriteThrough for scanouts */ + }; + + typedef uint32_t gen6_gtt_pte_t; +@@ -1385,7 +1386,7 @@ struct drm_i915_gem_object { + unsigned int pending_fenced_gpu_access:1; + unsigned int fenced_gpu_access:1; + +- unsigned int cache_level:2; ++ unsigned int cache_level:3; + + unsigned int has_aliasing_ppgtt_mapping:1; + unsigned int has_global_gtt_mapping:1; +@@ -1530,6 +1531,7 @@ struct drm_i915_file_private { + #define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) + #define HAS_VEBOX(dev) (INTEL_INFO(dev)->has_vebox_ring) + #define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) ++#define HAS_WT(dev) (IS_HASWELL(dev) && to_i915(dev)->ellc_size) + #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) + + #define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6) +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 66136cd88ed5..8e41b2c6eb1d 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3459,7 +3459,16 @@ int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data, + goto unlock; + } + +- args->caching = obj->cache_level != I915_CACHE_NONE; ++ switch (obj->cache_level) { ++ case I915_CACHE_LLC: ++ case I915_CACHE_L3_LLC: ++ args->caching = I915_CACHING_CACHED; ++ break; ++ ++ default: ++ args->caching = I915_CACHING_NONE; ++ break; ++ } + + drm_gem_object_unreference(&obj->base); + unlock: +@@ -3553,7 +3562,8 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, + * of uncaching, which would allow us to flush all the LLC-cached data + * with that bit in the PTE to main memory with just one PIPE_CONTROL. + */ +- ret = i915_gem_object_set_cache_level(obj, I915_CACHE_NONE); ++ ret = i915_gem_object_set_cache_level(obj, ++ HAS_WT(obj->base.dev) ? I915_CACHE_WT : I915_CACHE_NONE); + if (ret) + goto err_unpin_display; + +diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c +index c9420c280cf0..212f6d8c35ec 100644 +--- a/drivers/gpu/drm/i915/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/i915_gem_gtt.c +@@ -55,6 +55,7 @@ + #define HSW_WB_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x2) + #define HSW_WB_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x3) + #define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb) ++#define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6) + + static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr, + enum i915_cache_level level) +@@ -138,8 +139,16 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr, + gen6_gtt_pte_t pte = GEN6_PTE_VALID; + pte |= HSW_PTE_ADDR_ENCODE(addr); + +- if (level != I915_CACHE_NONE) ++ switch (level) { ++ case I915_CACHE_NONE: ++ break; ++ case I915_CACHE_WT: ++ pte |= HSW_WT_ELLC_LLC_AGE0; ++ break; ++ default: + pte |= HSW_WB_ELLC_LLC_AGE0; ++ break; ++ } + + return pte; + } +diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h +index 0bb3e5524382..55bb5729bd78 100644 +--- a/include/uapi/drm/i915_drm.h ++++ b/include/uapi/drm/i915_drm.h +@@ -334,6 +334,7 @@ typedef struct drm_i915_irq_wait { + #define I915_PARAM_HAS_PINNED_BATCHES 24 + #define I915_PARAM_HAS_EXEC_NO_RELOC 25 + #define I915_PARAM_HAS_EXEC_HANDLE_LUT 26 ++#define I915_PARAM_HAS_WT 27 + + typedef struct drm_i915_getparam { + int param; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0679-drm-i915-Allow-the-user-to-set-bo-into-the-DISPLAY-c.patch b/patches.baytrail/0679-drm-i915-Allow-the-user-to-set-bo-into-the-DISPLAY-c.patch new file mode 100644 index 000000000000..588ac3328fe1 --- /dev/null +++ b/patches.baytrail/0679-drm-i915-Allow-the-user-to-set-bo-into-the-DISPLAY-c.patch @@ -0,0 +1,55 @@ +From 5ec64f92dc305cd6378f496d9dd09825bfe8a248 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Thu, 8 Aug 2013 14:41:11 +0100 +Subject: drm/i915: Allow the user to set bo into the DISPLAY cache domain +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is primarily for the benefit of the create2 ioctl so that the +caller can avoid the later step of rebinding the bo with new PTE bits. +After introducing WT (and possibly GFDT) cacheing for display targets, +not everything in the display is earmarked as UC, and more importantly +what is is controlled by the kernel. + +Note that set_cache_level/get_cache_level for DISPLAY is not necessarily +idempotent; get_cache_level may return UC for architectures that have no +special cache domain for the display engine. + +Signed-off-by: Chris Wilson +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 4257d3ba3b87a84adb2f840620cb63512f0bab22) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 8e41b2c6eb1d..3d9e248bf422 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3465,6 +3465,10 @@ int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data, + args->caching = I915_CACHING_CACHED; + break; + ++ case I915_CACHE_WT: ++ args->caching = I915_CACHING_DISPLAY; ++ break; ++ + default: + args->caching = I915_CACHING_NONE; + break; +@@ -3491,6 +3495,9 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, + case I915_CACHING_CACHED: + level = I915_CACHE_LLC; + break; ++ case I915_CACHING_DISPLAY: ++ level = HAS_WT(dev) ? I915_CACHE_WT : I915_CACHE_NONE; ++ break; + default: + return -EINVAL; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0680-drm-i915-remove-set-but-unused-variables.patch b/patches.baytrail/0680-drm-i915-remove-set-but-unused-variables.patch new file mode 100644 index 000000000000..22b31f5e2909 --- /dev/null +++ b/patches.baytrail/0680-drm-i915-remove-set-but-unused-variables.patch @@ -0,0 +1,143 @@ +From 814174445820af4198b78ba86f8a2094cefaf441 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Mon, 12 Aug 2013 14:56:53 -0300 +Subject: drm/i915: remove set but unused variables + +Caught by "make W=1 drivers/gpu/drm/i915/". + +Signed-off-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit f3f08572fc245bc0cf5f102473ce0f54e693831d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 12 ++---------- + drivers/gpu/drm/i915/intel_dp.c | 3 --- + drivers/gpu/drm/i915/intel_hdmi.c | 2 -- + 3 files changed, 2 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 65bc851f5f91..52508e7f2658 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -690,7 +690,7 @@ vlv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, + { + u32 p1, p2, m1, m2, vco, bestn, bestm1, bestm2, bestp1, bestp2; + u32 m, n, fastclk; +- u32 updrate, minupdate, fracbits, p; ++ u32 updrate, minupdate, p; + unsigned long bestppm, ppm, absppm; + int dotclk, flag; + +@@ -701,7 +701,6 @@ vlv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc, + fastclk = dotclk / (2*100); + updrate = 0; + minupdate = 19200; +- fracbits = 1; + n = p = p1 = p2 = m = m1 = m2 = vco = bestn = 0; + bestm1 = bestm2 = bestp1 = bestp2 = 0; + +@@ -4419,13 +4418,10 @@ static void vlv_update_pll(struct intel_crtc *crtc) + int pipe = crtc->pipe; + u32 dpll, mdiv; + u32 bestn, bestm1, bestm2, bestp1, bestp2; +- bool is_hdmi; + u32 coreclk, reg_val, dpll_md; + + mutex_lock(&dev_priv->dpio_lock); + +- is_hdmi = intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI); +- + bestn = crtc->config.dpll.n; + bestm1 = crtc->config.dpll.m1; + bestm2 = crtc->config.dpll.m2; +@@ -8900,14 +8896,13 @@ intel_modeset_stage_output_state(struct drm_device *dev, + struct drm_crtc *new_crtc; + struct intel_connector *connector; + struct intel_encoder *encoder; +- int count, ro; ++ int ro; + + /* The upper layers ensure that we either disable a crtc or have a list + * of connectors. For paranoia, double-check this. */ + WARN_ON(!set->fb && (set->num_connectors != 0)); + WARN_ON(set->fb && (set->num_connectors == 0)); + +- count = 0; + list_for_each_entry(connector, &dev->mode_config.connector_list, + base.head) { + /* Otherwise traverse passed in connector list and get encoders +@@ -8941,7 +8936,6 @@ intel_modeset_stage_output_state(struct drm_device *dev, + /* connector->new_encoder is now updated for all connectors. */ + + /* Update crtc of enabled connectors. */ +- count = 0; + list_for_each_entry(connector, &dev->mode_config.connector_list, + base.head) { + if (!connector->new_encoder) +@@ -10301,7 +10295,6 @@ void intel_modeset_cleanup(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; +- struct intel_crtc *intel_crtc; + + /* + * Interrupts and polling as the first thing to avoid creating havoc. +@@ -10325,7 +10318,6 @@ void intel_modeset_cleanup(struct drm_device *dev) + if (!crtc->fb) + continue; + +- intel_crtc = to_intel_crtc(crtc); + intel_increase_pllclock(crtc); + } + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 9e22bfd850df..46f3e674210d 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -2337,7 +2337,6 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) + struct drm_device *dev = encoder->dev; + int i; + uint8_t voltage; +- bool clock_recovery = false; + int voltage_tries, loop_tries; + uint32_t DP = intel_dp->DP; + +@@ -2355,7 +2354,6 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) + voltage = 0xff; + voltage_tries = 0; + loop_tries = 0; +- clock_recovery = false; + for (;;) { + /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ + uint8_t link_status[DP_LINK_STATUS_SIZE]; +@@ -2376,7 +2374,6 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) + + if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) { + DRM_DEBUG_KMS("clock recovery OK\n"); +- clock_recovery = true; + break; + } + +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index dd4fa35e0a85..a619d9435107 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -1245,7 +1245,6 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) + { + struct intel_digital_port *intel_dig_port; + struct intel_encoder *intel_encoder; +- struct drm_encoder *encoder; + struct intel_connector *intel_connector; + + intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL); +@@ -1259,7 +1258,6 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) + } + + intel_encoder = &intel_dig_port->base; +- encoder = &intel_encoder->base; + + drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs, + DRM_MODE_ENCODER_TMDS); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0681-drm-i915-Print-the-changes-required-for-modeset.patch b/patches.baytrail/0681-drm-i915-Print-the-changes-required-for-modeset.patch new file mode 100644 index 000000000000..1ab5b59cb099 --- /dev/null +++ b/patches.baytrail/0681-drm-i915-Print-the-changes-required-for-modeset.patch @@ -0,0 +1,34 @@ +From 69c683376a25fa36ec2bae8ab184df959bccecd7 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Tue, 13 Aug 2013 18:48:47 +0100 +Subject: drm/i915: Print the changes required for modeset + +After computing the stage changes for the set_config, record those in +the debug log. + +Signed-off-by: Chris Wilson +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit a1d95703b7fa5cbc4abf53f63df51c49cbacc7b6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 52508e7f2658..63df05ea823e 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8886,6 +8886,9 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set, + drm_mode_debug_printmodeline(set->mode); + config->mode_changed = true; + } ++ ++ DRM_DEBUG_KMS("computed changes for [CRTC:%d], mode_changed=%d, fb_changed=%d\n", ++ set->crtc->base.id, config->mode_changed, config->fb_changed); + } + + static int +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0682-drm-i915-print-a-message-when-we-detect-an-early-Has.patch b/patches.baytrail/0682-drm-i915-print-a-message-when-we-detect-an-early-Has.patch new file mode 100644 index 000000000000..f517be98de05 --- /dev/null +++ b/patches.baytrail/0682-drm-i915-print-a-message-when-we-detect-an-early-Has.patch @@ -0,0 +1,65 @@ +From d05d6bca3d792161eecf1bf6985594fb548f4d8e Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Mon, 12 Aug 2013 14:34:08 -0300 +Subject: drm/i915: print a message when we detect an early Haswell SDV + +The machines that fall in this category are the SDVs that have a PCI +ID starting with 0x0C. These are very early pre-production machines +and may not fully work. Other Haswell SDVs have PCI IDs that match the +real Haswell machines and we expect them to work better. + +Even though they have problems, they still mostly work so I don't see +a reason to refuse loading our driver. But I do see a reason to reject +bug reports from these machines, so the message should help the bug +triagers. + +As far as I know, we don't implement some workarounds that are +specific to these machines and suspend/resume may not work on most of +them, but besides this, they may work. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61508 +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit ed1c9e2cf414e32cb7ea1217b51b39e70fc132d2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 8 ++++++++ + drivers/gpu/drm/i915/i915_drv.h | 2 ++ + 2 files changed, 10 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 45c262b9cb40..b30404d00757 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1488,6 +1488,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + + i915_dump_device_info(dev_priv); + ++ /* Not all pre-production machines fall into this category, only the ++ * very first ones. Almost everything should work, except for maybe ++ * suspend/resume. And we don't implement workarounds that affect only ++ * pre-production machines. */ ++ if (IS_HSW_EARLY_SDV(dev)) ++ DRM_INFO("This is an early pre-production Haswell machine. " ++ "It may not be fully functional.\n"); ++ + if (i915_get_bridge_dev(dev)) { + ret = -EIO; + goto free_priv; +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index dcae809eafe8..3fc432437524 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1511,6 +1511,8 @@ struct drm_i915_file_private { + #define IS_VALLEYVIEW(dev) (INTEL_INFO(dev)->is_valleyview) + #define IS_HASWELL(dev) (INTEL_INFO(dev)->is_haswell) + #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) ++#define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \ ++ ((dev)->pci_device & 0xFF00) == 0x0C00) + #define IS_ULT(dev) (IS_HASWELL(dev) && \ + ((dev)->pci_device & 0xFF00) == 0x0A00) + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0683-drm-i915-tune-the-RC6-threshold-for-stability.patch b/patches.baytrail/0683-drm-i915-tune-the-RC6-threshold-for-stability.patch new file mode 100644 index 000000000000..f8d6382d7a1b --- /dev/null +++ b/patches.baytrail/0683-drm-i915-tune-the-RC6-threshold-for-stability.patch @@ -0,0 +1,56 @@ +From a22a07b07d38df6c0f7f62b95098aaa5de2b0587 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?St=C3=A9phane=20Marchesin?= +Date: Tue, 13 Aug 2013 11:55:17 -0700 +Subject: drm/i915: tune the RC6 threshold for stability +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It's basically the same deal as the RC6+ issues on ivy bridge +except this time with RC6 on sandy bridge. Like last time the +core of the issue is that the timings don't work 100% with our +voltage regulator. So from time to time, the kernel will print +a warning message about the GPU not getting out of RC6. In +particular, I found this fairly easy to reproduce during +suspend/resume. + +Changing the threshold to 125000 instead of 50000 seems to fix +the issue. The previous patch used 150000 but as it turns out +this doesn't work everywhere. After getting such a machine, I +bisected the highest value which works, which is 125000, so here +it is. + +I also measured the idle power usage before/after this patch and +didn't see a difference on a sandy bridge laptop. On haswell and +up, it makes a big difference, so we want to keep it at 50k +there. It also seems like haswell doesn't have the RC6 issues +that sandy bridge has so the 50k value is fine. + +Signed-off-by: Stéphane Marchesin +Acked-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit 351aa5666d02062b52329bcfe4bcf9d1f882fba9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 4800bab89df1..d593c2dd7031 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3508,7 +3508,10 @@ static void gen6_enable_rps(struct drm_device *dev) + + I915_WRITE(GEN6_RC_SLEEP, 0); + I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); +- I915_WRITE(GEN6_RC6_THRESHOLD, 50000); ++ if (INTEL_INFO(dev)->gen <= 6 || IS_IVYBRIDGE(dev)) ++ I915_WRITE(GEN6_RC6_THRESHOLD, 125000); ++ else ++ I915_WRITE(GEN6_RC6_THRESHOLD, 50000); + I915_WRITE(GEN6_RC6p_THRESHOLD, 150000); + I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0684-drm-i915-Initialize-seqno-for-VECS-too.patch b/patches.baytrail/0684-drm-i915-Initialize-seqno-for-VECS-too.patch new file mode 100644 index 000000000000..660815380d12 --- /dev/null +++ b/patches.baytrail/0684-drm-i915-Initialize-seqno-for-VECS-too.patch @@ -0,0 +1,52 @@ +From 4af7854549457ba7c912431bdcf59b78baa56700 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Mon, 12 Aug 2013 16:53:03 -0700 +Subject: drm/i915: Initialize seqno for VECS too + +We require n-1 mailboxes for proper semaphore synchronization. All +semaphore synchronization code relies on proper values in these +mailboxes. The fact that we failed to touch the vebox ring by itself +was unlikely to be an issue since the HW should be initializing the +values to 0. However the error framework for testing seqno wrap +introduced by Mika, in addition to the hangcheck via seqno, and +i915_error_first_batchbuffer() combined caused a nice explosion. + +The problem is caused by seqno wrap because the wrap condition is not +properly setup. The wrap code attempts to set the sync mailboxes all +to 0, and then set the current seqno to one less than 0. In all cases, +the vebox mailbox wasn't properly being initialized. This caused a +wrap to not occur. When hangcheck kicks in with the bogus seqno +values, the rest just doesn't work. It makes me wonder if we shouldn't +consider a dumber version of hangcheck... + +How we messed this up: VECS support was written before the +aforementioned other features. Upon VECS being rebased, these facts +were missed. + +Cc: Mika Kuoppala +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65387 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67198 +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 5020150b3b8d2912466e28572f25b3cc56722aec) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ringbuffer.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 89a9c908c99d..a1aa3bc48dcc 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -1606,6 +1606,8 @@ void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno) + if (INTEL_INFO(ring->dev)->gen >= 6) { + I915_WRITE(RING_SYNC_0(ring->mmio_base), 0); + I915_WRITE(RING_SYNC_1(ring->mmio_base), 0); ++ if (HAS_VEBOX(ring->dev)) ++ I915_WRITE(RING_SYNC_2(ring->mmio_base), 0); + } + + ring->set_seqno(ring, seqno); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0685-drm-i915-Get-VECS-semaphore-info-on-error.patch b/patches.baytrail/0685-drm-i915-Get-VECS-semaphore-info-on-error.patch new file mode 100644 index 000000000000..bee59e2fabec --- /dev/null +++ b/patches.baytrail/0685-drm-i915-Get-VECS-semaphore-info-on-error.patch @@ -0,0 +1,51 @@ +From b794a83e5cfb7b0e210f3d9eb8d65d64d37e0e95 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Mon, 12 Aug 2013 16:53:04 -0700 +Subject: drm/i915: Get VECS semaphore info on error + +Ideally we could use for_each_ring with the ring flags as I've done a +couple times +(http://lists.freedesktop.org/archives/intel-gfx/2013-June/029450.html). +Until Daniel merges that patch though, we can just use this. + +Cc: Mika Kuoppala +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 4e5aabfd3106cfd68694db416e271996aadf114a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gpu_error.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c +index 60393cb9a7c7..558e568d5b45 100644 +--- a/drivers/gpu/drm/i915/i915_gpu_error.c ++++ b/drivers/gpu/drm/i915/i915_gpu_error.c +@@ -243,6 +243,11 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m, + err_printf(m, " SYNC_1: 0x%08x [last synced 0x%08x]\n", + error->semaphore_mboxes[ring][1], + error->semaphore_seqno[ring][1]); ++ if (HAS_VEBOX(dev)) { ++ err_printf(m, " SYNC_2: 0x%08x [last synced 0x%08x]\n", ++ error->semaphore_mboxes[ring][2], ++ error->semaphore_seqno[ring][2]); ++ } + } + err_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); + err_printf(m, " waiting: %s\n", yesno(error->waiting[ring])); +@@ -682,6 +687,12 @@ static void i915_record_ring_state(struct drm_device *dev, + error->semaphore_seqno[ring->id][1] = ring->sync_seqno[1]; + } + ++ if (HAS_VEBOX(dev)) { ++ error->semaphore_mboxes[ring->id][2] = ++ I915_READ(RING_SYNC_2(ring->mmio_base)); ++ error->semaphore_seqno[ring->id][2] = ring->sync_seqno[2]; ++ } ++ + if (INTEL_INFO(dev)->gen >= 4) { + error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); + error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0686-drm-i915-clarify-error-paths-in-create_stolen_for_pr.patch b/patches.baytrail/0686-drm-i915-clarify-error-paths-in-create_stolen_for_pr.patch new file mode 100644 index 000000000000..d75f2cf47835 --- /dev/null +++ b/patches.baytrail/0686-drm-i915-clarify-error-paths-in-create_stolen_for_pr.patch @@ -0,0 +1,43 @@ +From f9e3aa3b0256cd858bed801e3ff2b2eb3599696e Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 14 Aug 2013 10:01:32 +0200 +Subject: drm/i915: clarify error paths in create_stolen_for_preallocated + +Use the standard inversely ordered goto label stack for everything. +Spotted while reviewing place where we might need to to call +vma_destroy but failed to do so. + +Cc: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 4a025e26a2979193739f46e391ffc05cf0637d90) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_stolen.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 8b03327f74b9..9969d10b80f5 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -409,8 +409,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + ret = drm_mm_reserve_node(&ggtt->mm, &vma->node); + if (ret) { + DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); +- i915_gem_vma_destroy(vma); +- goto err_out; ++ goto err_vma; + } + } + +@@ -421,6 +420,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + + return obj; + ++err_vma: ++ i915_gem_vma_destroy(vma); + err_out: + drm_mm_remove_node(stolen); + kfree(stolen); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0687-drm-i915-Remove-node-only-when-allocated.patch b/patches.baytrail/0687-drm-i915-Remove-node-only-when-allocated.patch new file mode 100644 index 000000000000..ae0fd47230c7 --- /dev/null +++ b/patches.baytrail/0687-drm-i915-Remove-node-only-when-allocated.patch @@ -0,0 +1,56 @@ +From 6db784ea1b660252a389617787720b851f047f97 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 13 Aug 2013 18:09:06 -0700 +Subject: drm/i915: Remove node only when allocated + +VMAs can be created and not bound. One may think of it as lazy cleanup, +and safely gloss over the conditions which manufacture it. In either +case, when the object backing the i915 vma is destroyed, we must cleanup +the vma without stumbling into a bunch of pitfalls that assume the vma +is bound. + +NOTE: I was pretty certain the above condition could only happen when we +introduced the use of VMAs being looked up at execbuf, and already +existing. Paulo has hit this though, so I must be missing something. As +I believe the patch is correct anyway, therefore I won't scratch my head +too hard. + +v2: use goto destroy as a compromise (Chris) + +Cc: Chris Wilson +Cc: Paulo Zanoni +Signed-off-by: Ben Widawsky +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 433544bd25b06cb6dcdb79b6da8d748a0220898e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 3d9e248bf422..4a58ead0ba76 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2606,6 +2606,9 @@ int i915_vma_unbind(struct i915_vma *vma) + if (list_empty(&vma->vma_link)) + return 0; + ++ if (!drm_mm_node_allocated(&vma->node)) ++ goto destroy; ++ + if (obj->pin_count) + return -EBUSY; + +@@ -2643,6 +2646,8 @@ int i915_vma_unbind(struct i915_vma *vma) + obj->map_and_fenceable = true; + + drm_mm_remove_node(&vma->node); ++ ++destroy: + i915_gem_vma_destroy(vma); + + /* Since the unbound list is global, only move to that list if +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0688-drm-i915-cleanup-map-fence-in-bind.patch b/patches.baytrail/0688-drm-i915-cleanup-map-fence-in-bind.patch new file mode 100644 index 000000000000..a961ee93031b --- /dev/null +++ b/patches.baytrail/0688-drm-i915-cleanup-map-fence-in-bind.patch @@ -0,0 +1,67 @@ +From 8af30fecb75e77ff67b308c50d66baf278da2dd1 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Tue, 13 Aug 2013 18:09:07 -0700 +Subject: drm/i915: cleanup map&fence in bind + +Cleanup the map and fenceable setting during bind to make more sense, +and not check i915_is_ggtt() 2 unnecessary times + +v2: Move the bools into the if block (Chris) - There are ways to tidy +this function (fence calculations for instance) even further, but they +are quite invasive, so I am punting on those unless specifically asked. + +v3: Add newline between variable declaration and logic (Chris) + +Recommended-by: Chris Wilson +Reviewed-by: Chris Wilson +Signed-off-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 4bd561b3e8d7d2407cf465cb79c51a1ff1264343) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 4a58ead0ba76..01cc016e8d52 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3106,7 +3106,6 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; + u32 size, fence_size, fence_alignment, unfenced_alignment; +- bool mappable, fenceable; + size_t gtt_max = + map_and_fenceable ? dev_priv->gtt.mappable_end : vm->total; + struct i915_vma *vma; +@@ -3191,18 +3190,18 @@ search_free: + list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); + list_add_tail(&vma->mm_list, &vm->inactive_list); + +- fenceable = +- i915_is_ggtt(vm) && +- i915_gem_obj_ggtt_size(obj) == fence_size && +- (i915_gem_obj_ggtt_offset(obj) & (fence_alignment - 1)) == 0; ++ if (i915_is_ggtt(vm)) { ++ bool mappable, fenceable; + +- mappable = +- i915_is_ggtt(vm) && +- vma->node.start + obj->base.size <= dev_priv->gtt.mappable_end; ++ fenceable = ++ i915_gem_obj_ggtt_size(obj) == fence_size && ++ (i915_gem_obj_ggtt_offset(obj) & (fence_alignment - 1)) == 0; ++ ++ mappable = ++ vma->node.start + obj->base.size <= dev_priv->gtt.mappable_end; + +- /* Map and fenceable only changes if the VM is the global GGTT */ +- if (i915_is_ggtt(vm)) + obj->map_and_fenceable = mappable && fenceable; ++ } + + WARN_ON(map_and_fenceable && !obj->map_and_fenceable); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0689-drm-i915-use-vma-node-directly-and-rewrap-map-fence-.patch b/patches.baytrail/0689-drm-i915-use-vma-node-directly-and-rewrap-map-fence-.patch new file mode 100644 index 000000000000..4bd8104a6410 --- /dev/null +++ b/patches.baytrail/0689-drm-i915-use-vma-node-directly-and-rewrap-map-fence-.patch @@ -0,0 +1,41 @@ +From 6907fb3c9db9eae28162cc395e740198d6a02627 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 14 Aug 2013 10:21:23 +0200 +Subject: drm/i915: use vma->node directly and rewrap map&fence in bind + +Use () to make for neater alignment of the split lines, too. With this +we ditch another jump through the obj_gtt_size/offset indirection +maze. + +Cc: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 49987099e2cfce4eda5d428e2618fd4e93aba597) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 01cc016e8d52..31f23bb07201 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3193,12 +3193,11 @@ search_free: + if (i915_is_ggtt(vm)) { + bool mappable, fenceable; + +- fenceable = +- i915_gem_obj_ggtt_size(obj) == fence_size && +- (i915_gem_obj_ggtt_offset(obj) & (fence_alignment - 1)) == 0; ++ fenceable = (vma->node.size == fence_size && ++ (vma->node.start & (fence_alignment - 1)) == 0); + +- mappable = +- vma->node.start + obj->base.size <= dev_priv->gtt.mappable_end; ++ mappable = (vma->node.start + obj->base.size <= ++ dev_priv->gtt.mappable_end); + + obj->map_and_fenceable = mappable && fenceable; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0690-drm-i915-Drop-the-overzealous-warning-from-i915_gem_.patch b/patches.baytrail/0690-drm-i915-Drop-the-overzealous-warning-from-i915_gem_.patch new file mode 100644 index 000000000000..b0fec2624d3b --- /dev/null +++ b/patches.baytrail/0690-drm-i915-Drop-the-overzealous-warning-from-i915_gem_.patch @@ -0,0 +1,58 @@ +From 18e912c84426986f63aca7736536bf41a11e29f1 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 12 Aug 2013 11:46:17 +0100 +Subject: drm/i915: Drop the overzealous warning from i915_gem_set_cache_level +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +By our earlier reckoning, move from a snooped/llc setting to an uncached +setting, leaves the CPU cache in a consistent state irrespective of our +domain tracking - so we can forgo the warning about the lack of +invalidation. Similarly for any writes posted to the snooped CPU domain, +we know will be safely clflushed to the uncached PTEs after forcing the +domain change. + +This WARN started to pop up with + +commit d46f1c3f1372e3a72fab97c60480aa4a1084387f +Author: Chris Wilson +AuthorDate: Thu Aug 8 14:41:06 2013 +0100 + + drm/i915: Allow the GPU to cache stolen memory + +Ville brought up a scenario where the interaction of a set_caching +ioctl call from userspace on a scanout buffer (i.e. obj->pin_display +is set) resulted in the code getting confused and not properly +flushing stale cpu cachelines. Luckily we already prevent this by +rejecting caching changes when obj->pin_count is set. + +Signed-off-by: Chris Wilson +Cc: Ville Syrjälä +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68040 +Tested-by: cancan,feng +[danvet: Add buglink, bisect result and explain why Ville's scenario +is already taken care of.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 4b6d846e9a20ac8c9dd641d0ea875c28f331e241) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 31f23bb07201..c6baa3c5d7b3 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3428,7 +3428,6 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + * Just set it to the CPU cache for now. + */ + WARN_ON(obj->base.write_domain & ~I915_GEM_DOMAIN_CPU); +- WARN_ON(obj->base.read_domains & ~I915_GEM_DOMAIN_CPU); + + old_read_domains = obj->base.read_domains; + old_write_domain = obj->base.write_domain; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0691-drm-i915-check-the-power-well-when-redisabling-VGA.patch b/patches.baytrail/0691-drm-i915-check-the-power-well-when-redisabling-VGA.patch new file mode 100644 index 000000000000..faab53f60bad --- /dev/null +++ b/patches.baytrail/0691-drm-i915-check-the-power-well-when-redisabling-VGA.patch @@ -0,0 +1,58 @@ +From df7446535e93e9feb311b7cc7d746bdfa6da70f6 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 2 Aug 2013 16:22:24 -0300 +Subject: drm/i915: check the power well when redisabling VGA + +If the power well is disabled VGA is guaranteed to be disabled. + +This fixes unclaimed register messages that happen on suspend/resume. + +v2: Check the actual hw power well state instead of our own tracking +to make sure VGA is _really_ off (in case the BIOS/KVMr has just its +own request bit set). Requested by Ville. + +Note: Ville suggested whether it wouldn't be better to just enable the +power well over a slightly longer time in our resume code, since we +already do that. I tend to agree, but there's also the modeset force +code in the lid notifier which _also_ eventually calls redisable_vga. +We shouldn't ever need this on somewhat modern hw (everything with +opregion essentially) but the code to bail out isn't there. Hence +stick with this simple approach here for now. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67517 +Signed-off-by: Paulo Zanoni +[danvet: Summarize the discussion around the resume sequence and lid +notifier a bit.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 8dc8a27c9733a41cda84e8c70da8313e1d54c4ae) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 63df05ea823e..8f4dceef5480 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -10110,6 +10110,17 @@ void i915_redisable_vga(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + u32 vga_reg = i915_vgacntrl_reg(dev); + ++ /* This function can be called both from intel_modeset_setup_hw_state or ++ * at a very early point in our resume sequence, where the power well ++ * structures are not yet restored. Since this function is at a very ++ * paranoid "someone might have enabled VGA while we were not looking" ++ * level, just check if the power well is enabled instead of trying to ++ * follow the "don't touch the power well if we don't need it" policy ++ * the rest of the driver uses. */ ++ if (HAS_POWER_WELL(dev) && ++ (I915_READ(HSW_PWR_WELL_DRIVER) & HSW_PWR_WELL_STATE) == 0) ++ return; ++ + if (I915_READ(vga_reg) != VGA_DISP_DISABLE) { + DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n"); + i915_disable_vga(dev); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0692-drm-i915-clarify-Haswell-power-well-bit-names.patch b/patches.baytrail/0692-drm-i915-clarify-Haswell-power-well-bit-names.patch new file mode 100644 index 000000000000..850e53f457ce --- /dev/null +++ b/patches.baytrail/0692-drm-i915-clarify-Haswell-power-well-bit-names.patch @@ -0,0 +1,96 @@ +From fb9af3e5e1e180bff20e6ad653a50547e4d5e0e4 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 2 Aug 2013 16:22:25 -0300 +Subject: drm/i915: clarify Haswell power well bit names + +Whenever I need to work with the HSW_PWER_WELL_* register bits I have +to look at the documentation to find out which bit is to request the +power well and which one shows its current state. Rename the bits so I +won't need to look the docs every time. + +Signed-off-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 6aedd1f539f51b7b0c3d6be0088c3541f9d2c294) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 4 ++-- + drivers/gpu/drm/i915/intel_display.c | 2 +- + drivers/gpu/drm/i915/intel_pm.c | 13 +++++++------ + 3 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 11800316799f..019fd1f9d286 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -4833,8 +4833,8 @@ + #define HSW_PWR_WELL_DRIVER 0x45404 /* CTL2 */ + #define HSW_PWR_WELL_KVMR 0x45408 /* CTL3 */ + #define HSW_PWR_WELL_DEBUG 0x4540C /* CTL4 */ +-#define HSW_PWR_WELL_ENABLE (1<<31) +-#define HSW_PWR_WELL_STATE (1<<30) ++#define HSW_PWR_WELL_ENABLE_REQUEST (1<<31) ++#define HSW_PWR_WELL_STATE_ENABLED (1<<30) + #define HSW_PWR_WELL_CTL5 0x45410 + #define HSW_PWR_WELL_ENABLE_SINGLE_STEP (1<<31) + #define HSW_PWR_WELL_PWR_GATE_OVERRIDE (1<<20) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 8f4dceef5480..cec940eb0147 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -10118,7 +10118,7 @@ void i915_redisable_vga(struct drm_device *dev) + * follow the "don't touch the power well if we don't need it" policy + * the rest of the driver uses. */ + if (HAS_POWER_WELL(dev) && +- (I915_READ(HSW_PWR_WELL_DRIVER) & HSW_PWR_WELL_STATE) == 0) ++ (I915_READ(HSW_PWR_WELL_DRIVER) & HSW_PWR_WELL_STATE_ENABLED) == 0) + return; + + if (I915_READ(vga_reg) != VGA_DISP_DISABLE) { +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index d593c2dd7031..d82d70588d11 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -5285,7 +5285,7 @@ bool intel_display_power_enabled(struct drm_device *dev, + case POWER_DOMAIN_TRANSCODER_B: + case POWER_DOMAIN_TRANSCODER_C: + return I915_READ(HSW_PWR_WELL_DRIVER) == +- (HSW_PWR_WELL_ENABLE | HSW_PWR_WELL_STATE); ++ (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); + default: + BUG(); + } +@@ -5298,17 +5298,18 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) + uint32_t tmp; + + tmp = I915_READ(HSW_PWR_WELL_DRIVER); +- is_enabled = tmp & HSW_PWR_WELL_STATE; +- enable_requested = tmp & HSW_PWR_WELL_ENABLE; ++ is_enabled = tmp & HSW_PWR_WELL_STATE_ENABLED; ++ enable_requested = tmp & HSW_PWR_WELL_ENABLE_REQUEST; + + if (enable) { + if (!enable_requested) +- I915_WRITE(HSW_PWR_WELL_DRIVER, HSW_PWR_WELL_ENABLE); ++ I915_WRITE(HSW_PWR_WELL_DRIVER, ++ HSW_PWR_WELL_ENABLE_REQUEST); + + if (!is_enabled) { + DRM_DEBUG_KMS("Enabling power well\n"); + if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) & +- HSW_PWR_WELL_STATE), 20)) ++ HSW_PWR_WELL_STATE_ENABLED), 20)) + DRM_ERROR("Timeout enabling power well\n"); + } + } else { +@@ -5428,7 +5429,7 @@ void intel_init_power_well(struct drm_device *dev) + + /* We're taking over the BIOS, so clear any requests made by it since + * the driver is in charge now. */ +- if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE) ++ if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST) + I915_WRITE(HSW_PWR_WELL_BIOS, 0); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0693-drm-i915-Only-unmask-required-PM-interrupts.patch b/patches.baytrail/0693-drm-i915-Only-unmask-required-PM-interrupts.patch new file mode 100644 index 000000000000..7f50493fb0d3 --- /dev/null +++ b/patches.baytrail/0693-drm-i915-Only-unmask-required-PM-interrupts.patch @@ -0,0 +1,46 @@ +From efe7db1c227423bf920c9a49b4f99f1eaae97937 Mon Sep 17 00:00:00 2001 +From: Vinit Azad +Date: Wed, 14 Aug 2013 13:34:33 -0700 +Subject: drm/i915: Only unmask required PM interrupts + +Un-masking all PM interrupts causes hardware to generate +interrupts regardless of whether the interrupts are enabled +on the DE side. Since turbo only need up/down threshold and +rc6 timeout interrupt, mask all other interrupts bits to avoid +unnecessary overhead/wake up. + +Note that our interrupt handler isn't being fired since we do set the +IER bits properly (IIR bits aren't set). The overhead isn't because +our driver is reacting to these interrupts, but because hardware keeps +generating internal messages when PMINTRMSK doesn't mask out the +up/down EI interrupts (which happen periodically). + +Signed-off-by: Vinit Azad +[danvet: Add follow-up explanation of the precise effects from Vinit +as a note to the commit message.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit fd547d25a8ac3f390fee4a689de86a64e3d65fe1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index d82d70588d11..21f4c958bbfe 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3453,8 +3453,8 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) + I915_WRITE(GEN6_PMIMR, I915_READ(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS); + I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); + spin_unlock_irq(&dev_priv->irq_lock); +- /* unmask all PM interrupts */ +- I915_WRITE(GEN6_PMINTRMSK, 0); ++ /* only unmask PM interrupts we need. Mask all others. */ ++ I915_WRITE(GEN6_PMINTRMSK, ~GEN6_PM_RPS_EVENTS); + } + + static void gen6_enable_rps(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0694-drm-i915-explicit-store-base-gem-object-in-dma_buf-p.patch b/patches.baytrail/0694-drm-i915-explicit-store-base-gem-object-in-dma_buf-p.patch new file mode 100644 index 000000000000..a62d090ee656 --- /dev/null +++ b/patches.baytrail/0694-drm-i915-explicit-store-base-gem-object-in-dma_buf-p.patch @@ -0,0 +1,96 @@ +From dd7c8b3a3ca14b05de35905b74d25f01cf06ac54 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Thu, 8 Aug 2013 09:10:38 +0200 +Subject: drm/i915: explicit store base gem object in dma_buf->priv + +Makes it more obviously correct what tricks we play by reusing the drm +prime release helper. + +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 608806a549c656c925eeb253cbed768535f26e41) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_dmabuf.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c +index f7e1682ddb8b..e918b05fcbdd 100644 +--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c ++++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c +@@ -27,10 +27,15 @@ + #include "i915_drv.h" + #include + ++static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf *buf) ++{ ++ return to_intel_bo(buf->priv); ++} ++ + static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachment, + enum dma_data_direction dir) + { +- struct drm_i915_gem_object *obj = attachment->dmabuf->priv; ++ struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf); + struct sg_table *st; + struct scatterlist *src, *dst; + int ret, i; +@@ -85,7 +90,7 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *sg, + enum dma_data_direction dir) + { +- struct drm_i915_gem_object *obj = attachment->dmabuf->priv; ++ struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf); + + mutex_lock(&obj->base.dev->struct_mutex); + +@@ -100,7 +105,7 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, + + static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf) + { +- struct drm_i915_gem_object *obj = dma_buf->priv; ++ struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); + struct drm_device *dev = obj->base.dev; + struct sg_page_iter sg_iter; + struct page **pages; +@@ -148,7 +153,7 @@ error: + + static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) + { +- struct drm_i915_gem_object *obj = dma_buf->priv; ++ struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); + struct drm_device *dev = obj->base.dev; + int ret; + +@@ -191,7 +196,7 @@ static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct * + + static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size_t length, enum dma_data_direction direction) + { +- struct drm_i915_gem_object *obj = dma_buf->priv; ++ struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); + struct drm_device *dev = obj->base.dev; + int ret; + bool write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE); +@@ -222,9 +227,7 @@ static const struct dma_buf_ops i915_dmabuf_ops = { + struct dma_buf *i915_gem_prime_export(struct drm_device *dev, + struct drm_gem_object *gem_obj, int flags) + { +- struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); +- +- return dma_buf_export(obj, &i915_dmabuf_ops, obj->base.size, flags); ++ return dma_buf_export(gem_obj, &i915_dmabuf_ops, gem_obj->size, flags); + } + + static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj) +@@ -261,7 +264,7 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, + + /* is this one of own objects? */ + if (dma_buf->ops == &i915_dmabuf_ops) { +- obj = dma_buf->priv; ++ obj = dma_buf_to_obj(dma_buf); + /* is it from our device? */ + if (obj->base.dev == dev) { + /* +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0695-drm-i915-enable-the-power-well-before-module-unload.patch b/patches.baytrail/0695-drm-i915-enable-the-power-well-before-module-unload.patch new file mode 100644 index 000000000000..0b8d1ae3cc46 --- /dev/null +++ b/patches.baytrail/0695-drm-i915-enable-the-power-well-before-module-unload.patch @@ -0,0 +1,56 @@ +From eeb26a49896e9fd80098af7ae380518af425022a Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Wed, 14 Aug 2013 14:40:37 -0300 +Subject: drm/i915: enable the power well before module unload + +Our driver initialization doesn't seem to be ready to load when the +power well is disabled: we hit a few "Unclaimed register" messages. So +do just like we already do for the suspend/resume path: enable the +power well before unloading. + +At some point we'll want to be able to survive suspend/resume and +load/unload with the power well disabled, but for now let's just fix +the regression. + +Regression introduced by the following commit: + +commit bf51d5e2cda5d36d98e4b46ac7fca9461e512c41 +Author: Paulo Zanoni +Date: Wed Jul 3 17:12:13 2013 -0300 + drm/i915: switch disable_power_well default value to 1 + +Bug can be reproduced by running the "module_reload" script from +intel-gpu-tools. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67813 +Signed-off-by: Paulo Zanoni +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 79f8dea13391f8220470997f9a5213ab5aa9f1c7) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index b30404d00757..d2dc02b67512 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1688,8 +1688,13 @@ int i915_driver_unload(struct drm_device *dev) + + intel_gpu_ips_teardown(); + +- if (HAS_POWER_WELL(dev)) ++ if (HAS_POWER_WELL(dev)) { ++ /* The i915.ko module is still not prepared to be loaded when ++ * the power well is not enabled, so just enable it in case ++ * we're going to unload/reload. */ ++ intel_set_power_well(dev, true); + i915_remove_power_well(dev); ++ } + + i915_teardown_sysfs(dev); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0696-i915-Add-a-Kconfig-option-to-turn-on-i915.preliminar.patch b/patches.baytrail/0696-i915-Add-a-Kconfig-option-to-turn-on-i915.preliminar.patch new file mode 100644 index 000000000000..a2b57b9ff105 --- /dev/null +++ b/patches.baytrail/0696-i915-Add-a-Kconfig-option-to-turn-on-i915.preliminar.patch @@ -0,0 +1,65 @@ +From 21c5bc9f7206d0e29c74757164e5107968dcd91e Mon Sep 17 00:00:00 2001 +From: Josh Triplett +Date: Tue, 13 Aug 2013 16:23:17 -0700 +Subject: i915: Add a Kconfig option to turn on i915.preliminary_hw_support by + default + +When building kernels for a preliminary hardware target, having to add a +kernel command-line option can prove inconvenient. Add a Kconfig option +that changes the default of this option to 1. + +Signed-off-by: Josh Triplett +Reviewed-by: Damien Lespiau +[danvet: Pimp the Kconfig help text a bit as suggested by Damien in +his 2nd review.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 99486b8e6140da7721c932e708a6c17dc1dd970a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/Kconfig | 11 +++++++++++ + drivers/gpu/drm/i915/i915_drv.c | 4 ++-- + 2 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig +index b16c50ee769c..d979cec588c8 100644 +--- a/drivers/gpu/drm/Kconfig ++++ b/drivers/gpu/drm/Kconfig +@@ -167,6 +167,17 @@ config DRM_I915_KMS + the driver to bind to PCI devices, which precludes loading things + like intelfb. + ++config DRM_I915_PRELIMINARY_HW_SUPPORT ++ bool "Enable preliminary support for prerelease Intel hardware by default" ++ depends on DRM_I915 ++ help ++ Choose this option if you have prerelease Intel hardware and want the ++ i915 driver to support it by default. You can enable such support at ++ runtime with the module option i915.preliminary_hw_support=1; this ++ option changes the default for that module option. ++ ++ If in doubt, say "N". ++ + config DRM_MGA + tristate "Matrox g200/g400" + depends on DRM && PCI +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index eec47bd00353..a9c8f18e26fc 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -122,10 +122,10 @@ int i915_enable_psr __read_mostly = 0; + module_param_named(enable_psr, i915_enable_psr, int, 0600); + MODULE_PARM_DESC(enable_psr, "Enable PSR (default: false)"); + +-unsigned int i915_preliminary_hw_support __read_mostly = 0; ++unsigned int i915_preliminary_hw_support __read_mostly = IS_ENABLED(CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT); + module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600); + MODULE_PARM_DESC(preliminary_hw_support, +- "Enable preliminary hardware support. (default: false)"); ++ "Enable preliminary hardware support."); + + int i915_disable_power_well __read_mostly = 1; + module_param_named(disable_power_well, i915_disable_power_well, int, 0600); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0697-drm-i915-s-obj-exec_list-obj-obj_exec_link-in-debugf.patch b/patches.baytrail/0697-drm-i915-s-obj-exec_list-obj-obj_exec_link-in-debugf.patch new file mode 100644 index 000000000000..2338df9b9cb0 --- /dev/null +++ b/patches.baytrail/0697-drm-i915-s-obj-exec_list-obj-obj_exec_link-in-debugf.patch @@ -0,0 +1,98 @@ +From 9467ced15de2abc07bf100c21bd6e53e97e7fd7a Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 14 Aug 2013 11:38:33 +0200 +Subject: drm/i915: s/obj->exec_list/obj->obj_exec_link in debugfs + +To convert the execbuf code over to use vmas natively we need to +shuffle the exec_list a bit. This patch here just prepares things with +the debugfs code, which also uses the old exec_list list_head, newly +called obj_exec_link. + +Signed-off-by: Ben Widawsky +[danvet: Split out from Ben's big patch.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit b25cb2f8828aca6204d9c93d4d677f27e3ae9fa6) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 12 ++++++------ + drivers/gpu/drm/i915/i915_drv.h | 2 ++ + drivers/gpu/drm/i915/i915_gem.c | 1 + + 3 files changed, 9 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index eb87865c20d4..4785d8c14654 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -195,9 +195,9 @@ static int obj_rank_by_stolen(void *priv, + struct list_head *A, struct list_head *B) + { + struct drm_i915_gem_object *a = +- container_of(A, struct drm_i915_gem_object, exec_list); ++ container_of(A, struct drm_i915_gem_object, obj_exec_link); + struct drm_i915_gem_object *b = +- container_of(B, struct drm_i915_gem_object, exec_list); ++ container_of(B, struct drm_i915_gem_object, obj_exec_link); + + return a->stolen->start - b->stolen->start; + } +@@ -221,7 +221,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data) + if (obj->stolen == NULL) + continue; + +- list_add(&obj->exec_list, &stolen); ++ list_add(&obj->obj_exec_link, &stolen); + + total_obj_size += obj->base.size; + total_gtt_size += i915_gem_obj_ggtt_size(obj); +@@ -231,7 +231,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data) + if (obj->stolen == NULL) + continue; + +- list_add(&obj->exec_list, &stolen); ++ list_add(&obj->obj_exec_link, &stolen); + + total_obj_size += obj->base.size; + count++; +@@ -239,11 +239,11 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data) + list_sort(NULL, &stolen, obj_rank_by_stolen); + seq_puts(m, "Stolen:\n"); + while (!list_empty(&stolen)) { +- obj = list_first_entry(&stolen, typeof(*obj), exec_list); ++ obj = list_first_entry(&stolen, typeof(*obj), obj_exec_link); + seq_puts(m, " "); + describe_obj(m, obj); + seq_putc(m, '\n'); +- list_del_init(&obj->exec_list); ++ list_del_init(&obj->obj_exec_link); + } + mutex_unlock(&dev->struct_mutex); + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 3fc432437524..315e530c6488 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1312,6 +1312,8 @@ struct drm_i915_gem_object { + struct list_head global_list; + + struct list_head ring_list; ++ /** Used in execbuf to temporarily hold a ref */ ++ struct list_head obj_exec_link; + /** This object's place in the batchbuffer or on the eviction list */ + struct list_head exec_list; + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index c6baa3c5d7b3..6223a71a640a 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3980,6 +3980,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, + INIT_LIST_HEAD(&obj->global_list); + INIT_LIST_HEAD(&obj->ring_list); + INIT_LIST_HEAD(&obj->exec_list); ++ INIT_LIST_HEAD(&obj->obj_exec_link); + INIT_LIST_HEAD(&obj->vma_list); + + obj->ops = ops; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0698-drm-i915-Switch-eviction-code-to-use-vmas.patch b/patches.baytrail/0698-drm-i915-Switch-eviction-code-to-use-vmas.patch new file mode 100644 index 000000000000..d2c3e22bca2a --- /dev/null +++ b/patches.baytrail/0698-drm-i915-Switch-eviction-code-to-use-vmas.patch @@ -0,0 +1,132 @@ +From 2398fcd316955ec37343d396ebfc068b6f699ed5 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 14 Aug 2013 11:38:34 +0200 +Subject: drm/i915: Switch eviction code to use vmas + +The execbuf wants to do relocations usings vmas, so we need a +vma->exec_list. The eviction code also uses the old obj execbuf list +for it's own book-keeping, but would really prefer to deal in vmas +only. So switch it over to the new list. + +Again this is just a prep patch for the big execbuf vma conversion. + +Signed-off-by: Ben Widawsky +[danvet: Split out from Ben's big execbuf vma patch.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 82a55ad1a0585e4e01a47f72fe81fb5a2d2c0fb1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 4 ++++ + drivers/gpu/drm/i915/i915_gem.c | 1 + + drivers/gpu/drm/i915/i915_gem_evict.c | 31 ++++++++++++++----------------- + 3 files changed, 19 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 315e530c6488..3f1f65865d3c 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -563,6 +563,10 @@ struct i915_vma { + struct list_head mm_list; + + struct list_head vma_link; /* Link in the object's VMA list */ ++ ++ /** This vma's place in the batchbuffer or on the eviction list */ ++ struct list_head exec_list; ++ + }; + + struct i915_ctx_hang_stats { +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 6223a71a640a..10e3c536f911 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -4120,6 +4120,7 @@ struct i915_vma *i915_gem_vma_create(struct drm_i915_gem_object *obj, + + INIT_LIST_HEAD(&vma->vma_link); + INIT_LIST_HEAD(&vma->mm_list); ++ INIT_LIST_HEAD(&vma->exec_list); + vma->vm = vm; + vma->obj = obj; + +diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c +index 425939b7d343..87875884770c 100644 +--- a/drivers/gpu/drm/i915/i915_gem_evict.c ++++ b/drivers/gpu/drm/i915/i915_gem_evict.c +@@ -37,7 +37,7 @@ mark_free(struct i915_vma *vma, struct list_head *unwind) + if (vma->obj->pin_count) + return false; + +- list_add(&vma->obj->exec_list, unwind); ++ list_add(&vma->exec_list, unwind); + return drm_mm_scan_add_block(&vma->node); + } + +@@ -49,7 +49,6 @@ i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm, + drm_i915_private_t *dev_priv = dev->dev_private; + struct list_head eviction_list, unwind_list; + struct i915_vma *vma; +- struct drm_i915_gem_object *obj; + int ret = 0; + + trace_i915_gem_evict(dev, min_size, alignment, mappable); +@@ -104,14 +103,13 @@ i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm, + none: + /* Nothing found, clean up and bail out! */ + while (!list_empty(&unwind_list)) { +- obj = list_first_entry(&unwind_list, +- struct drm_i915_gem_object, ++ vma = list_first_entry(&unwind_list, ++ struct i915_vma, + exec_list); +- vma = i915_gem_obj_to_vma(obj, vm); + ret = drm_mm_scan_remove_block(&vma->node); + BUG_ON(ret); + +- list_del_init(&obj->exec_list); ++ list_del_init(&vma->exec_list); + } + + /* We expect the caller to unpin, evict all and try again, or give up. +@@ -125,28 +123,27 @@ found: + * temporary list. */ + INIT_LIST_HEAD(&eviction_list); + while (!list_empty(&unwind_list)) { +- obj = list_first_entry(&unwind_list, +- struct drm_i915_gem_object, ++ vma = list_first_entry(&unwind_list, ++ struct i915_vma, + exec_list); +- vma = i915_gem_obj_to_vma(obj, vm); + if (drm_mm_scan_remove_block(&vma->node)) { +- list_move(&obj->exec_list, &eviction_list); +- drm_gem_object_reference(&obj->base); ++ list_move(&vma->exec_list, &eviction_list); ++ drm_gem_object_reference(&vma->obj->base); + continue; + } +- list_del_init(&obj->exec_list); ++ list_del_init(&vma->exec_list); + } + + /* Unbinding will emit any required flushes */ + while (!list_empty(&eviction_list)) { +- obj = list_first_entry(&eviction_list, +- struct drm_i915_gem_object, ++ vma = list_first_entry(&eviction_list, ++ struct i915_vma, + exec_list); + if (ret == 0) +- ret = i915_vma_unbind(i915_gem_obj_to_vma(obj, vm)); ++ ret = i915_vma_unbind(vma); + +- list_del_init(&obj->exec_list); +- drm_gem_object_unreference(&obj->base); ++ list_del_init(&vma->exec_list); ++ drm_gem_object_unreference(&vma->obj->base); + } + + return ret; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0699-drm-i915-prepare-bind_to_vm-for-preallocated-vma.patch b/patches.baytrail/0699-drm-i915-prepare-bind_to_vm-for-preallocated-vma.patch new file mode 100644 index 000000000000..ac7da2cd3b78 --- /dev/null +++ b/patches.baytrail/0699-drm-i915-prepare-bind_to_vm-for-preallocated-vma.patch @@ -0,0 +1,93 @@ +From 35d850faa406c7663ed2b2d137dcca25b8dd4d8c Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 14 Aug 2013 11:38:35 +0200 +Subject: drm/i915: prepare bind_to_vm for preallocated vma + +In the new execbuf code we want to track buffers using the vmas even +before they're all properly mapped. Which means that bind_to_vm needs +to deal with buffers which have preallocated vmas which aren't yet +bound. + +This patch implements this prep work and adjusts our WARN/BUG checks. + +Signed-off-by: Ben Widawsky +[danvet: Split out from Ben's big execbuf patch. Also move one BUG +back to its original place to deflate the diff a notch.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit accfef2e5a8f713bfa0c06696b5e10754686dc72) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 3 +++ + drivers/gpu/drm/i915/i915_gem.c | 23 +++++++++++++++++------ + 2 files changed, 20 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 3f1f65865d3c..2b503d58dcd3 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1913,6 +1913,9 @@ unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o, + struct i915_address_space *vm); + struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, + struct i915_address_space *vm); ++struct i915_vma * ++i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, ++ struct i915_address_space *vm); + /* Some GGTT VM helpers */ + #define obj_to_ggtt(obj) \ + (&((struct drm_i915_private *)(obj)->base.dev->dev_private)->gtt.base) +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 10e3c536f911..199107e734fb 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3111,9 +3111,6 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, + struct i915_vma *vma; + int ret; + +- if (WARN_ON(!list_empty(&obj->vma_list))) +- return -EBUSY; +- + fence_size = i915_gem_get_gtt_size(dev, + obj->base.size, + obj->tiling_mode); +@@ -3152,16 +3149,17 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, + + i915_gem_object_pin_pages(obj); + +- /* FIXME: For now we only ever use 1 VMA per object */ + BUG_ON(!i915_is_ggtt(vm)); +- WARN_ON(!list_empty(&obj->vma_list)); + +- vma = i915_gem_vma_create(obj, vm); ++ vma = i915_gem_obj_lookup_or_create_vma(obj, vm); + if (IS_ERR(vma)) { + ret = PTR_ERR(vma); + goto err_unpin; + } + ++ /* For now we only ever use 1 vma per object */ ++ WARN_ON(!list_is_singular(&obj->vma_list)); ++ + search_free: + ret = drm_mm_insert_node_in_range_generic(&vm->mm, &vma->node, + size, alignment, +@@ -4870,3 +4868,16 @@ struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, + + return NULL; + } ++ ++struct i915_vma * ++i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, ++ struct i915_address_space *vm) ++{ ++ struct i915_vma *vma; ++ ++ vma = i915_gem_obj_to_vma(obj, vm); ++ if (!vma) ++ vma = i915_gem_vma_create(obj, vm); ++ ++ return vma; ++} +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0700-drm-i915-vma-Correct-use-after-free-in-eviction.patch b/patches.baytrail/0700-drm-i915-vma-Correct-use-after-free-in-eviction.patch new file mode 100644 index 000000000000..bbdad48d9ec2 --- /dev/null +++ b/patches.baytrail/0700-drm-i915-vma-Correct-use-after-free-in-eviction.patch @@ -0,0 +1,101 @@ +From 0ad450007d58cee44cdeae115f9e7b84c79fa220 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Fri, 16 Aug 2013 13:29:33 -0700 +Subject: drm/i915/vma: Correct use after free in eviction +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The vma will [possibly] be destroyed during unbind in eviction. +Immediately after this, we try to delete the list entry. + +Chris and Ville did the debug on this before I woke up, I just get to +take credit for the fix :p + +For future reference the Oops that Mika reported: + +[ 403.472448] BUG: unable to handle kernel paging request at 6b6b6b6b +[ 403.472473] IP: [] __list_del_entry+0x20/0xe0 +[ 403.472514] *pdpt = 000000002e89c001 *pde = 0000000000000000 +[ 403.472556] Oops: 0000 [#1] SMP +[ 403.472582] Modules linked in: mxm_wmi snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_seq_midi snd_rawmidi psmouse snd_seq_midi_event snd_seq serio_raw snd_timer snd_seq_device snd soundcore snd_page_alloc wmi bnep rfcomm bluetooth mac_hid parport_pc ppdev lp parport usbhid dm_crypt firewire_ohci firewire_core crc_itu_t i915 drm_kms_helper e1000e ptp drm i2c_algo_bit pps_core xhci_hcd video +[ 403.472895] CPU: 2 PID: 1940 Comm: Xorg Not tainted 3.11.0-rc2+ #827 +[ 403.472938] Hardware name: /DZ77BH-55K, BIOS BHZ7710H.86A.0070.2012.0416.2117 04/16/2012 +[ 403.473002] task: ec866c00 ti: ee6a2000 task.ti: ee6a2000 +[ 403.473039] EIP: 0060:[] EFLAGS: 00013202 CPU: 2 +[ 403.473078] EIP is at __list_del_entry+0x20/0xe0 +[ 403.473109] EAX: f016d9bc EBX: f016d9bc ECX: 6b6b6b6b EDX: 6b6b6b6b +[ 403.473151] ESI: 00000000 EDI: ee6a3c90 EBP: ee6a3c60 ESP: ee6a3c48 +[ 403.473193] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 +[ 403.473230] CR0: 80050033 CR2: 6b6b6b6b CR3: 2ec43000 CR4: 001407f0 +[ 403.473271] Stack: +[ 403.473285] f63b2ff0 f61f98c0 f61f8000 f016d9bc 00000000 f016d9bc ee6a3cac f8519a4a +[ 403.473347] 00000000 00000000 10000000 f61f8000 0100a000 10000000 00000001 008ca000 +[ 403.473410] f64ee840 f61f98c0 f016d9bc f016dcec ee6a3c98 ee6a3c98 f61f98c0 dcc58f00 +[ 403.473472] Call Trace: +[ 403.473509] [] i915_gem_evict_something+0x17a/0x2d0 [i915] +[ 403.473567] [] i915_gem_object_pin+0x271/0x660 [i915] +[ 403.473622] [] ? i915_ggtt_clear_range+0x20/0x20 [i915] +[ 403.473676] [] i915_gem_object_pin_to_display_plane+0xda/0x190 [i915] +[ 403.473742] [] intel_pin_and_fence_fb_obj+0xba/0x140 [i915] +[ 403.473800] [] intel_gen7_queue_flip+0x30/0x1c0 [i915] +[ 403.473856] [] intel_crtc_page_flip+0x1a0/0x320 [i915] +[ 403.473911] [] ? drm_framebuffer_reference+0x39/0x80 [drm] +[ 403.473965] [] drm_mode_page_flip_ioctl+0x28b/0x320 [drm] +[ 403.474018] [] drm_ioctl+0x4b8/0x560 [drm] +[ 403.474064] [] ? drm_mode_gamma_get_ioctl+0xd0/0xd0 [drm] +[ 403.474113] [] ? do_sync_read+0x6a/0xa0 +[ 403.474154] [] ? drm_copy_field+0x80/0x80 [drm] +[ 403.474193] [] do_vfs_ioctl+0x7c/0x5b0 +[ 403.474228] [] ? vfs_read+0xef/0x160 +[ 403.474263] [] ? ktime_get_ts+0x4b/0x120 +[ 403.474298] [] SyS_ioctl+0x97/0xa0 +[ 403.474330] [] sysenter_do_call+0x12/0x22 +[ 403.474364] Code: 55 f4 8b 45 f8 e9 75 ff ff ff 90 55 89 e5 53 83 ec 14 8b 08 8b 50 04 81 f9 00 01 10 00 74 24 81 fa 00 02 20 00 0f 84 8e 00 00 00 <8b> 1a 39 d8 75 62 8b 59 04 39 d8 75 35 89 51 04 89 0a 83 c4 14 +[ 403.474566] EIP: [] __list_del_entry+0x20/0xe0 SS:ESP 0068:ee6a3c48 +[ 403.476513] CR2: 000000006b6b6b6b + +v2: Missed the drm_object_unreference use after free (Ville) +Daniel Vetter writes: + +Reported-by: Mika Kuoppala +Cc: Ville Syrjälä +Cc: Chris Wilson +Signed-off-by: Ben Widawsky +Reviewed-by: Chris Wilson +[danvet: Add the Oops from Mika to the commit message.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 8637b407cf1740c52a01b9fc0cf506f31e225151) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_evict.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c +index 87875884770c..91b700155850 100644 +--- a/drivers/gpu/drm/i915/i915_gem_evict.c ++++ b/drivers/gpu/drm/i915/i915_gem_evict.c +@@ -136,14 +136,17 @@ found: + + /* Unbinding will emit any required flushes */ + while (!list_empty(&eviction_list)) { ++ struct drm_gem_object *obj; + vma = list_first_entry(&eviction_list, + struct i915_vma, + exec_list); ++ ++ obj = &vma->obj->base; ++ list_del_init(&vma->exec_list); + if (ret == 0) + ret = i915_vma_unbind(vma); + +- list_del_init(&vma->exec_list); +- drm_gem_object_unreference(&vma->obj->base); ++ drm_gem_object_unreference(obj); + } + + return ret; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0701-drm-i915-make-IVB-FDI-training-match-spec-v3.patch b/patches.baytrail/0701-drm-i915-make-IVB-FDI-training-match-spec-v3.patch new file mode 100644 index 000000000000..07d467ed7c83 --- /dev/null +++ b/patches.baytrail/0701-drm-i915-make-IVB-FDI-training-match-spec-v3.patch @@ -0,0 +1,210 @@ +From c765f4ea9dd19fc714e5dc8187b9272b1e6087f4 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Mon, 19 Aug 2013 11:04:55 -0700 +Subject: drm/i915: make IVB FDI training match spec v3 + +The existing code was trying different vswing and preemphasis settings +in the wrong place, and wasn't trying them enough. So add a loop to +walk through them, properly disabling FDI TX and RX in between if a +failure is detected. + +v2: remove unneeded reg writes, add delays around bit lock checks (Jesse) +v3: fix TX and RX disable per spec (Paulo) + fix delays per spec (Paulo) + make RX symbol lock check match TX bit lock check (Paulo) + +Signed-off-by: Jesse Barnes +Reviewed-by: Paulo Zanoni +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=51983 +Signed-off-by: Daniel Vetter +(cherry picked from commit 139ccd3fb12b3d17a773d2d61140f955a47fa470) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 142 ++++++++++++++++++----------------- + 1 file changed, 72 insertions(+), 70 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index cec940eb0147..0426c92a4c18 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2597,7 +2597,7 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc) + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; +- u32 reg, temp, i; ++ u32 reg, temp, i, j; + + /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit + for train result */ +@@ -2613,97 +2613,99 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc) + DRM_DEBUG_KMS("FDI_RX_IIR before link train 0x%x\n", + I915_READ(FDI_RX_IIR(pipe))); + +- /* enable CPU FDI TX and PCH FDI RX */ +- reg = FDI_TX_CTL(pipe); +- temp = I915_READ(reg); +- temp &= ~FDI_DP_PORT_WIDTH_MASK; +- temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes); +- temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB); +- temp |= FDI_LINK_TRAIN_PATTERN_1_IVB; +- temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; +- temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; +- temp |= FDI_COMPOSITE_SYNC; +- I915_WRITE(reg, temp | FDI_TX_ENABLE); +- +- I915_WRITE(FDI_RX_MISC(pipe), +- FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); +- +- reg = FDI_RX_CTL(pipe); +- temp = I915_READ(reg); +- temp &= ~FDI_LINK_TRAIN_AUTO; +- temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; +- temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; +- temp |= FDI_COMPOSITE_SYNC; +- I915_WRITE(reg, temp | FDI_RX_ENABLE); ++ /* Try each vswing and preemphasis setting twice before moving on */ ++ for (j = 0; j < ARRAY_SIZE(snb_b_fdi_train_param) * 2; j++) { ++ /* disable first in case we need to retry */ ++ reg = FDI_TX_CTL(pipe); ++ temp = I915_READ(reg); ++ temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB); ++ temp &= ~FDI_TX_ENABLE; ++ I915_WRITE(reg, temp); + +- POSTING_READ(reg); +- udelay(150); ++ reg = FDI_RX_CTL(pipe); ++ temp = I915_READ(reg); ++ temp &= ~FDI_LINK_TRAIN_AUTO; ++ temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; ++ temp &= ~FDI_RX_ENABLE; ++ I915_WRITE(reg, temp); + +- for (i = 0; i < 4; i++) { ++ /* enable CPU FDI TX and PCH FDI RX */ + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); ++ temp &= ~FDI_DP_PORT_WIDTH_MASK; ++ temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes); ++ temp |= FDI_LINK_TRAIN_PATTERN_1_IVB; + temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; +- temp |= snb_b_fdi_train_param[i]; +- I915_WRITE(reg, temp); ++ temp |= snb_b_fdi_train_param[j/2]; ++ temp |= FDI_COMPOSITE_SYNC; ++ I915_WRITE(reg, temp | FDI_TX_ENABLE); + +- POSTING_READ(reg); +- udelay(500); ++ I915_WRITE(FDI_RX_MISC(pipe), ++ FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); + +- reg = FDI_RX_IIR(pipe); ++ reg = FDI_RX_CTL(pipe); + temp = I915_READ(reg); +- DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); +- +- if (temp & FDI_RX_BIT_LOCK || +- (I915_READ(reg) & FDI_RX_BIT_LOCK)) { +- I915_WRITE(reg, temp | FDI_RX_BIT_LOCK); +- DRM_DEBUG_KMS("FDI train 1 done, level %i.\n", i); +- break; +- } +- } +- if (i == 4) +- DRM_ERROR("FDI train 1 fail!\n"); ++ temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; ++ temp |= FDI_COMPOSITE_SYNC; ++ I915_WRITE(reg, temp | FDI_RX_ENABLE); + +- /* Train 2 */ +- reg = FDI_TX_CTL(pipe); +- temp = I915_READ(reg); +- temp &= ~FDI_LINK_TRAIN_NONE_IVB; +- temp |= FDI_LINK_TRAIN_PATTERN_2_IVB; +- temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; +- temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; +- I915_WRITE(reg, temp); ++ POSTING_READ(reg); ++ udelay(1); /* should be 0.5us */ + +- reg = FDI_RX_CTL(pipe); +- temp = I915_READ(reg); +- temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; +- temp |= FDI_LINK_TRAIN_PATTERN_2_CPT; +- I915_WRITE(reg, temp); ++ for (i = 0; i < 4; i++) { ++ reg = FDI_RX_IIR(pipe); ++ temp = I915_READ(reg); ++ DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); + +- POSTING_READ(reg); +- udelay(150); ++ if (temp & FDI_RX_BIT_LOCK || ++ (I915_READ(reg) & FDI_RX_BIT_LOCK)) { ++ I915_WRITE(reg, temp | FDI_RX_BIT_LOCK); ++ DRM_DEBUG_KMS("FDI train 1 done, level %i.\n", ++ i); ++ break; ++ } ++ udelay(1); /* should be 0.5us */ ++ } ++ if (i == 4) { ++ DRM_DEBUG_KMS("FDI train 1 fail on vswing %d\n", j / 2); ++ continue; ++ } + +- for (i = 0; i < 4; i++) { ++ /* Train 2 */ + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); +- temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; +- temp |= snb_b_fdi_train_param[i]; ++ temp &= ~FDI_LINK_TRAIN_NONE_IVB; ++ temp |= FDI_LINK_TRAIN_PATTERN_2_IVB; ++ I915_WRITE(reg, temp); ++ ++ reg = FDI_RX_CTL(pipe); ++ temp = I915_READ(reg); ++ temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; ++ temp |= FDI_LINK_TRAIN_PATTERN_2_CPT; + I915_WRITE(reg, temp); + + POSTING_READ(reg); +- udelay(500); ++ udelay(2); /* should be 1.5us */ + +- reg = FDI_RX_IIR(pipe); +- temp = I915_READ(reg); +- DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); ++ for (i = 0; i < 4; i++) { ++ reg = FDI_RX_IIR(pipe); ++ temp = I915_READ(reg); ++ DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); + +- if (temp & FDI_RX_SYMBOL_LOCK) { +- I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK); +- DRM_DEBUG_KMS("FDI train 2 done, level %i.\n", i); +- break; ++ if (temp & FDI_RX_SYMBOL_LOCK || ++ (I915_READ(reg) & FDI_RX_SYMBOL_LOCK)) { ++ I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK); ++ DRM_DEBUG_KMS("FDI train 2 done, level %i.\n", ++ i); ++ goto train_done; ++ } ++ udelay(2); /* should be 1.5us */ + } ++ if (i == 4) ++ DRM_DEBUG_KMS("FDI train 2 fail on vswing %d\n", j / 2); + } +- if (i == 4) +- DRM_ERROR("FDI train 2 fail!\n"); + ++train_done: + DRM_DEBUG_KMS("FDI train done.\n"); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0702-drm-i915-Remove-DSPARB_HWCONTROL.patch b/patches.baytrail/0702-drm-i915-Remove-DSPARB_HWCONTROL.patch new file mode 100644 index 000000000000..b7efcd3ac745 --- /dev/null +++ b/patches.baytrail/0702-drm-i915-Remove-DSPARB_HWCONTROL.patch @@ -0,0 +1,37 @@ +From 68defbb9192bd9475be4610b394c6470df179b31 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 19 Aug 2013 19:32:00 +0100 +Subject: drm/i915: Remove DSPARB_HWCONTROL() + +This define hasn't been used since: + + commit 652c393a3368af84359da37c45afc35a91144960 + Author: Jesse Barnes + Date: Mon Aug 17 13:31:43 2009 -0700 + + drm/i915: add dynamic clock frequency control + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 8254860096df085d633207d4d68550bb2ca29f17) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 2b503d58dcd3..db709ee266ab 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1562,8 +1562,6 @@ struct drm_i915_file_private { + #define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev)) + #define SUPPORTS_TV(dev) (INTEL_INFO(dev)->supports_tv) + #define I915_HAS_HOTPLUG(dev) (INTEL_INFO(dev)->has_hotplug) +-/* dsparb controlled by hw only */ +-#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) + + #define HAS_FW_BLC(dev) (INTEL_INFO(dev)->gen > 2) + #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0703-drm-i915-Remove-HAS_PIPE_CONTROL.patch b/patches.baytrail/0703-drm-i915-Remove-HAS_PIPE_CONTROL.patch new file mode 100644 index 000000000000..eafe8e9be47a --- /dev/null +++ b/patches.baytrail/0703-drm-i915-Remove-HAS_PIPE_CONTROL.patch @@ -0,0 +1,37 @@ +From 22bfdf7afe5adf9298b289e8a91322a17f179526 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 19 Aug 2013 19:32:01 +0100 +Subject: drm/i915: Remove HAS_PIPE_CONTROL() + +The code using this was removed in: + + commit 88f23b8fa3e6357c423af24ec31c661fc12f884b + Author: Chris Wilson + Date: Sun Dec 5 15:08:31 2010 +0000 + + drm/i915: Avoid using PIPE_CONTROL on Ironlake + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit fdaa930bee14abe5ed1d1aead5bc6a9a5660ccbf) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index db709ee266ab..28ac24916e17 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1569,8 +1569,6 @@ struct drm_i915_file_private { + + #define HAS_IPS(dev) (IS_ULT(dev)) + +-#define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5) +- + #define HAS_DDI(dev) (INTEL_INFO(dev)->has_ddi) + #define HAS_POWER_WELL(dev) (IS_HASWELL(dev)) + #define HAS_FPGA_DBG_UNCLAIMED(dev) (INTEL_INFO(dev)->has_fpga_dbg) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0704-drm-Remove-IS_IRONLAKE_D.patch b/patches.baytrail/0704-drm-Remove-IS_IRONLAKE_D.patch new file mode 100644 index 000000000000..310ecf81689e --- /dev/null +++ b/patches.baytrail/0704-drm-Remove-IS_IRONLAKE_D.patch @@ -0,0 +1,39 @@ +From 96dcf53403726417b635b2c26f638b6238763909 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 19 Aug 2013 19:32:02 +0100 +Subject: drm: Remove IS_IRONLAKE_D() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This define hasn't been used since: + + commit cfdf1fa23f4074c9f8766dc67a928bbf680b1ac9 + Author: Kristian Høgsberg + Date: Wed Dec 16 15:16:16 2009 -0500 + + drm/i915: Implement IS_* macros using static tables + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 3abdb33410d8b130437613a2fe3d5bf667ca34da) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 28ac24916e17..0a613128cd6e 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1505,7 +1505,6 @@ struct drm_i915_file_private { + #define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011) + #define IS_PINEVIEW(dev) (INTEL_INFO(dev)->is_pineview) + #define IS_G33(dev) (INTEL_INFO(dev)->is_g33) +-#define IS_IRONLAKE_D(dev) ((dev)->pci_device == 0x0042) + #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) + #define IS_IVYBRIDGE(dev) (INTEL_INFO(dev)->is_ivybridge) + #define IS_IVB_GT1(dev) ((dev)->pci_device == 0x0156 || \ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0705-drm-i915-Remove-I915_READ_-NOPID-SYNC_0-SYNC_1.patch b/patches.baytrail/0705-drm-i915-Remove-I915_READ_-NOPID-SYNC_0-SYNC_1.patch new file mode 100644 index 000000000000..ccab81db65d1 --- /dev/null +++ b/patches.baytrail/0705-drm-i915-Remove-I915_READ_-NOPID-SYNC_0-SYNC_1.patch @@ -0,0 +1,33 @@ +From 96fe1bdd81984a0279f84d1eb6f280cdfda029c3 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Mon, 19 Aug 2013 19:32:03 +0100 +Subject: drm/i915: Remove I915_READ_{NOPID, SYNC_0, SYNC_1})() + +The code directly uses the registers and ring->mmio_base. + +Signed-off-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit e3ce7633ba38a97c2203ab60f381ce1642940328) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ringbuffer.h | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index 5e6be842d225..432ad5311ba6 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -33,10 +33,6 @@ struct intel_hw_status_page { + #define I915_READ_IMR(ring) I915_READ(RING_IMR((ring)->mmio_base)) + #define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) + +-#define I915_READ_NOPID(ring) I915_READ(RING_NOPID((ring)->mmio_base)) +-#define I915_READ_SYNC_0(ring) I915_READ(RING_SYNC_0((ring)->mmio_base)) +-#define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base)) +- + enum intel_ring_hangcheck_action { + HANGCHECK_WAIT, + HANGCHECK_ACTIVE, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0706-drm-i915-Expose-energy-counter-on-SNB-through-debugf.patch b/patches.baytrail/0706-drm-i915-Expose-energy-counter-on-SNB-through-debugf.patch new file mode 100644 index 000000000000..b8bdf384c028 --- /dev/null +++ b/patches.baytrail/0706-drm-i915-Expose-energy-counter-on-SNB-through-debugf.patch @@ -0,0 +1,103 @@ +From 2df657b0da4e04ffbc20468b888434b765e72c7f Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Tue, 20 Aug 2013 10:29:23 +0100 +Subject: drm/i915: Expose energy counter on SNB+ through debugfs + +On SNB and IVB, there's an MSR (also exposed through MCHBAR) we can use +to read out the amount of energy used over time. Expose this in sysfs +to make it easy to do power comparisons with different configurations. + +If the platform supports it, the file will show up under the +drm/card0/power subdirectory of the PCI device in sysfs as gt_energy_uJ. +The value in the file is a running total of energy (in microjoules) +consumed by the graphics device. + +v2: move to sysfs (Ben, Daniel) + expose a simple value (Chris) + drop unrelated hunk (Ben) + +Signed-off-by: Jesse Barnes + +v3: by Ben +Tied it into existing rc6 sysfs entries and named that a more generic +"power attrs." Fixed rebase conflicts. + +Signed-off-by: Ben Widawsky + +v4: Since RAPL is a real driver that already exists to serve power +monitoring, place our entry in debugfs. This gives me a fallback +location for systems that do not expose it otherwise. + +Signed-off-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit ec013e7f491cceef0e87190a3c6b132ce49f7ce4) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 23 +++++++++++++++++++++++ + drivers/gpu/drm/i915/i915_reg.h | 2 ++ + 2 files changed, 25 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 4785d8c14654..236d97e51c3a 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include + #include "intel_drv.h" + #include "intel_ringbuffer.h" +@@ -1769,6 +1770,27 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) + return 0; + } + ++static int i915_energy_uJ(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ u64 power; ++ u32 units; ++ ++ if (INTEL_INFO(dev)->gen < 6) ++ return -ENODEV; ++ ++ rdmsrl(MSR_RAPL_POWER_UNIT, power); ++ power = (power & 0x1f00) >> 8; ++ units = 1000000 / (1 << power); /* convert to uJ */ ++ power = I915_READ(MCH_SECP_NRG_STTS); ++ power *= units; ++ ++ seq_printf(m, "%llu", (long long unsigned)power); ++ return 0; ++} ++ + static int + i915_wedged_get(void *data, u64 *val) + { +@@ -2208,6 +2230,7 @@ static struct drm_info_list i915_debugfs_list[] = { + {"i915_dpio", i915_dpio_info, 0}, + {"i915_llc", i915_llc, 0}, + {"i915_edp_psr_status", i915_edp_psr_status, 0}, ++ {"i915_energy_uJ", i915_energy_uJ, 0}, + }; + #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 019fd1f9d286..711f0658c5c4 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -1449,6 +1449,8 @@ + #define MCH_SSKPD_WM0_MASK 0x3f + #define MCH_SSKPD_WM0_VAL 0xc + ++#define MCH_SECP_NRG_STTS (MCHBAR_MIRROR_BASE_SNB + 0x592c) ++ + /* Clocking configuration register */ + #define CLKCFG 0x10c00 + #define CLKCFG_FSB_400 (5 << 0) /* hrawclk 100 */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0707-drm-i915-add-the-FCLK-case-to-intel_ddi_get_cdclk_fr.patch b/patches.baytrail/0707-drm-i915-add-the-FCLK-case-to-intel_ddi_get_cdclk_fr.patch new file mode 100644 index 000000000000..0cb7c95cb8ee --- /dev/null +++ b/patches.baytrail/0707-drm-i915-add-the-FCLK-case-to-intel_ddi_get_cdclk_fr.patch @@ -0,0 +1,42 @@ +From 37a83e5e4eb745dc4181de10a4debd9ee166a51b Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Tue, 6 Aug 2013 18:57:11 -0300 +Subject: drm/i915: add the FCLK case to intel_ddi_get_cdclk_freq + +We already have code to disable LCPLL and switch to FCLK, so we need this too. +We still don't call the code to disable LCPLL, but we'll call it when we add +support for Package C8+. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit a40066412cc2ace1c1299e7a4d7a81dc33395b6f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_ddi.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c +index b8c096b4a1de..63aca49d11a8 100644 +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -1139,10 +1139,13 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) + + int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) + { +- if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) ++ uint32_t lcpll = I915_READ(LCPLL_CTL); ++ ++ if (lcpll & LCPLL_CD_SOURCE_FCLK) ++ return 800000; ++ else if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) + return 450000; +- else if ((I915_READ(LCPLL_CTL) & LCPLL_CLK_FREQ_MASK) == +- LCPLL_CLK_FREQ_450) ++ else if ((lcpll & LCPLL_CLK_FREQ_MASK) == LCPLL_CLK_FREQ_450) + return 450000; + else if (IS_ULT(dev_priv->dev)) + return 337500; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0708-drm-i915-wrap-GTIMR-changes.patch b/patches.baytrail/0708-drm-i915-wrap-GTIMR-changes.patch new file mode 100644 index 000000000000..bd43f0fa1315 --- /dev/null +++ b/patches.baytrail/0708-drm-i915-wrap-GTIMR-changes.patch @@ -0,0 +1,151 @@ +From 9d42c74ecac4cca476f9bcf160f40275ffe7ffc2 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Tue, 6 Aug 2013 18:57:12 -0300 +Subject: drm/i915: wrap GTIMR changes + +Just like the functions that touch DEIMR and SDEIMR, but for GTIMR. +The new functions contain a POSTING_READ(GTIMR) which was not present +at the 2 callers inside i915_irq.c. + +The implementation is based on ibx_display_interrupt_update. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 43eaea131823c5ca13d03364e61bd15f0b22a0f7) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 34 +++++++++++++++++++++++++++++---- + drivers/gpu/drm/i915/intel_drv.h | 3 +++ + drivers/gpu/drm/i915/intel_ringbuffer.c | 22 ++++++--------------- + 3 files changed, 39 insertions(+), 20 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 36cf7073690e..5315161d6e71 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -104,6 +104,34 @@ ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) + } + } + ++/** ++ * ilk_update_gt_irq - update GTIMR ++ * @dev_priv: driver private ++ * @interrupt_mask: mask of interrupt bits to update ++ * @enabled_irq_mask: mask of interrupt bits to enable ++ */ ++static void ilk_update_gt_irq(struct drm_i915_private *dev_priv, ++ uint32_t interrupt_mask, ++ uint32_t enabled_irq_mask) ++{ ++ assert_spin_locked(&dev_priv->irq_lock); ++ ++ dev_priv->gt_irq_mask &= ~interrupt_mask; ++ dev_priv->gt_irq_mask |= (~enabled_irq_mask & interrupt_mask); ++ I915_WRITE(GTIMR, dev_priv->gt_irq_mask); ++ POSTING_READ(GTIMR); ++} ++ ++void ilk_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) ++{ ++ ilk_update_gt_irq(dev_priv, mask, mask); ++} ++ ++void ilk_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) ++{ ++ ilk_update_gt_irq(dev_priv, mask, 0); ++} ++ + static bool ivb_can_enable_err_int(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -806,8 +834,7 @@ static void ivybridge_parity_work(struct work_struct *work) + I915_WRITE(GEN7_MISCCPCTL, misccpctl); + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- dev_priv->gt_irq_mask &= ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT; +- I915_WRITE(GTIMR, dev_priv->gt_irq_mask); ++ ilk_enable_gt_irq(dev_priv, GT_RENDER_L3_PARITY_ERROR_INTERRUPT); + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + + mutex_unlock(&dev_priv->dev->struct_mutex); +@@ -837,8 +864,7 @@ static void ivybridge_parity_error_irq_handler(struct drm_device *dev) + return; + + spin_lock(&dev_priv->irq_lock); +- dev_priv->gt_irq_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; +- I915_WRITE(GTIMR, dev_priv->gt_irq_mask); ++ ilk_disable_gt_irq(dev_priv, GT_RENDER_L3_PARITY_ERROR_INTERRUPT); + spin_unlock(&dev_priv->irq_lock); + + queue_work(dev_priv->wq, &dev_priv->l3_parity.error_work); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 01455aa8b8bb..a8462064714c 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -778,5 +778,8 @@ extern void intel_edp_psr_update(struct drm_device *dev); + extern void hsw_disable_lcpll(struct drm_i915_private *dev_priv, + bool switch_to_fclk, bool allow_power_down); + extern void hsw_restore_lcpll(struct drm_i915_private *dev_priv); ++extern void ilk_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); ++extern void ilk_disable_gt_irq(struct drm_i915_private *dev_priv, ++ uint32_t mask); + + #endif /* __INTEL_DRV_H__ */ +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index a1aa3bc48dcc..c26c90607355 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -836,11 +836,8 @@ gen5_ring_get_irq(struct intel_ring_buffer *ring) + return false; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (ring->irq_refcount++ == 0) { +- dev_priv->gt_irq_mask &= ~ring->irq_enable_mask; +- I915_WRITE(GTIMR, dev_priv->gt_irq_mask); +- POSTING_READ(GTIMR); +- } ++ if (ring->irq_refcount++ == 0) ++ ilk_enable_gt_irq(dev_priv, ring->irq_enable_mask); + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + + return true; +@@ -854,11 +851,8 @@ gen5_ring_put_irq(struct intel_ring_buffer *ring) + unsigned long flags; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); +- if (--ring->irq_refcount == 0) { +- dev_priv->gt_irq_mask |= ring->irq_enable_mask; +- I915_WRITE(GTIMR, dev_priv->gt_irq_mask); +- POSTING_READ(GTIMR); +- } ++ if (--ring->irq_refcount == 0) ++ ilk_disable_gt_irq(dev_priv, ring->irq_enable_mask); + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + } + +@@ -1040,9 +1034,7 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring) + GT_RENDER_L3_PARITY_ERROR_INTERRUPT)); + else + I915_WRITE_IMR(ring, ~ring->irq_enable_mask); +- dev_priv->gt_irq_mask &= ~ring->irq_enable_mask; +- I915_WRITE(GTIMR, dev_priv->gt_irq_mask); +- POSTING_READ(GTIMR); ++ ilk_enable_gt_irq(dev_priv, ring->irq_enable_mask); + } + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + +@@ -1063,9 +1055,7 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring) + ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT); + else + I915_WRITE_IMR(ring, ~0); +- dev_priv->gt_irq_mask |= ring->irq_enable_mask; +- I915_WRITE(GTIMR, dev_priv->gt_irq_mask); +- POSTING_READ(GTIMR); ++ ilk_disable_gt_irq(dev_priv, ring->irq_enable_mask); + } + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0709-drm-i915-wrap-GEN6_PMIMR-changes.patch b/patches.baytrail/0709-drm-i915-wrap-GEN6_PMIMR-changes.patch new file mode 100644 index 000000000000..33cc03ff6492 --- /dev/null +++ b/patches.baytrail/0709-drm-i915-wrap-GEN6_PMIMR-changes.patch @@ -0,0 +1,164 @@ +From 13d18277dc1bf6a7f3eabc886596c860d96ae21f Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Tue, 6 Aug 2013 18:57:13 -0300 +Subject: drm/i915: wrap GEN6_PMIMR changes + +Just like we're doing with the other IMR changes. + +One of the functional changes is that not every caller was doing the +POSTING_READ. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit edbfdb456053d0738e6b06a3827ead4158bfc918) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 47 ++++++++++++++++++++++++++++----- + drivers/gpu/drm/i915/intel_drv.h | 3 +++ + drivers/gpu/drm/i915/intel_pm.c | 2 +- + drivers/gpu/drm/i915/intel_ringbuffer.c | 8 ++---- + 4 files changed, 46 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 5315161d6e71..bb4bd21399a1 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -132,6 +132,41 @@ void ilk_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) + ilk_update_gt_irq(dev_priv, mask, 0); + } + ++/** ++ * snb_update_pm_irq - update GEN6_PMIMR ++ * @dev_priv: driver private ++ * @interrupt_mask: mask of interrupt bits to update ++ * @enabled_irq_mask: mask of interrupt bits to enable ++ */ ++static void snb_update_pm_irq(struct drm_i915_private *dev_priv, ++ uint32_t interrupt_mask, ++ uint32_t enabled_irq_mask) ++{ ++ uint32_t pmimr = I915_READ(GEN6_PMIMR); ++ pmimr &= ~interrupt_mask; ++ pmimr |= (~enabled_irq_mask & interrupt_mask); ++ ++ assert_spin_locked(&dev_priv->irq_lock); ++ ++ I915_WRITE(GEN6_PMIMR, pmimr); ++ POSTING_READ(GEN6_PMIMR); ++} ++ ++void snb_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) ++{ ++ snb_update_pm_irq(dev_priv, mask, mask); ++} ++ ++void snb_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) ++{ ++ snb_update_pm_irq(dev_priv, mask, 0); ++} ++ ++static void snb_set_pm_irq(struct drm_i915_private *dev_priv, uint32_t val) ++{ ++ snb_update_pm_irq(dev_priv, 0xffffffff, ~val); ++} ++ + static bool ivb_can_enable_err_int(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -739,15 +774,14 @@ static void gen6_pm_rps_work(struct work_struct *work) + { + drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, + rps.work); +- u32 pm_iir, pm_imr; ++ u32 pm_iir; + u8 new_delay; + + spin_lock_irq(&dev_priv->irq_lock); + pm_iir = dev_priv->rps.pm_iir; + dev_priv->rps.pm_iir = 0; +- pm_imr = I915_READ(GEN6_PMIMR); + /* Make sure not to corrupt PMIMR state used by ringbuffer code */ +- I915_WRITE(GEN6_PMIMR, pm_imr & ~GEN6_PM_RPS_EVENTS); ++ snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS); + spin_unlock_irq(&dev_priv->irq_lock); + + if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0) +@@ -921,8 +955,7 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, + + spin_lock(&dev_priv->irq_lock); + dev_priv->rps.pm_iir |= pm_iir; +- I915_WRITE(GEN6_PMIMR, dev_priv->rps.pm_iir); +- POSTING_READ(GEN6_PMIMR); ++ snb_set_pm_irq(dev_priv, dev_priv->rps.pm_iir); + spin_unlock(&dev_priv->irq_lock); + + queue_work(dev_priv->wq, &dev_priv->rps.work); +@@ -1005,8 +1038,8 @@ static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv, + if (pm_iir & GEN6_PM_RPS_EVENTS) { + spin_lock(&dev_priv->irq_lock); + dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS; +- I915_WRITE(GEN6_PMIMR, dev_priv->rps.pm_iir); +- /* never want to mask useful interrupts. (also posting read) */ ++ snb_set_pm_irq(dev_priv, dev_priv->rps.pm_iir); ++ /* never want to mask useful interrupts. */ + WARN_ON(I915_READ_NOTRACE(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS); + spin_unlock(&dev_priv->irq_lock); + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index a8462064714c..8222f2426b47 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -781,5 +781,8 @@ extern void hsw_restore_lcpll(struct drm_i915_private *dev_priv); + extern void ilk_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); + extern void ilk_disable_gt_irq(struct drm_i915_private *dev_priv, + uint32_t mask); ++extern void snb_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); ++extern void snb_disable_pm_irq(struct drm_i915_private *dev_priv, ++ uint32_t mask); + + #endif /* __INTEL_DRV_H__ */ +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 21f4c958bbfe..8dca2530a8f4 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3450,7 +3450,7 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) + + spin_lock_irq(&dev_priv->irq_lock); + WARN_ON(dev_priv->rps.pm_iir); +- I915_WRITE(GEN6_PMIMR, I915_READ(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS); ++ snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS); + I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); + spin_unlock_irq(&dev_priv->irq_lock); + /* only unmask PM interrupts we need. Mask all others. */ +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index c26c90607355..f05cceac5a52 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -1074,10 +1074,8 @@ hsw_vebox_get_irq(struct intel_ring_buffer *ring) + + spin_lock_irqsave(&dev_priv->irq_lock, flags); + if (ring->irq_refcount++ == 0) { +- u32 pm_imr = I915_READ(GEN6_PMIMR); + I915_WRITE_IMR(ring, ~ring->irq_enable_mask); +- I915_WRITE(GEN6_PMIMR, pm_imr & ~ring->irq_enable_mask); +- POSTING_READ(GEN6_PMIMR); ++ snb_enable_pm_irq(dev_priv, ring->irq_enable_mask); + } + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + +@@ -1096,10 +1094,8 @@ hsw_vebox_put_irq(struct intel_ring_buffer *ring) + + spin_lock_irqsave(&dev_priv->irq_lock, flags); + if (--ring->irq_refcount == 0) { +- u32 pm_imr = I915_READ(GEN6_PMIMR); + I915_WRITE_IMR(ring, ~0); +- I915_WRITE(GEN6_PMIMR, pm_imr | ring->irq_enable_mask); +- POSTING_READ(GEN6_PMIMR); ++ snb_disable_pm_irq(dev_priv, ring->irq_enable_mask); + } + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0710-drm-i915-don-t-update-GEN6_PMIMR-when-it-s-not-neede.patch b/patches.baytrail/0710-drm-i915-don-t-update-GEN6_PMIMR-when-it-s-not-neede.patch new file mode 100644 index 000000000000..f157781e6df6 --- /dev/null +++ b/patches.baytrail/0710-drm-i915-don-t-update-GEN6_PMIMR-when-it-s-not-neede.patch @@ -0,0 +1,54 @@ +From cf5c5c4e71cbef94065855caf9640ef8998797ef Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Tue, 6 Aug 2013 18:57:14 -0300 +Subject: drm/i915: don't update GEN6_PMIMR when it's not needed + +I did some brief tests and the "new_val = pmimr" condition usually +happens a few times after exiting games. + +Note: This is also prep work to track the GEN6_PMIMR register state in +dev_priv->pm_imr. This happens in the next patch. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +[danvet: Add note to explain why we want this, as per the discussion +between Chris and Paulo.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit f52ecbcf8009ef18cda86b30efd837338cd25392) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index bb4bd21399a1..d9d3dfae26f7 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -142,14 +142,18 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv, + uint32_t interrupt_mask, + uint32_t enabled_irq_mask) + { +- uint32_t pmimr = I915_READ(GEN6_PMIMR); +- pmimr &= ~interrupt_mask; +- pmimr |= (~enabled_irq_mask & interrupt_mask); ++ uint32_t pmimr, new_val; + + assert_spin_locked(&dev_priv->irq_lock); + +- I915_WRITE(GEN6_PMIMR, pmimr); +- POSTING_READ(GEN6_PMIMR); ++ pmimr = new_val = I915_READ(GEN6_PMIMR); ++ new_val &= ~interrupt_mask; ++ new_val |= (~enabled_irq_mask & interrupt_mask); ++ ++ if (new_val != pmimr) { ++ I915_WRITE(GEN6_PMIMR, new_val); ++ POSTING_READ(GEN6_PMIMR); ++ } + } + + void snb_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0711-drm-i915-add-dev_priv-pm_irq_mask.patch b/patches.baytrail/0711-drm-i915-add-dev_priv-pm_irq_mask.patch new file mode 100644 index 000000000000..274a5d6e1638 --- /dev/null +++ b/patches.baytrail/0711-drm-i915-add-dev_priv-pm_irq_mask.patch @@ -0,0 +1,71 @@ +From 5af61ed05db36b63a414a07f1fd4e670f4c9efe8 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Tue, 6 Aug 2013 18:57:15 -0300 +Subject: drm/i915: add dev_priv->pm_irq_mask + +Just like irq_mask and gt_irq_mask, use it to track the status of +GEN6_PMIMR so we don't need to read it again every time we call +snb_update_pm_irq. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 605cd25b1ffa09a2f86b5c4bd120086dd5ea10a7) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/i915_irq.c | 12 +++++++----- + 2 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 0a613128cd6e..5cc71ac04beb 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1123,6 +1123,7 @@ typedef struct drm_i915_private { + /** Cached value of IMR to avoid reads in updating the bitfield */ + u32 irq_mask; + u32 gt_irq_mask; ++ u32 pm_irq_mask; + + struct work_struct hotplug_work; + bool enable_hotplug_processing; +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index d9d3dfae26f7..b470191a6a7e 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -142,16 +142,17 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv, + uint32_t interrupt_mask, + uint32_t enabled_irq_mask) + { +- uint32_t pmimr, new_val; ++ uint32_t new_val; + + assert_spin_locked(&dev_priv->irq_lock); + +- pmimr = new_val = I915_READ(GEN6_PMIMR); ++ new_val = dev_priv->pm_irq_mask; + new_val &= ~interrupt_mask; + new_val |= (~enabled_irq_mask & interrupt_mask); + +- if (new_val != pmimr) { +- I915_WRITE(GEN6_PMIMR, new_val); ++ if (new_val != dev_priv->pm_irq_mask) { ++ dev_priv->pm_irq_mask = new_val; ++ I915_WRITE(GEN6_PMIMR, dev_priv->pm_irq_mask); + POSTING_READ(GEN6_PMIMR); + } + } +@@ -2263,8 +2264,9 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev) + if (HAS_VEBOX(dev)) + pm_irqs |= PM_VEBOX_USER_INTERRUPT; + ++ dev_priv->pm_irq_mask = 0xffffffff; + I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); +- I915_WRITE(GEN6_PMIMR, 0xffffffff); ++ I915_WRITE(GEN6_PMIMR, dev_priv->pm_irq_mask); + I915_WRITE(GEN6_PMIER, pm_irqs); + POSTING_READ(GEN6_PMIER); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0712-drm-i915-don-t-disable-reenable-IVB-error-interrupts.patch b/patches.baytrail/0712-drm-i915-don-t-disable-reenable-IVB-error-interrupts.patch new file mode 100644 index 000000000000..485fd979febc --- /dev/null +++ b/patches.baytrail/0712-drm-i915-don-t-disable-reenable-IVB-error-interrupts.patch @@ -0,0 +1,56 @@ +From 7648296b694658587a30921e68808c4b1be40f5e Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Tue, 6 Aug 2013 18:57:16 -0300 +Subject: drm/i915: don't disable/reenable IVB error interrupts when not needed + +If the error interrupts are already disabled, don't disable and +reenable them. This is going to be needed when we're in PC8+, where +all the interrupts are disabled so we won't risk re-enabling +DE_ERR_INT_IVB. + +v2: Use dev_priv->irq_mask (Chris) + +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 333a820416ccb0e24974b6ebe7d447c0c28c7b76) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index b470191a6a7e..eeced610821c 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1373,6 +1373,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u32 de_iir, gt_iir, de_ier, sde_ier = 0; + irqreturn_t ret = IRQ_NONE; ++ bool err_int_reenable = false; + + atomic_inc(&dev_priv->irq_received); + +@@ -1401,7 +1402,9 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + * handler. */ + if (IS_HASWELL(dev)) { + spin_lock(&dev_priv->irq_lock); +- ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); ++ err_int_reenable = ~dev_priv->irq_mask & DE_ERR_INT_IVB; ++ if (err_int_reenable) ++ ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); + spin_unlock(&dev_priv->irq_lock); + } + +@@ -1437,7 +1440,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + } + } + +- if (IS_HASWELL(dev)) { ++ if (err_int_reenable) { + spin_lock(&dev_priv->irq_lock); + if (ivb_can_enable_err_int(dev)) + ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0713-drm-i915-don-t-queue-PM-events-we-won-t-process.patch b/patches.baytrail/0713-drm-i915-don-t-queue-PM-events-we-won-t-process.patch new file mode 100644 index 000000000000..57ae4a6228a2 --- /dev/null +++ b/patches.baytrail/0713-drm-i915-don-t-queue-PM-events-we-won-t-process.patch @@ -0,0 +1,71 @@ +From 60fdf55ca4a9c2de2428dc58213927a5bfa29ff8 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 15 Aug 2013 11:50:01 -0300 +Subject: drm/i915: don't queue PM events we won't process + +On SNB/IVB/VLV we only call gen6_rps_irq_handler if one of the IIR +bits set is part of GEN6_PM_RPS_EVENTS, but at gen6_rps_irq_handler we +add all the enabled IIR bits to the work queue, not only the ones that +are part of GEN6_PM_RPS_EVENTS. But then gen6_pm_rps_work only +processes GEN6_PM_RPS_EVENTS, so it's useless to add anything that's +not GEN6_PM_RPS_EVENTS to the work queue. + +As a bonus, gen6_rps_irq_handler looks more similar to +hsw_pm_irq_handler, so we may be able to merge them in the future. + +v2: - Add a WARN in case we queued something we're not going to + process. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ben Widawsky (v1) +Signed-off-by: Daniel Vetter +(cherry picked from commit 60611c137641af41895828cfc74f5be64ed69b49) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index eeced610821c..b04130e7bff2 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -789,6 +789,9 @@ static void gen6_pm_rps_work(struct work_struct *work) + snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS); + spin_unlock_irq(&dev_priv->irq_lock); + ++ /* Make sure we didn't queue anything we're not going to process. */ ++ WARN_ON(pm_iir & ~GEN6_PM_RPS_EVENTS); ++ + if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0) + return; + +@@ -959,7 +962,7 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, + */ + + spin_lock(&dev_priv->irq_lock); +- dev_priv->rps.pm_iir |= pm_iir; ++ dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS; + snb_set_pm_irq(dev_priv, dev_priv->rps.pm_iir); + spin_unlock(&dev_priv->irq_lock); + +@@ -1128,7 +1131,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) + if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS) + gmbus_irq_handler(dev); + +- if (pm_iir & GEN6_PM_RPS_EVENTS) ++ if (pm_iir) + gen6_rps_irq_handler(dev_priv, pm_iir); + + I915_WRITE(GTIIR, gt_iir); +@@ -1433,7 +1436,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + if (pm_iir) { + if (IS_HASWELL(dev)) + hsw_pm_irq_handler(dev_priv, pm_iir); +- else if (pm_iir & GEN6_PM_RPS_EVENTS) ++ else + gen6_rps_irq_handler(dev_priv, pm_iir); + I915_WRITE(GEN6_PMIIR, pm_iir); + ret = IRQ_HANDLED; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0714-drm-i915-fix-how-we-mask-PMIMR-when-adding-work-to-t.patch b/patches.baytrail/0714-drm-i915-fix-how-we-mask-PMIMR-when-adding-work-to-t.patch new file mode 100644 index 000000000000..11f9309b0198 --- /dev/null +++ b/patches.baytrail/0714-drm-i915-fix-how-we-mask-PMIMR-when-adding-work-to-t.patch @@ -0,0 +1,100 @@ +From 4609be6ede808afa10b534d13b88efd09aa17e63 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 9 Aug 2013 17:04:36 -0300 +Subject: drm/i915: fix how we mask PMIMR when adding work to the queue + +It seems we've been doing this ever since we started processing the +RPS events on a work queue, on commit "drm/i915: move gen6 rps +handling to workqueue", 4912d04193733a825216b926ffd290fada88ab07. + +The problem is: when we add work to the queue, instead of just masking +the bits we queued and leaving all the others on their current state, +we mask the bits we queued and unmask all the others. This basically +means we'll be unmasking a bunch of interrupts we're not going to +process. And if you look at gen6_pm_rps_work, we unmask back only +GEN6_PM_RPS_EVENTS, which means the bits we unmasked when adding work +to the queue will remain unmasked after we process the queue. + +Notice that even though we unmask those unrelated interrupts, we never +enable them on IER, so they don't fire our interrupt handler, they +just stay there on IIR waiting to be cleared when something else +triggers the interrupt handler. + +So this patch does what seems to make more sense: mask only the bits +we add to the queue, without unmasking anything else, and so we'll +unmask them after we process the queue. + +As a side effect we also have to remove that WARN, because it is not +only making sure we don't mask useful interrupts, it is also making +sure we do unmask useless interrupts! That piece of code should not be +responsible for knowing which bits should be unmasked, so just don't +assert anything, and trust that snb_disable_pm_irq should be doing the +right thing. + +With i915.enable_pc8=1 I was getting ocasional "GEN6_PMIIR is not 0" +error messages due to the fact that we unmask those unrelated +interrupts but don't enable them. + +Note: if bugs start bisecting to this patch, then it probably means +someone was relying on the fact that we unmask everything by accident, +then we should fix gen5_gt_irq_postinstall or whoever needs the +accidentally unmasked interrupts. Or maybe I was just wrong and we +need to revert this patch :) + +Note: This started to be a more real issue with the addition of the +VEBOX support since now we do enable more than just the minimal set of +RPS interrupts in the IER register. Which means after the first rps +interrupt has happened we will never mask the VEBOX user interrupts +again and so will blow through cpu time needlessly when running video +workloads. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ben Widawsky +[danvet: Add note that this started to matter with VEBOX much more.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 4d3b3d5fd7d42a522a6c444388826bb23264db9f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index b04130e7bff2..aaad8c639a3a 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -167,11 +167,6 @@ void snb_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) + snb_update_pm_irq(dev_priv, mask, 0); + } + +-static void snb_set_pm_irq(struct drm_i915_private *dev_priv, uint32_t val) +-{ +- snb_update_pm_irq(dev_priv, 0xffffffff, ~val); +-} +- + static bool ivb_can_enable_err_int(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -963,7 +958,7 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, + + spin_lock(&dev_priv->irq_lock); + dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS; +- snb_set_pm_irq(dev_priv, dev_priv->rps.pm_iir); ++ snb_disable_pm_irq(dev_priv, pm_iir & GEN6_PM_RPS_EVENTS); + spin_unlock(&dev_priv->irq_lock); + + queue_work(dev_priv->wq, &dev_priv->rps.work); +@@ -1046,9 +1041,7 @@ static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv, + if (pm_iir & GEN6_PM_RPS_EVENTS) { + spin_lock(&dev_priv->irq_lock); + dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS; +- snb_set_pm_irq(dev_priv, dev_priv->rps.pm_iir); +- /* never want to mask useful interrupts. */ +- WARN_ON(I915_READ_NOTRACE(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS); ++ snb_disable_pm_irq(dev_priv, pm_iir & GEN6_PM_RPS_EVENTS); + spin_unlock(&dev_priv->irq_lock); + + queue_work(dev_priv->wq, &dev_priv->rps.work); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0715-drm-i915-merge-HSW-and-SNB-PM-irq-handlers.patch b/patches.baytrail/0715-drm-i915-merge-HSW-and-SNB-PM-irq-handlers.patch new file mode 100644 index 000000000000..5ea60eaae122 --- /dev/null +++ b/patches.baytrail/0715-drm-i915-merge-HSW-and-SNB-PM-irq-handlers.patch @@ -0,0 +1,108 @@ +From b7db2611a077dc0f1b04fe1d4c3f30bb0280286d Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Thu, 15 Aug 2013 11:51:32 -0300 +Subject: drm/i915: merge HSW and SNB PM irq handlers + +Because hsw_pm_irq_handler does exactly what gen6_rps_irq_handler does +and also processes the 2 additional VEBOX bits. So merge those +functions and wrap the VEBOX bits on a HAS_VEBOX check. This +check isn't really necessary since the bits are reserved on +SNB/IVB/VLV, but it's a good documentation on who uses them. + +v2: - Change IS_HASWELL check to HAS_VEBOX + +Signed-off-by: Paulo Zanoni +Reviewed-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit 1403c0d4d46f2eed2ab13b89561c853988ad7513) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 50 ++++++++++------------------------------- + 1 file changed, 12 insertions(+), 38 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index aaad8c639a3a..9e2ea5b16233 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -942,28 +942,6 @@ static void snb_gt_irq_handler(struct drm_device *dev, + ivybridge_parity_error_irq_handler(dev); + } + +-/* Legacy way of handling PM interrupts */ +-static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, +- u32 pm_iir) +-{ +- /* +- * IIR bits should never already be set because IMR should +- * prevent an interrupt from being shown in IIR. The warning +- * displays a case where we've unsafely cleared +- * dev_priv->rps.pm_iir. Although missing an interrupt of the same +- * type is not a problem, it displays a problem in the logic. +- * +- * The mask bit in IMR is cleared by dev_priv->rps.work. +- */ +- +- spin_lock(&dev_priv->irq_lock); +- dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS; +- snb_disable_pm_irq(dev_priv, pm_iir & GEN6_PM_RPS_EVENTS); +- spin_unlock(&dev_priv->irq_lock); +- +- queue_work(dev_priv->wq, &dev_priv->rps.work); +-} +- + #define HPD_STORM_DETECT_PERIOD 1000 + #define HPD_STORM_THRESHOLD 5 + +@@ -1030,13 +1008,10 @@ static void dp_aux_irq_handler(struct drm_device *dev) + wake_up_all(&dev_priv->gmbus_wait_queue); + } + +-/* Unlike gen6_rps_irq_handler() from which this function is originally derived, +- * we must be able to deal with other PM interrupts. This is complicated because +- * of the way in which we use the masks to defer the RPS work (which for +- * posterity is necessary because of forcewake). +- */ +-static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv, +- u32 pm_iir) ++/* The RPS events need forcewake, so we add them to a work queue and mask their ++ * IMR bits until the work is done. Other interrupts can be processed without ++ * the work queue. */ ++static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) + { + if (pm_iir & GEN6_PM_RPS_EVENTS) { + spin_lock(&dev_priv->irq_lock); +@@ -1047,12 +1022,14 @@ static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv, + queue_work(dev_priv->wq, &dev_priv->rps.work); + } + +- if (pm_iir & PM_VEBOX_USER_INTERRUPT) +- notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); ++ if (HAS_VEBOX(dev_priv->dev)) { ++ if (pm_iir & PM_VEBOX_USER_INTERRUPT) ++ notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); + +- if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) { +- DRM_ERROR("VEBOX CS error interrupt 0x%08x\n", pm_iir); +- i915_handle_error(dev_priv->dev, false); ++ if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) { ++ DRM_ERROR("VEBOX CS error interrupt 0x%08x\n", pm_iir); ++ i915_handle_error(dev_priv->dev, false); ++ } + } + } + +@@ -1427,10 +1404,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) + if (INTEL_INFO(dev)->gen >= 6) { + u32 pm_iir = I915_READ(GEN6_PMIIR); + if (pm_iir) { +- if (IS_HASWELL(dev)) +- hsw_pm_irq_handler(dev_priv, pm_iir); +- else +- gen6_rps_irq_handler(dev_priv, pm_iir); ++ gen6_rps_irq_handler(dev_priv, pm_iir); + I915_WRITE(GEN6_PMIIR, pm_iir); + ret = IRQ_HANDLED; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0716-drm-i915-Cleaning-up-the-relocate-entry-function.patch b/patches.baytrail/0716-drm-i915-Cleaning-up-the-relocate-entry-function.patch new file mode 100644 index 000000000000..1576ea12c44b --- /dev/null +++ b/patches.baytrail/0716-drm-i915-Cleaning-up-the-relocate-entry-function.patch @@ -0,0 +1,126 @@ +From 007d5b7c201dc874a00ec1217e37e8aac4b55d30 Mon Sep 17 00:00:00 2001 +From: Rafael Barbalho +Date: Wed, 21 Aug 2013 17:10:51 +0100 +Subject: drm/i915: Cleaning up the relocate entry function + +As the relocate entry function was getting a bit too big I've moved +the code that used to use either the cpu or the gtt to for the +relocation into two separate functions. + +Signed-off-by: Rafael Barbalho +Signed-off-by: Daniel Vetter +(cherry picked from commit 5032d871f7d300aee10c309ea004eb4f851553fe) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 88 ++++++++++++++++++------------ + 1 file changed, 54 insertions(+), 34 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 7dcf78cf6781..792c52a235ee 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -172,6 +172,56 @@ static inline int use_cpu_reloc(struct drm_i915_gem_object *obj) + } + + static int ++relocate_entry_cpu(struct drm_i915_gem_object *obj, ++ struct drm_i915_gem_relocation_entry *reloc) ++{ ++ uint32_t page_offset = offset_in_page(reloc->offset); ++ char *vaddr; ++ int ret = -EINVAL; ++ ++ ret = i915_gem_object_set_to_cpu_domain(obj, 1); ++ if (ret) ++ return ret; ++ ++ vaddr = kmap_atomic(i915_gem_object_get_page(obj, ++ reloc->offset >> PAGE_SHIFT)); ++ *(uint32_t *)(vaddr + page_offset) = reloc->delta; ++ kunmap_atomic(vaddr); ++ ++ return 0; ++} ++ ++static int ++relocate_entry_gtt(struct drm_i915_gem_object *obj, ++ struct drm_i915_gem_relocation_entry *reloc) ++{ ++ struct drm_device *dev = obj->base.dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ uint32_t __iomem *reloc_entry; ++ void __iomem *reloc_page; ++ int ret = -EINVAL; ++ ++ ret = i915_gem_object_set_to_gtt_domain(obj, true); ++ if (ret) ++ return ret; ++ ++ ret = i915_gem_object_put_fence(obj); ++ if (ret) ++ return ret; ++ ++ /* Map the page containing the relocation we're going to perform. */ ++ reloc->offset += i915_gem_obj_ggtt_offset(obj); ++ reloc_page = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, ++ reloc->offset & PAGE_MASK); ++ reloc_entry = (uint32_t __iomem *) ++ (reloc_page + offset_in_page(reloc->offset)); ++ iowrite32(reloc->delta, reloc_entry); ++ io_mapping_unmap_atomic(reloc_page); ++ ++ return 0; ++} ++ ++static int + i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, + struct eb_objects *eb, + struct drm_i915_gem_relocation_entry *reloc, +@@ -255,40 +305,10 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, + return -EFAULT; + + reloc->delta += target_offset; +- if (use_cpu_reloc(obj)) { +- uint32_t page_offset = offset_in_page(reloc->offset); +- char *vaddr; +- +- ret = i915_gem_object_set_to_cpu_domain(obj, 1); +- if (ret) +- return ret; +- +- vaddr = kmap_atomic(i915_gem_object_get_page(obj, +- reloc->offset >> PAGE_SHIFT)); +- *(uint32_t *)(vaddr + page_offset) = reloc->delta; +- kunmap_atomic(vaddr); +- } else { +- struct drm_i915_private *dev_priv = dev->dev_private; +- uint32_t __iomem *reloc_entry; +- void __iomem *reloc_page; +- +- ret = i915_gem_object_set_to_gtt_domain(obj, true); +- if (ret) +- return ret; +- +- ret = i915_gem_object_put_fence(obj); +- if (ret) +- return ret; +- +- /* Map the page containing the relocation we're going to perform. */ +- reloc->offset += i915_gem_obj_ggtt_offset(obj); +- reloc_page = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, +- reloc->offset & PAGE_MASK); +- reloc_entry = (uint32_t __iomem *) +- (reloc_page + offset_in_page(reloc->offset)); +- iowrite32(reloc->delta, reloc_entry); +- io_mapping_unmap_atomic(reloc_page); +- } ++ if (use_cpu_reloc(obj)) ++ ret = relocate_entry_cpu(obj, reloc); ++ else ++ ret = relocate_entry_gtt(obj, reloc); + + /* and update the user's relocation entry */ + reloc->presumed_offset = target_offset; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0717-drm-i915-drop-WaMbcDriverBootEnable-workaround.patch b/patches.baytrail/0717-drm-i915-drop-WaMbcDriverBootEnable-workaround.patch new file mode 100644 index 000000000000..a85d55b2c458 --- /dev/null +++ b/patches.baytrail/0717-drm-i915-drop-WaMbcDriverBootEnable-workaround.patch @@ -0,0 +1,93 @@ +From b8b71bdccc8c0409799da9ecaca9d04339f17170 Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Wed, 21 Aug 2013 08:08:55 -0700 +Subject: drm/i915: drop WaMbcDriverBootEnable workaround +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Turns out the BIOS will do this for us as needed, and if we try to do it +again we risk hangs or other bad behavior. + +Note that this seems to break libva on ChromeOS after resumes (but +strangely _not_ after booting up). + +This essentially reverts + +commit b4ae3f22d238617ca11610b29fde16cf8c0bc6e0 +Author: Jesse Barnes +Date: Thu Jun 14 11:04:48 2012 -0700 + + drm/i915: load boot context at driver init time + +and + +commit b3bf076697a68a8577f4a5f7407de0bb2b3b56ac +Author: Paulo Zanoni +Date: Tue Nov 20 13:27:44 2012 -0200 + + drm/i915: implement WaMbcDriverBootEnable on Haswell + +Signed-off-by: Jesse Barnes +Reported-and-Tested-by: Stéphane Marchesin +[danvet: Add note about impact and regression citation.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 3414caf63421762e57b26aa999e5187b42ee1606) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 17 ----------------- + 1 file changed, 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 8dca2530a8f4..178da3ec31b4 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4864,10 +4864,6 @@ static void gen6_init_clock_gating(struct drm_device *dev) + ILK_DPARBUNIT_CLOCK_GATE_ENABLE | + ILK_DPFDUNIT_CLOCK_GATE_ENABLE); + +- /* WaMbcDriverBootEnable:snb */ +- I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | +- GEN6_MBCTL_ENABLE_BOOT_FETCH); +- + g4x_disable_trickle_feed(dev); + + /* The default value should be 0x200 according to docs, but the two +@@ -4963,10 +4959,6 @@ static void haswell_init_clock_gating(struct drm_device *dev) + I915_WRITE(CACHE_MODE_1, + _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); + +- /* WaMbcDriverBootEnable:hsw */ +- I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | +- GEN6_MBCTL_ENABLE_BOOT_FETCH); +- + /* WaSwitchSolVfFArbitrationPriority:hsw */ + I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); + +@@ -5050,10 +5042,6 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) + + g4x_disable_trickle_feed(dev); + +- /* WaMbcDriverBootEnable:ivb */ +- I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | +- GEN6_MBCTL_ENABLE_BOOT_FETCH); +- + /* WaVSRefCountFullforceMissDisable:ivb */ + gen7_setup_fixed_func_scheduler(dev_priv); + +@@ -5113,11 +5101,6 @@ static void valleyview_init_clock_gating(struct drm_device *dev) + I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | + GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); + +- /* WaMbcDriverBootEnable:vlv */ +- I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) | +- GEN6_MBCTL_ENABLE_BOOT_FETCH); +- +- + /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock + * gating disable must be set. Failure to set it results in + * flickering pixels due to Z write ordering failures after +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0718-drm-i915-grab-force_wake-when-restoring-LCPLL.patch b/patches.baytrail/0718-drm-i915-grab-force_wake-when-restoring-LCPLL.patch new file mode 100644 index 000000000000..78d27d63bea7 --- /dev/null +++ b/patches.baytrail/0718-drm-i915-grab-force_wake-when-restoring-LCPLL.patch @@ -0,0 +1,53 @@ +From 3dd012f943c1fde747737e4792da2c9a8721ad79 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Mon, 19 Aug 2013 13:18:07 -0300 +Subject: drm/i915: grab force_wake when restoring LCPLL + +If LCPLL is disabled, there's a chance we might be in package C8 state +or deeper, and we'll get a hard hang when restoring LCPLL (also, a red +led lights up on my motherboard). So grab the force_wake, which will +get us out of RC6 and, as a consequence, out of PC8+ (since we need +RC6 to get into PC8+). + +Note: Discussions with hw designers are still ongoing what exactly +goes boom here. But I think we can go ahead and just merge this little +hack for now until it's clear what we actually need. + +Signed-off-by: Paulo Zanoni +[danvet: Add small note about the current state of the discussion +around this hack.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 215733fadb87709e91b3a622d786865292c9ab11) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 0426c92a4c18..d46f554c2a9e 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -6033,6 +6033,10 @@ void hsw_restore_lcpll(struct drm_i915_private *dev_priv) + LCPLL_POWER_DOWN_ALLOW)) == LCPLL_PLL_LOCK) + return; + ++ /* Make sure we're not on PC8 state before disabling PC8, otherwise ++ * we'll hang the machine! */ ++ dev_priv->uncore.funcs.force_wake_get(dev_priv); ++ + if (val & LCPLL_POWER_DOWN_ALLOW) { + val &= ~LCPLL_POWER_DOWN_ALLOW; + I915_WRITE(LCPLL_CTL, val); +@@ -6060,6 +6064,8 @@ void hsw_restore_lcpll(struct drm_i915_private *dev_priv) + LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1)) + DRM_ERROR("Switching back to LCPLL failed\n"); + } ++ ++ dev_priv->uncore.funcs.force_wake_put(dev_priv); + } + + static void haswell_modeset_global_resources(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0719-drm-i915-fix-SDEIMR-assertion-when-disabling-LCPLL.patch b/patches.baytrail/0719-drm-i915-fix-SDEIMR-assertion-when-disabling-LCPLL.patch new file mode 100644 index 000000000000..4efabef6dcc5 --- /dev/null +++ b/patches.baytrail/0719-drm-i915-fix-SDEIMR-assertion-when-disabling-LCPLL.patch @@ -0,0 +1,48 @@ +From 4221861eb8c2f5921f7455ac93a0f67843983265 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Mon, 19 Aug 2013 13:18:08 -0300 +Subject: drm/i915: fix SDEIMR assertion when disabling LCPLL + +This was causing WARNs in one machine, so instead of trying to guess +exactly which hotplug bits should exist, just do the test on the +non-HPD bits. We don't care about the state of the hotplug bits, we +just care about the others, that need to be 1. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit bd633a7c1ca0663ba10426a0a6aeda0257cbe804) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index d46f554c2a9e..29e43b2cf908 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -5932,11 +5932,7 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv) + struct intel_ddi_plls *plls = &dev_priv->ddi_plls; + struct intel_crtc *crtc; + unsigned long irqflags; +- uint32_t val, pch_hpd_mask; +- +- pch_hpd_mask = SDE_PORTB_HOTPLUG_CPT | SDE_PORTC_HOTPLUG_CPT; +- if (!(dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE)) +- pch_hpd_mask |= SDE_PORTD_HOTPLUG_CPT | SDE_CRT_HOTPLUG_CPT; ++ uint32_t val; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) + WARN(crtc->base.enabled, "CRTC for pipe %c enabled\n", +@@ -5962,7 +5958,7 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv) + WARN((val & ~DE_PCH_EVENT_IVB) != val, + "Unexpected DEIMR bits enabled: 0x%x\n", val); + val = I915_READ(SDEIMR); +- WARN((val & ~pch_hpd_mask) != val, ++ WARN((val | SDE_HOTPLUG_MASK_CPT) != 0xffffffff, + "Unexpected SDEIMR bits enabled: 0x%x\n", val); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0720-drm-i915-allow-package-C8-states-on-Haswell-disabled.patch b/patches.baytrail/0720-drm-i915-allow-package-C8-states-on-Haswell-disabled.patch new file mode 100644 index 000000000000..afa3558441d7 --- /dev/null +++ b/patches.baytrail/0720-drm-i915-allow-package-C8-states-on-Haswell-disabled.patch @@ -0,0 +1,677 @@ +From 8a15d0a7767762e5901533b37c17bd2fa126617b Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Mon, 19 Aug 2013 13:18:09 -0300 +Subject: drm/i915: allow package C8+ states on Haswell (disabled) + +This patch allows PC8+ states on Haswell. These states can only be +reached when all the display outputs are disabled, and they allow some +more power savings. + +The fact that the graphics device is allowing PC8+ doesn't mean that +the machine will actually enter PC8+: all the other devices also need +to allow PC8+. + +For now this option is disabled by default. You need i915.allow_pc8=1 +if you want it. + +This patch adds a big comment inside i915_drv.h explaining how it +works and how it tracks things. Read it. + +v2: (this is not really v2, many previous versions were already sent, + but they had different names) + - Use the new functions to enable/disable GTIMR and GEN6_PMIMR + - Rename almost all variables and functions to names suggested by + Chris + - More WARNs on the IRQ handling code + - Also disable PC8 when there's GPU work to do (thanks to Ben for + the help on this), so apps can run caster + - Enable PC8 on a delayed work function that is delayed for 5 + seconds. This makes sure we only enable PC8+ if we're really + idle + - Make sure we're not in PC8+ when suspending +v3: - WARN if IRQs are disabled on __wait_seqno + - Replace some DRM_ERRORs with WARNs + - Fix calls to restore GT and PM interrupts + - Use intel_mark_busy instead of intel_ring_advance to disable PC8 +v4: - Use the force_wake, Luke! +v5: - Remove the "IIR is not zero" WARNs + - Move the force_wake chunk to its own patch + - Only restore what's missing from RC6, not everything + +Signed-off-by: Paulo Zanoni +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit c67a470b1db781c54be07a87217cff35a91f564e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 10 +++ + drivers/gpu/drm/i915/i915_drv.c | 11 +++ + drivers/gpu/drm/i915/i915_drv.h | 72 +++++++++++++++ + drivers/gpu/drm/i915/i915_gem.c | 2 + + drivers/gpu/drm/i915/i915_irq.c | 101 +++++++++++++++++++++ + drivers/gpu/drm/i915/intel_display.c | 170 ++++++++++++++++++++++++++++++++++- + drivers/gpu/drm/i915/intel_dp.c | 3 + + drivers/gpu/drm/i915/intel_drv.h | 8 ++ + drivers/gpu/drm/i915/intel_i2c.c | 2 + + drivers/gpu/drm/i915/intel_pm.c | 13 ++- + 10 files changed, 390 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index d2dc02b67512..4c7669f3f586 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1486,6 +1486,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + mutex_init(&dev_priv->rps.hw_lock); + mutex_init(&dev_priv->modeset_restore_lock); + ++ mutex_init(&dev_priv->pc8.lock); ++ dev_priv->pc8.requirements_met = false; ++ dev_priv->pc8.gpu_idle = false; ++ dev_priv->pc8.irqs_disabled = false; ++ dev_priv->pc8.enabled = false; ++ dev_priv->pc8.disable_count = 2; /* requirements_met + gpu_idle */ ++ INIT_DELAYED_WORK(&dev_priv->pc8.enable_work, hsw_enable_pc8_work); ++ + i915_dump_device_info(dev_priv); + + /* Not all pre-production machines fall into this category, only the +@@ -1740,6 +1748,8 @@ int i915_driver_unload(struct drm_device *dev) + cancel_work_sync(&dev_priv->gpu_error.work); + i915_destroy_error_state(dev); + ++ cancel_delayed_work_sync(&dev_priv->pc8.enable_work); ++ + if (dev->pdev->msi_enabled) + pci_disable_msi(dev->pdev); + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index a9c8f18e26fc..f19736208214 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -141,6 +141,10 @@ module_param_named(fastboot, i915_fastboot, bool, 0600); + MODULE_PARM_DESC(fastboot, "Try to skip unnecessary mode sets at boot time " + "(default: false)"); + ++int i915_enable_pc8 __read_mostly = 0; ++module_param_named(enable_pc8, i915_enable_pc8, int, 0600); ++MODULE_PARM_DESC(enable_pc8, "Enable support for low power package C states (PC8+) (default: false)"); ++ + bool i915_prefault_disable __read_mostly; + module_param_named(prefault_disable, i915_prefault_disable, bool, 0600); + MODULE_PARM_DESC(prefault_disable, +@@ -557,6 +561,9 @@ static int i915_drm_freeze(struct drm_device *dev) + dev_priv->modeset_restore = MODESET_SUSPENDED; + mutex_unlock(&dev_priv->modeset_restore_lock); + ++ /* We do a lot of poking in a lot of registers, make sure they work ++ * properly. */ ++ hsw_disable_package_c8(dev_priv); + intel_set_power_well(dev, true); + + drm_kms_helper_poll_disable(dev); +@@ -713,6 +720,10 @@ static int __i915_drm_thaw(struct drm_device *dev) + schedule_work(&dev_priv->console_resume_work); + } + ++ /* Undo what we did at i915_drm_freeze so the refcount goes back to the ++ * expected level. */ ++ hsw_enable_package_c8(dev_priv); ++ + mutex_lock(&dev_priv->modeset_restore_lock); + dev_priv->modeset_restore = MODESET_DONE; + mutex_unlock(&dev_priv->modeset_restore_lock); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 5cc71ac04beb..85a352860a83 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1076,6 +1076,75 @@ struct intel_wm_level { + uint32_t fbc_val; + }; + ++/* ++ * This struct tracks the state needed for the Package C8+ feature. ++ * ++ * Package states C8 and deeper are really deep PC states that can only be ++ * reached when all the devices on the system allow it, so even if the graphics ++ * device allows PC8+, it doesn't mean the system will actually get to these ++ * states. ++ * ++ * Our driver only allows PC8+ when all the outputs are disabled, the power well ++ * is disabled and the GPU is idle. When these conditions are met, we manually ++ * do the other conditions: disable the interrupts, clocks and switch LCPLL ++ * refclk to Fclk. ++ * ++ * When we really reach PC8 or deeper states (not just when we allow it) we lose ++ * the state of some registers, so when we come back from PC8+ we need to ++ * restore this state. We don't get into PC8+ if we're not in RC6, so we don't ++ * need to take care of the registers kept by RC6. ++ * ++ * The interrupt disabling is part of the requirements. We can only leave the ++ * PCH HPD interrupts enabled. If we're in PC8+ and we get another interrupt we ++ * can lock the machine. ++ * ++ * Ideally every piece of our code that needs PC8+ disabled would call ++ * hsw_disable_package_c8, which would increment disable_count and prevent the ++ * system from reaching PC8+. But we don't have a symmetric way to do this for ++ * everything, so we have the requirements_met and gpu_idle variables. When we ++ * switch requirements_met or gpu_idle to true we decrease disable_count, and ++ * increase it in the opposite case. The requirements_met variable is true when ++ * all the CRTCs, encoders and the power well are disabled. The gpu_idle ++ * variable is true when the GPU is idle. ++ * ++ * In addition to everything, we only actually enable PC8+ if disable_count ++ * stays at zero for at least some seconds. This is implemented with the ++ * enable_work variable. We do this so we don't enable/disable PC8 dozens of ++ * consecutive times when all screens are disabled and some background app ++ * queries the state of our connectors, or we have some application constantly ++ * waking up to use the GPU. Only after the enable_work function actually ++ * enables PC8+ the "enable" variable will become true, which means that it can ++ * be false even if disable_count is 0. ++ * ++ * The irqs_disabled variable becomes true exactly after we disable the IRQs and ++ * goes back to false exactly before we reenable the IRQs. We use this variable ++ * to check if someone is trying to enable/disable IRQs while they're supposed ++ * to be disabled. This shouldn't happen and we'll print some error messages in ++ * case it happens, but if it actually happens we'll also update the variables ++ * inside struct regsave so when we restore the IRQs they will contain the ++ * latest expected values. ++ * ++ * For more, read "Display Sequences for Package C8" on our documentation. ++ */ ++struct i915_package_c8 { ++ bool requirements_met; ++ bool gpu_idle; ++ bool irqs_disabled; ++ /* Only true after the delayed work task actually enables it. */ ++ bool enabled; ++ int disable_count; ++ struct mutex lock; ++ struct delayed_work enable_work; ++ ++ struct { ++ uint32_t deimr; ++ uint32_t sdeimr; ++ uint32_t gtimr; ++ uint32_t gtier; ++ uint32_t gen6_pmimr; ++ } regsave; ++}; ++ + typedef struct drm_i915_private { + struct drm_device *dev; + struct kmem_cache *slab; +@@ -1260,6 +1329,8 @@ typedef struct drm_i915_private { + uint16_t cur_latency[5]; + } wm; + ++ struct i915_package_c8 pc8; ++ + /* Old dri1 support infrastructure, beware the dragons ya fools entering + * here! */ + struct i915_dri1_state dri1; +@@ -1635,6 +1706,7 @@ extern unsigned int i915_preliminary_hw_support __read_mostly; + extern int i915_disable_power_well __read_mostly; + extern int i915_enable_ips __read_mostly; + extern bool i915_fastboot __read_mostly; ++extern int i915_enable_pc8 __read_mostly; + extern bool i915_prefault_disable __read_mostly; + + extern int i915_suspend(struct drm_device *dev, pm_message_t state); +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 199107e734fb..2d1cb10d846f 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -999,6 +999,8 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, + bool wait_forever = true; + int ret; + ++ WARN(dev_priv->pc8.irqs_disabled, "IRQs disabled\n"); ++ + if (i915_seqno_passed(ring->get_seqno(ring, true), seqno)) + return 0; + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 9e2ea5b16233..0eac036fb833 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -85,6 +85,12 @@ ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) + { + assert_spin_locked(&dev_priv->irq_lock); + ++ if (dev_priv->pc8.irqs_disabled) { ++ WARN(1, "IRQs disabled\n"); ++ dev_priv->pc8.regsave.deimr &= ~mask; ++ return; ++ } ++ + if ((dev_priv->irq_mask & mask) != 0) { + dev_priv->irq_mask &= ~mask; + I915_WRITE(DEIMR, dev_priv->irq_mask); +@@ -97,6 +103,12 @@ ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) + { + assert_spin_locked(&dev_priv->irq_lock); + ++ if (dev_priv->pc8.irqs_disabled) { ++ WARN(1, "IRQs disabled\n"); ++ dev_priv->pc8.regsave.deimr |= mask; ++ return; ++ } ++ + if ((dev_priv->irq_mask & mask) != mask) { + dev_priv->irq_mask |= mask; + I915_WRITE(DEIMR, dev_priv->irq_mask); +@@ -116,6 +128,14 @@ static void ilk_update_gt_irq(struct drm_i915_private *dev_priv, + { + assert_spin_locked(&dev_priv->irq_lock); + ++ if (dev_priv->pc8.irqs_disabled) { ++ WARN(1, "IRQs disabled\n"); ++ dev_priv->pc8.regsave.gtimr &= ~interrupt_mask; ++ dev_priv->pc8.regsave.gtimr |= (~enabled_irq_mask & ++ interrupt_mask); ++ return; ++ } ++ + dev_priv->gt_irq_mask &= ~interrupt_mask; + dev_priv->gt_irq_mask |= (~enabled_irq_mask & interrupt_mask); + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); +@@ -146,6 +166,14 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv, + + assert_spin_locked(&dev_priv->irq_lock); + ++ if (dev_priv->pc8.irqs_disabled) { ++ WARN(1, "IRQs disabled\n"); ++ dev_priv->pc8.regsave.gen6_pmimr &= ~interrupt_mask; ++ dev_priv->pc8.regsave.gen6_pmimr |= (~enabled_irq_mask & ++ interrupt_mask); ++ return; ++ } ++ + new_val = dev_priv->pm_irq_mask; + new_val &= ~interrupt_mask; + new_val |= (~enabled_irq_mask & interrupt_mask); +@@ -257,6 +285,15 @@ static void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, + + assert_spin_locked(&dev_priv->irq_lock); + ++ if (dev_priv->pc8.irqs_disabled && ++ (interrupt_mask & SDE_HOTPLUG_MASK_CPT)) { ++ WARN(1, "IRQs disabled\n"); ++ dev_priv->pc8.regsave.sdeimr &= ~interrupt_mask; ++ dev_priv->pc8.regsave.sdeimr |= (~enabled_irq_mask & ++ interrupt_mask); ++ return; ++ } ++ + I915_WRITE(SDEIMR, sdeimr); + POSTING_READ(SDEIMR); + } +@@ -3159,3 +3196,67 @@ void intel_hpd_init(struct drm_device *dev) + dev_priv->display.hpd_irq_setup(dev); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + } ++ ++/* Disable interrupts so we can allow Package C8+. */ ++void hsw_pc8_disable_interrupts(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ unsigned long irqflags; ++ ++ spin_lock_irqsave(&dev_priv->irq_lock, irqflags); ++ ++ dev_priv->pc8.regsave.deimr = I915_READ(DEIMR); ++ dev_priv->pc8.regsave.sdeimr = I915_READ(SDEIMR); ++ dev_priv->pc8.regsave.gtimr = I915_READ(GTIMR); ++ dev_priv->pc8.regsave.gtier = I915_READ(GTIER); ++ dev_priv->pc8.regsave.gen6_pmimr = I915_READ(GEN6_PMIMR); ++ ++ ironlake_disable_display_irq(dev_priv, ~DE_PCH_EVENT_IVB); ++ ibx_disable_display_interrupt(dev_priv, ~SDE_HOTPLUG_MASK_CPT); ++ ilk_disable_gt_irq(dev_priv, 0xffffffff); ++ snb_disable_pm_irq(dev_priv, 0xffffffff); ++ ++ dev_priv->pc8.irqs_disabled = true; ++ ++ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); ++} ++ ++/* Restore interrupts so we can recover from Package C8+. */ ++void hsw_pc8_restore_interrupts(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ unsigned long irqflags; ++ uint32_t val, expected; ++ ++ spin_lock_irqsave(&dev_priv->irq_lock, irqflags); ++ ++ val = I915_READ(DEIMR); ++ expected = ~DE_PCH_EVENT_IVB; ++ WARN(val != expected, "DEIMR is 0x%08x, not 0x%08x\n", val, expected); ++ ++ val = I915_READ(SDEIMR) & ~SDE_HOTPLUG_MASK_CPT; ++ expected = ~SDE_HOTPLUG_MASK_CPT; ++ WARN(val != expected, "SDEIMR non-HPD bits are 0x%08x, not 0x%08x\n", ++ val, expected); ++ ++ val = I915_READ(GTIMR); ++ expected = 0xffffffff; ++ WARN(val != expected, "GTIMR is 0x%08x, not 0x%08x\n", val, expected); ++ ++ val = I915_READ(GEN6_PMIMR); ++ expected = 0xffffffff; ++ WARN(val != expected, "GEN6_PMIMR is 0x%08x, not 0x%08x\n", val, ++ expected); ++ ++ dev_priv->pc8.irqs_disabled = false; ++ ++ ironlake_enable_display_irq(dev_priv, ~dev_priv->pc8.regsave.deimr); ++ ibx_enable_display_interrupt(dev_priv, ++ ~dev_priv->pc8.regsave.sdeimr & ++ ~SDE_HOTPLUG_MASK_CPT); ++ ilk_enable_gt_irq(dev_priv, ~dev_priv->pc8.regsave.gtimr); ++ snb_enable_pm_irq(dev_priv, ~dev_priv->pc8.regsave.gen6_pmimr); ++ I915_WRITE(GTIER, dev_priv->pc8.regsave.gtier); ++ ++ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); ++} +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 29e43b2cf908..6cf35357afad 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -6064,6 +6064,166 @@ void hsw_restore_lcpll(struct drm_i915_private *dev_priv) + dev_priv->uncore.funcs.force_wake_put(dev_priv); + } + ++void hsw_enable_pc8_work(struct work_struct *__work) ++{ ++ struct drm_i915_private *dev_priv = ++ container_of(to_delayed_work(__work), struct drm_i915_private, ++ pc8.enable_work); ++ struct drm_device *dev = dev_priv->dev; ++ uint32_t val; ++ ++ if (dev_priv->pc8.enabled) ++ return; ++ ++ DRM_DEBUG_KMS("Enabling package C8+\n"); ++ ++ dev_priv->pc8.enabled = true; ++ ++ if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { ++ val = I915_READ(SOUTH_DSPCLK_GATE_D); ++ val &= ~PCH_LP_PARTITION_LEVEL_DISABLE; ++ I915_WRITE(SOUTH_DSPCLK_GATE_D, val); ++ } ++ ++ lpt_disable_clkout_dp(dev); ++ hsw_pc8_disable_interrupts(dev); ++ hsw_disable_lcpll(dev_priv, true, true); ++} ++ ++static void __hsw_enable_package_c8(struct drm_i915_private *dev_priv) ++{ ++ WARN_ON(!mutex_is_locked(&dev_priv->pc8.lock)); ++ WARN(dev_priv->pc8.disable_count < 1, ++ "pc8.disable_count: %d\n", dev_priv->pc8.disable_count); ++ ++ dev_priv->pc8.disable_count--; ++ if (dev_priv->pc8.disable_count != 0) ++ return; ++ ++ schedule_delayed_work(&dev_priv->pc8.enable_work, ++ msecs_to_jiffies(5 * 1000)); ++} ++ ++static void __hsw_disable_package_c8(struct drm_i915_private *dev_priv) ++{ ++ struct drm_device *dev = dev_priv->dev; ++ uint32_t val; ++ ++ WARN_ON(!mutex_is_locked(&dev_priv->pc8.lock)); ++ WARN(dev_priv->pc8.disable_count < 0, ++ "pc8.disable_count: %d\n", dev_priv->pc8.disable_count); ++ ++ dev_priv->pc8.disable_count++; ++ if (dev_priv->pc8.disable_count != 1) ++ return; ++ ++ cancel_delayed_work_sync(&dev_priv->pc8.enable_work); ++ if (!dev_priv->pc8.enabled) ++ return; ++ ++ DRM_DEBUG_KMS("Disabling package C8+\n"); ++ ++ hsw_restore_lcpll(dev_priv); ++ hsw_pc8_restore_interrupts(dev); ++ lpt_init_pch_refclk(dev); ++ ++ if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { ++ val = I915_READ(SOUTH_DSPCLK_GATE_D); ++ val |= PCH_LP_PARTITION_LEVEL_DISABLE; ++ I915_WRITE(SOUTH_DSPCLK_GATE_D, val); ++ } ++ ++ intel_prepare_ddi(dev); ++ i915_gem_init_swizzling(dev); ++ mutex_lock(&dev_priv->rps.hw_lock); ++ gen6_update_ring_freq(dev); ++ mutex_unlock(&dev_priv->rps.hw_lock); ++ dev_priv->pc8.enabled = false; ++} ++ ++void hsw_enable_package_c8(struct drm_i915_private *dev_priv) ++{ ++ mutex_lock(&dev_priv->pc8.lock); ++ __hsw_enable_package_c8(dev_priv); ++ mutex_unlock(&dev_priv->pc8.lock); ++} ++ ++void hsw_disable_package_c8(struct drm_i915_private *dev_priv) ++{ ++ mutex_lock(&dev_priv->pc8.lock); ++ __hsw_disable_package_c8(dev_priv); ++ mutex_unlock(&dev_priv->pc8.lock); ++} ++ ++static bool hsw_can_enable_package_c8(struct drm_i915_private *dev_priv) ++{ ++ struct drm_device *dev = dev_priv->dev; ++ struct intel_crtc *crtc; ++ uint32_t val; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) ++ if (crtc->base.enabled) ++ return false; ++ ++ /* This case is still possible since we have the i915.disable_power_well ++ * parameter and also the KVMr or something else might be requesting the ++ * power well. */ ++ val = I915_READ(HSW_PWR_WELL_DRIVER); ++ if (val != 0) { ++ DRM_DEBUG_KMS("Not enabling PC8: power well on\n"); ++ return false; ++ } ++ ++ return true; ++} ++ ++/* Since we're called from modeset_global_resources there's no way to ++ * symmetrically increase and decrease the refcount, so we use ++ * dev_priv->pc8.requirements_met to track whether we already have the refcount ++ * or not. ++ */ ++static void hsw_update_package_c8(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ bool allow; ++ ++ if (!i915_enable_pc8) ++ return; ++ ++ mutex_lock(&dev_priv->pc8.lock); ++ ++ allow = hsw_can_enable_package_c8(dev_priv); ++ ++ if (allow == dev_priv->pc8.requirements_met) ++ goto done; ++ ++ dev_priv->pc8.requirements_met = allow; ++ ++ if (allow) ++ __hsw_enable_package_c8(dev_priv); ++ else ++ __hsw_disable_package_c8(dev_priv); ++ ++done: ++ mutex_unlock(&dev_priv->pc8.lock); ++} ++ ++static void hsw_package_c8_gpu_idle(struct drm_i915_private *dev_priv) ++{ ++ if (!dev_priv->pc8.gpu_idle) { ++ dev_priv->pc8.gpu_idle = true; ++ hsw_enable_package_c8(dev_priv); ++ } ++} ++ ++static void hsw_package_c8_gpu_busy(struct drm_i915_private *dev_priv) ++{ ++ if (dev_priv->pc8.gpu_idle) { ++ dev_priv->pc8.gpu_idle = false; ++ hsw_disable_package_c8(dev_priv); ++ } ++} ++ + static void haswell_modeset_global_resources(struct drm_device *dev) + { + bool enable = false; +@@ -6079,6 +6239,8 @@ static void haswell_modeset_global_resources(struct drm_device *dev) + } + + intel_set_power_well(dev, enable); ++ ++ hsw_update_package_c8(dev); + } + + static int haswell_crtc_mode_set(struct drm_crtc *crtc, +@@ -7314,13 +7476,19 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) + + void intel_mark_busy(struct drm_device *dev) + { +- i915_update_gfx_val(dev->dev_private); ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ hsw_package_c8_gpu_busy(dev_priv); ++ i915_update_gfx_val(dev_priv); + } + + void intel_mark_idle(struct drm_device *dev) + { ++ struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + ++ hsw_package_c8_gpu_idle(dev_priv); ++ + if (!i915_powersave) + return; + +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 46f3e674210d..79c14e298ba6 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -344,6 +344,8 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, + else + precharge = 5; + ++ intel_aux_display_runtime_get(dev_priv); ++ + /* Try to wait for any previous AUX channel activity */ + for (try = 0; try < 3; try++) { + status = I915_READ_NOTRACE(ch_ctl); +@@ -434,6 +436,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, + ret = recv_bytes; + out: + pm_qos_update_request(&dev_priv->pm_qos, PM_QOS_DEFAULT_VALUE); ++ intel_aux_display_runtime_put(dev_priv); + + return ret; + } +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 8222f2426b47..176080822a74 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -745,6 +745,7 @@ extern void intel_set_power_well(struct drm_device *dev, bool enable); + extern void intel_enable_gt_powersave(struct drm_device *dev); + extern void intel_disable_gt_powersave(struct drm_device *dev); + extern void ironlake_teardown_rc6(struct drm_device *dev); ++void gen6_update_ring_freq(struct drm_device *dev); + + extern bool intel_ddi_get_hw_state(struct intel_encoder *encoder, + enum pipe *pipe); +@@ -784,5 +785,12 @@ extern void ilk_disable_gt_irq(struct drm_i915_private *dev_priv, + extern void snb_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); + extern void snb_disable_pm_irq(struct drm_i915_private *dev_priv, + uint32_t mask); ++extern void hsw_enable_pc8_work(struct work_struct *__work); ++extern void hsw_enable_package_c8(struct drm_i915_private *dev_priv); ++extern void hsw_disable_package_c8(struct drm_i915_private *dev_priv); ++extern void hsw_pc8_disable_interrupts(struct drm_device *dev); ++extern void hsw_pc8_restore_interrupts(struct drm_device *dev); ++extern void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv); ++extern void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv); + + #endif /* __INTEL_DRV_H__ */ +diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c +index 639fe192997c..d1c1e0f7f262 100644 +--- a/drivers/gpu/drm/i915/intel_i2c.c ++++ b/drivers/gpu/drm/i915/intel_i2c.c +@@ -398,6 +398,7 @@ gmbus_xfer(struct i2c_adapter *adapter, + int i, reg_offset; + int ret = 0; + ++ intel_aux_display_runtime_get(dev_priv); + mutex_lock(&dev_priv->gmbus_mutex); + + if (bus->force_bit) { +@@ -497,6 +498,7 @@ timeout: + + out: + mutex_unlock(&dev_priv->gmbus_mutex); ++ intel_aux_display_runtime_put(dev_priv); + return ret; + } + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 178da3ec31b4..46056820d1d2 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3607,7 +3607,7 @@ static void gen6_enable_rps(struct drm_device *dev) + gen6_gt_force_wake_put(dev_priv); + } + +-static void gen6_update_ring_freq(struct drm_device *dev) ++void gen6_update_ring_freq(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + int min_freq = 15; +@@ -5416,6 +5416,17 @@ void intel_init_power_well(struct drm_device *dev) + I915_WRITE(HSW_PWR_WELL_BIOS, 0); + } + ++/* Disables PC8 so we can use the GMBUS and DP AUX interrupts. */ ++void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv) ++{ ++ hsw_disable_package_c8(dev_priv); ++} ++ ++void intel_aux_display_runtime_put(struct drm_i915_private *dev_priv) ++{ ++ hsw_enable_package_c8(dev_priv); ++} ++ + /* Set up chip specific power management-related functions */ + void intel_init_pm(struct drm_device *dev) + { +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0721-drm-i915-add-i915_pc8_status-debugfs-file.patch b/patches.baytrail/0721-drm-i915-add-i915_pc8_status-debugfs-file.patch new file mode 100644 index 000000000000..a9f5d86207e5 --- /dev/null +++ b/patches.baytrail/0721-drm-i915-add-i915_pc8_status-debugfs-file.patch @@ -0,0 +1,65 @@ +From 05f863c6fb1796559ab08845fe67556e31340067 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Mon, 19 Aug 2013 13:18:10 -0300 +Subject: drm/i915: add i915_pc8_status debugfs file + +Make it print the value of the variables on the PC8 struct. + +v2: Update to recent renames and add the new fields. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 371db66add2ef701abd3f4295c4cd6bbc24cd5ca) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 236d97e51c3a..39df30e7d9af 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -1788,6 +1788,31 @@ static int i915_energy_uJ(struct seq_file *m, void *data) + power *= units; + + seq_printf(m, "%llu", (long long unsigned)power); ++ ++ return 0; ++} ++ ++static int i915_pc8_status(struct seq_file *m, void *unused) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (!IS_HASWELL(dev)) { ++ seq_puts(m, "not supported\n"); ++ return 0; ++ } ++ ++ mutex_lock(&dev_priv->pc8.lock); ++ seq_printf(m, "Requirements met: %s\n", ++ yesno(dev_priv->pc8.requirements_met)); ++ seq_printf(m, "GPU idle: %s\n", yesno(dev_priv->pc8.gpu_idle)); ++ seq_printf(m, "Disable count: %d\n", dev_priv->pc8.disable_count); ++ seq_printf(m, "IRQs disabled: %s\n", ++ yesno(dev_priv->pc8.irqs_disabled)); ++ seq_printf(m, "Enabled: %s\n", yesno(dev_priv->pc8.enabled)); ++ mutex_unlock(&dev_priv->pc8.lock); ++ + return 0; + } + +@@ -2231,6 +2256,7 @@ static struct drm_info_list i915_debugfs_list[] = { + {"i915_llc", i915_llc, 0}, + {"i915_edp_psr_status", i915_edp_psr_status, 0}, + {"i915_energy_uJ", i915_energy_uJ, 0}, ++ {"i915_pc8_status", i915_pc8_status, 0}, + }; + #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0722-drm-i915-add-i915.pc8_timeout-function.patch b/patches.baytrail/0722-drm-i915-add-i915.pc8_timeout-function.patch new file mode 100644 index 000000000000..adae78075fe7 --- /dev/null +++ b/patches.baytrail/0722-drm-i915-add-i915.pc8_timeout-function.patch @@ -0,0 +1,84 @@ +From 7b750380f5da4eb0cc683840208a8d22a035c549 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Mon, 19 Aug 2013 13:18:11 -0300 +Subject: drm/i915: add i915.pc8_timeout function + +We currently only enter PC8+ after all its required conditions are +met, there's no rendering, and we stay like that for at least 5 +seconds. + +I chose "5 seconds" because this value is conservative and won't make +us enter/leave PC8+ thousands of times after the screen is off: some +desktop environments have applications that wake up and do rendering +every 1-3 seconds, even when the screen is off and the machine is +completely idle. + +But when I was testing my PC8+ patches I set the default value to +100ms so I could use the bad-behaving desktop environments to +stress-test my patches. I also thought it would be a good idea to ask +our power management team to test different values, but I'm pretty +sure they would ask me for an easy way to change the timeout. So to +help these 2 cases I decided to create an option that would make it +easier to change the default value. I also expect people making +specific products that use our driver could try to find the perfect +timeout for them. + +Anyway, fixing the bad-behaving applications will always lead to +better power savings than just changing the timeout value: you need to +stop waking the Kernel, not quickly put it back to sleep again after +you wake it for nothing. Bad sleep leads to bad mood! + +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 900587453219f6090a1e28db1bb790aa64820131) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 4 ++++ + drivers/gpu/drm/i915/i915_drv.h | 1 + + drivers/gpu/drm/i915/intel_display.c | 2 +- + 3 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index f19736208214..ad28a72cf373 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -145,6 +145,10 @@ int i915_enable_pc8 __read_mostly = 0; + module_param_named(enable_pc8, i915_enable_pc8, int, 0600); + MODULE_PARM_DESC(enable_pc8, "Enable support for low power package C states (PC8+) (default: false)"); + ++int i915_pc8_timeout __read_mostly = 5000; ++module_param_named(pc8_timeout, i915_pc8_timeout, int, 0600); ++MODULE_PARM_DESC(pc8_timeout, "Number of msecs of idleness required to enter PC8+ (default: 5000)"); ++ + bool i915_prefault_disable __read_mostly; + module_param_named(prefault_disable, i915_prefault_disable, bool, 0600); + MODULE_PARM_DESC(prefault_disable, +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 85a352860a83..8ee15b471854 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1707,6 +1707,7 @@ extern int i915_disable_power_well __read_mostly; + extern int i915_enable_ips __read_mostly; + extern bool i915_fastboot __read_mostly; + extern int i915_enable_pc8 __read_mostly; ++extern int i915_pc8_timeout __read_mostly; + extern bool i915_prefault_disable __read_mostly; + + extern int i915_suspend(struct drm_device *dev, pm_message_t state); +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 6cf35357afad..7453d6f82631 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -6101,7 +6101,7 @@ static void __hsw_enable_package_c8(struct drm_i915_private *dev_priv) + return; + + schedule_delayed_work(&dev_priv->pc8.enable_work, +- msecs_to_jiffies(5 * 1000)); ++ msecs_to_jiffies(i915_pc8_timeout)); + } + + static void __hsw_disable_package_c8(struct drm_i915_private *dev_priv) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0723-drm-i915-enable-Package-C8-by-default.patch b/patches.baytrail/0723-drm-i915-enable-Package-C8-by-default.patch new file mode 100644 index 000000000000..b23a169d4214 --- /dev/null +++ b/patches.baytrail/0723-drm-i915-enable-Package-C8-by-default.patch @@ -0,0 +1,37 @@ +From 903952164d72be4d06d2184fe2596aa4dcc25122 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Mon, 19 Aug 2013 13:18:12 -0300 +Subject: drm/i915: enable Package C8+ by default + +This should be working, so enable it by default. Also easy to revert. + +v2: Rebase, s/allow/enable/. + +Signed-off-by: Paulo Zanoni +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit e27e9708c45879f16fb824a2da94cd65e150a0c8) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index ad28a72cf373..735dd5625e9e 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -141,9 +141,9 @@ module_param_named(fastboot, i915_fastboot, bool, 0600); + MODULE_PARM_DESC(fastboot, "Try to skip unnecessary mode sets at boot time " + "(default: false)"); + +-int i915_enable_pc8 __read_mostly = 0; ++int i915_enable_pc8 __read_mostly = 1; + module_param_named(enable_pc8, i915_enable_pc8, int, 0600); +-MODULE_PARM_DESC(enable_pc8, "Enable support for low power package C states (PC8+) (default: false)"); ++MODULE_PARM_DESC(enable_pc8, "Enable support for low power package C states (PC8+) (default: true)"); + + int i915_pc8_timeout __read_mostly = 5000; + module_param_named(pc8_timeout, i915_pc8_timeout, int, 0600); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0724-drm-i915-Use-POSTING_READ-in-lcpll-code.patch b/patches.baytrail/0724-drm-i915-Use-POSTING_READ-in-lcpll-code.patch new file mode 100644 index 000000000000..88aafe79a4a2 --- /dev/null +++ b/patches.baytrail/0724-drm-i915-Use-POSTING_READ-in-lcpll-code.patch @@ -0,0 +1,46 @@ +From c0ead2313b0c1357569b715fc6088f73a6f6d611 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 21 Aug 2013 23:38:08 +0200 +Subject: drm/i915: Use POSTING_READ in lcpll code + +If we don't use the return value of a mmio read our coding style is to +use the POSTING_READ macro. This avoids cluttering the mmio traces. + +While at it add the missing posting read in the lcpll enable function +that Paulo spotted. + +v2: Drop the _NOTRACE changes, tracing such wait_for loops in the modeset +code might actually be rather useful! + +Cc: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +(cherry picked from commit 35d8f2eb259e2d32c4bb67e9733ba0cba031f64f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 7453d6f82631..58da4ddc3e16 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -6036,13 +6036,14 @@ void hsw_restore_lcpll(struct drm_i915_private *dev_priv) + if (val & LCPLL_POWER_DOWN_ALLOW) { + val &= ~LCPLL_POWER_DOWN_ALLOW; + I915_WRITE(LCPLL_CTL, val); ++ POSTING_READ(LCPLL_CTL); + } + + val = I915_READ(D_COMP); + val |= D_COMP_COMP_FORCE; + val &= ~D_COMP_COMP_DISABLE; + I915_WRITE(D_COMP, val); +- I915_READ(D_COMP); ++ POSTING_READ(D_COMP); + + val = I915_READ(LCPLL_CTL); + val &= ~LCPLL_PLL_DISABLE; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0725-drm-i915-Fix-context-size-calculation-on-SNB-IVB-VLV.patch b/patches.baytrail/0725-drm-i915-Fix-context-size-calculation-on-SNB-IVB-VLV.patch new file mode 100644 index 000000000000..0f20181b4931 --- /dev/null +++ b/patches.baytrail/0725-drm-i915-Fix-context-size-calculation-on-SNB-IVB-VLV.patch @@ -0,0 +1,78 @@ +From c3cf69ab684bc7b0db033ec54b8e15daa29e991a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Thu, 22 Aug 2013 19:23:13 +0300 +Subject: drm/i915: Fix context size calculation on SNB/IVB/VLV +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +All the different context sizes reported in the CXT_SIZE register +aren't meant to be simply added together. + +While BSpec is somewhat unclear on the topic of the actual context +size, empirical tests have now revealed the truth. So let's add a +big fat comment to remind people how it all works. + +As a result of correctly interpreting CXT_SIZE, the IVB context +size is reduced from three pages to two, while SNB context size +remains at two pages. + +Signed-off-by: Ville Syrjälä +Acked-by: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit e8016055335687b90e7cd5bbfa30e0c269417f34) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 711f0658c5c4..8e51ecf2a6f9 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -1707,15 +1707,26 @@ + */ + #define CCID 0x2180 + #define CCID_EN (1<<0) ++/* ++ * Notes on SNB/IVB/VLV context size: ++ * - Power context is saved elsewhere (LLC or stolen) ++ * - Ring/execlist context is saved on SNB, not on IVB ++ * - Extended context size already includes render context size ++ * - We always need to follow the extended context size. ++ * SNB BSpec has comments indicating that we should use the ++ * render context size instead if execlists are disabled, but ++ * based on empirical testing that's just nonsense. ++ * - Pipelined/VF state is saved on SNB/IVB respectively ++ * - GT1 size just indicates how much of render context ++ * doesn't need saving on GT1 ++ */ + #define CXT_SIZE 0x21a0 + #define GEN6_CXT_POWER_SIZE(cxt_reg) ((cxt_reg >> 24) & 0x3f) + #define GEN6_CXT_RING_SIZE(cxt_reg) ((cxt_reg >> 18) & 0x3f) + #define GEN6_CXT_RENDER_SIZE(cxt_reg) ((cxt_reg >> 12) & 0x3f) + #define GEN6_CXT_EXTENDED_SIZE(cxt_reg) ((cxt_reg >> 6) & 0x3f) + #define GEN6_CXT_PIPELINE_SIZE(cxt_reg) ((cxt_reg >> 0) & 0x3f) +-#define GEN6_CXT_TOTAL_SIZE(cxt_reg) (GEN6_CXT_POWER_SIZE(cxt_reg) + \ +- GEN6_CXT_RING_SIZE(cxt_reg) + \ +- GEN6_CXT_RENDER_SIZE(cxt_reg) + \ ++#define GEN6_CXT_TOTAL_SIZE(cxt_reg) (GEN6_CXT_RING_SIZE(cxt_reg) + \ + GEN6_CXT_EXTENDED_SIZE(cxt_reg) + \ + GEN6_CXT_PIPELINE_SIZE(cxt_reg)) + #define GEN7_CXT_SIZE 0x21a8 +@@ -1725,11 +1736,7 @@ + #define GEN7_CXT_EXTENDED_SIZE(ctx_reg) ((ctx_reg >> 9) & 0x7f) + #define GEN7_CXT_GT1_SIZE(ctx_reg) ((ctx_reg >> 6) & 0x7) + #define GEN7_CXT_VFSTATE_SIZE(ctx_reg) ((ctx_reg >> 0) & 0x3f) +-#define GEN7_CXT_TOTAL_SIZE(ctx_reg) (GEN7_CXT_POWER_SIZE(ctx_reg) + \ +- GEN7_CXT_RING_SIZE(ctx_reg) + \ +- GEN7_CXT_RENDER_SIZE(ctx_reg) + \ +- GEN7_CXT_EXTENDED_SIZE(ctx_reg) + \ +- GEN7_CXT_GT1_SIZE(ctx_reg) + \ ++#define GEN7_CXT_TOTAL_SIZE(ctx_reg) (GEN7_CXT_EXTENDED_SIZE(ctx_reg) + \ + GEN7_CXT_VFSTATE_SIZE(ctx_reg)) + /* Haswell does have the CXT_SIZE register however it does not appear to be + * valid. Now, docs explain in dwords what is in the context object. The full +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0726-drm-i915-Print-seqnos-as-unsigned-in-debugfs.patch b/patches.baytrail/0726-drm-i915-Print-seqnos-as-unsigned-in-debugfs.patch new file mode 100644 index 000000000000..8c5171b50052 --- /dev/null +++ b/patches.baytrail/0726-drm-i915-Print-seqnos-as-unsigned-in-debugfs.patch @@ -0,0 +1,35 @@ +From d1a73b7b43b6ac07c8a64c3c98a520a03ed9e541 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Thu, 22 Aug 2013 19:21:30 +0300 +Subject: drm/i915: Print seqnos as unsigned in debugfs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +I don't like seeing signed seqnos. Make them unsigned. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit fb1ae911f4e58c2cf28fcd48b59f54d17283da07) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 39df30e7d9af..55ab9246e1b9 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -100,7 +100,7 @@ static void + describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) + { + struct i915_vma *vma; +- seq_printf(m, "%pK: %s%s%s %8zdKiB %02x %02x %d %d %d%s%s%s", ++ seq_printf(m, "%pK: %s%s%s %8zdKiB %02x %02x %u %u %u%s%s%s", + &obj->base, + get_pin_flag(obj), + get_tiling_flag(obj), +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0727-gpu-vga_switcheroo-add-driver-control-power-feature..patch b/patches.baytrail/0727-gpu-vga_switcheroo-add-driver-control-power-feature..patch new file mode 100644 index 000000000000..7e7391973e29 --- /dev/null +++ b/patches.baytrail/0727-gpu-vga_switcheroo-add-driver-control-power-feature..patch @@ -0,0 +1,359 @@ +From 8b8040b69f7c13d44347e614bc29ca404411c7e8 Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Mon, 10 Sep 2012 12:28:36 +1000 +Subject: gpu/vga_switcheroo: add driver control power feature. (v3) + +For optimus and powerxpress muxless we really want the GPU +driver deciding when to power up/down the GPU, not userspace. + +This adds the ability for a driver to dynamically power up/down +the GPU and remove the switcheroo from controlling it, the +switcheroo reports the dynamic state to userspace also. + +It also adds 2 power domains, one for machine where the power +switch is controlled outside the GPU D3 state, so the powerdown +ordering is done correctly, and the second for the hdmi audio +device to make sure it can resume for PCI config space accesses. + +v1.1: fix build with switcheroo off + +v2: add power domain support for radeon and v1 nvidia dsms +v2.1: fix typo in off case + +v3: add audio power domain for hdmi audio + misc audio fixes + +v4: use PCI_SLOT macro, drop power reference on hdmi audio resume +failure also. + +Signed-off-by: Dave Airlie +(cherry picked from commit 0d69704ae348c03bc216b01e32a0e9a2372be419) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 2 +- + drivers/gpu/drm/nouveau/nouveau_vga.c | 2 +- + drivers/gpu/drm/radeon/radeon_device.c | 2 +- + drivers/gpu/vga/vga_switcheroo.c | 147 +++++++++++++++++++++++++++++++-- + include/linux/vga_switcheroo.h | 13 ++- + 5 files changed, 156 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 4c7669f3f586..3e4e6073d171 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1296,7 +1296,7 @@ static int i915_load_modeset_init(struct drm_device *dev) + + intel_register_dsm_handler(); + +- ret = vga_switcheroo_register_client(dev->pdev, &i915_switcheroo_ops); ++ ret = vga_switcheroo_register_client(dev->pdev, &i915_switcheroo_ops, false); + if (ret) + goto cleanup_vga_client; + +diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c +index 25d3495725eb..40a09f11a600 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_vga.c ++++ b/drivers/gpu/drm/nouveau/nouveau_vga.c +@@ -79,7 +79,7 @@ nouveau_vga_init(struct nouveau_drm *drm) + { + struct drm_device *dev = drm->dev; + vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); +- vga_switcheroo_register_client(dev->pdev, &nouveau_switcheroo_ops); ++ vga_switcheroo_register_client(dev->pdev, &nouveau_switcheroo_ops, false); + } + + void +diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c +index 8df1525f71d2..6ea7983790d7 100644 +--- a/drivers/gpu/drm/radeon/radeon_device.c ++++ b/drivers/gpu/drm/radeon/radeon_device.c +@@ -1169,7 +1169,7 @@ int radeon_device_init(struct radeon_device *rdev, + /* this will fail for cards that aren't VGA class devices, just + * ignore it */ + vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); +- vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops); ++ vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, false); + + r = radeon_init(rdev); + if (r) +diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c +index cf787e1d9322..ec0ae2d1686a 100644 +--- a/drivers/gpu/vga/vga_switcheroo.c ++++ b/drivers/gpu/vga/vga_switcheroo.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + #include + +@@ -37,6 +38,7 @@ struct vga_switcheroo_client { + const struct vga_switcheroo_client_ops *ops; + int id; + bool active; ++ bool driver_power_control; + struct list_head list; + }; + +@@ -132,7 +134,7 @@ EXPORT_SYMBOL(vga_switcheroo_unregister_handler); + + static int register_client(struct pci_dev *pdev, + const struct vga_switcheroo_client_ops *ops, +- int id, bool active) ++ int id, bool active, bool driver_power_control) + { + struct vga_switcheroo_client *client; + +@@ -145,6 +147,7 @@ static int register_client(struct pci_dev *pdev, + client->ops = ops; + client->id = id; + client->active = active; ++ client->driver_power_control = driver_power_control; + + mutex_lock(&vgasr_mutex); + list_add_tail(&client->list, &vgasr_priv.clients); +@@ -160,10 +163,11 @@ static int register_client(struct pci_dev *pdev, + } + + int vga_switcheroo_register_client(struct pci_dev *pdev, +- const struct vga_switcheroo_client_ops *ops) ++ const struct vga_switcheroo_client_ops *ops, ++ bool driver_power_control) + { + return register_client(pdev, ops, -1, +- pdev == vga_default_device()); ++ pdev == vga_default_device(), driver_power_control); + } + EXPORT_SYMBOL(vga_switcheroo_register_client); + +@@ -171,7 +175,7 @@ int vga_switcheroo_register_audio_client(struct pci_dev *pdev, + const struct vga_switcheroo_client_ops *ops, + int id, bool active) + { +- return register_client(pdev, ops, id | ID_BIT_AUDIO, active); ++ return register_client(pdev, ops, id | ID_BIT_AUDIO, active, false); + } + EXPORT_SYMBOL(vga_switcheroo_register_audio_client); + +@@ -258,10 +262,11 @@ static int vga_switcheroo_show(struct seq_file *m, void *v) + int i = 0; + mutex_lock(&vgasr_mutex); + list_for_each_entry(client, &vgasr_priv.clients, list) { +- seq_printf(m, "%d:%s%s:%c:%s:%s\n", i, ++ seq_printf(m, "%d:%s%s:%c:%s%s:%s\n", i, + client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" : "IGD", + client_is_vga(client) ? "" : "-Audio", + client->active ? '+' : ' ', ++ client->driver_power_control ? "Dyn" : "", + client->pwr_state ? "Pwr" : "Off", + pci_name(client->pdev)); + i++; +@@ -277,6 +282,8 @@ static int vga_switcheroo_debugfs_open(struct inode *inode, struct file *file) + + static int vga_switchon(struct vga_switcheroo_client *client) + { ++ if (client->driver_power_control) ++ return 0; + if (vgasr_priv.handler->power_state) + vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON); + /* call the driver callback to turn on device */ +@@ -287,6 +294,8 @@ static int vga_switchon(struct vga_switcheroo_client *client) + + static int vga_switchoff(struct vga_switcheroo_client *client) + { ++ if (client->driver_power_control) ++ return 0; + /* call the driver callback to turn off device */ + client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF); + if (vgasr_priv.handler->power_state) +@@ -402,6 +411,8 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, + list_for_each_entry(client, &vgasr_priv.clients, list) { + if (client->active || client_is_audio(client)) + continue; ++ if (client->driver_power_control) ++ continue; + set_audio_state(client->id, VGA_SWITCHEROO_OFF); + if (client->pwr_state == VGA_SWITCHEROO_ON) + vga_switchoff(client); +@@ -413,6 +424,8 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, + list_for_each_entry(client, &vgasr_priv.clients, list) { + if (client->active || client_is_audio(client)) + continue; ++ if (client->driver_power_control) ++ continue; + if (client->pwr_state == VGA_SWITCHEROO_OFF) + vga_switchon(client); + set_audio_state(client->id, VGA_SWITCHEROO_ON); +@@ -565,3 +578,127 @@ err: + return err; + } + EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch); ++ ++static void vga_switcheroo_power_switch(struct pci_dev *pdev, enum vga_switcheroo_state state) ++{ ++ struct vga_switcheroo_client *client; ++ ++ if (!vgasr_priv.handler->power_state) ++ return; ++ ++ client = find_client_from_pci(&vgasr_priv.clients, pdev); ++ if (!client) ++ return; ++ ++ if (!client->driver_power_control) ++ return; ++ ++ vgasr_priv.handler->power_state(client->id, state); ++} ++ ++/* force a PCI device to a certain state - mainly to turn off audio clients */ ++ ++void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic) ++{ ++ struct vga_switcheroo_client *client; ++ ++ client = find_client_from_pci(&vgasr_priv.clients, pdev); ++ if (!client) ++ return; ++ ++ if (!client->driver_power_control) ++ return; ++ ++ client->pwr_state = dynamic; ++ set_audio_state(client->id, dynamic); ++} ++EXPORT_SYMBOL(vga_switcheroo_set_dynamic_switch); ++ ++/* switcheroo power domain */ ++static int vga_switcheroo_runtime_suspend(struct device *dev) ++{ ++ struct pci_dev *pdev = to_pci_dev(dev); ++ int ret; ++ ++ ret = dev->bus->pm->runtime_suspend(dev); ++ if (ret) ++ return ret; ++ ++ vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF); ++ return 0; ++} ++ ++static int vga_switcheroo_runtime_resume(struct device *dev) ++{ ++ struct pci_dev *pdev = to_pci_dev(dev); ++ int ret; ++ ++ vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON); ++ ret = dev->bus->pm->runtime_resume(dev); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++/* this version is for the case where the power switch is separate ++ to the device being powered down. */ ++int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain) ++{ ++ /* copy over all the bus versions */ ++ if (dev->bus && dev->bus->pm) { ++ domain->ops = *dev->bus->pm; ++ domain->ops.runtime_suspend = vga_switcheroo_runtime_suspend; ++ domain->ops.runtime_resume = vga_switcheroo_runtime_resume; ++ ++ dev->pm_domain = domain; ++ return 0; ++ } ++ dev->pm_domain = NULL; ++ return -EINVAL; ++} ++EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_ops); ++ ++static int vga_switcheroo_runtime_resume_hdmi_audio(struct device *dev) ++{ ++ struct pci_dev *pdev = to_pci_dev(dev); ++ int ret; ++ struct vga_switcheroo_client *client, *found = NULL; ++ ++ /* we need to check if we have to switch back on the video ++ device so the audio device can come back */ ++ list_for_each_entry(client, &vgasr_priv.clients, list) { ++ if (PCI_SLOT(client->pdev->devfn) == PCI_SLOT(pdev->devfn) && client_is_vga(client)) { ++ found = client; ++ ret = pm_runtime_get_sync(&client->pdev->dev); ++ if (ret) { ++ if (ret != 1) ++ return ret; ++ } ++ break; ++ } ++ } ++ ret = dev->bus->pm->runtime_resume(dev); ++ ++ /* put the reference for the gpu */ ++ if (found) { ++ pm_runtime_mark_last_busy(&found->pdev->dev); ++ pm_runtime_put_autosuspend(&found->pdev->dev); ++ } ++ return ret; ++} ++ ++int vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev, struct dev_pm_domain *domain) ++{ ++ /* copy over all the bus versions */ ++ if (dev->bus && dev->bus->pm) { ++ domain->ops = *dev->bus->pm; ++ domain->ops.runtime_resume = vga_switcheroo_runtime_resume_hdmi_audio; ++ ++ dev->pm_domain = domain; ++ return 0; ++ } ++ dev->pm_domain = NULL; ++ return -EINVAL; ++} ++EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_optimus_hdmi_audio); +diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h +index ddb419cf4530..502073a53dd3 100644 +--- a/include/linux/vga_switcheroo.h ++++ b/include/linux/vga_switcheroo.h +@@ -45,7 +45,8 @@ struct vga_switcheroo_client_ops { + #if defined(CONFIG_VGA_SWITCHEROO) + void vga_switcheroo_unregister_client(struct pci_dev *dev); + int vga_switcheroo_register_client(struct pci_dev *dev, +- const struct vga_switcheroo_client_ops *ops); ++ const struct vga_switcheroo_client_ops *ops, ++ bool driver_power_control); + int vga_switcheroo_register_audio_client(struct pci_dev *pdev, + const struct vga_switcheroo_client_ops *ops, + int id, bool active); +@@ -60,11 +61,15 @@ int vga_switcheroo_process_delayed_switch(void); + + int vga_switcheroo_get_client_state(struct pci_dev *dev); + ++void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic); ++ ++int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain); ++int vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev, struct dev_pm_domain *domain); + #else + + static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {} + static inline int vga_switcheroo_register_client(struct pci_dev *dev, +- const struct vga_switcheroo_client_ops *ops) { return 0; } ++ const struct vga_switcheroo_client_ops *ops, bool driver_power_control) { return 0; } + static inline void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info) {} + static inline int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) { return 0; } + static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev, +@@ -74,6 +79,10 @@ static inline void vga_switcheroo_unregister_handler(void) {} + static inline int vga_switcheroo_process_delayed_switch(void) { return 0; } + static inline int vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; } + ++static inline void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic) {} ++ ++static inline int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain) { return -EINVAL; } ++static inline int vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev, struct dev_pm_domain *domain) { return -EINVAL; } + + #endif + #endif /* _LINUX_VGA_SWITCHEROO_H_ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0728-drm-edid-Add-both-60Hz-and-59.94Hz-CEA-modes-to-conn.patch b/patches.baytrail/0728-drm-edid-Add-both-60Hz-and-59.94Hz-CEA-modes-to-conn.patch new file mode 100644 index 000000000000..5ce772595ef2 --- /dev/null +++ b/patches.baytrail/0728-drm-edid-Add-both-60Hz-and-59.94Hz-CEA-modes-to-conn.patch @@ -0,0 +1,171 @@ +From 37b6d52b6a180c5434345df1d3bfb7d83a44e652 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 31 May 2013 15:23:41 +0300 +Subject: drm/edid: Add both 60Hz and 59.94Hz CEA modes to connector's mode + list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Having both modes can be beneficial for video playback cases. If you can +match the video framerate exactly, and the audio and video clocks come +from the same source, you should be able to avoid dropped/repeated +frames without expensive operations such as resampling the audio to +match video output rate. + +Rather than add both variants based on the CEA extension short video +descriptors in do_cea_modes(), add only one variant there. Once all +the EDID has been fully probed, do a loop over the entire probed mode +list, during which we add the other variants for all modes that match +CEA modes. This allows us to match modes that didn't come via the CEA +short video descriptors. For example one Samsung TV here doesn't have +the 640x480-60 mode as a SVD, but instead it's specified via a detailed +timing descriptor. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit e6e792092e816bea0797995c886fb057c91d4546) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_edid.c | 102 ++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 88 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 9d4d21f46a8a..298e1052fcc3 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -2353,6 +2353,31 @@ u8 *drm_find_cea_extension(struct edid *edid) + } + EXPORT_SYMBOL(drm_find_cea_extension); + ++/* ++ * Calculate the alternate clock for the CEA mode ++ * (60Hz vs. 59.94Hz etc.) ++ */ ++static unsigned int ++cea_mode_alternate_clock(const struct drm_display_mode *cea_mode) ++{ ++ unsigned int clock = cea_mode->clock; ++ ++ if (cea_mode->vrefresh % 6 != 0) ++ return clock; ++ ++ /* ++ * edid_cea_modes contains the 59.94Hz ++ * variant for 240 and 480 line modes, ++ * and the 60Hz variant otherwise. ++ */ ++ if (cea_mode->vdisplay == 240 || cea_mode->vdisplay == 480) ++ clock = clock * 1001 / 1000; ++ else ++ clock = DIV_ROUND_UP(clock * 1000, 1001); ++ ++ return clock; ++} ++ + /** + * drm_match_cea_mode - look for a CEA mode matching given mode + * @to_match: display mode +@@ -2371,21 +2396,9 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match) + const struct drm_display_mode *cea_mode = &edid_cea_modes[mode]; + unsigned int clock1, clock2; + +- clock1 = clock2 = cea_mode->clock; +- + /* Check both 60Hz and 59.94Hz */ +- if (cea_mode->vrefresh % 6 == 0) { +- /* +- * edid_cea_modes contains the 59.94Hz +- * variant for 240 and 480 line modes, +- * and the 60Hz variant otherwise. +- */ +- if (cea_mode->vdisplay == 240 || +- cea_mode->vdisplay == 480) +- clock1 = clock1 * 1001 / 1000; +- else +- clock2 = DIV_ROUND_UP(clock2 * 1000, 1001); +- } ++ clock1 = cea_mode->clock; ++ clock2 = cea_mode_alternate_clock(cea_mode); + + if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || + KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && +@@ -2396,6 +2409,66 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match) + } + EXPORT_SYMBOL(drm_match_cea_mode); + ++static int ++add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid) ++{ ++ struct drm_device *dev = connector->dev; ++ struct drm_display_mode *mode, *tmp; ++ LIST_HEAD(list); ++ int modes = 0; ++ ++ /* Don't add CEA modes if the CEA extension block is missing */ ++ if (!drm_find_cea_extension(edid)) ++ return 0; ++ ++ /* ++ * Go through all probed modes and create a new mode ++ * with the alternate clock for certain CEA modes. ++ */ ++ list_for_each_entry(mode, &connector->probed_modes, head) { ++ const struct drm_display_mode *cea_mode; ++ struct drm_display_mode *newmode; ++ u8 cea_mode_idx = drm_match_cea_mode(mode) - 1; ++ unsigned int clock1, clock2; ++ ++ if (cea_mode_idx >= ARRAY_SIZE(edid_cea_modes)) ++ continue; ++ ++ cea_mode = &edid_cea_modes[cea_mode_idx]; ++ ++ clock1 = cea_mode->clock; ++ clock2 = cea_mode_alternate_clock(cea_mode); ++ ++ if (clock1 == clock2) ++ continue; ++ ++ if (mode->clock != clock1 && mode->clock != clock2) ++ continue; ++ ++ newmode = drm_mode_duplicate(dev, cea_mode); ++ if (!newmode) ++ continue; ++ ++ /* ++ * The current mode could be either variant. Make ++ * sure to pick the "other" clock for the new mode. ++ */ ++ if (mode->clock != clock1) ++ newmode->clock = clock1; ++ else ++ newmode->clock = clock2; ++ ++ list_add_tail(&newmode->head, &list); ++ } ++ ++ list_for_each_entry_safe(mode, tmp, &list, head) { ++ list_del(&mode->head); ++ drm_mode_probed_add(connector, mode); ++ modes++; ++ } ++ ++ return modes; ++} + + static int + do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len) +@@ -3044,6 +3117,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) + if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF) + num_modes += add_inferred_modes(connector, edid); + num_modes += add_cea_modes(connector, edid); ++ num_modes += add_alternate_cea_modes(connector, edid); + + if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) + edid_fixup_preferred(connector, quirks); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0729-drm-Add-support-for-alternate-clocks-of-4k-modes.patch b/patches.baytrail/0729-drm-Add-support-for-alternate-clocks-of-4k-modes.patch new file mode 100644 index 000000000000..6cf5be691a30 --- /dev/null +++ b/patches.baytrail/0729-drm-Add-support-for-alternate-clocks-of-4k-modes.patch @@ -0,0 +1,117 @@ +From e2715a7aafa472744a6162f5fe7dbcfbca549d66 Mon Sep 17 00:00:00 2001 +From: "Lespiau, Damien" +Date: Mon, 19 Aug 2013 16:58:55 +0100 +Subject: drm: Add support for alternate clocks of 4k modes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +v2: Fix hmdi typo (Simon Farnsworth, Ville Syrjälä) + +Suggested-by: Ville Syrjälä +Signed-off-by: Damien Lespiau +Reviewed-by: Ville Syrjälä +Reviewed-by: Simon Farnsworth +Reviewed-by: Thierry Reding +Signed-off-by: Dave Airlie +(cherry picked from commit 3f2f653378112c1453c0d83c81746a9225e4bc75) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_edid.c | 68 ++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 62 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 298e1052fcc3..4adcea91d728 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -2409,6 +2409,54 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match) + } + EXPORT_SYMBOL(drm_match_cea_mode); + ++/* ++ * Calculate the alternate clock for HDMI modes (those from the HDMI vendor ++ * specific block). ++ * ++ * It's almost like cea_mode_alternate_clock(), we just need to add an ++ * exception for the VIC 4 mode (4096x2160@24Hz): no alternate clock for this ++ * one. ++ */ ++static unsigned int ++hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode) ++{ ++ if (hdmi_mode->vdisplay == 4096 && hdmi_mode->hdisplay == 2160) ++ return hdmi_mode->clock; ++ ++ return cea_mode_alternate_clock(hdmi_mode); ++} ++ ++/* ++ * drm_match_hdmi_mode - look for a HDMI mode matching given mode ++ * @to_match: display mode ++ * ++ * An HDMI mode is one defined in the HDMI vendor specific block. ++ * ++ * Returns the HDMI Video ID (VIC) of the mode or 0 if it isn't one. ++ */ ++static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match) ++{ ++ u8 mode; ++ ++ if (!to_match->clock) ++ return 0; ++ ++ for (mode = 0; mode < ARRAY_SIZE(edid_4k_modes); mode++) { ++ const struct drm_display_mode *hdmi_mode = &edid_4k_modes[mode]; ++ unsigned int clock1, clock2; ++ ++ /* Make sure to also match alternate clocks */ ++ clock1 = hdmi_mode->clock; ++ clock2 = hdmi_mode_alternate_clock(hdmi_mode); ++ ++ if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || ++ KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && ++ drm_mode_equal_no_clocks(to_match, hdmi_mode)) ++ return mode + 1; ++ } ++ return 0; ++} ++ + static int + add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid) + { +@@ -2426,18 +2474,26 @@ add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid) + * with the alternate clock for certain CEA modes. + */ + list_for_each_entry(mode, &connector->probed_modes, head) { +- const struct drm_display_mode *cea_mode; ++ const struct drm_display_mode *cea_mode = NULL; + struct drm_display_mode *newmode; +- u8 cea_mode_idx = drm_match_cea_mode(mode) - 1; ++ u8 mode_idx = drm_match_cea_mode(mode) - 1; + unsigned int clock1, clock2; + +- if (cea_mode_idx >= ARRAY_SIZE(edid_cea_modes)) +- continue; ++ if (mode_idx < ARRAY_SIZE(edid_cea_modes)) { ++ cea_mode = &edid_cea_modes[mode_idx]; ++ clock2 = cea_mode_alternate_clock(cea_mode); ++ } else { ++ mode_idx = drm_match_hdmi_mode(mode) - 1; ++ if (mode_idx < ARRAY_SIZE(edid_4k_modes)) { ++ cea_mode = &edid_4k_modes[mode_idx]; ++ clock2 = hdmi_mode_alternate_clock(cea_mode); ++ } ++ } + +- cea_mode = &edid_cea_modes[cea_mode_idx]; ++ if (!cea_mode) ++ continue; + + clock1 = cea_mode->clock; +- clock2 = cea_mode_alternate_clock(cea_mode); + + if (clock1 == clock2) + continue; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0730-drm-Make-drm_match_cea_mode-return-the-underlying-2D.patch b/patches.baytrail/0730-drm-Make-drm_match_cea_mode-return-the-underlying-2D.patch new file mode 100644 index 000000000000..ccc137f3091c --- /dev/null +++ b/patches.baytrail/0730-drm-Make-drm_match_cea_mode-return-the-underlying-2D.patch @@ -0,0 +1,119 @@ +From c0910899d5419b491aa0cefd7504777042eeef19 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Wed, 25 Sep 2013 16:45:27 +0100 +Subject: drm: Make drm_match_cea_mode() return the underlying 2D VIC for 3d + modes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When scanning out a stereo mode, the AVI infoframe vic field has to be +the underlyng 2D VIC. Before that commit, we weren't matching the CEA +mode because of the extra stereo flag and then were setting the VIC +field in the AVI infoframe to 0. + +Reviewed-by: Ville Syrjälä +Signed-off-by: Damien Lespiau +Acked-by: Dave Airlie +Signed-off-by: Daniel Vetter +(cherry picked from commit f2ecf2e3bc01868f244fc6ba9cf8fe5d8446db5b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_edid.c | 4 ++-- + drivers/gpu/drm/drm_modes.c | 18 ++++++++++++------ + include/drm/drm_crtc.h | 2 +- + 3 files changed, 15 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 4adcea91d728..1e5db5bb8eaf 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -2402,7 +2402,7 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match) + + if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || + KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && +- drm_mode_equal_no_clocks(to_match, cea_mode)) ++ drm_mode_equal_no_clocks_no_stereo(to_match, cea_mode)) + return mode + 1; + } + return 0; +@@ -2451,7 +2451,7 @@ static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match) + + if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || + KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && +- drm_mode_equal_no_clocks(to_match, hdmi_mode)) ++ drm_mode_equal_no_clocks_no_stereo(to_match, hdmi_mode)) + return mode + 1; + } + return 0; +diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c +index a371ff865a88..1d29b473fe6a 100644 +--- a/drivers/gpu/drm/drm_modes.c ++++ b/drivers/gpu/drm/drm_modes.c +@@ -848,12 +848,16 @@ bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_displ + } else if (mode1->clock != mode2->clock) + return false; + +- return drm_mode_equal_no_clocks(mode1, mode2); ++ if ((mode1->flags & DRM_MODE_FLAG_3D_MASK) != ++ (mode2->flags & DRM_MODE_FLAG_3D_MASK)) ++ return false; ++ ++ return drm_mode_equal_no_clocks_no_stereo(mode1, mode2); + } + EXPORT_SYMBOL(drm_mode_equal); + + /** +- * drm_mode_equal_no_clocks - test modes for equality ++ * drm_mode_equal_no_clocks_no_stereo - test modes for equality + * @mode1: first mode + * @mode2: second mode + * +@@ -861,12 +865,13 @@ EXPORT_SYMBOL(drm_mode_equal); + * None. + * + * Check to see if @mode1 and @mode2 are equivalent, but +- * don't check the pixel clocks. ++ * don't check the pixel clocks nor the stereo layout. + * + * RETURNS: + * True if the modes are equal, false otherwise. + */ +-bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2) ++bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, ++ const struct drm_display_mode *mode2) + { + if (mode1->hdisplay == mode2->hdisplay && + mode1->hsync_start == mode2->hsync_start && +@@ -878,12 +883,13 @@ bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const struct + mode1->vsync_end == mode2->vsync_end && + mode1->vtotal == mode2->vtotal && + mode1->vscan == mode2->vscan && +- mode1->flags == mode2->flags) ++ (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) == ++ (mode2->flags & ~DRM_MODE_FLAG_3D_MASK)) + return true; + + return false; + } +-EXPORT_SYMBOL(drm_mode_equal_no_clocks); ++EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo); + + /** + * drm_mode_validate_size - make sure modes adhere to size constraints +diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h +index 2cbbfd44c6df..c2f130e584c3 100644 +--- a/include/drm/drm_crtc.h ++++ b/include/drm/drm_crtc.h +@@ -920,7 +920,7 @@ extern void drm_mode_config_reset(struct drm_device *dev); + extern void drm_mode_config_cleanup(struct drm_device *dev); + extern void drm_mode_set_name(struct drm_display_mode *mode); + extern bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2); +-extern bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2); ++extern bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2); + extern int drm_mode_width(const struct drm_display_mode *mode); + extern int drm_mode_height(const struct drm_display_mode *mode); + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0731-drm-Add-a-helper-to-forge-HDMI-vendor-infoframes.patch b/patches.baytrail/0731-drm-Add-a-helper-to-forge-HDMI-vendor-infoframes.patch new file mode 100644 index 000000000000..ca6dd1366231 --- /dev/null +++ b/patches.baytrail/0731-drm-Add-a-helper-to-forge-HDMI-vendor-infoframes.patch @@ -0,0 +1,93 @@ +From 72c90e7927c6dd7b5b95f32ab1b496d2392b5bf7 Mon Sep 17 00:00:00 2001 +From: "Lespiau, Damien" +Date: Mon, 19 Aug 2013 16:59:03 +0100 +Subject: drm: Add a helper to forge HDMI vendor infoframes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This can then be used by DRM drivers to setup their vendor infoframes. + +v2: Fix hmdi typo (Simon Farnsworth) +v3: Adapt to the hdmi_vendor_infoframe rename + +Signed-off-by: Damien Lespiau +Reviewed-by: Simon Farnsworth +Reviewed-by: Ville Syrjälä +Reviewed-by: Thierry Reding +Signed-off-by: Dave Airlie +(cherry picked from commit 83dd000865eaaeb0799bf5e6d12f8d8cdb740e91) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_edid.c | 36 ++++++++++++++++++++++++++++++++++++ + include/drm/drm_edid.h | 4 ++++ + 2 files changed, 40 insertions(+) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 1e5db5bb8eaf..63c50ce3934f 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -3266,3 +3266,39 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, + return 0; + } + EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode); ++ ++/** ++ * drm_hdmi_vendor_infoframe_from_display_mode() - fill an HDMI infoframe with ++ * data from a DRM display mode ++ * @frame: HDMI vendor infoframe ++ * @mode: DRM display mode ++ * ++ * Note that there's is a need to send HDMI vendor infoframes only when using a ++ * 4k or stereoscopic 3D mode. So when giving any other mode as input this ++ * function will return -EINVAL, error that can be safely ignored. ++ * ++ * Returns 0 on success or a negative error code on failure. ++ */ ++int ++drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, ++ const struct drm_display_mode *mode) ++{ ++ int err; ++ u8 vic; ++ ++ if (!frame || !mode) ++ return -EINVAL; ++ ++ vic = drm_match_hdmi_mode(mode); ++ if (!vic) ++ return -EINVAL; ++ ++ err = hdmi_vendor_infoframe_init(frame); ++ if (err < 0) ++ return err; ++ ++ frame->vic = vic; ++ ++ return 0; ++} ++EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode); +diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h +index fc481fc17085..7b75621fda4c 100644 +--- a/include/drm/drm_edid.h ++++ b/include/drm/drm_edid.h +@@ -256,6 +256,7 @@ struct drm_encoder; + struct drm_connector; + struct drm_display_mode; + struct hdmi_avi_infoframe; ++struct hdmi_vendor_infoframe; + + void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid); + int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads); +@@ -268,5 +269,8 @@ int drm_load_edid_firmware(struct drm_connector *connector); + int + drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, + const struct drm_display_mode *mode); ++int ++drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, ++ const struct drm_display_mode *mode); + + #endif /* __DRM_EDID_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0732-drm-Add-HDMI-stereo-3D-flags-to-struct-drm_mode_mode.patch b/patches.baytrail/0732-drm-Add-HDMI-stereo-3D-flags-to-struct-drm_mode_mode.patch new file mode 100644 index 000000000000..fbb5d7d8e10e --- /dev/null +++ b/patches.baytrail/0732-drm-Add-HDMI-stereo-3D-flags-to-struct-drm_mode_mode.patch @@ -0,0 +1,101 @@ +From e50c807fd4bc10bb9aa712884d618eb7e04832fb Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Wed, 25 Sep 2013 16:45:21 +0100 +Subject: drm: Add HDMI stereo 3D flags to struct drm_mode_modeinfo +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +HDMI 1.4a defines a few layouts that we'd like to expose. This commits +add new modeinfo flags that can be used to list the supported stereo +layouts (when querying the list of modes) and to set a given stereo 3D +mode (when setting a mode). + +v2: Add a drm_mode_is_stereo() helper + +Reviewed-by: Ville Syrjälä +Signed-off-by: Damien Lespiau +Acked-by: Dave Airlie +Signed-off-by: Daniel Vetter +(cherry picked from commit 4aa17cf0d889cfc984b68a78ae02070cef21bb6b) +Signed-off-by: Darren Hart +--- + include/drm/drm_crtc.h | 14 ++++++++++++++ + include/uapi/drm/drm_mode.h | 36 ++++++++++++++++++++++-------------- + 2 files changed, 36 insertions(+), 14 deletions(-) + +diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h +index c2f130e584c3..f96e7ff0035b 100644 +--- a/include/drm/drm_crtc.h ++++ b/include/drm/drm_crtc.h +@@ -179,6 +179,20 @@ struct drm_display_mode { + int hsync; /* in kHz */ + }; + ++#define DRM_MODE_FLAG_3D_MASK (DRM_MODE_FLAG_3D_FRAME_PACKING | \ ++ DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE | \ ++ DRM_MODE_FLAG_3D_LINE_ALTERNATIVE | \ ++ DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL | \ ++ DRM_MODE_FLAG_3D_L_DEPTH | \ ++ DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH | \ ++ DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | \ ++ DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF) ++ ++static inline bool drm_mode_is_stereo(const struct drm_display_mode *mode) ++{ ++ return mode->flags & DRM_MODE_FLAG_3D_MASK; ++} ++ + enum drm_connector_status { + connector_status_connected = 1, + connector_status_disconnected = 2, +diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h +index cc2e00eac2f1..acc75bac67f1 100644 +--- a/include/uapi/drm/drm_mode.h ++++ b/include/uapi/drm/drm_mode.h +@@ -44,20 +44,28 @@ + + /* Video mode flags */ + /* bit compatible with the xorg definitions. */ +-#define DRM_MODE_FLAG_PHSYNC (1<<0) +-#define DRM_MODE_FLAG_NHSYNC (1<<1) +-#define DRM_MODE_FLAG_PVSYNC (1<<2) +-#define DRM_MODE_FLAG_NVSYNC (1<<3) +-#define DRM_MODE_FLAG_INTERLACE (1<<4) +-#define DRM_MODE_FLAG_DBLSCAN (1<<5) +-#define DRM_MODE_FLAG_CSYNC (1<<6) +-#define DRM_MODE_FLAG_PCSYNC (1<<7) +-#define DRM_MODE_FLAG_NCSYNC (1<<8) +-#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */ +-#define DRM_MODE_FLAG_BCAST (1<<10) +-#define DRM_MODE_FLAG_PIXMUX (1<<11) +-#define DRM_MODE_FLAG_DBLCLK (1<<12) +-#define DRM_MODE_FLAG_CLKDIV2 (1<<13) ++#define DRM_MODE_FLAG_PHSYNC (1<<0) ++#define DRM_MODE_FLAG_NHSYNC (1<<1) ++#define DRM_MODE_FLAG_PVSYNC (1<<2) ++#define DRM_MODE_FLAG_NVSYNC (1<<3) ++#define DRM_MODE_FLAG_INTERLACE (1<<4) ++#define DRM_MODE_FLAG_DBLSCAN (1<<5) ++#define DRM_MODE_FLAG_CSYNC (1<<6) ++#define DRM_MODE_FLAG_PCSYNC (1<<7) ++#define DRM_MODE_FLAG_NCSYNC (1<<8) ++#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */ ++#define DRM_MODE_FLAG_BCAST (1<<10) ++#define DRM_MODE_FLAG_PIXMUX (1<<11) ++#define DRM_MODE_FLAG_DBLCLK (1<<12) ++#define DRM_MODE_FLAG_CLKDIV2 (1<<13) ++#define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14) ++#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (1<<15) ++#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (1<<16) ++#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL (1<<17) ++#define DRM_MODE_FLAG_3D_L_DEPTH (1<<18) ++#define DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH (1<<19) ++#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (1<<20) ++#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (1<<21) + + /* DPMS flags */ + /* bit compatible with the xorg definitions. */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0733-drm-edid-Expose-mandatory-stereo-modes-for-HDMI-sink.patch b/patches.baytrail/0733-drm-edid-Expose-mandatory-stereo-modes-for-HDMI-sink.patch new file mode 100644 index 000000000000..06c39a858f83 --- /dev/null +++ b/patches.baytrail/0733-drm-edid-Expose-mandatory-stereo-modes-for-HDMI-sink.patch @@ -0,0 +1,185 @@ +From e1d29de699eecba1881efaa77805b0da587c189f Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Wed, 25 Sep 2013 16:45:23 +0100 +Subject: drm/edid: Expose mandatory stereo modes for HDMI sinks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For now, let's just look at the 3D_present flag of the CEA HDMI vendor +block to detect if the sink supports a small list of then mandatory 3D +formats. + +See the HDMI 1.4a 3D extraction for detail: + http://www.hdmi.org/manufacturer/specification.aspx + +v2: Rename freq to vrefresh, make the mandatory structure a bit more + compact, fix some white space issues and add a couple of const + (Ville Syrjälä) + +Reviewed-by: Ville Syrjälä +Signed-off-by: Damien Lespiau +Acked-by: Dave Airlie +Signed-off-by: Daniel Vetter +(cherry picked from commit c858cfcae6dd3829e8708a48d009c2f676b79d4d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_edid.c | 110 ++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 103 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 63c50ce3934f..41a5f3428e93 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -2551,13 +2551,95 @@ do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len) + return modes; + } + ++struct stereo_mandatory_mode { ++ int width, height, vrefresh; ++ unsigned int flags; ++}; ++ ++static const struct stereo_mandatory_mode stereo_mandatory_modes[] = { ++ { 1920, 1080, 24, ++ DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING }, ++ { 1920, 1080, 50, ++ DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF }, ++ { 1920, 1080, 60, ++ DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF }, ++ { 1280, 720, 50, ++ DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING }, ++ { 1280, 720, 60, ++ DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING } ++}; ++ ++static bool ++stereo_match_mandatory(const struct drm_display_mode *mode, ++ const struct stereo_mandatory_mode *stereo_mode) ++{ ++ unsigned int interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE; ++ ++ return mode->hdisplay == stereo_mode->width && ++ mode->vdisplay == stereo_mode->height && ++ interlaced == (stereo_mode->flags & DRM_MODE_FLAG_INTERLACE) && ++ drm_mode_vrefresh(mode) == stereo_mode->vrefresh; ++} ++ ++static const struct stereo_mandatory_mode * ++hdmi_find_stereo_mandatory_mode(const struct drm_display_mode *mode) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++) ++ if (stereo_match_mandatory(mode, &stereo_mandatory_modes[i])) ++ return &stereo_mandatory_modes[i]; ++ ++ return NULL; ++} ++ ++static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector) ++{ ++ struct drm_device *dev = connector->dev; ++ const struct drm_display_mode *mode; ++ struct list_head stereo_modes; ++ int modes = 0; ++ ++ INIT_LIST_HEAD(&stereo_modes); ++ ++ list_for_each_entry(mode, &connector->probed_modes, head) { ++ const struct stereo_mandatory_mode *mandatory; ++ u32 stereo_layouts, layout; ++ ++ mandatory = hdmi_find_stereo_mandatory_mode(mode); ++ if (!mandatory) ++ continue; ++ ++ stereo_layouts = mandatory->flags & DRM_MODE_FLAG_3D_MASK; ++ do { ++ struct drm_display_mode *new_mode; ++ ++ layout = 1 << (ffs(stereo_layouts) - 1); ++ stereo_layouts &= ~layout; ++ ++ new_mode = drm_mode_duplicate(dev, mode); ++ if (!new_mode) ++ continue; ++ ++ new_mode->flags |= layout; ++ list_add_tail(&new_mode->head, &stereo_modes); ++ modes++; ++ } while (stereo_layouts); ++ } ++ ++ list_splice_tail(&stereo_modes, &connector->probed_modes); ++ ++ return modes; ++} ++ + /* + * do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block + * @connector: connector corresponding to the HDMI sink + * @db: start of the CEA vendor specific block + * @len: length of the CEA block payload, ie. one can access up to db[len] + * +- * Parses the HDMI VSDB looking for modes to add to @connector. ++ * Parses the HDMI VSDB looking for modes to add to @connector. This function ++ * also adds the stereo 3d modes when applicable. + */ + static int + do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len) +@@ -2583,10 +2665,15 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len) + + /* the declared length is not long enough for the 2 first bytes + * of additional video format capabilities */ +- offset += 2; +- if (len < (8 + offset)) ++ if (len < (8 + offset + 2)) + goto out; + ++ /* 3D_Present */ ++ offset++; ++ if (db[8 + offset] & (1 << 7)) ++ modes += add_hdmi_mandatory_stereo_modes(connector); ++ ++ offset++; + vic_len = db[8 + offset] >> 5; + + for (i = 0; i < vic_len && len >= (9 + offset + i); i++) { +@@ -2666,8 +2753,8 @@ static int + add_cea_modes(struct drm_connector *connector, struct edid *edid) + { + const u8 *cea = drm_find_cea_extension(edid); +- const u8 *db; +- u8 dbl; ++ const u8 *db, *hdmi = NULL; ++ u8 dbl, hdmi_len; + int modes = 0; + + if (cea && cea_revision(cea) >= 3) { +@@ -2682,11 +2769,20 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid) + + if (cea_db_tag(db) == VIDEO_BLOCK) + modes += do_cea_modes(connector, db + 1, dbl); +- else if (cea_db_is_hdmi_vsdb(db)) +- modes += do_hdmi_vsdb_modes(connector, db, dbl); ++ else if (cea_db_is_hdmi_vsdb(db)) { ++ hdmi = db; ++ hdmi_len = dbl; ++ } + } + } + ++ /* ++ * We parse the HDMI VSDB after having added the cea modes as we will ++ * be patching their flags when the sink supports stereo 3D. ++ */ ++ if (hdmi) ++ modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len); ++ + return modes; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0734-drm-Extract-add_hdmi_mode-out-of-do_hdmi_vsdb_modes.patch b/patches.baytrail/0734-drm-Extract-add_hdmi_mode-out-of-do_hdmi_vsdb_modes.patch new file mode 100644 index 000000000000..53a7a8e1b5ae --- /dev/null +++ b/patches.baytrail/0734-drm-Extract-add_hdmi_mode-out-of-do_hdmi_vsdb_modes.patch @@ -0,0 +1,92 @@ +From 882c8bf1162976bec507fc41d2ad1b2a112f075c Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Wed, 25 Sep 2013 16:45:24 +0100 +Subject: drm: Extract add_hdmi_mode() out of do_hdmi_vsdb_modes() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +So we respect a nice design of having similar functions at the same +level, in this case: + +do_hdmi_vsdb_modes() + - add_hdmi_mandatory_stereo_modes() + - add_hdmi_mode() + +Reviewed-by: Ville Syrjälä +Signed-off-by: Damien Lespiau +Acked-by: Dave Airlie +Signed-off-by: Daniel Vetter +(cherry picked from commit 1deee8d76724b478240f1bba5affe017e4f9bfa3) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_edid.c | 36 +++++++++++++++++++++--------------- + 1 file changed, 21 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 41a5f3428e93..a23a3be52a09 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -2632,6 +2632,26 @@ static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector) + return modes; + } + ++static int add_hdmi_mode(struct drm_connector *connector, u8 vic) ++{ ++ struct drm_device *dev = connector->dev; ++ struct drm_display_mode *newmode; ++ ++ vic--; /* VICs start at 1 */ ++ if (vic >= ARRAY_SIZE(edid_4k_modes)) { ++ DRM_ERROR("Unknown HDMI VIC: %d\n", vic); ++ return 0; ++ } ++ ++ newmode = drm_mode_duplicate(dev, &edid_4k_modes[vic]); ++ if (!newmode) ++ return 0; ++ ++ drm_mode_probed_add(connector, newmode); ++ ++ return 1; ++} ++ + /* + * do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block + * @connector: connector corresponding to the HDMI sink +@@ -2644,7 +2664,6 @@ static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector) + static int + do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len) + { +- struct drm_device *dev = connector->dev; + int modes = 0, offset = 0, i; + u8 vic_len; + +@@ -2677,23 +2696,10 @@ do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len) + vic_len = db[8 + offset] >> 5; + + for (i = 0; i < vic_len && len >= (9 + offset + i); i++) { +- struct drm_display_mode *newmode; + u8 vic; + + vic = db[9 + offset + i]; +- +- vic--; /* VICs start at 1 */ +- if (vic >= ARRAY_SIZE(edid_4k_modes)) { +- DRM_ERROR("Unknown HDMI VIC: %d\n", vic); +- continue; +- } +- +- newmode = drm_mode_duplicate(dev, &edid_4k_modes[vic]); +- if (!newmode) +- continue; +- +- drm_mode_probed_add(connector, newmode); +- modes++; ++ modes += add_hdmi_mode(connector, vic); + } + + out: +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0735-drm-Code-stereo-layouts-as-an-enum-rather-than-a-bit.patch b/patches.baytrail/0735-drm-Code-stereo-layouts-as-an-enum-rather-than-a-bit.patch new file mode 100644 index 000000000000..0a65ee762b26 --- /dev/null +++ b/patches.baytrail/0735-drm-Code-stereo-layouts-as-an-enum-rather-than-a-bit.patch @@ -0,0 +1,173 @@ +From 875ef39de7745758b997b8ba2dca6cb3ae9a8720 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Fri, 27 Sep 2013 12:11:48 +0100 +Subject: drm: Code stereo layouts as an enum rather than a bit field +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This allows us to use fewer bits in the mode structure, leaving room for +future work while allowing more stereo layouts types than we could have +ever dreamt of. + +I also exposed the previously private DRM_MODE_FLAG_3D_MASK to set in +stone that we are using 5 bits for the stereo layout enum, reserving 32 +values. + +Even with that reservation, we gain 3 bits from the previous encoding. + +The code adding the mandatory stereo modes needeed to be adapted as it was +relying or being able to or stereo layouts together. + +Suggested-by: Daniel Vetter +Signed-off-by: Damien Lespiau +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit f7e121b76469624459152542c1b809a1ebc835fe) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_edid.c | 47 +++++++++++++++------------------------------ + include/drm/drm_crtc.h | 9 --------- + include/uapi/drm/drm_mode.h | 19 ++++++++++-------- + 3 files changed, 26 insertions(+), 49 deletions(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index a23a3be52a09..802daf1dfa60 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -2557,16 +2557,16 @@ struct stereo_mandatory_mode { + }; + + static const struct stereo_mandatory_mode stereo_mandatory_modes[] = { +- { 1920, 1080, 24, +- DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING }, ++ { 1920, 1080, 24, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM }, ++ { 1920, 1080, 24, DRM_MODE_FLAG_3D_FRAME_PACKING }, + { 1920, 1080, 50, + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF }, + { 1920, 1080, 60, + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF }, +- { 1280, 720, 50, +- DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING }, +- { 1280, 720, 60, +- DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | DRM_MODE_FLAG_3D_FRAME_PACKING } ++ { 1280, 720, 50, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM }, ++ { 1280, 720, 50, DRM_MODE_FLAG_3D_FRAME_PACKING }, ++ { 1280, 720, 60, DRM_MODE_FLAG_3D_TOP_AND_BOTTOM }, ++ { 1280, 720, 60, DRM_MODE_FLAG_3D_FRAME_PACKING } + }; + + static bool +@@ -2581,50 +2581,33 @@ stereo_match_mandatory(const struct drm_display_mode *mode, + drm_mode_vrefresh(mode) == stereo_mode->vrefresh; + } + +-static const struct stereo_mandatory_mode * +-hdmi_find_stereo_mandatory_mode(const struct drm_display_mode *mode) +-{ +- int i; +- +- for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++) +- if (stereo_match_mandatory(mode, &stereo_mandatory_modes[i])) +- return &stereo_mandatory_modes[i]; +- +- return NULL; +-} +- + static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector) + { + struct drm_device *dev = connector->dev; + const struct drm_display_mode *mode; + struct list_head stereo_modes; +- int modes = 0; ++ int modes = 0, i; + + INIT_LIST_HEAD(&stereo_modes); + + list_for_each_entry(mode, &connector->probed_modes, head) { +- const struct stereo_mandatory_mode *mandatory; +- u32 stereo_layouts, layout; +- +- mandatory = hdmi_find_stereo_mandatory_mode(mode); +- if (!mandatory) +- continue; +- +- stereo_layouts = mandatory->flags & DRM_MODE_FLAG_3D_MASK; +- do { ++ for (i = 0; i < ARRAY_SIZE(stereo_mandatory_modes); i++) { ++ const struct stereo_mandatory_mode *mandatory; + struct drm_display_mode *new_mode; + +- layout = 1 << (ffs(stereo_layouts) - 1); +- stereo_layouts &= ~layout; ++ if (!stereo_match_mandatory(mode, ++ &stereo_mandatory_modes[i])) ++ continue; + ++ mandatory = &stereo_mandatory_modes[i]; + new_mode = drm_mode_duplicate(dev, mode); + if (!new_mode) + continue; + +- new_mode->flags |= layout; ++ new_mode->flags |= mandatory->flags; + list_add_tail(&new_mode->head, &stereo_modes); + modes++; +- } while (stereo_layouts); ++ } + } + + list_splice_tail(&stereo_modes, &connector->probed_modes); +diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h +index f96e7ff0035b..b228321549fa 100644 +--- a/include/drm/drm_crtc.h ++++ b/include/drm/drm_crtc.h +@@ -179,15 +179,6 @@ struct drm_display_mode { + int hsync; /* in kHz */ + }; + +-#define DRM_MODE_FLAG_3D_MASK (DRM_MODE_FLAG_3D_FRAME_PACKING | \ +- DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE | \ +- DRM_MODE_FLAG_3D_LINE_ALTERNATIVE | \ +- DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL | \ +- DRM_MODE_FLAG_3D_L_DEPTH | \ +- DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH | \ +- DRM_MODE_FLAG_3D_TOP_AND_BOTTOM | \ +- DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF) +- + static inline bool drm_mode_is_stereo(const struct drm_display_mode *mode) + { + return mode->flags & DRM_MODE_FLAG_3D_MASK; +diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h +index acc75bac67f1..82adefbabfa4 100644 +--- a/include/uapi/drm/drm_mode.h ++++ b/include/uapi/drm/drm_mode.h +@@ -58,14 +58,17 @@ + #define DRM_MODE_FLAG_PIXMUX (1<<11) + #define DRM_MODE_FLAG_DBLCLK (1<<12) + #define DRM_MODE_FLAG_CLKDIV2 (1<<13) +-#define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14) +-#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (1<<15) +-#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (1<<16) +-#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL (1<<17) +-#define DRM_MODE_FLAG_3D_L_DEPTH (1<<18) +-#define DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH (1<<19) +-#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (1<<20) +-#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (1<<21) ++#define DRM_MODE_FLAG_3D_MASK (0x1f<<14) ++#define DRM_MODE_FLAG_3D_NONE (0<<14) ++#define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14) ++#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (2<<14) ++#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (3<<14) ++#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL (4<<14) ++#define DRM_MODE_FLAG_3D_L_DEPTH (5<<14) ++#define DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH (6<<14) ++#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (7<<14) ++#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (8<<14) ++ + + /* DPMS flags */ + /* bit compatible with the xorg definitions. */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0736-drm-Set-the-relevant-infoframe-field-when-scanning-o.patch b/patches.baytrail/0736-drm-Set-the-relevant-infoframe-field-when-scanning-o.patch new file mode 100644 index 000000000000..32dfce4b58da --- /dev/null +++ b/patches.baytrail/0736-drm-Set-the-relevant-infoframe-field-when-scanning-o.patch @@ -0,0 +1,96 @@ +From c3548aa81d870cadc6a9328acbccc4d2fb2c3005 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Wed, 25 Sep 2013 16:45:26 +0100 +Subject: drm: Set the relevant infoframe field when scanning out a 3D mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When scanning out a 3D mode on HDMI, we need to send an HDMI infoframe +with the corresponding layout to the sink. + +v2: Make s3d_structure_from_display_mode() less subtle (Ville Syrjälä) + +Reviewed-by: Ville Syrjälä +Signed-off-by: Damien Lespiau +Acked-by: Dave Airlie +Signed-off-by: Daniel Vetter +(cherry picked from commit 4eed4a0a4ac31830b4c328739cabb69721584bfc) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_edid.c | 40 ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 38 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 802daf1dfa60..61fdd6b532fc 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -3352,6 +3352,33 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, + } + EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode); + ++static enum hdmi_3d_structure ++s3d_structure_from_display_mode(const struct drm_display_mode *mode) ++{ ++ u32 layout = mode->flags & DRM_MODE_FLAG_3D_MASK; ++ ++ switch (layout) { ++ case DRM_MODE_FLAG_3D_FRAME_PACKING: ++ return HDMI_3D_STRUCTURE_FRAME_PACKING; ++ case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE: ++ return HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE; ++ case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE: ++ return HDMI_3D_STRUCTURE_LINE_ALTERNATIVE; ++ case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL: ++ return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL; ++ case DRM_MODE_FLAG_3D_L_DEPTH: ++ return HDMI_3D_STRUCTURE_L_DEPTH; ++ case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH: ++ return HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH; ++ case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM: ++ return HDMI_3D_STRUCTURE_TOP_AND_BOTTOM; ++ case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF: ++ return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF; ++ default: ++ return HDMI_3D_STRUCTURE_INVALID; ++ } ++} ++ + /** + * drm_hdmi_vendor_infoframe_from_display_mode() - fill an HDMI infoframe with + * data from a DRM display mode +@@ -3369,20 +3396,29 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, + const struct drm_display_mode *mode) + { + int err; ++ u32 s3d_flags; + u8 vic; + + if (!frame || !mode) + return -EINVAL; + + vic = drm_match_hdmi_mode(mode); +- if (!vic) ++ s3d_flags = mode->flags & DRM_MODE_FLAG_3D_MASK; ++ ++ if (!vic && !s3d_flags) ++ return -EINVAL; ++ ++ if (vic && s3d_flags) + return -EINVAL; + + err = hdmi_vendor_infoframe_init(frame); + if (err < 0) + return err; + +- frame->vic = vic; ++ if (vic) ++ frame->vic = vic; ++ else ++ frame->s3d_struct = s3d_structure_from_display_mode(mode); + + return 0; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0737-drm-i915-hdmi-Write-HDMI-vendor-specific-infoframes.patch b/patches.baytrail/0737-drm-i915-hdmi-Write-HDMI-vendor-specific-infoframes.patch new file mode 100644 index 000000000000..fc20f4a8588e --- /dev/null +++ b/patches.baytrail/0737-drm-i915-hdmi-Write-HDMI-vendor-specific-infoframes.patch @@ -0,0 +1,140 @@ +From 8c51d5617e620c11e9067180b810740b35905828 Mon Sep 17 00:00:00 2001 +From: "Lespiau, Damien" +Date: Mon, 19 Aug 2013 16:59:04 +0100 +Subject: drm/i915/hdmi: Write HDMI vendor specific infoframes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With all the common infoframe bits now in place, we can finally write +the vendor specific infoframes in our driver. + +Signed-off-by: Damien Lespiau +Reviewed-by: Ville Syrjälä +Reviewed-by: Thierry Reding +Signed-off-by: Dave Airlie +(cherry picked from commit c8bb75afff8eaed89476a00f733c666e1b44115b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 2 ++ + drivers/gpu/drm/i915/intel_hdmi.c | 28 ++++++++++++++++++++++++++++ + 2 files changed, 30 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 8e51ecf2a6f9..b6a58f720f9a 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -4168,6 +4168,8 @@ + _TRANSCODER(trans, HSW_VIDEO_DIP_CTL_A, HSW_VIDEO_DIP_CTL_B) + #define HSW_TVIDEO_DIP_AVI_DATA(trans) \ + _TRANSCODER(trans, HSW_VIDEO_DIP_AVI_DATA_A, HSW_VIDEO_DIP_AVI_DATA_B) ++#define HSW_TVIDEO_DIP_VS_DATA(trans) \ ++ _TRANSCODER(trans, HSW_VIDEO_DIP_VS_DATA_A, HSW_VIDEO_DIP_VS_DATA_B) + #define HSW_TVIDEO_DIP_SPD_DATA(trans) \ + _TRANSCODER(trans, HSW_VIDEO_DIP_SPD_DATA_A, HSW_VIDEO_DIP_SPD_DATA_B) + #define HSW_TVIDEO_DIP_GCP(trans) \ +diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c +index a619d9435107..4148cc85bf7f 100644 +--- a/drivers/gpu/drm/i915/intel_hdmi.c ++++ b/drivers/gpu/drm/i915/intel_hdmi.c +@@ -74,6 +74,8 @@ static u32 g4x_infoframe_index(enum hdmi_infoframe_type type) + return VIDEO_DIP_SELECT_AVI; + case HDMI_INFOFRAME_TYPE_SPD: + return VIDEO_DIP_SELECT_SPD; ++ case HDMI_INFOFRAME_TYPE_VENDOR: ++ return VIDEO_DIP_SELECT_VENDOR; + default: + DRM_DEBUG_DRIVER("unknown info frame type %d\n", type); + return 0; +@@ -87,6 +89,8 @@ static u32 g4x_infoframe_enable(enum hdmi_infoframe_type type) + return VIDEO_DIP_ENABLE_AVI; + case HDMI_INFOFRAME_TYPE_SPD: + return VIDEO_DIP_ENABLE_SPD; ++ case HDMI_INFOFRAME_TYPE_VENDOR: ++ return VIDEO_DIP_ENABLE_VENDOR; + default: + DRM_DEBUG_DRIVER("unknown info frame type %d\n", type); + return 0; +@@ -100,6 +104,8 @@ static u32 hsw_infoframe_enable(enum hdmi_infoframe_type type) + return VIDEO_DIP_ENABLE_AVI_HSW; + case HDMI_INFOFRAME_TYPE_SPD: + return VIDEO_DIP_ENABLE_SPD_HSW; ++ case HDMI_INFOFRAME_TYPE_VENDOR: ++ return VIDEO_DIP_ENABLE_VS_HSW; + default: + DRM_DEBUG_DRIVER("unknown info frame type %d\n", type); + return 0; +@@ -114,6 +120,8 @@ static u32 hsw_infoframe_data_reg(enum hdmi_infoframe_type type, + return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder); + case HDMI_INFOFRAME_TYPE_SPD: + return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder); ++ case HDMI_INFOFRAME_TYPE_VENDOR: ++ return HSW_TVIDEO_DIP_VS_DATA(cpu_transcoder); + default: + DRM_DEBUG_DRIVER("unknown info frame type %d\n", type); + return 0; +@@ -392,6 +400,21 @@ static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder) + intel_write_infoframe(encoder, &frame); + } + ++static void ++intel_hdmi_set_hdmi_infoframe(struct drm_encoder *encoder, ++ struct drm_display_mode *adjusted_mode) ++{ ++ union hdmi_infoframe frame; ++ int ret; ++ ++ ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi, ++ adjusted_mode); ++ if (ret < 0) ++ return; ++ ++ intel_write_infoframe(encoder, &frame); ++} ++ + static void g4x_set_infoframes(struct drm_encoder *encoder, + struct drm_display_mode *adjusted_mode) + { +@@ -454,6 +477,7 @@ static void g4x_set_infoframes(struct drm_encoder *encoder, + + intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); + intel_hdmi_set_spd_infoframe(encoder); ++ intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode); + } + + static void ibx_set_infoframes(struct drm_encoder *encoder, +@@ -515,6 +539,7 @@ static void ibx_set_infoframes(struct drm_encoder *encoder, + + intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); + intel_hdmi_set_spd_infoframe(encoder); ++ intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode); + } + + static void cpt_set_infoframes(struct drm_encoder *encoder, +@@ -550,6 +575,7 @@ static void cpt_set_infoframes(struct drm_encoder *encoder, + + intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); + intel_hdmi_set_spd_infoframe(encoder); ++ intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode); + } + + static void vlv_set_infoframes(struct drm_encoder *encoder, +@@ -584,6 +610,7 @@ static void vlv_set_infoframes(struct drm_encoder *encoder, + + intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); + intel_hdmi_set_spd_infoframe(encoder); ++ intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode); + } + + static void hsw_set_infoframes(struct drm_encoder *encoder, +@@ -611,6 +638,7 @@ static void hsw_set_infoframes(struct drm_encoder *encoder, + + intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); + intel_hdmi_set_spd_infoframe(encoder); ++ intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode); + } + + static void intel_hdmi_mode_set(struct intel_encoder *encoder) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0738-drm-Pass-page-flip-ioctl-flags-to-driver.patch b/patches.baytrail/0738-drm-Pass-page-flip-ioctl-flags-to-driver.patch new file mode 100644 index 000000000000..b5e8028b38e9 --- /dev/null +++ b/patches.baytrail/0738-drm-Pass-page-flip-ioctl-flags-to-driver.patch @@ -0,0 +1,304 @@ +From 32487c1ae57e369b4475b8581b3b754869786b2e Mon Sep 17 00:00:00 2001 +From: Keith Packard +Date: Mon, 22 Jul 2013 18:49:58 -0700 +Subject: drm: Pass page flip ioctl flags to driver + +This lets drivers see the flags requested by the application + +[airlied: fixup for rcar/imx/msm] + +Signed-off-by: Keith Packard +Signed-off-by: Dave Airlie +(cherry picked from commit ed8d19756e80ec63003a93aa4d70406e6ba61522) +Signed-off-by: James Ausmus + +Conflicts: + drivers/gpu/drm/msm/mdp4/mdp4_crtc.c + drivers/gpu/drm/rcar-du/rcar_du_crtc.c + (drivers don't exist in this tree) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_crtc.c | 2 +- + drivers/gpu/drm/exynos/exynos_drm_crtc.c | 5 +++-- + drivers/gpu/drm/i915/i915_drv.h | 3 ++- + drivers/gpu/drm/i915/intel_display.c | 23 +++++++++++++++-------- + drivers/gpu/drm/nouveau/nouveau_display.c | 3 ++- + drivers/gpu/drm/nouveau/nouveau_display.h | 3 ++- + drivers/gpu/drm/omapdrm/omap_crtc.c | 3 ++- + drivers/gpu/drm/radeon/radeon_display.c | 3 ++- + drivers/gpu/drm/shmobile/shmob_drm_crtc.c | 3 ++- + drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 3 ++- + drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 3 ++- + drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 3 ++- + drivers/staging/imx-drm/ipuv3-crtc.c | 3 ++- + include/drm/drm_crtc.h | 3 ++- + 14 files changed, 41 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c +index f4831510d38a..a014cb1ebcaf 100644 +--- a/drivers/gpu/drm/drm_crtc.c ++++ b/drivers/gpu/drm/drm_crtc.c +@@ -3521,7 +3521,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, + } + + old_fb = crtc->fb; +- ret = crtc->funcs->page_flip(crtc, fb, e); ++ ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags); + if (ret) { + if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { + spin_lock_irqsave(&dev->event_lock, flags); +diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c +index c200e4d71e3d..0b3dff8e69c1 100644 +--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c +@@ -197,8 +197,9 @@ static struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { + }; + + static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, +- struct drm_framebuffer *fb, +- struct drm_pending_vblank_event *event) ++ struct drm_framebuffer *fb, ++ struct drm_pending_vblank_event *event, ++ uint32_t page_flip_flags) + { + struct drm_device *dev = crtc->dev; + struct exynos_drm_private *dev_priv = dev->dev_private; +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 8ee15b471854..52a3785a3fdf 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -380,7 +380,8 @@ struct drm_i915_display_funcs { + void (*init_clock_gating)(struct drm_device *dev); + int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_i915_gem_object *obj); ++ struct drm_i915_gem_object *obj, ++ uint32_t flags); + int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb, + int x, int y); + void (*hpd_irq_setup)(struct drm_device *dev); +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 58da4ddc3e16..2ed6214010c6 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -7654,7 +7654,8 @@ inline static void intel_mark_page_flip_active(struct intel_crtc *intel_crtc) + static int intel_gen2_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_i915_gem_object *obj) ++ struct drm_i915_gem_object *obj, ++ uint32_t flags) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +@@ -7698,7 +7699,8 @@ err: + static int intel_gen3_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_i915_gem_object *obj) ++ struct drm_i915_gem_object *obj, ++ uint32_t flags) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +@@ -7739,7 +7741,8 @@ err: + static int intel_gen4_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_i915_gem_object *obj) ++ struct drm_i915_gem_object *obj, ++ uint32_t flags) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +@@ -7787,7 +7790,8 @@ err: + static int intel_gen6_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_i915_gem_object *obj) ++ struct drm_i915_gem_object *obj, ++ uint32_t flags) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +@@ -7837,7 +7841,8 @@ err: + static int intel_gen7_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_i915_gem_object *obj) ++ struct drm_i915_gem_object *obj, ++ uint32_t flags) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +@@ -7887,14 +7892,16 @@ err: + static int intel_default_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_i915_gem_object *obj) ++ struct drm_i915_gem_object *obj, ++ uint32_t flags) + { + return -ENODEV; + } + + static int intel_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_pending_vblank_event *event) ++ struct drm_pending_vblank_event *event, ++ uint32_t page_flip_flags) + { + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -7964,7 +7971,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, + atomic_inc(&intel_crtc->unpin_work_count); + intel_crtc->reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); + +- ret = dev_priv->display.queue_flip(dev, crtc, fb, obj); ++ ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, page_flip_flags); + if (ret) + goto cleanup_pending; + +diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c +index 05ae27277543..dbd5a2a12e09 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_display.c ++++ b/drivers/gpu/drm/nouveau/nouveau_display.c +@@ -554,7 +554,8 @@ fail: + + int + nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, +- struct drm_pending_vblank_event *event) ++ struct drm_pending_vblank_event *event, ++ uint32_t page_flip_flags) + { + struct drm_device *dev = crtc->dev; + struct nouveau_drm *drm = nouveau_drm(dev); +diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h +index 185e74132a6d..3238594855d3 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_display.h ++++ b/drivers/gpu/drm/nouveau/nouveau_display.h +@@ -60,7 +60,8 @@ int nouveau_display_suspend(struct drm_device *dev); + void nouveau_display_resume(struct drm_device *dev); + + int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, +- struct drm_pending_vblank_event *event); ++ struct drm_pending_vblank_event *event, ++ uint32_t page_flip_flags); + int nouveau_finish_page_flip(struct nouveau_channel *, + struct nouveau_page_flip_state *); + +diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c +index 79b200aee18a..09f6bd923456 100644 +--- a/drivers/gpu/drm/omapdrm/omap_crtc.c ++++ b/drivers/gpu/drm/omapdrm/omap_crtc.c +@@ -308,7 +308,8 @@ static void page_flip_cb(void *arg) + + static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_pending_vblank_event *event) ++ struct drm_pending_vblank_event *event, ++ uint32_t page_flip_flags) + { + struct drm_device *dev = crtc->dev; + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); +diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c +index eb18bb7af1cc..bb46f75c1a27 100644 +--- a/drivers/gpu/drm/radeon/radeon_display.c ++++ b/drivers/gpu/drm/radeon/radeon_display.c +@@ -339,7 +339,8 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) + + static int radeon_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_pending_vblank_event *event) ++ struct drm_pending_vblank_event *event, ++ uint32_t page_flip_flags) + { + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; +diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c +index 99e2034e49cc..54bad98e9477 100644 +--- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c ++++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c +@@ -465,7 +465,8 @@ void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc) + + static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_pending_vblank_event *event) ++ struct drm_pending_vblank_event *event, ++ uint32_t page_flip_flags) + { + struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc); + struct drm_device *dev = scrtc->crtc.dev; +diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +index 5dd3c7d031d5..274c4b64aebb 100644 +--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c ++++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +@@ -153,7 +153,8 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc) + + static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_pending_vblank_event *event) ++ struct drm_pending_vblank_event *event, ++ uint32_t page_flip_flags) + { + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); + struct drm_device *dev = crtc->dev; +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +index 3e3c7ab33ca2..5705179407c7 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +@@ -1705,7 +1705,8 @@ int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num, + + int vmw_du_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_pending_vblank_event *event) ++ struct drm_pending_vblank_event *event, ++ uint32_t page_flip_flags) + { + struct vmw_private *dev_priv = vmw_priv(crtc->dev); + struct drm_framebuffer *old_fb = crtc->fb; +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +index 6fa89c9d6214..8d038c36bd57 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +@@ -123,7 +123,8 @@ struct vmw_display_unit { + void vmw_display_unit_cleanup(struct vmw_display_unit *du); + int vmw_du_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_pending_vblank_event *event); ++ struct drm_pending_vblank_event *event, ++ uint32_t page_flip_flags); + void vmw_du_crtc_save(struct drm_crtc *crtc); + void vmw_du_crtc_restore(struct drm_crtc *crtc); + void vmw_du_crtc_gamma_set(struct drm_crtc *crtc, +diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c +index ff5c63350932..467c49cf9fc2 100644 +--- a/drivers/staging/imx-drm/ipuv3-crtc.c ++++ b/drivers/staging/imx-drm/ipuv3-crtc.c +@@ -134,7 +134,8 @@ static void ipu_crtc_dpms(struct drm_crtc *crtc, int mode) + + static int ipu_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_pending_vblank_event *event) ++ struct drm_pending_vblank_event *event, ++ uint32_t page_flip_flags) + { + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); + int ret; +diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h +index b228321549fa..7a2d68f946c6 100644 +--- a/include/drm/drm_crtc.h ++++ b/include/drm/drm_crtc.h +@@ -365,7 +365,8 @@ struct drm_crtc_funcs { + */ + int (*page_flip)(struct drm_crtc *crtc, + struct drm_framebuffer *fb, +- struct drm_pending_vblank_event *event); ++ struct drm_pending_vblank_event *event, ++ uint32_t flags); + + int (*set_property)(struct drm_crtc *crtc, + struct drm_property *property, uint64_t val); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0739-drm-implement-experimental-render-nodes.patch b/patches.baytrail/0739-drm-implement-experimental-render-nodes.patch new file mode 100644 index 000000000000..5d4dc7949d01 --- /dev/null +++ b/patches.baytrail/0739-drm-implement-experimental-render-nodes.patch @@ -0,0 +1,408 @@ +From cf6d66e6543ba38ff6d62af743b1f0155ddb15f9 Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Sun, 25 Aug 2013 18:29:00 +0200 +Subject: drm: implement experimental render nodes + +Render nodes provide an API for userspace to use non-privileged GPU +commands without any running DRM-Master. It is useful for offscreen +rendering, GPGPU clients, and normal render clients which do not perform +modesetting. + +Compared to legacy clients, render clients no longer need any +authentication to perform client ioctls. Instead, user-space controls +render/client access to GPUs via filesystem access-modes on the +render-node. Once a render-node was opened, a client has full access to +the client/render operations on the GPU. However, no modesetting or ioctls +that affect global state are allowed on render nodes. + +To prevent privilege-escalation, drivers must explicitly state that they +support render nodes. They must mark their render-only ioctls as +DRM_RENDER_ALLOW so render clients can use them. Furthermore, they must +support clients without any attached master. + +If filesystem access-modes are not enough for fine-grained access control +to render nodes (very unlikely, considering the versaitlity of FS-ACLs), +you may still fall-back to fd-passing from server to client (which allows +arbitrary access-control). However, note that revoking access is +currently impossible and unlikely to get implemented. + +Note: Render clients no longer have any associated DRM-Master as they are +supposed to be independent of any server state. DRM core highly depends on +file_priv->master to be non-NULL for modesetting/ctx/etc. commands. +Therefore, drivers must be very careful to not require DRM-Master if they +support DRIVER_RENDER. + +So far render-nodes are protected by "drm_rnodes". As long as this +module-parameter is not set to 1, a driver will not create render nodes. +This allows us to experiment with the API a bit before we stabilize it. + +v2: drop insecure GEM_FLINK to force use of dmabuf + +Signed-off-by: David Herrmann +Signed-off-by: Dave Airlie +(cherry picked from commit 1793126fcebd7c18834f95d43b55e387a8803aa8) +Signed-off-by: Darren Hart +--- + Documentation/DocBook/drm.tmpl | 69 ++++++++++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/drm_drv.c | 13 ++++---- + drivers/gpu/drm/drm_fops.c | 14 ++++----- + drivers/gpu/drm/drm_pci.c | 9 ++++++ + drivers/gpu/drm/drm_platform.c | 9 ++++++ + drivers/gpu/drm/drm_stub.c | 10 ++++++ + drivers/gpu/drm/drm_usb.c | 9 ++++++ + include/drm/drmP.h | 9 ++++++ + 8 files changed, 129 insertions(+), 13 deletions(-) + +diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl +index da1e28263002..d31fafbed4dc 100644 +--- a/Documentation/DocBook/drm.tmpl ++++ b/Documentation/DocBook/drm.tmpl +@@ -233,6 +233,12 @@ + Driver implements DRM PRIME buffer sharing. + + ++ ++ DRIVER_RENDER ++ ++ Driver supports dedicated render nodes. ++ ++ + + + +@@ -2497,6 +2503,69 @@ int (*resume) (struct drm_device *); + info, since man pages should cover the rest. + + ++ ++ ++ ++ Render nodes ++ ++ DRM core provides multiple character-devices for user-space to use. ++ Depending on which device is opened, user-space can perform a different ++ set of operations (mainly ioctls). The primary node is always created ++ and called card<num>. Additionally, a currently ++ unused control node, called controlD<num> is also ++ created. The primary node provides all legacy operations and ++ historically was the only interface used by userspace. With KMS, the ++ control node was introduced. However, the planned KMS control interface ++ has never been written and so the control node stays unused to date. ++ ++ ++ With the increased use of offscreen renderers and GPGPU applications, ++ clients no longer require running compositors or graphics servers to ++ make use of a GPU. But the DRM API required unprivileged clients to ++ authenticate to a DRM-Master prior to getting GPU access. To avoid this ++ step and to grant clients GPU access without authenticating, render ++ nodes were introduced. Render nodes solely serve render clients, that ++ is, no modesetting or privileged ioctls can be issued on render nodes. ++ Only non-global rendering commands are allowed. If a driver supports ++ render nodes, it must advertise it via the DRIVER_RENDER ++ DRM driver capability. If not supported, the primary node must be used ++ for render clients together with the legacy drmAuth authentication ++ procedure. ++ ++ ++ If a driver advertises render node support, DRM core will create a ++ separate render node called renderD<num>. There will ++ be one render node per device. No ioctls except PRIME-related ioctls ++ will be allowed on this node. Especially GEM_OPEN will be ++ explicitly prohibited. Render nodes are designed to avoid the ++ buffer-leaks, which occur if clients guess the flink names or mmap ++ offsets on the legacy interface. Additionally to this basic interface, ++ drivers must mark their driver-dependent render-only ioctls as ++ DRM_RENDER_ALLOW so render clients can use them. Driver ++ authors must be careful not to allow any privileged ioctls on render ++ nodes. ++ ++ ++ With render nodes, user-space can now control access to the render node ++ via basic file-system access-modes. A running graphics server which ++ authenticates clients on the privileged primary/legacy node is no longer ++ required. Instead, a client can open the render node and is immediately ++ granted GPU access. Communication between clients (or servers) is done ++ via PRIME. FLINK from render node to legacy node is not supported. New ++ clients must not use the insecure FLINK interface. ++ ++ ++ Besides dropping all modeset/global ioctls, render nodes also drop the ++ DRM-Master concept. There is no reason to associate render clients with ++ a DRM-Master as they are independent of any graphics server. Besides, ++ they must work without any running master, anyway. ++ Drivers must be able to run without a master object if they support ++ render nodes. If, on the other hand, a driver requires shared state ++ between clients which is visible to user-space and accessible beyond ++ open-file boundaries, they cannot support render nodes. ++ ++ ++ + + + +diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c +index 2994cd7513e9..b1f0a0bf77cb 100644 +--- a/drivers/gpu/drm/drm_drv.c ++++ b/drivers/gpu/drm/drm_drv.c +@@ -68,7 +68,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = { + DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED), +- DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED), ++ DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), + + DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), +@@ -131,14 +131,14 @@ static const struct drm_ioctl_desc drm_ioctls[] = { + + DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + +- DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED), ++ DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), + + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED), + +- DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED), +- DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED), ++ DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED), +@@ -415,9 +415,10 @@ long drm_ioctl(struct file *filp, + DRM_DEBUG("no function\n"); + retcode = -EINVAL; + } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) || +- ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) || ++ ((ioctl->flags & DRM_AUTH) && !drm_is_render_client(file_priv) && !file_priv->authenticated) || + ((ioctl->flags & DRM_MASTER) && !file_priv->is_master) || +- (!(ioctl->flags & DRM_CONTROL_ALLOW) && (file_priv->minor->type == DRM_MINOR_CONTROL))) { ++ (!(ioctl->flags & DRM_CONTROL_ALLOW) && (file_priv->minor->type == DRM_MINOR_CONTROL)) || ++ (!(ioctl->flags & DRM_RENDER_ALLOW) && drm_is_render_client(file_priv))) { + retcode = -EACCES; + } else { + if (cmd & (IOC_IN | IOC_OUT)) { +diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c +index 88e80c37f568..a4e4f32ec1e3 100644 +--- a/drivers/gpu/drm/drm_fops.c ++++ b/drivers/gpu/drm/drm_fops.c +@@ -283,10 +283,10 @@ static int drm_open_helper(struct inode *inode, struct file *filp, + goto out_free; + } + +- +- /* if there is no current master make this fd it */ ++ /* if there is no current master make this fd it, but do not create ++ * any master object for render clients */ + mutex_lock(&dev->struct_mutex); +- if (!priv->minor->master) { ++ if (!priv->minor->master && !drm_is_render_client(priv)) { + /* create a new master */ + priv->minor->master = drm_master_create(priv->minor); + if (!priv->minor->master) { +@@ -324,12 +324,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp, + goto out_free; + } + } +- mutex_unlock(&dev->struct_mutex); +- } else { ++ } else if (!drm_is_render_client(priv)) { + /* get a reference to the master */ + priv->master = drm_master_get(priv->minor->master); +- mutex_unlock(&dev->struct_mutex); + } ++ mutex_unlock(&dev->struct_mutex); + + mutex_lock(&dev->struct_mutex); + list_add(&priv->lhead, &dev->filelist); +@@ -508,7 +507,8 @@ int drm_release(struct inode *inode, struct file *filp) + iput(container_of(dev->dev_mapping, struct inode, i_data)); + + /* drop the reference held my the file priv */ +- drm_master_put(&file_priv->master); ++ if (file_priv->master) ++ drm_master_put(&file_priv->master); + file_priv->is_master = 0; + list_del(&file_priv->lhead); + mutex_unlock(&dev->struct_mutex); +diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c +index 83fb3dba1b25..564075586a60 100644 +--- a/drivers/gpu/drm/drm_pci.c ++++ b/drivers/gpu/drm/drm_pci.c +@@ -358,6 +358,12 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, + goto err_g2; + } + ++ if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) { ++ ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER); ++ if (ret) ++ goto err_g21; ++ } ++ + if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) + goto err_g3; + +@@ -387,6 +393,9 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, + err_g4: + drm_put_minor(&dev->primary); + err_g3: ++ if (dev->render) ++ drm_put_minor(&dev->render); ++err_g21: + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_put_minor(&dev->control); + err_g2: +diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c +index b8a282ea8751..53ae674dee85 100644 +--- a/drivers/gpu/drm/drm_platform.c ++++ b/drivers/gpu/drm/drm_platform.c +@@ -69,6 +69,12 @@ int drm_get_platform_dev(struct platform_device *platdev, + goto err_g1; + } + ++ if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) { ++ ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER); ++ if (ret) ++ goto err_g11; ++ } ++ + ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); + if (ret) + goto err_g2; +@@ -100,6 +106,9 @@ int drm_get_platform_dev(struct platform_device *platdev, + err_g3: + drm_put_minor(&dev->primary); + err_g2: ++ if (dev->render) ++ drm_put_minor(&dev->render); ++err_g11: + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_put_minor(&dev->control); + err_g1: +diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c +index 31442a45dae0..d9c90b11e443 100644 +--- a/drivers/gpu/drm/drm_stub.c ++++ b/drivers/gpu/drm/drm_stub.c +@@ -40,6 +40,9 @@ + unsigned int drm_debug = 0; /* 1 to enable debug output */ + EXPORT_SYMBOL(drm_debug); + ++unsigned int drm_rnodes = 0; /* 1 to enable experimental render nodes API */ ++EXPORT_SYMBOL(drm_rnodes); ++ + unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ + EXPORT_SYMBOL(drm_vblank_offdelay); + +@@ -56,11 +59,13 @@ MODULE_AUTHOR(CORE_AUTHOR); + MODULE_DESCRIPTION(CORE_DESC); + MODULE_LICENSE("GPL and additional rights"); + MODULE_PARM_DESC(debug, "Enable debug output"); ++MODULE_PARM_DESC(rnodes, "Enable experimental render nodes API"); + MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs]"); + MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]"); + MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps"); + + module_param_named(debug, drm_debug, int, 0600); ++module_param_named(rnodes, drm_rnodes, int, 0600); + module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600); + module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); + module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); +@@ -468,6 +473,9 @@ void drm_put_dev(struct drm_device *dev) + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_put_minor(&dev->control); + ++ if (dev->render) ++ drm_put_minor(&dev->render); ++ + if (driver->driver_features & DRIVER_GEM) + drm_gem_destroy(dev); + +@@ -484,6 +492,8 @@ void drm_unplug_dev(struct drm_device *dev) + /* for a USB device */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_unplug_minor(dev->control); ++ if (dev->render) ++ drm_unplug_minor(dev->render); + drm_unplug_minor(dev->primary); + + mutex_lock(&drm_global_mutex); +diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c +index 34a156f0c336..87664723b9ce 100644 +--- a/drivers/gpu/drm/drm_usb.c ++++ b/drivers/gpu/drm/drm_usb.c +@@ -33,6 +33,12 @@ int drm_get_usb_dev(struct usb_interface *interface, + if (ret) + goto err_g1; + ++ if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) { ++ ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER); ++ if (ret) ++ goto err_g11; ++ } ++ + ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); + if (ret) + goto err_g2; +@@ -62,6 +68,9 @@ int drm_get_usb_dev(struct usb_interface *interface, + err_g3: + drm_put_minor(&dev->primary); + err_g2: ++ if (dev->render) ++ drm_put_minor(&dev->render); ++err_g11: + drm_put_minor(&dev->control); + err_g1: + kfree(dev); +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index f65eaddd4844..adb4c330b086 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -150,6 +150,7 @@ int drm_err(const char *func, const char *format, ...); + #define DRIVER_GEM 0x1000 + #define DRIVER_MODESET 0x2000 + #define DRIVER_PRIME 0x4000 ++#define DRIVER_RENDER 0x8000 + + #define DRIVER_BUS_PCI 0x1 + #define DRIVER_BUS_PLATFORM 0x2 +@@ -304,6 +305,7 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, + #define DRM_ROOT_ONLY 0x4 + #define DRM_CONTROL_ALLOW 0x8 + #define DRM_UNLOCKED 0x10 ++#define DRM_RENDER_ALLOW 0x20 + + struct drm_ioctl_desc { + unsigned int cmd; +@@ -1189,6 +1191,7 @@ struct drm_device { + unsigned int agp_buffer_token; + struct drm_minor *control; /**< Control node for card */ + struct drm_minor *primary; /**< render type primary screen head */ ++ struct drm_minor *render; /**< render node for card */ + + struct drm_mode_config mode_config; /**< Current mode config */ + +@@ -1235,6 +1238,11 @@ static inline bool drm_modeset_is_locked(struct drm_device *dev) + return mutex_is_locked(&dev->mode_config.mutex); + } + ++static inline bool drm_is_render_client(struct drm_file *file_priv) ++{ ++ return file_priv->minor->type == DRM_MINOR_RENDER; ++} ++ + /******************************************************************/ + /** \name Internal function definitions */ + /*@{*/ +@@ -1435,6 +1443,7 @@ extern void drm_put_dev(struct drm_device *dev); + extern int drm_put_minor(struct drm_minor **minor); + extern void drm_unplug_dev(struct drm_device *dev); + extern unsigned int drm_debug; ++extern unsigned int drm_rnodes; + + extern unsigned int drm_vblank_offdelay; + extern unsigned int drm_timestamp_precision; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0740-drm-i915-Support-render-nodes.patch b/patches.baytrail/0740-drm-i915-Support-render-nodes.patch new file mode 100644 index 000000000000..fd739e4f4bcd --- /dev/null +++ b/patches.baytrail/0740-drm-i915-Support-render-nodes.patch @@ -0,0 +1,110 @@ +From d9594201b0019c6fee90ceb4eabcc05977ca1f5d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= +Date: Sun, 25 Aug 2013 18:29:01 +0200 +Subject: drm/i915: Support render nodes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Enable support for drm render nodes for i915 by flagging the ioctls that +are safe and just needed for rendering. + +v2: mark reg_read, set_caching and get_caching (ickle, danvet) + +Signed-off-by: Kristian Høgsberg +Signed-off-by: David Herrmann +Reviewed-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit 10ba50129ab0bdbc0ee712e50913d1c8db88c5f0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 42 ++++++++++++++++++++--------------------- + drivers/gpu/drm/i915/i915_drv.c | 3 ++- + 2 files changed, 23 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 3e4e6073d171..fdaa0915ce56 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1866,7 +1866,7 @@ const struct drm_ioctl_desc i915_ioctls[] = { + DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), +- DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH), ++ DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH), +@@ -1879,35 +1879,35 @@ const struct drm_ioctl_desc i915_ioctls[] = { + DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED), ++ DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_SET_CACHING, i915_gem_set_caching_ioctl, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_GET_CACHING, i915_gem_get_caching_ioctl, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED), ++ DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_SET_CACHING, i915_gem_set_caching_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_GET_CACHING, i915_gem_get_caching_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED), ++ DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), ++ DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, intel_sprite_get_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_UNLOCKED), +- DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_UNLOCKED), ++ DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + }; + + int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 735dd5625e9e..ccb28ead3501 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -1022,7 +1022,8 @@ static struct drm_driver driver = { + */ + .driver_features = + DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | +- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME, ++ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME | ++ DRIVER_RENDER, + .load = i915_driver_load, + .unload = i915_driver_unload, + .open = i915_driver_open, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0741-drm-i915-Don-t-mask-EI-UP-interrupt-on-IVB-SNB.patch b/patches.baytrail/0741-drm-i915-Don-t-mask-EI-UP-interrupt-on-IVB-SNB.patch new file mode 100644 index 000000000000..aded221e6da9 --- /dev/null +++ b/patches.baytrail/0741-drm-i915-Don-t-mask-EI-UP-interrupt-on-IVB-SNB.patch @@ -0,0 +1,72 @@ +From 174fb53dddc9f0348751ce4f2022b0c9b24d5e5d Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Thu, 22 Aug 2013 21:09:00 +0300 +Subject: drm/i915: Don't mask EI UP interrupt on IVB|SNB + +Submitting a batchbuffer which simulates a gpu +hang by doing MI_BATCH_BUFFER_START into itself, +to test hangcheck, started to hard hang the whole box +(IVB). Bisecting lead to this commit: + +commit 664b422c2966cd39b8f67e8d53a566ea8c877cd6 +Author: Vinit Azad +Date: Wed Aug 14 13:34:33 2013 -0700 + + drm/i915: Only unmask required PM interrupts + +Experimenting with the mask register showed that +unmasking EI UP will prevent the hard hang in IVB and SNB. +HSW doesn't hang with EI UP masked. + +Considering we are just disabling interrupts that aren't even +delivered to driver, this change is more likely to paper over some +weirdness in gpu's internal state machine. But until better +explanation can be found, let's trade little bit of power +for stability on these architectures. + +v2: - Unmask EI_EXPIRED directly in I915_WRITE (Vinit) +v3: - Only unmask on SNB and IVB + +Cc: Vinit Azad +Signed-off-by: Mika Kuoppala +Acked-by: Vinit Azad +Signed-off-by: Daniel Vetter +(cherry picked from commit a9c1f90c8e1792127f8348c1cc2565b79b2ef20a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_pm.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 46056820d1d2..6b1d00389952 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -3447,14 +3447,24 @@ int intel_enable_rc6(const struct drm_device *dev) + static void gen6_enable_rps_interrupts(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; ++ u32 enabled_intrs; + + spin_lock_irq(&dev_priv->irq_lock); + WARN_ON(dev_priv->rps.pm_iir); + snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS); + I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); + spin_unlock_irq(&dev_priv->irq_lock); ++ + /* only unmask PM interrupts we need. Mask all others. */ +- I915_WRITE(GEN6_PMINTRMSK, ~GEN6_PM_RPS_EVENTS); ++ enabled_intrs = GEN6_PM_RPS_EVENTS; ++ ++ /* IVB and SNB hard hangs on looping batchbuffer ++ * if GEN6_PM_UP_EI_EXPIRED is masked. ++ */ ++ if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) ++ enabled_intrs |= GEN6_PM_RP_UP_EI_EXPIRED; ++ ++ I915_WRITE(GEN6_PMINTRMSK, ~enabled_intrs); + } + + static void gen6_enable_rps(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0742-drm-i915-sanitize-forcewake-registers-on-reset.patch b/patches.baytrail/0742-drm-i915-sanitize-forcewake-registers-on-reset.patch new file mode 100644 index 000000000000..5f7c182e709c --- /dev/null +++ b/patches.baytrail/0742-drm-i915-sanitize-forcewake-registers-on-reset.patch @@ -0,0 +1,60 @@ +From 8a90bc85114de48f9ac89480394179a6397ff7b4 Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala +Date: Fri, 23 Aug 2013 16:52:30 +0300 +Subject: drm/i915: sanitize forcewake registers on reset + +In reset we try to restore the forcewake state to +pre reset state, using forcewake_count. The reset +doesn't seem to clear the forcewake bits so we +get warn on forcewake ack register not clearing. + +Use same mechanism as intel_uncore_sanitize() does +when loading driver to reset the forcewake bits, right +after the chip has been reset. + +Reviewed-by: Chris Wilson +Signed-off-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit 521198a2e7095c8c7daa8d7d3a76a110c346be6f) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_uncore.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c +index 8f5bc869c023..8649f1c36b00 100644 +--- a/drivers/gpu/drm/i915/intel_uncore.c ++++ b/drivers/gpu/drm/i915/intel_uncore.c +@@ -261,7 +261,7 @@ void intel_uncore_init(struct drm_device *dev) + } + } + +-void intel_uncore_sanitize(struct drm_device *dev) ++static void intel_uncore_forcewake_reset(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + +@@ -272,6 +272,11 @@ void intel_uncore_sanitize(struct drm_device *dev) + if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) + __gen6_gt_force_wake_mt_reset(dev_priv); + } ++} ++ ++void intel_uncore_sanitize(struct drm_device *dev) ++{ ++ intel_uncore_forcewake_reset(dev); + + /* BIOS often leaves RC6 enabled, but disable it for hw init */ + intel_disable_gt_powersave(dev); +@@ -549,6 +554,8 @@ static int gen6_do_reset(struct drm_device *dev) + /* Spin waiting for the device to ack the reset request */ + ret = wait_for((__raw_i915_read32(dev_priv, GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); + ++ intel_uncore_forcewake_reset(dev); ++ + /* If reset with a user forcewake, try to restore, otherwise turn it off */ + if (dev_priv->uncore.forcewake_count) + dev_priv->uncore.funcs.force_wake_get(dev_priv); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0743-drm-i915-Adjust-available-RPS-information-through-sy.patch b/patches.baytrail/0743-drm-i915-Adjust-available-RPS-information-through-sy.patch new file mode 100644 index 000000000000..3c18f7df9e5e --- /dev/null +++ b/patches.baytrail/0743-drm-i915-Adjust-available-RPS-information-through-sy.patch @@ -0,0 +1,98 @@ +From d288060e0119bb349ee3590833de9d0a9ba0a121 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 26 Aug 2013 16:18:54 +0100 +Subject: drm/i915: Adjust available RPS information through sysfs for vlv + +Valleyview has its own render power state implementation with different +capability knobs - it has no RP0,RP1,RPn but rather RPe. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67734 +Signed-off-by: Chris Wilson +Tested-by: kobe.qin@intel.com +Reviewed-by: Jani Nikula +Signed-off-by: Daniel Vetter +(cherry picked from commit 97e4eed7dc532e20208b0bdf7ad1136569da2f35) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_sysfs.c | 36 +++++++++++++++++++++++++++++++----- + 1 file changed, 31 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c +index a777e7f3b0df..c8c4112de110 100644 +--- a/drivers/gpu/drm/i915/i915_sysfs.c ++++ b/drivers/gpu/drm/i915/i915_sysfs.c +@@ -224,6 +224,18 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev, + return snprintf(buf, PAGE_SIZE, "%d\n", ret); + } + ++static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev); ++ struct drm_device *dev = minor->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ return snprintf(buf, PAGE_SIZE, "%d\n", ++ vlv_gpu_freq(dev_priv->mem_freq, ++ dev_priv->rps.rpe_delay)); ++} ++ + static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) + { + struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev); +@@ -366,6 +378,7 @@ static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL); + static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, gt_max_freq_mhz_store); + static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, gt_min_freq_mhz_store); + ++static DEVICE_ATTR(vlv_rpe_freq_mhz, S_IRUGO, vlv_rpe_freq_mhz_show, NULL); + + static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf); + static DEVICE_ATTR(gt_RP0_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL); +@@ -409,6 +422,14 @@ static const struct attribute *gen6_attrs[] = { + NULL, + }; + ++static const struct attribute *vlv_attrs[] = { ++ &dev_attr_gt_cur_freq_mhz.attr, ++ &dev_attr_gt_max_freq_mhz.attr, ++ &dev_attr_gt_min_freq_mhz.attr, ++ &dev_attr_vlv_rpe_freq_mhz.attr, ++ NULL, ++}; ++ + static ssize_t error_state_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +@@ -492,11 +513,13 @@ void i915_setup_sysfs(struct drm_device *dev) + DRM_ERROR("l3 parity sysfs setup failed\n"); + } + +- if (INTEL_INFO(dev)->gen >= 6) { ++ ret = 0; ++ if (IS_VALLEYVIEW(dev)) ++ ret = sysfs_create_files(&dev->primary->kdev.kobj, vlv_attrs); ++ else if (INTEL_INFO(dev)->gen >= 6) + ret = sysfs_create_files(&dev->primary->kdev.kobj, gen6_attrs); +- if (ret) +- DRM_ERROR("gen6 sysfs setup failed\n"); +- } ++ if (ret) ++ DRM_ERROR("RPS sysfs setup failed\n"); + + ret = sysfs_create_bin_file(&dev->primary->kdev.kobj, + &error_state_attr); +@@ -507,7 +530,10 @@ void i915_setup_sysfs(struct drm_device *dev) + void i915_teardown_sysfs(struct drm_device *dev) + { + sysfs_remove_bin_file(&dev->primary->kdev.kobj, &error_state_attr); +- sysfs_remove_files(&dev->primary->kdev.kobj, gen6_attrs); ++ if (IS_VALLEYVIEW(dev)) ++ sysfs_remove_files(&dev->primary->kdev.kobj, vlv_attrs); ++ else ++ sysfs_remove_files(&dev->primary->kdev.kobj, gen6_attrs); + device_remove_bin_file(&dev->primary->kdev, &dpf_attrs); + #ifdef CONFIG_PM + sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0744-drm-i915-Apply-the-force-detect-VGA-w-a-to-Valleyvie.patch b/patches.baytrail/0744-drm-i915-Apply-the-force-detect-VGA-w-a-to-Valleyvie.patch new file mode 100644 index 000000000000..fbbbeca70cf5 --- /dev/null +++ b/patches.baytrail/0744-drm-i915-Apply-the-force-detect-VGA-w-a-to-Valleyvie.patch @@ -0,0 +1,38 @@ +From 42ec6e38ed7569d4ba3bcd99e2b8897addbefcb9 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 26 Aug 2013 19:51:06 -0300 +Subject: drm/i915: Apply the force-detect VGA w/a to Valleyview + +It appears that Valleyview shares its VGA encoder with more recent +siblings and requires the same forced detection cycle after a hardware +reset before we can rely on hotplugging. + +Reported-and-tested-by: kobeqin +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67733 +Tested-by: kobeqin +Signed-off-by: Chris Wilson +[danvet: Check for gen >= 5 insted, acked by Chris.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 10603caacf599297c7da0c4f4db440d015b8131a) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_crt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c +index b5a3875f22c7..ea9022ef15d5 100644 +--- a/drivers/gpu/drm/i915/intel_crt.c ++++ b/drivers/gpu/drm/i915/intel_crt.c +@@ -688,7 +688,7 @@ static void intel_crt_reset(struct drm_connector *connector) + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crt *crt = intel_attached_crt(connector); + +- if (HAS_PCH_SPLIT(dev)) { ++ if (INTEL_INFO(dev)->gen >= 5) { + u32 adpa; + + adpa = I915_READ(crt->adpa_reg); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0745-drm-i915-Report-requested-frequency-alongside-curren.patch b/patches.baytrail/0745-drm-i915-Report-requested-frequency-alongside-curren.patch new file mode 100644 index 000000000000..09cc4c02e1a3 --- /dev/null +++ b/patches.baytrail/0745-drm-i915-Report-requested-frequency-alongside-curren.patch @@ -0,0 +1,57 @@ +From c14d45427f665322a45ba6ca9f1cd414b2cc6932 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 26 Aug 2013 19:51:01 -0300 +Subject: drm/i915: Report requested frequency alongside current frequency in + debugfs + +It can be useful to compare at times the current vs requested frequency +of the GPU, so provide the contents of RPNSWREQ alonside CAGF. + +Signed-off-by: Chris Wilson +Reviewed-by: Rodrigo Vivi +Signed-off-by: Daniel Vetter +(cherry picked from commit 8e8c06cd34dbd68d36b0c561b8850478ddc5fb84) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_debugfs.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 55ab9246e1b9..a6f4cb5af185 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -857,7 +857,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) + u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); + u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS); + u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); +- u32 rpstat, cagf; ++ u32 rpstat, cagf, reqf; + u32 rpupei, rpcurup, rpprevup; + u32 rpdownei, rpcurdown, rpprevdown; + int max_freq; +@@ -869,6 +869,14 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) + + gen6_gt_force_wake_get(dev_priv); + ++ reqf = I915_READ(GEN6_RPNSWREQ); ++ reqf &= ~GEN6_TURBO_DISABLE; ++ if (IS_HASWELL(dev)) ++ reqf >>= 24; ++ else ++ reqf >>= 25; ++ reqf *= GT_FREQUENCY_MULTIPLIER; ++ + rpstat = I915_READ(GEN6_RPSTAT1); + rpupei = I915_READ(GEN6_RP_CUR_UP_EI); + rpcurup = I915_READ(GEN6_RP_CUR_UP); +@@ -893,6 +901,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) + gt_perf_status & 0xff); + seq_printf(m, "Render p-state limit: %d\n", + rp_state_limits & 0xff); ++ seq_printf(m, "RPNSWREQ: %dMHz\n", reqf); + seq_printf(m, "CAGF: %dMHz\n", cagf); + seq_printf(m, "RP CUR UP EI: %dus\n", rpupei & + GEN6_CURICONT_MASK); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0746-drm-i915-tune-down-hangcheck-noise.patch b/patches.baytrail/0746-drm-i915-tune-down-hangcheck-noise.patch new file mode 100644 index 000000000000..761d7566d6f2 --- /dev/null +++ b/patches.baytrail/0746-drm-i915-tune-down-hangcheck-noise.patch @@ -0,0 +1,45 @@ +From e734e113b6e30ba4c48c1a52a31ebda26aa4ae30 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 28 Aug 2013 10:57:59 +0200 +Subject: drm/i915: tune down hangcheck noise + +We already have a big splashing *ERROR* for all the relevant cases of +hangs, so this one here is redudant. And it results in an unclean +dmesg when running with simulated hangs. Regression has been +introduced in + +commit 05407ff889ceebe383aa5907219f86582ef96b72 +Author: Mika Kuoppala +Date: Thu May 30 09:04:29 2013 +0300 + + drm/i915: detect hang using per ring hangcheck_score + +Cc: Mika Kuoppala +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68641 +Signed-off-by: Daniel Vetter +(cherry picked from commit b8d88d1d40c18d42e3fedc289832e28d14bc1f00) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_irq.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 0eac036fb833..4c137d6ea761 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -2073,9 +2073,9 @@ static void i915_hangcheck_elapsed(unsigned long data) + + for_each_ring(ring, dev_priv, i) { + if (ring->hangcheck.score > FIRE) { +- DRM_ERROR("%s on %s\n", +- stuck[i] ? "stuck" : "no progress", +- ring->name); ++ DRM_INFO("%s on %s\n", ++ stuck[i] ? "stuck" : "no progress", ++ ring->name); + rings_hung++; + } + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0747-drm-i915-fix-lvds-dp-panel-fitter-setting.patch b/patches.baytrail/0747-drm-i915-fix-lvds-dp-panel-fitter-setting.patch new file mode 100644 index 000000000000..f46298890b8e --- /dev/null +++ b/patches.baytrail/0747-drm-i915-fix-lvds-dp-panel-fitter-setting.patch @@ -0,0 +1,53 @@ +From f778f35845f34a99bce7fedab0cfd8dedc3728fa Mon Sep 17 00:00:00 2001 +From: Imre Deak +Date: Tue, 27 Aug 2013 12:24:09 +0300 +Subject: drm/i915: fix lvds/dp panel fitter setting + +If need to enable the panel fitter, the crtc timings have to be +programmed according to the panel's native (fixed) mode. This isn't the +case atm, since after the encoder changes adjusted_mode to fixed +mode the crtc_* timing fields of adjusted_mode will stay at their original +non-native values that the user passed in. This results in a corrupted +output. + +One exception is when we have a second pass of computing encoder configs +due to bandwidth limitation, since then we'll set adjusted_mode.crtc_* +fields to the fixed mode values set in the first pass; so in this case +things will work out. + +Fix this by updating the adjusted_mode.crtc_* fields when we set the +fixed panel mode. + +This regression has been introduced in + +commit 135c81b8c3c9a70d7b55758c9c2a247a4abb7b64 +Author: Daniel Vetter +Date: Sun Jul 21 21:37:09 2013 +0200 + + drm/i915: clean up crtc timings computation + +Signed-off-by: Imre Deak +Reviewed-by: Mika Kuoppala +Signed-off-by: Daniel Vetter +(cherry picked from commit a52690e445637dda7f71878965d64d9b6a15a2b7) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_panel.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index a43c33bc4a35..913cb9d7fd32 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -50,6 +50,8 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, + adjusted_mode->vtotal = fixed_mode->vtotal; + + adjusted_mode->clock = fixed_mode->clock; ++ ++ drm_mode_set_crtcinfo(adjusted_mode, 0); + } + + /* adjusted_mode has been preset to be the panel's fixed mode */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0748-drm-i915-Embed-the-ring-private-within-the-struct-in.patch b/patches.baytrail/0748-drm-i915-Embed-the-ring-private-within-the-struct-in.patch new file mode 100644 index 000000000000..fce3fd8f0e1d --- /dev/null +++ b/patches.baytrail/0748-drm-i915-Embed-the-ring-private-within-the-struct-in.patch @@ -0,0 +1,275 @@ +From 2320eff2d3605eb807173d17c6877f2c615911b2 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 26 Aug 2013 20:58:11 +0100 +Subject: drm/i915: Embed the ring->private within the struct intel_ring_buffer + +We now have more devices using ring->private than not, and they all want +the same structure. Worse, I would like to use a scratch page from +outside of intel_ringbuffer.c and so for convenience would like to reuse +ring->private. Embed the object into the struct intel_ringbuffer so that +we can keep the code clean. + +Signed-off-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit 0d1aacac36530fce058d7a0db3da7befd5765417) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- + drivers/gpu/drm/i915/intel_ringbuffer.c | 99 ++++++++++----------------------- + drivers/gpu/drm/i915/intel_ringbuffer.h | 6 +- + 3 files changed, 35 insertions(+), 72 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c +index 558e568d5b45..aba9d7498996 100644 +--- a/drivers/gpu/drm/i915/i915_gpu_error.c ++++ b/drivers/gpu/drm/i915/i915_gpu_error.c +@@ -641,7 +641,7 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, + if (WARN_ON(ring->id != RCS)) + return NULL; + +- obj = ring->private; ++ obj = ring->scratch.obj; + if (acthd >= i915_gem_obj_ggtt_offset(obj) && + acthd < i915_gem_obj_ggtt_offset(obj) + obj->base.size) + return i915_error_object_create(dev_priv, obj); +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index f05cceac5a52..460ee1026fca 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -33,16 +33,6 @@ + #include "i915_trace.h" + #include "intel_drv.h" + +-/* +- * 965+ support PIPE_CONTROL commands, which provide finer grained control +- * over cache flushing. +- */ +-struct pipe_control { +- struct drm_i915_gem_object *obj; +- volatile u32 *cpu_page; +- u32 gtt_offset; +-}; +- + static inline int ring_space(struct intel_ring_buffer *ring) + { + int space = (ring->head & HEAD_ADDR) - (ring->tail + I915_RING_FREE_SPACE); +@@ -175,8 +165,7 @@ gen4_render_ring_flush(struct intel_ring_buffer *ring, + static int + intel_emit_post_sync_nonzero_flush(struct intel_ring_buffer *ring) + { +- struct pipe_control *pc = ring->private; +- u32 scratch_addr = pc->gtt_offset + 128; ++ u32 scratch_addr = ring->scratch.gtt_offset + 128; + int ret; + + +@@ -213,8 +202,7 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring, + u32 invalidate_domains, u32 flush_domains) + { + u32 flags = 0; +- struct pipe_control *pc = ring->private; +- u32 scratch_addr = pc->gtt_offset + 128; ++ u32 scratch_addr = ring->scratch.gtt_offset + 128; + int ret; + + /* Force SNB workarounds for PIPE_CONTROL flushes */ +@@ -306,8 +294,7 @@ gen7_render_ring_flush(struct intel_ring_buffer *ring, + u32 invalidate_domains, u32 flush_domains) + { + u32 flags = 0; +- struct pipe_control *pc = ring->private; +- u32 scratch_addr = pc->gtt_offset + 128; ++ u32 scratch_addr = ring->scratch.gtt_offset + 128; + int ret; + + /* +@@ -481,68 +468,43 @@ out: + static int + init_pipe_control(struct intel_ring_buffer *ring) + { +- struct pipe_control *pc; +- struct drm_i915_gem_object *obj; + int ret; + +- if (ring->private) ++ if (ring->scratch.obj) + return 0; + +- pc = kmalloc(sizeof(*pc), GFP_KERNEL); +- if (!pc) +- return -ENOMEM; +- +- obj = i915_gem_alloc_object(ring->dev, 4096); +- if (obj == NULL) { ++ ring->scratch.obj = i915_gem_alloc_object(ring->dev, 4096); ++ if (ring->scratch.obj == NULL) { + DRM_ERROR("Failed to allocate seqno page\n"); + ret = -ENOMEM; + goto err; + } + +- i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); ++ i915_gem_object_set_cache_level(ring->scratch.obj, I915_CACHE_LLC); + +- ret = i915_gem_obj_ggtt_pin(obj, 4096, true, false); ++ ret = i915_gem_obj_ggtt_pin(ring->scratch.obj, 4096, true, false); + if (ret) + goto err_unref; + +- pc->gtt_offset = i915_gem_obj_ggtt_offset(obj); +- pc->cpu_page = kmap(sg_page(obj->pages->sgl)); +- if (pc->cpu_page == NULL) { ++ ring->scratch.gtt_offset = i915_gem_obj_ggtt_offset(ring->scratch.obj); ++ ring->scratch.cpu_page = kmap(sg_page(ring->scratch.obj->pages->sgl)); ++ if (ring->scratch.cpu_page == NULL) { + ret = -ENOMEM; + goto err_unpin; + } + + DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n", +- ring->name, pc->gtt_offset); +- +- pc->obj = obj; +- ring->private = pc; ++ ring->name, ring->scratch.gtt_offset); + return 0; + + err_unpin: +- i915_gem_object_unpin(obj); ++ i915_gem_object_unpin(ring->scratch.obj); + err_unref: +- drm_gem_object_unreference(&obj->base); ++ drm_gem_object_unreference(&ring->scratch.obj->base); + err: +- kfree(pc); + return ret; + } + +-static void +-cleanup_pipe_control(struct intel_ring_buffer *ring) +-{ +- struct pipe_control *pc = ring->private; +- struct drm_i915_gem_object *obj; +- +- obj = pc->obj; +- +- kunmap(sg_page(obj->pages->sgl)); +- i915_gem_object_unpin(obj); +- drm_gem_object_unreference(&obj->base); +- +- kfree(pc); +-} +- + static int init_render_ring(struct intel_ring_buffer *ring) + { + struct drm_device *dev = ring->dev; +@@ -607,16 +569,16 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring) + { + struct drm_device *dev = ring->dev; + +- if (!ring->private) ++ if (ring->scratch.obj == NULL) + return; + +- if (HAS_BROKEN_CS_TLB(dev)) +- drm_gem_object_unreference(to_gem_object(ring->private)); +- +- if (INTEL_INFO(dev)->gen >= 5) +- cleanup_pipe_control(ring); ++ if (INTEL_INFO(dev)->gen >= 5) { ++ kunmap(sg_page(ring->scratch.obj->pages->sgl)); ++ i915_gem_object_unpin(ring->scratch.obj); ++ } + +- ring->private = NULL; ++ drm_gem_object_unreference(&ring->scratch.obj->base); ++ ring->scratch.obj = NULL; + } + + static void +@@ -742,8 +704,7 @@ do { \ + static int + pc_render_add_request(struct intel_ring_buffer *ring) + { +- struct pipe_control *pc = ring->private; +- u32 scratch_addr = pc->gtt_offset + 128; ++ u32 scratch_addr = ring->scratch.gtt_offset + 128; + int ret; + + /* For Ironlake, MI_USER_INTERRUPT was deprecated and apparently +@@ -761,7 +722,7 @@ pc_render_add_request(struct intel_ring_buffer *ring) + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WRITE_FLUSH | + PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); +- intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); ++ intel_ring_emit(ring, ring->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, ring->outstanding_lazy_request); + intel_ring_emit(ring, 0); + PIPE_CONTROL_FLUSH(ring, scratch_addr); +@@ -780,7 +741,7 @@ pc_render_add_request(struct intel_ring_buffer *ring) + PIPE_CONTROL_WRITE_FLUSH | + PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | + PIPE_CONTROL_NOTIFY); +- intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); ++ intel_ring_emit(ring, ring->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, ring->outstanding_lazy_request); + intel_ring_emit(ring, 0); + intel_ring_advance(ring); +@@ -814,15 +775,13 @@ ring_set_seqno(struct intel_ring_buffer *ring, u32 seqno) + static u32 + pc_render_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency) + { +- struct pipe_control *pc = ring->private; +- return pc->cpu_page[0]; ++ return ring->scratch.cpu_page[0]; + } + + static void + pc_render_set_seqno(struct intel_ring_buffer *ring, u32 seqno) + { +- struct pipe_control *pc = ring->private; +- pc->cpu_page[0] = seqno; ++ ring->scratch.cpu_page[0] = seqno; + } + + static bool +@@ -1141,8 +1100,7 @@ i830_dispatch_execbuffer(struct intel_ring_buffer *ring, + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + } else { +- struct drm_i915_gem_object *obj = ring->private; +- u32 cs_offset = i915_gem_obj_ggtt_offset(obj); ++ u32 cs_offset = ring->scratch.gtt_offset; + + if (len > I830_BATCH_LIMIT) + return -ENOSPC; +@@ -1835,7 +1793,8 @@ int intel_init_render_ring_buffer(struct drm_device *dev) + return ret; + } + +- ring->private = obj; ++ ring->scratch.obj = obj; ++ ring->scratch.gtt_offset = i915_gem_obj_ggtt_offset(obj); + } + + return intel_init_ring_buffer(dev, ring); +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h +index 432ad5311ba6..68b1ca974d59 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.h ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.h +@@ -155,7 +155,11 @@ struct intel_ring_buffer { + + struct intel_ring_hangcheck hangcheck; + +- void *private; ++ struct { ++ struct drm_i915_gem_object *obj; ++ u32 gtt_offset; ++ volatile u32 *cpu_page; ++ } scratch; + }; + + static inline bool +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0749-drm-i915-Use-RCS-flips-on-Ivybridge.patch b/patches.baytrail/0749-drm-i915-Use-RCS-flips-on-Ivybridge.patch new file mode 100644 index 000000000000..7bd57916de94 --- /dev/null +++ b/patches.baytrail/0749-drm-i915-Use-RCS-flips-on-Ivybridge.patch @@ -0,0 +1,139 @@ +From d23382f3305731e890eb4b2f8a6f8297b7b3d2f9 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 26 Aug 2013 20:58:12 +0100 +Subject: drm/i915: Use RCS flips on Ivybridge+ +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RCS flips do work on Iybridge+ so long as we can unmask the messages +through DERRMR. However, there are quite a few workarounds mentioned +regarding unmasking more than one event or triggering more than one +message through DERRMR. Those workarounds in principle prevent us from +performing pipelined flips (and asynchronous flips across multiple +planes) and equally apply to the "known good" BCS ring. Given that it +already appears to work, and also appears to work with unmasking all 3 +planes at once (and queuing flips across multiple planes), be brave. + +Bugzlla: https://bugs.freedesktop.org/show_bug.cgi?id=67600 +Signed-off-by: Chris Wilson +Lightly-tested-by: Stephane Marchesin +Cc: Stephane Marchesin +Cc: Ben Widawsky +Tested-by: Stéphane Marchesin +Signed-off-by: Daniel Vetter +(cherry picked from commit ffe74d75502e3a9b0791240b5562bcbecc6ab8dc) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 18 ++++++++++++++++ + drivers/gpu/drm/i915/intel_display.c | 40 ++++++++++++++++++++++++++++-------- + 2 files changed, 49 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index b6a58f720f9a..b2fa2a4c4454 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -245,6 +245,7 @@ + * address/value pairs. Don't overdue it, though, x <= 2^4 must hold! + */ + #define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1) ++#define MI_STORE_REGISTER_MEM(x) MI_INSTR(0x24, 2*x-1) + #define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */ + #define MI_FLUSH_DW_STORE_INDEX (1<<21) + #define MI_INVALIDATE_TLB (1<<18) +@@ -693,6 +694,23 @@ + #define FPGA_DBG_RM_NOCLAIM (1<<31) + + #define DERRMR 0x44050 ++#define DERRMR_PIPEA_SCANLINE (1<<0) ++#define DERRMR_PIPEA_PRI_FLIP_DONE (1<<1) ++#define DERRMR_PIPEA_SPR_FLIP_DONE (1<<2) ++#define DERRMR_PIPEA_VBLANK (1<<3) ++#define DERRMR_PIPEA_HBLANK (1<<5) ++#define DERRMR_PIPEB_SCANLINE (1<<8) ++#define DERRMR_PIPEB_PRI_FLIP_DONE (1<<9) ++#define DERRMR_PIPEB_SPR_FLIP_DONE (1<<10) ++#define DERRMR_PIPEB_VBLANK (1<<11) ++#define DERRMR_PIPEB_HBLANK (1<<13) ++/* Note that PIPEC is not a simple translation of PIPEA/PIPEB */ ++#define DERRMR_PIPEC_SCANLINE (1<<14) ++#define DERRMR_PIPEC_PRI_FLIP_DONE (1<<15) ++#define DERRMR_PIPEC_SPR_FLIP_DONE (1<<20) ++#define DERRMR_PIPEC_VBLANK (1<<21) ++#define DERRMR_PIPEC_HBLANK (1<<22) ++ + + /* GM45+ chicken bits -- debug workaround bits that may be required + * for various sorts of correct behavior. The top 16 bits of each are +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 2ed6214010c6..b27738d0b49d 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -7832,12 +7832,6 @@ err: + return ret; + } + +-/* +- * On gen7 we currently use the blit ring because (in early silicon at least) +- * the render ring doesn't give us interrpts for page flip completion, which +- * means clients will hang after the first flip is queued. Fortunately the +- * blit ring generates interrupts properly, so use it instead. +- */ + static int intel_gen7_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, +@@ -7846,9 +7840,13 @@ static int intel_gen7_queue_flip(struct drm_device *dev, + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; ++ struct intel_ring_buffer *ring; + uint32_t plane_bit = 0; +- int ret; ++ int len, ret; ++ ++ ring = obj->ring; ++ if (ring == NULL || ring->id != RCS) ++ ring = &dev_priv->ring[BCS]; + + ret = intel_pin_and_fence_fb_obj(dev, obj, ring); + if (ret) +@@ -7870,10 +7868,34 @@ static int intel_gen7_queue_flip(struct drm_device *dev, + goto err_unpin; + } + +- ret = intel_ring_begin(ring, 4); ++ len = 4; ++ if (ring->id == RCS) ++ len += 6; ++ ++ ret = intel_ring_begin(ring, len); + if (ret) + goto err_unpin; + ++ /* Unmask the flip-done completion message. Note that the bspec says that ++ * we should do this for both the BCS and RCS, and that we must not unmask ++ * more than one flip event at any time (or ensure that one flip message ++ * can be sent by waiting for flip-done prior to queueing new flips). ++ * Experimentation says that BCS works despite DERRMR masking all ++ * flip-done completion events and that unmasking all planes at once ++ * for the RCS also doesn't appear to drop events. Setting the DERRMR ++ * to zero does lead to lockups within MI_DISPLAY_FLIP. ++ */ ++ if (ring->id == RCS) { ++ intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); ++ intel_ring_emit(ring, DERRMR); ++ intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE | ++ DERRMR_PIPEB_PRI_FLIP_DONE | ++ DERRMR_PIPEC_PRI_FLIP_DONE)); ++ intel_ring_emit(ring, MI_STORE_REGISTER_MEM(1)); ++ intel_ring_emit(ring, DERRMR); ++ intel_ring_emit(ring, ring->scratch.gtt_offset + 256); ++ } ++ + intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit); + intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); + intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0750-i915_gem-Convert-kmem_cache_alloc-.GFP_ZERO-to-kmem_.patch b/patches.baytrail/0750-i915_gem-Convert-kmem_cache_alloc-.GFP_ZERO-to-kmem_.patch new file mode 100644 index 000000000000..180daa16ffd4 --- /dev/null +++ b/patches.baytrail/0750-i915_gem-Convert-kmem_cache_alloc-.GFP_ZERO-to-kmem_.patch @@ -0,0 +1,31 @@ +From 82e887441d15ff185652ee7a16f3f589559fb052 Mon Sep 17 00:00:00 2001 +From: Joe Perches +Date: Thu, 29 Aug 2013 13:11:07 -0700 +Subject: i915_gem: Convert kmem_cache_alloc(...GFP_ZERO) to kmem_cache_zalloc + +The helper exists, might as well use it instead of __GFP_ZERO. + +Signed-off-by: Joe Perches +Signed-off-by: Daniel Vetter +(cherry picked from commit fac15c108248e8d592fb8f4cbcf26d98b3485526) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 2d1cb10d846f..61313054fce6 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -212,7 +212,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, + void *i915_gem_object_alloc(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- return kmem_cache_alloc(dev_priv->slab, GFP_KERNEL | __GFP_ZERO); ++ return kmem_cache_zalloc(dev_priv->slab, GFP_KERNEL); + } + + void i915_gem_object_free(struct drm_i915_gem_object *obj) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0751-drm-i915-split-PCI-IDs-out-into-i915_drm.h-v4.patch b/patches.baytrail/0751-drm-i915-split-PCI-IDs-out-into-i915_drm.h-v4.patch new file mode 100644 index 000000000000..7f39724fc31e --- /dev/null +++ b/patches.baytrail/0751-drm-i915-split-PCI-IDs-out-into-i915_drm.h-v4.patch @@ -0,0 +1,444 @@ +From 8fcdd52b91ace48187d374503504329730e76bbd Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Fri, 26 Jul 2013 13:32:51 -0700 +Subject: drm/i915: split PCI IDs out into i915_drm.h v4 + +For use by userspace (at some point in the future) and other kernel code. + +v2: move PCI IDs to uabi (Chris) + move PCI IDs to drm/ (Dave) +v3: fixup Quanta detection - needs to come first (Daniel) +v4: fix up PCI match structure init for easier use by userspace (Chris) + +Signed-off-by: Jesse Barnes +Signed-off-by: Daniel Vetter +(cherry picked from commit a0a1807544fe59b42d3760ee912ea4c6741298f5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.c | 164 +++++++------------------------ + include/drm/i915_drm.h | 2 + + include/drm/i915_pciids.h | 211 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 247 insertions(+), 130 deletions(-) + create mode 100644 include/drm/i915_pciids.h + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index ccb28ead3501..69d8ed5416c3 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -157,25 +157,6 @@ MODULE_PARM_DESC(prefault_disable, + static struct drm_driver driver; + extern int intel_agp_enabled; + +-#define INTEL_VGA_DEVICE(id, info) { \ +- .class = PCI_BASE_CLASS_DISPLAY << 16, \ +- .class_mask = 0xff0000, \ +- .vendor = 0x8086, \ +- .device = id, \ +- .subvendor = PCI_ANY_ID, \ +- .subdevice = PCI_ANY_ID, \ +- .driver_data = (unsigned long) info } +- +-#define INTEL_QUANTA_VGA_DEVICE(info) { \ +- .class = PCI_BASE_CLASS_DISPLAY << 16, \ +- .class_mask = 0xff0000, \ +- .vendor = 0x8086, \ +- .device = 0x16a, \ +- .subvendor = 0x152d, \ +- .subdevice = 0x8990, \ +- .driver_data = (unsigned long) info } +- +- + static const struct intel_device_info intel_i830_info = { + .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2, + .has_overlay = 1, .overlay_needs_physical = 1, +@@ -350,118 +331,41 @@ static const struct intel_device_info intel_haswell_m_info = { + .has_vebox_ring = 1, + }; + ++/* ++ * Make sure any device matches here are from most specific to most ++ * general. For example, since the Quanta match is based on the subsystem ++ * and subvendor IDs, we need it to come before the more general IVB ++ * PCI ID matches, otherwise we'll use the wrong info struct above. ++ */ ++#define INTEL_PCI_IDS \ ++ INTEL_I830_IDS(&intel_i830_info), \ ++ INTEL_I845G_IDS(&intel_845g_info), \ ++ INTEL_I85X_IDS(&intel_i85x_info), \ ++ INTEL_I865G_IDS(&intel_i865g_info), \ ++ INTEL_I915G_IDS(&intel_i915g_info), \ ++ INTEL_I915GM_IDS(&intel_i915gm_info), \ ++ INTEL_I945G_IDS(&intel_i945g_info), \ ++ INTEL_I945GM_IDS(&intel_i945gm_info), \ ++ INTEL_I965G_IDS(&intel_i965g_info), \ ++ INTEL_G33_IDS(&intel_g33_info), \ ++ INTEL_I965GM_IDS(&intel_i965gm_info), \ ++ INTEL_GM45_IDS(&intel_gm45_info), \ ++ INTEL_G45_IDS(&intel_g45_info), \ ++ INTEL_PINEVIEW_IDS(&intel_pineview_info), \ ++ INTEL_IRONLAKE_D_IDS(&intel_ironlake_d_info), \ ++ INTEL_IRONLAKE_M_IDS(&intel_ironlake_m_info), \ ++ INTEL_SNB_D_IDS(&intel_sandybridge_d_info), \ ++ INTEL_SNB_M_IDS(&intel_sandybridge_m_info), \ ++ INTEL_IVB_Q_IDS(&intel_ivybridge_q_info), /* must be first IVB */ \ ++ INTEL_IVB_M_IDS(&intel_ivybridge_m_info), \ ++ INTEL_IVB_D_IDS(&intel_ivybridge_d_info), \ ++ INTEL_HSW_D_IDS(&intel_haswell_d_info), \ ++ INTEL_HSW_M_IDS(&intel_haswell_m_info), \ ++ INTEL_VLV_M_IDS(&intel_valleyview_m_info), \ ++ INTEL_VLV_D_IDS(&intel_valleyview_d_info) ++ + static const struct pci_device_id pciidlist[] = { /* aka */ +- INTEL_VGA_DEVICE(0x3577, &intel_i830_info), /* I830_M */ +- INTEL_VGA_DEVICE(0x2562, &intel_845g_info), /* 845_G */ +- INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), /* I855_GM */ +- INTEL_VGA_DEVICE(0x358e, &intel_i85x_info), +- INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), /* I865_G */ +- INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), /* I915_G */ +- INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), /* E7221_G */ +- INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info), /* I915_GM */ +- INTEL_VGA_DEVICE(0x2772, &intel_i945g_info), /* I945_G */ +- INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info), /* I945_GM */ +- INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info), /* I945_GME */ +- INTEL_VGA_DEVICE(0x2972, &intel_i965g_info), /* I946_GZ */ +- INTEL_VGA_DEVICE(0x2982, &intel_i965g_info), /* G35_G */ +- INTEL_VGA_DEVICE(0x2992, &intel_i965g_info), /* I965_Q */ +- INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info), /* I965_G */ +- INTEL_VGA_DEVICE(0x29b2, &intel_g33_info), /* Q35_G */ +- INTEL_VGA_DEVICE(0x29c2, &intel_g33_info), /* G33_G */ +- INTEL_VGA_DEVICE(0x29d2, &intel_g33_info), /* Q33_G */ +- INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info), /* I965_GM */ +- INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info), /* I965_GME */ +- INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info), /* GM45_G */ +- INTEL_VGA_DEVICE(0x2e02, &intel_g45_info), /* IGD_E_G */ +- INTEL_VGA_DEVICE(0x2e12, &intel_g45_info), /* Q45_G */ +- INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */ +- INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */ +- INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */ +- INTEL_VGA_DEVICE(0x2e92, &intel_g45_info), /* B43_G.1 */ +- INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), +- INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), +- INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), +- INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), +- INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), +- INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info), +- INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info), +- INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), +- INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info), +- INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), +- INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info), +- INTEL_VGA_DEVICE(0x0156, &intel_ivybridge_m_info), /* GT1 mobile */ +- INTEL_VGA_DEVICE(0x0166, &intel_ivybridge_m_info), /* GT2 mobile */ +- INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */ +- INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */ +- INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */ +- INTEL_QUANTA_VGA_DEVICE(&intel_ivybridge_q_info), /* Quanta transcode */ +- INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ +- INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ +- INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ +- INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT3 desktop */ +- INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */ +- INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */ +- INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT3 server */ +- INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ +- INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ +- INTEL_VGA_DEVICE(0x0426, &intel_haswell_m_info), /* GT2 mobile */ +- INTEL_VGA_DEVICE(0x040B, &intel_haswell_d_info), /* GT1 reserved */ +- INTEL_VGA_DEVICE(0x041B, &intel_haswell_d_info), /* GT2 reserved */ +- INTEL_VGA_DEVICE(0x042B, &intel_haswell_d_info), /* GT3 reserved */ +- INTEL_VGA_DEVICE(0x040E, &intel_haswell_d_info), /* GT1 reserved */ +- INTEL_VGA_DEVICE(0x041E, &intel_haswell_d_info), /* GT2 reserved */ +- INTEL_VGA_DEVICE(0x042E, &intel_haswell_d_info), /* GT3 reserved */ +- INTEL_VGA_DEVICE(0x0C02, &intel_haswell_d_info), /* SDV GT1 desktop */ +- INTEL_VGA_DEVICE(0x0C12, &intel_haswell_d_info), /* SDV GT2 desktop */ +- INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT3 desktop */ +- INTEL_VGA_DEVICE(0x0C0A, &intel_haswell_d_info), /* SDV GT1 server */ +- INTEL_VGA_DEVICE(0x0C1A, &intel_haswell_d_info), /* SDV GT2 server */ +- INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT3 server */ +- INTEL_VGA_DEVICE(0x0C06, &intel_haswell_m_info), /* SDV GT1 mobile */ +- INTEL_VGA_DEVICE(0x0C16, &intel_haswell_m_info), /* SDV GT2 mobile */ +- INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT3 mobile */ +- INTEL_VGA_DEVICE(0x0C0B, &intel_haswell_d_info), /* SDV GT1 reserved */ +- INTEL_VGA_DEVICE(0x0C1B, &intel_haswell_d_info), /* SDV GT2 reserved */ +- INTEL_VGA_DEVICE(0x0C2B, &intel_haswell_d_info), /* SDV GT3 reserved */ +- INTEL_VGA_DEVICE(0x0C0E, &intel_haswell_d_info), /* SDV GT1 reserved */ +- INTEL_VGA_DEVICE(0x0C1E, &intel_haswell_d_info), /* SDV GT2 reserved */ +- INTEL_VGA_DEVICE(0x0C2E, &intel_haswell_d_info), /* SDV GT3 reserved */ +- INTEL_VGA_DEVICE(0x0A02, &intel_haswell_d_info), /* ULT GT1 desktop */ +- INTEL_VGA_DEVICE(0x0A12, &intel_haswell_d_info), /* ULT GT2 desktop */ +- INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT3 desktop */ +- INTEL_VGA_DEVICE(0x0A0A, &intel_haswell_d_info), /* ULT GT1 server */ +- INTEL_VGA_DEVICE(0x0A1A, &intel_haswell_d_info), /* ULT GT2 server */ +- INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT3 server */ +- INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */ +- INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */ +- INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT3 mobile */ +- INTEL_VGA_DEVICE(0x0A0B, &intel_haswell_d_info), /* ULT GT1 reserved */ +- INTEL_VGA_DEVICE(0x0A1B, &intel_haswell_d_info), /* ULT GT2 reserved */ +- INTEL_VGA_DEVICE(0x0A2B, &intel_haswell_d_info), /* ULT GT3 reserved */ +- INTEL_VGA_DEVICE(0x0A0E, &intel_haswell_m_info), /* ULT GT1 reserved */ +- INTEL_VGA_DEVICE(0x0A1E, &intel_haswell_m_info), /* ULT GT2 reserved */ +- INTEL_VGA_DEVICE(0x0A2E, &intel_haswell_m_info), /* ULT GT3 reserved */ +- INTEL_VGA_DEVICE(0x0D02, &intel_haswell_d_info), /* CRW GT1 desktop */ +- INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT2 desktop */ +- INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT3 desktop */ +- INTEL_VGA_DEVICE(0x0D0A, &intel_haswell_d_info), /* CRW GT1 server */ +- INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT2 server */ +- INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT3 server */ +- INTEL_VGA_DEVICE(0x0D06, &intel_haswell_m_info), /* CRW GT1 mobile */ +- INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */ +- INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT3 mobile */ +- INTEL_VGA_DEVICE(0x0D0B, &intel_haswell_d_info), /* CRW GT1 reserved */ +- INTEL_VGA_DEVICE(0x0D1B, &intel_haswell_d_info), /* CRW GT2 reserved */ +- INTEL_VGA_DEVICE(0x0D2B, &intel_haswell_d_info), /* CRW GT3 reserved */ +- INTEL_VGA_DEVICE(0x0D0E, &intel_haswell_d_info), /* CRW GT1 reserved */ +- INTEL_VGA_DEVICE(0x0D1E, &intel_haswell_d_info), /* CRW GT2 reserved */ +- INTEL_VGA_DEVICE(0x0D2E, &intel_haswell_d_info), /* CRW GT3 reserved */ +- INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), +- INTEL_VGA_DEVICE(0x0f31, &intel_valleyview_m_info), +- INTEL_VGA_DEVICE(0x0f32, &intel_valleyview_m_info), +- INTEL_VGA_DEVICE(0x0f33, &intel_valleyview_m_info), +- INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), +- INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), ++ INTEL_PCI_IDS, + {0, 0, 0} + }; + +diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h +index 63d609d8a3f6..7276a72710e2 100644 +--- a/include/drm/i915_drm.h ++++ b/include/drm/i915_drm.h +@@ -26,6 +26,7 @@ + #ifndef _I915_DRM_H_ + #define _I915_DRM_H_ + ++#include + #include + + /* For use by IPS driver */ +@@ -34,4 +35,5 @@ extern bool i915_gpu_raise(void); + extern bool i915_gpu_lower(void); + extern bool i915_gpu_busy(void); + extern bool i915_gpu_turbo_disable(void); ++ + #endif /* _I915_DRM_H_ */ +diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h +new file mode 100644 +index 000000000000..8a10f5c354e6 +--- /dev/null ++++ b/include/drm/i915_pciids.h +@@ -0,0 +1,211 @@ ++/* ++ * Copyright 2013 Intel Corporation ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++#ifndef _I915_PCIIDS_H ++#define _I915_PCIIDS_H ++ ++/* ++ * A pci_device_id struct { ++ * __u32 vendor, device; ++ * __u32 subvendor, subdevice; ++ * __u32 class, class_mask; ++ * kernel_ulong_t driver_data; ++ * }; ++ * Don't use C99 here because "class" is reserved and we want to ++ * give userspace flexibility. ++ */ ++#define INTEL_VGA_DEVICE(id, info) { \ ++ 0x8086, id, \ ++ ~0, ~0, \ ++ 0x030000, 0xff0000, \ ++ (unsigned long) info } ++ ++#define INTEL_QUANTA_VGA_DEVICE(info) { \ ++ 0x8086, 0x16a, \ ++ 0x152d, 0x8990, \ ++ 0x030000, 0xff0000, \ ++ (unsigned long) info } ++ ++#define INTEL_I830_IDS(info) \ ++ INTEL_VGA_DEVICE(0x3577, info) ++ ++#define INTEL_I845G_IDS(info) \ ++ INTEL_VGA_DEVICE(0x2562, info) ++ ++#define INTEL_I85X_IDS(info) \ ++ INTEL_VGA_DEVICE(0x3582, info), /* I855_GM */ \ ++ INTEL_VGA_DEVICE(0x358e, info) ++ ++#define INTEL_I865G_IDS(info) \ ++ INTEL_VGA_DEVICE(0x2572, info) /* I865_G */ ++ ++#define INTEL_I915G_IDS(info) \ ++ INTEL_VGA_DEVICE(0x2582, info), /* I915_G */ \ ++ INTEL_VGA_DEVICE(0x258a, info) /* E7221_G */ ++ ++#define INTEL_I915GM_IDS(info) \ ++ INTEL_VGA_DEVICE(0x2592, info) /* I915_GM */ ++ ++#define INTEL_I945G_IDS(info) \ ++ INTEL_VGA_DEVICE(0x2772, info) /* I945_G */ ++ ++#define INTEL_I945GM_IDS(info) \ ++ INTEL_VGA_DEVICE(0x27a2, info), /* I945_GM */ \ ++ INTEL_VGA_DEVICE(0x27ae, info) /* I945_GME */ ++ ++#define INTEL_I965G_IDS(info) \ ++ INTEL_VGA_DEVICE(0x2972, info), /* I946_GZ */ \ ++ INTEL_VGA_DEVICE(0x2982, info), /* G35_G */ \ ++ INTEL_VGA_DEVICE(0x2992, info), /* I965_Q */ \ ++ INTEL_VGA_DEVICE(0x29a2, info) /* I965_G */ ++ ++#define INTEL_G33_IDS(info) \ ++ INTEL_VGA_DEVICE(0x29b2, info), /* Q35_G */ \ ++ INTEL_VGA_DEVICE(0x29c2, info), /* G33_G */ \ ++ INTEL_VGA_DEVICE(0x29d2, info) /* Q33_G */ ++ ++#define INTEL_I965GM_IDS(info) \ ++ INTEL_VGA_DEVICE(0x2a02, info), /* I965_GM */ \ ++ INTEL_VGA_DEVICE(0x2a12, info) /* I965_GME */ ++ ++#define INTEL_GM45_IDS(info) \ ++ INTEL_VGA_DEVICE(0x2a42, info) /* GM45_G */ ++ ++#define INTEL_G45_IDS(info) \ ++ INTEL_VGA_DEVICE(0x2e02, info), /* IGD_E_G */ \ ++ INTEL_VGA_DEVICE(0x2e12, info), /* Q45_G */ \ ++ INTEL_VGA_DEVICE(0x2e22, info), /* G45_G */ \ ++ INTEL_VGA_DEVICE(0x2e32, info), /* G41_G */ \ ++ INTEL_VGA_DEVICE(0x2e42, info), /* B43_G */ \ ++ INTEL_VGA_DEVICE(0x2e92, info) /* B43_G.1 */ ++ ++#define INTEL_PINEVIEW_IDS(info) \ ++ INTEL_VGA_DEVICE(0xa001, info), \ ++ INTEL_VGA_DEVICE(0xa011, info) ++ ++#define INTEL_IRONLAKE_D_IDS(info) \ ++ INTEL_VGA_DEVICE(0x0042, info) ++ ++#define INTEL_IRONLAKE_M_IDS(info) \ ++ INTEL_VGA_DEVICE(0x0046, info) ++ ++#define INTEL_SNB_D_IDS(info) \ ++ INTEL_VGA_DEVICE(0x0102, info), \ ++ INTEL_VGA_DEVICE(0x0112, info), \ ++ INTEL_VGA_DEVICE(0x0122, info), \ ++ INTEL_VGA_DEVICE(0x010A, info) ++ ++#define INTEL_SNB_M_IDS(info) \ ++ INTEL_VGA_DEVICE(0x0106, info), \ ++ INTEL_VGA_DEVICE(0x0116, info), \ ++ INTEL_VGA_DEVICE(0x0126, info) ++ ++#define INTEL_IVB_M_IDS(info) \ ++ INTEL_VGA_DEVICE(0x0156, info), /* GT1 mobile */ \ ++ INTEL_VGA_DEVICE(0x0166, info) /* GT2 mobile */ ++ ++#define INTEL_IVB_D_IDS(info) \ ++ INTEL_VGA_DEVICE(0x0152, info), /* GT1 desktop */ \ ++ INTEL_VGA_DEVICE(0x0162, info), /* GT2 desktop */ \ ++ INTEL_VGA_DEVICE(0x015a, info), /* GT1 server */ \ ++ INTEL_VGA_DEVICE(0x016a, info) /* GT2 server */ ++ ++#define INTEL_IVB_Q_IDS(info) \ ++ INTEL_QUANTA_VGA_DEVICE(info) /* Quanta transcode */ ++ ++#define INTEL_HSW_D_IDS(info) \ ++ INTEL_VGA_DEVICE(0x0402, info), /* GT1 desktop */ \ ++ INTEL_VGA_DEVICE(0x0412, info), /* GT2 desktop */ \ ++ INTEL_VGA_DEVICE(0x0422, info), /* GT3 desktop */ \ ++ INTEL_VGA_DEVICE(0x040a, info), /* GT1 server */ \ ++ INTEL_VGA_DEVICE(0x041a, info), /* GT2 server */ \ ++ INTEL_VGA_DEVICE(0x042a, info), /* GT3 server */ \ ++ INTEL_VGA_DEVICE(0x040B, info), /* GT1 reserved */ \ ++ INTEL_VGA_DEVICE(0x041B, info), /* GT2 reserved */ \ ++ INTEL_VGA_DEVICE(0x042B, info), /* GT3 reserved */ \ ++ INTEL_VGA_DEVICE(0x040E, info), /* GT1 reserved */ \ ++ INTEL_VGA_DEVICE(0x041E, info), /* GT2 reserved */ \ ++ INTEL_VGA_DEVICE(0x042E, info), /* GT3 reserved */ \ ++ INTEL_VGA_DEVICE(0x0C02, info), /* SDV GT1 desktop */ \ ++ INTEL_VGA_DEVICE(0x0C12, info), /* SDV GT2 desktop */ \ ++ INTEL_VGA_DEVICE(0x0C22, info), /* SDV GT3 desktop */ \ ++ INTEL_VGA_DEVICE(0x0C0A, info), /* SDV GT1 server */ \ ++ INTEL_VGA_DEVICE(0x0C1A, info), /* SDV GT2 server */ \ ++ INTEL_VGA_DEVICE(0x0C2A, info), /* SDV GT3 server */ \ ++ INTEL_VGA_DEVICE(0x0C0B, info), /* SDV GT1 reserved */ \ ++ INTEL_VGA_DEVICE(0x0C1B, info), /* SDV GT2 reserved */ \ ++ INTEL_VGA_DEVICE(0x0C2B, info), /* SDV GT3 reserved */ \ ++ INTEL_VGA_DEVICE(0x0C0E, info), /* SDV GT1 reserved */ \ ++ INTEL_VGA_DEVICE(0x0C1E, info), /* SDV GT2 reserved */ \ ++ INTEL_VGA_DEVICE(0x0C2E, info), /* SDV GT3 reserved */ \ ++ INTEL_VGA_DEVICE(0x0A02, info), /* ULT GT1 desktop */ \ ++ INTEL_VGA_DEVICE(0x0A12, info), /* ULT GT2 desktop */ \ ++ INTEL_VGA_DEVICE(0x0A22, info), /* ULT GT3 desktop */ \ ++ INTEL_VGA_DEVICE(0x0A0A, info), /* ULT GT1 server */ \ ++ INTEL_VGA_DEVICE(0x0A1A, info), /* ULT GT2 server */ \ ++ INTEL_VGA_DEVICE(0x0A2A, info), /* ULT GT3 server */ \ ++ INTEL_VGA_DEVICE(0x0A0B, info), /* ULT GT1 reserved */ \ ++ INTEL_VGA_DEVICE(0x0A1B, info), /* ULT GT2 reserved */ \ ++ INTEL_VGA_DEVICE(0x0A2B, info), /* ULT GT3 reserved */ \ ++ INTEL_VGA_DEVICE(0x0D02, info), /* CRW GT1 desktop */ \ ++ INTEL_VGA_DEVICE(0x0D12, info), /* CRW GT2 desktop */ \ ++ INTEL_VGA_DEVICE(0x0D22, info), /* CRW GT3 desktop */ \ ++ INTEL_VGA_DEVICE(0x0D0A, info), /* CRW GT1 server */ \ ++ INTEL_VGA_DEVICE(0x0D1A, info), /* CRW GT2 server */ \ ++ INTEL_VGA_DEVICE(0x0D2A, info), /* CRW GT3 server */ \ ++ INTEL_VGA_DEVICE(0x0D0B, info), /* CRW GT1 reserved */ \ ++ INTEL_VGA_DEVICE(0x0D1B, info), /* CRW GT2 reserved */ \ ++ INTEL_VGA_DEVICE(0x0D2B, info), /* CRW GT3 reserved */ \ ++ INTEL_VGA_DEVICE(0x0D0E, info), /* CRW GT1 reserved */ \ ++ INTEL_VGA_DEVICE(0x0D1E, info), /* CRW GT2 reserved */ \ ++ INTEL_VGA_DEVICE(0x0D2E, info) /* CRW GT3 reserved */ \ ++ ++#define INTEL_HSW_M_IDS(info) \ ++ INTEL_VGA_DEVICE(0x0406, info), /* GT1 mobile */ \ ++ INTEL_VGA_DEVICE(0x0416, info), /* GT2 mobile */ \ ++ INTEL_VGA_DEVICE(0x0426, info), /* GT2 mobile */ \ ++ INTEL_VGA_DEVICE(0x0C06, info), /* SDV GT1 mobile */ \ ++ INTEL_VGA_DEVICE(0x0C16, info), /* SDV GT2 mobile */ \ ++ INTEL_VGA_DEVICE(0x0C26, info), /* SDV GT3 mobile */ \ ++ INTEL_VGA_DEVICE(0x0A06, info), /* ULT GT1 mobile */ \ ++ INTEL_VGA_DEVICE(0x0A16, info), /* ULT GT2 mobile */ \ ++ INTEL_VGA_DEVICE(0x0A26, info), /* ULT GT3 mobile */ \ ++ INTEL_VGA_DEVICE(0x0A0E, info), /* ULT GT1 reserved */ \ ++ INTEL_VGA_DEVICE(0x0A1E, info), /* ULT GT2 reserved */ \ ++ INTEL_VGA_DEVICE(0x0A2E, info), /* ULT GT3 reserved */ \ ++ INTEL_VGA_DEVICE(0x0D06, info), /* CRW GT1 mobile */ \ ++ INTEL_VGA_DEVICE(0x0D16, info), /* CRW GT2 mobile */ \ ++ INTEL_VGA_DEVICE(0x0D26, info) /* CRW GT3 mobile */ ++ ++#define INTEL_VLV_M_IDS(info) \ ++ INTEL_VGA_DEVICE(0x0f30, info), \ ++ INTEL_VGA_DEVICE(0x0f31, info), \ ++ INTEL_VGA_DEVICE(0x0f32, info), \ ++ INTEL_VGA_DEVICE(0x0f33, info), \ ++ INTEL_VGA_DEVICE(0x0157, info) ++ ++#define INTEL_VLV_D_IDS(info) \ ++ INTEL_VGA_DEVICE(0x0155, info) ++ ++#endif /* _I915_PCIIDS_H */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0752-x86-add-early-quirk-for-reserving-Intel-graphics-sto.patch b/patches.baytrail/0752-x86-add-early-quirk-for-reserving-Intel-graphics-sto.patch new file mode 100644 index 000000000000..cfdd2567ba3d --- /dev/null +++ b/patches.baytrail/0752-x86-add-early-quirk-for-reserving-Intel-graphics-sto.patch @@ -0,0 +1,285 @@ +From a6a880cb0762203b853d8620e47b05dbc7d528fc Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Fri, 26 Jul 2013 13:32:52 -0700 +Subject: x86: add early quirk for reserving Intel graphics stolen memory v5 + +Systems with Intel graphics controllers set aside memory exclusively for +gfx driver use. This memory is not always marked in the E820 as +reserved or as RAM, and so is subject to overlap from E820 manipulation +later in the boot process. On some systems, MMIO space is allocated on +top, despite the efforts of the "RAM buffer" approach, which simply +rounds memory boundaries up to 64M to try to catch space that may decode +as RAM and so is not suitable for MMIO. + +v2: use read_pci_config for 32 bit reads instead of adding a new one + (Chris) + add gen6 stolen size function (Chris) +v3: use a function pointer (Chris) + drop gen2 bits (Daniel) +v4: call e820_sanitize_map after adding the region +v5: fixup comments (Peter) + simplify loop (Chris) + +Acked-by: Ingo Molnar +Signed-off-by: Jesse Barnes +Acked-by: H. Peter Anvin +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66726 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66844 +Signed-off-by: Daniel Vetter +(cherry picked from commit 814c5f1f52a4beb3710317022acd6ad34fc0b6b9) +Signed-off-by: Darren Hart +--- + arch/x86/kernel/early-quirks.c | 154 ++++++++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/i915/i915_reg.h | 15 ---- + include/drm/i915_drm.h | 32 +++++++++ + 3 files changed, 186 insertions(+), 15 deletions(-) + +diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c +index 63bdb29b2549..b3cd3ebae077 100644 +--- a/arch/x86/kernel/early-quirks.c ++++ b/arch/x86/kernel/early-quirks.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -216,6 +217,157 @@ static void __init intel_remapping_check(int num, int slot, int func) + + } + ++/* ++ * Systems with Intel graphics controllers set aside memory exclusively ++ * for gfx driver use. This memory is not marked in the E820 as reserved ++ * or as RAM, and so is subject to overlap from E820 manipulation later ++ * in the boot process. On some systems, MMIO space is allocated on top, ++ * despite the efforts of the "RAM buffer" approach, which simply rounds ++ * memory boundaries up to 64M to try to catch space that may decode ++ * as RAM and so is not suitable for MMIO. ++ * ++ * And yes, so far on current devices the base addr is always under 4G. ++ */ ++static u32 __init intel_stolen_base(int num, int slot, int func) ++{ ++ u32 base; ++ ++ /* ++ * For the PCI IDs in this quirk, the stolen base is always ++ * in 0x5c, aka the BDSM register (yes that's really what ++ * it's called). ++ */ ++ base = read_pci_config(num, slot, func, 0x5c); ++ base &= ~((1<<20) - 1); ++ ++ return base; ++} ++ ++#define KB(x) ((x) * 1024) ++#define MB(x) (KB (KB (x))) ++#define GB(x) (MB (KB (x))) ++ ++static size_t __init gen3_stolen_size(int num, int slot, int func) ++{ ++ size_t stolen_size; ++ u16 gmch_ctrl; ++ ++ gmch_ctrl = read_pci_config_16(0, 0, 0, I830_GMCH_CTRL); ++ ++ switch (gmch_ctrl & I855_GMCH_GMS_MASK) { ++ case I855_GMCH_GMS_STOLEN_1M: ++ stolen_size = MB(1); ++ break; ++ case I855_GMCH_GMS_STOLEN_4M: ++ stolen_size = MB(4); ++ break; ++ case I855_GMCH_GMS_STOLEN_8M: ++ stolen_size = MB(8); ++ break; ++ case I855_GMCH_GMS_STOLEN_16M: ++ stolen_size = MB(16); ++ break; ++ case I855_GMCH_GMS_STOLEN_32M: ++ stolen_size = MB(32); ++ break; ++ case I915_GMCH_GMS_STOLEN_48M: ++ stolen_size = MB(48); ++ break; ++ case I915_GMCH_GMS_STOLEN_64M: ++ stolen_size = MB(64); ++ break; ++ case G33_GMCH_GMS_STOLEN_128M: ++ stolen_size = MB(128); ++ break; ++ case G33_GMCH_GMS_STOLEN_256M: ++ stolen_size = MB(256); ++ break; ++ case INTEL_GMCH_GMS_STOLEN_96M: ++ stolen_size = MB(96); ++ break; ++ case INTEL_GMCH_GMS_STOLEN_160M: ++ stolen_size = MB(160); ++ break; ++ case INTEL_GMCH_GMS_STOLEN_224M: ++ stolen_size = MB(224); ++ break; ++ case INTEL_GMCH_GMS_STOLEN_352M: ++ stolen_size = MB(352); ++ break; ++ default: ++ stolen_size = 0; ++ break; ++ } ++ ++ return stolen_size; ++} ++ ++static size_t __init gen6_stolen_size(int num, int slot, int func) ++{ ++ u16 gmch_ctrl; ++ ++ gmch_ctrl = read_pci_config_16(num, slot, func, SNB_GMCH_CTRL); ++ gmch_ctrl >>= SNB_GMCH_GMS_SHIFT; ++ gmch_ctrl &= SNB_GMCH_GMS_MASK; ++ ++ return gmch_ctrl << 25; /* 32 MB units */ ++} ++ ++typedef size_t (*stolen_size_fn)(int num, int slot, int func); ++ ++static struct pci_device_id intel_stolen_ids[] __initdata = { ++ INTEL_I915G_IDS(gen3_stolen_size), ++ INTEL_I915GM_IDS(gen3_stolen_size), ++ INTEL_I945G_IDS(gen3_stolen_size), ++ INTEL_I945GM_IDS(gen3_stolen_size), ++ INTEL_VLV_M_IDS(gen3_stolen_size), ++ INTEL_VLV_D_IDS(gen3_stolen_size), ++ INTEL_PINEVIEW_IDS(gen3_stolen_size), ++ INTEL_I965G_IDS(gen3_stolen_size), ++ INTEL_G33_IDS(gen3_stolen_size), ++ INTEL_I965GM_IDS(gen3_stolen_size), ++ INTEL_GM45_IDS(gen3_stolen_size), ++ INTEL_G45_IDS(gen3_stolen_size), ++ INTEL_IRONLAKE_D_IDS(gen3_stolen_size), ++ INTEL_IRONLAKE_M_IDS(gen3_stolen_size), ++ INTEL_SNB_D_IDS(gen6_stolen_size), ++ INTEL_SNB_M_IDS(gen6_stolen_size), ++ INTEL_IVB_M_IDS(gen6_stolen_size), ++ INTEL_IVB_D_IDS(gen6_stolen_size), ++ INTEL_HSW_D_IDS(gen6_stolen_size), ++ INTEL_HSW_M_IDS(gen6_stolen_size), ++}; ++ ++static void __init intel_graphics_stolen(int num, int slot, int func) ++{ ++ size_t size; ++ int i; ++ u32 start; ++ u16 device, subvendor, subdevice; ++ ++ device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID); ++ subvendor = read_pci_config_16(num, slot, func, ++ PCI_SUBSYSTEM_VENDOR_ID); ++ subdevice = read_pci_config_16(num, slot, func, PCI_SUBSYSTEM_ID); ++ ++ for (i = 0; i < ARRAY_SIZE(intel_stolen_ids); i++) { ++ if (intel_stolen_ids[i].device == device) { ++ stolen_size_fn stolen_size = ++ (stolen_size_fn)intel_stolen_ids[i].driver_data; ++ size = stolen_size(num, slot, func); ++ start = intel_stolen_base(num, slot, func); ++ if (size && start) { ++ /* Mark this space as reserved */ ++ e820_add_region(start, size, E820_RESERVED); ++ sanitize_e820_map(e820.map, ++ ARRAY_SIZE(e820.map), ++ &e820.nr_map); ++ } ++ return; ++ } ++ } ++} ++ + #define QFLAG_APPLY_ONCE 0x1 + #define QFLAG_APPLIED 0x2 + #define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED) +@@ -251,6 +403,8 @@ static struct chipset early_qrk[] __initdata = { + PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check }, + { PCI_VENDOR_ID_INTEL, 0x3406, PCI_CLASS_BRIDGE_HOST, + PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check }, ++ { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA, PCI_ANY_ID, ++ QFLAG_APPLY_ONCE, intel_graphics_stolen }, + {} + }; + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index b2fa2a4c4454..dcc58ea157fe 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -33,21 +33,6 @@ + #define _MASKED_BIT_ENABLE(a) (((a) << 16) | (a)) + #define _MASKED_BIT_DISABLE(a) ((a) << 16) + +-/* +- * The Bridge device's PCI config space has information about the +- * fb aperture size and the amount of pre-reserved memory. +- * This is all handled in the intel-gtt.ko module. i915.ko only +- * cares about the vga bit for the vga rbiter. +- */ +-#define INTEL_GMCH_CTRL 0x52 +-#define INTEL_GMCH_VGA_DISABLE (1 << 1) +-#define SNB_GMCH_CTRL 0x50 +-#define SNB_GMCH_GGMS_SHIFT 8 /* GTT Graphics Memory Size */ +-#define SNB_GMCH_GGMS_MASK 0x3 +-#define SNB_GMCH_GMS_SHIFT 3 /* Graphics Mode Select */ +-#define SNB_GMCH_GMS_MASK 0x1f +- +- + /* PCI config space */ + + #define HPLLCC 0xc0 /* 855 only */ +diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h +index 7276a72710e2..3abfa6ea226e 100644 +--- a/include/drm/i915_drm.h ++++ b/include/drm/i915_drm.h +@@ -36,4 +36,36 @@ extern bool i915_gpu_lower(void); + extern bool i915_gpu_busy(void); + extern bool i915_gpu_turbo_disable(void); + ++/* ++ * The Bridge device's PCI config space has information about the ++ * fb aperture size and the amount of pre-reserved memory. ++ * This is all handled in the intel-gtt.ko module. i915.ko only ++ * cares about the vga bit for the vga rbiter. ++ */ ++#define INTEL_GMCH_CTRL 0x52 ++#define INTEL_GMCH_VGA_DISABLE (1 << 1) ++#define SNB_GMCH_CTRL 0x50 ++#define SNB_GMCH_GGMS_SHIFT 8 /* GTT Graphics Memory Size */ ++#define SNB_GMCH_GGMS_MASK 0x3 ++#define SNB_GMCH_GMS_SHIFT 3 /* Graphics Mode Select */ ++#define SNB_GMCH_GMS_MASK 0x1f ++ ++#define I830_GMCH_CTRL 0x52 ++ ++#define I855_GMCH_GMS_MASK 0xF0 ++#define I855_GMCH_GMS_STOLEN_0M 0x0 ++#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) ++#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) ++#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) ++#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) ++#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) ++#define I915_GMCH_GMS_STOLEN_48M (0x6 << 4) ++#define I915_GMCH_GMS_STOLEN_64M (0x7 << 4) ++#define G33_GMCH_GMS_STOLEN_128M (0x8 << 4) ++#define G33_GMCH_GMS_STOLEN_256M (0x9 << 4) ++#define INTEL_GMCH_GMS_STOLEN_96M (0xa << 4) ++#define INTEL_GMCH_GMS_STOLEN_160M (0xb << 4) ++#define INTEL_GMCH_GMS_STOLEN_224M (0xc << 4) ++#define INTEL_GMCH_GMS_STOLEN_352M (0xd << 4) ++ + #endif /* _I915_DRM_H_ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0753-drm-i915-enable-trickle-feed-on-Haswell.patch b/patches.baytrail/0753-drm-i915-enable-trickle-feed-on-Haswell.patch new file mode 100644 index 000000000000..2131ba9559f2 --- /dev/null +++ b/patches.baytrail/0753-drm-i915-enable-trickle-feed-on-Haswell.patch @@ -0,0 +1,102 @@ +From 72c858663ac200d764a873bcbfce8eae135d2e77 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni +Date: Fri, 23 Aug 2013 19:51:28 -0300 +Subject: drm/i915: enable trickle feed on Haswell +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We shouldn't disable the trickle feed bits on Haswell. Our +documentation explicitly says the trickle feed bits of PRI_CTL and +CUR_CTL should not be programmed to 1, and the hardware engineer also +asked us to not program the SPR_CTL field to 1. Leaving the bits as 1 +could cause underflows. + +Reported-by: Arthur Runyan +Signed-off-by: Paulo Zanoni +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 1f5d76dbb636c73912c9ff1c90ff46dd2273f098) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 1 + + drivers/gpu/drm/i915/intel_display.c | 10 +++++++--- + drivers/gpu/drm/i915/intel_pm.c | 2 -- + drivers/gpu/drm/i915/intel_sprite.c | 7 +++++-- + 4 files changed, 13 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index dcc58ea157fe..c159e1a6810f 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -3313,6 +3313,7 @@ + #define MCURSOR_PIPE_A 0x00 + #define MCURSOR_PIPE_B (1 << 28) + #define MCURSOR_GAMMA_ENABLE (1 << 26) ++#define CURSOR_TRICKLE_FEED_DISABLE (1 << 14) + #define _CURABASE (dev_priv->info->display_mmio_offset + 0x70084) + #define _CURAPOS (dev_priv->info->display_mmio_offset + 0x70088) + #define CURSOR_POS_MASK 0x007FF +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index b27738d0b49d..2fd611ac91ba 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -2077,8 +2077,10 @@ static int ironlake_update_plane(struct drm_crtc *crtc, + else + dspcntr &= ~DISPPLANE_TILED; + +- /* must disable */ +- dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; ++ if (IS_HASWELL(dev)) ++ dspcntr &= ~DISPPLANE_TRICKLE_FEED_DISABLE; ++ else ++ dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; + + I915_WRITE(reg, dspcntr); + +@@ -6764,8 +6766,10 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) + cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); + cntl |= CURSOR_MODE_DISABLE; + } +- if (IS_HASWELL(dev)) ++ if (IS_HASWELL(dev)) { + cntl |= CURSOR_PIPE_CSC_ENABLE; ++ cntl &= ~CURSOR_TRICKLE_FEED_DISABLE; ++ } + I915_WRITE(CURCNTR_IVB(pipe), cntl); + + intel_crtc->cursor_visible = visible; +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 6b1d00389952..0c115cc4899f 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4960,8 +4960,6 @@ static void haswell_init_clock_gating(struct drm_device *dev) + I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | + GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); + +- g4x_disable_trickle_feed(dev); +- + /* WaVSRefCountFullforceMissDisable:hsw */ + gen7_setup_fixed_func_scheduler(dev_priv); + +diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c +index 78b621cdd108..ad6ec4b39005 100644 +--- a/drivers/gpu/drm/i915/intel_sprite.c ++++ b/drivers/gpu/drm/i915/intel_sprite.c +@@ -260,8 +260,11 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, + if (obj->tiling_mode != I915_TILING_NONE) + sprctl |= SPRITE_TILED; + +- /* must disable */ +- sprctl |= SPRITE_TRICKLE_FEED_DISABLE; ++ if (IS_HASWELL(dev)) ++ sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE; ++ else ++ sprctl |= SPRITE_TRICKLE_FEED_DISABLE; ++ + sprctl |= SPRITE_ENABLE; + + if (IS_HASWELL(dev)) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0754-drm-i915-Pin-pages-whilst-mapping-the-dma-buf.patch b/patches.baytrail/0754-drm-i915-Pin-pages-whilst-mapping-the-dma-buf.patch new file mode 100644 index 000000000000..71ef8b2580cb --- /dev/null +++ b/patches.baytrail/0754-drm-i915-Pin-pages-whilst-mapping-the-dma-buf.patch @@ -0,0 +1,94 @@ +From 91886177feb405d8735efd14df9ba7cf0e4098bc Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 26 Aug 2013 19:50:55 -0300 +Subject: drm/i915: Pin pages whilst mapping the dma-buf + +As we attempt to kmalloc after calling get_pages, there is a possibility +that the shrinker may reap the pages we just acquired. To prevent this +we need to increment the pages_pin_count early, so rearrange the code +and error paths to make it so. + +Signed-off-by: Chris Wilson +Reviewed-by: Damien Lespiau +Signed-off-by: Daniel Vetter +(cherry picked from commit 5cfacdedb1a94efd29faeaab53f939554a3f5943) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_dmabuf.c | 41 ++++++++++++++++++---------------- + 1 file changed, 22 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c +index e918b05fcbdd..7d5752fda5f1 100644 +--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c ++++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c +@@ -42,27 +42,24 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme + + ret = i915_mutex_lock_interruptible(obj->base.dev); + if (ret) +- return ERR_PTR(ret); ++ goto err; + + ret = i915_gem_object_get_pages(obj); +- if (ret) { +- st = ERR_PTR(ret); +- goto out; +- } ++ if (ret) ++ goto err_unlock; ++ ++ i915_gem_object_pin_pages(obj); + + /* Copy sg so that we make an independent mapping */ + st = kmalloc(sizeof(struct sg_table), GFP_KERNEL); + if (st == NULL) { +- st = ERR_PTR(-ENOMEM); +- goto out; ++ ret = -ENOMEM; ++ goto err_unpin; + } + + ret = sg_alloc_table(st, obj->pages->nents, GFP_KERNEL); +- if (ret) { +- kfree(st); +- st = ERR_PTR(ret); +- goto out; +- } ++ if (ret) ++ goto err_free; + + src = obj->pages->sgl; + dst = st->sgl; +@@ -73,17 +70,23 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme + } + + if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) { +- sg_free_table(st); +- kfree(st); +- st = ERR_PTR(-ENOMEM); +- goto out; ++ ret =-ENOMEM; ++ goto err_free_sg; + } + +- i915_gem_object_pin_pages(obj); +- +-out: + mutex_unlock(&obj->base.dev->struct_mutex); + return st; ++ ++err_free_sg: ++ sg_free_table(st); ++err_free: ++ kfree(st); ++err_unpin: ++ i915_gem_object_unpin_pages(obj); ++err_unlock: ++ mutex_unlock(&obj->base.dev->struct_mutex); ++err: ++ return ERR_PTR(ret); + } + + static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0755-i915-Update-VGA-arbiter-support-for-newer-devices.patch b/patches.baytrail/0755-i915-Update-VGA-arbiter-support-for-newer-devices.patch new file mode 100644 index 000000000000..79e99e8579bd --- /dev/null +++ b/patches.baytrail/0755-i915-Update-VGA-arbiter-support-for-newer-devices.patch @@ -0,0 +1,137 @@ +From d849169ef2bbffbee90e550acd987086548fbc6f Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Wed, 28 Aug 2013 09:39:08 -0600 +Subject: i915: Update VGA arbiter support for newer devices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is intended to add VGA arbiter support for Intel HD graphics on +Core processors. The old GMCH registers no longer exist, so even +though it appears that i915 participates in VGA arbitration, it doesn't +work. On Intel HD graphics we already attempt to disable VGA regions +of the device. This makes registering as a VGA client unnecessary since +we don't intend to operate differently depending on how many VGA devices +are present. We can disable VGA memory regions by clearing the memory +enable bit in the VGA MSR. That only leaves VGA IO, which we update +the VGA arbiter to know that we don't participate in VGA memory +arbitration. We also add a hook on unload to re-enable memory and +reinstate VGA memory arbitration. + +v3: Use explicit LEGACY_IO | LEGACY_MEM when restoring rather than + LEGACY_MASK, per Ville's comments. + +v2: I915_READ/WRITE accessors don't work in i915_disable_vga, use inb/outb + directly. Also, on the driver unbind VGA enable path, acquire legacy + IO to re-enable VGA memory. Correct comment. + +Signed-off-by: Alex Williamson +Reviewed-by: Ville Syrjälä +[danvet: Add patch changelog. Also squash in a fixup to have a dummy +static inline for vga_set_legacy_decoding for CONFIG_VGA_ARB=n as +reported by the 0-day kernel build bot.] +Signed-off-by: Daniel Vetter + +fixup 2 + +(cherry picked from commit 81b5c7bc8de3e6f63419139c2fc91bf81dea8a7d) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_dma.c | 9 ++++++--- + drivers/gpu/drm/i915/intel_display.c | 25 +++++++++++++++++++++++++ + include/linux/vgaarb.h | 7 +++++++ + 3 files changed, 38 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index fdaa0915ce56..3de60503378e 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -1290,9 +1290,12 @@ static int i915_load_modeset_init(struct drm_device *dev) + * then we do not take part in VGA arbitration and the + * vga_client_register() fails with -ENODEV. + */ +- ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode); +- if (ret && ret != -ENODEV) +- goto out; ++ if (!HAS_PCH_SPLIT(dev)) { ++ ret = vga_client_register(dev->pdev, dev, NULL, ++ i915_vga_set_decode); ++ if (ret && ret != -ENODEV) ++ goto out; ++ } + + intel_register_dsm_handler(); + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 2fd611ac91ba..369fdb452125 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -10045,6 +10045,15 @@ static void i915_disable_vga(struct drm_device *dev) + outb(SR01, VGA_SR_INDEX); + sr1 = inb(VGA_SR_DATA); + outb(sr1 | 1<<5, VGA_SR_DATA); ++ ++ /* Disable VGA memory on Intel HD */ ++ if (HAS_PCH_SPLIT(dev)) { ++ outb(inb(VGA_MSR_READ) & ~VGA_MSR_MEM_EN, VGA_MSR_WRITE); ++ vga_set_legacy_decoding(dev->pdev, VGA_RSRC_LEGACY_IO | ++ VGA_RSRC_NORMAL_IO | ++ VGA_RSRC_NORMAL_MEM); ++ } ++ + vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); + udelay(300); + +@@ -10052,6 +10061,20 @@ static void i915_disable_vga(struct drm_device *dev) + POSTING_READ(vga_reg); + } + ++static void i915_enable_vga(struct drm_device *dev) ++{ ++ /* Enable VGA memory on Intel HD */ ++ if (HAS_PCH_SPLIT(dev)) { ++ vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); ++ outb(inb(VGA_MSR_READ) | VGA_MSR_MEM_EN, VGA_MSR_WRITE); ++ vga_set_legacy_decoding(dev->pdev, VGA_RSRC_LEGACY_IO | ++ VGA_RSRC_LEGACY_MEM | ++ VGA_RSRC_NORMAL_IO | ++ VGA_RSRC_NORMAL_MEM); ++ vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); ++ } ++} ++ + void intel_modeset_init_hw(struct drm_device *dev) + { + intel_init_power_well(dev); +@@ -10543,6 +10566,8 @@ void intel_modeset_cleanup(struct drm_device *dev) + + intel_disable_fbc(dev); + ++ i915_enable_vga(dev); ++ + intel_disable_gt_powersave(dev); + + ironlake_teardown_rc6(dev); +diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h +index 2c02f3a8d2ba..80cf8173a65b 100644 +--- a/include/linux/vgaarb.h ++++ b/include/linux/vgaarb.h +@@ -65,8 +65,15 @@ struct pci_dev; + * out of the arbitration process (and can be safe to take + * interrupts at any time. + */ ++#if defined(CONFIG_VGA_ARB) + extern void vga_set_legacy_decoding(struct pci_dev *pdev, + unsigned int decodes); ++#else ++static inline void vga_set_legacy_decoding(struct pci_dev *pdev, ++ unsigned int decodes) ++{ ++} ++#endif + + /** + * vga_get - acquire & locks VGA resources +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0756-drm-i915-Don-t-call-sg_free_table-if-sg_alloc_table-.patch b/patches.baytrail/0756-drm-i915-Don-t-call-sg_free_table-if-sg_alloc_table-.patch new file mode 100644 index 000000000000..719c6bf07880 --- /dev/null +++ b/patches.baytrail/0756-drm-i915-Don-t-call-sg_free_table-if-sg_alloc_table-.patch @@ -0,0 +1,32 @@ +From 710dd08d2f6c863d3d70a340b3e61010799daa89 Mon Sep 17 00:00:00 2001 +From: Damien Lespiau +Date: Fri, 30 Aug 2013 15:39:26 +0100 +Subject: drm/i915: Don't call sg_free_table() if sg_alloc_table() fails + +One needs to call __sg_free_table() if __sg_alloc_table() fails, but +sg_alloc_table() does that for us already. + +Signed-off-by: Damien Lespiau +Reviewd-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit d2933a5b8f8f11cbdf9d2e44f0c7c7abeeb64e6b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 61313054fce6..f21a0c36a40b 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -1774,7 +1774,6 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) + + page_count = obj->base.size / PAGE_SIZE; + if (sg_alloc_table(st, page_count, GFP_KERNEL)) { +- sg_free_table(st); + kfree(st); + return -ENOMEM; + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0757-drm-i915-Fix-pipe-config-warnings-when-dealing-with-.patch b/patches.baytrail/0757-drm-i915-Fix-pipe-config-warnings-when-dealing-with-.patch new file mode 100644 index 000000000000..d4e96babb619 --- /dev/null +++ b/patches.baytrail/0757-drm-i915-Fix-pipe-config-warnings-when-dealing-with-.patch @@ -0,0 +1,98 @@ +From 8b440bc751d5c535ea74818380676ef054245102 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Mon, 2 Sep 2013 21:13:39 +0300 +Subject: drm/i915: Fix pipe config warnings when dealing with LVDS fixed mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +intel_fixed_panel_mode() overwrote the adjusted_mode with the fixed mode +only partially. Notably it forgot to copy over the sync flags. The LVDS code however programmed the hardware with the sync flags from fixed mode, and then later the pipe config comparison obviously failed as we +filled out the adjusted_mode in get_config from the real registers. + +Just call drm_mode_copy() in intel_fixed_panel_mode() to copy over the +whole thing, and then just use adjusted_mode in the LVDS code to figure +out which sync settings the hardware needs. + +Also constify the fixed_mode argument to intel_fixed_panel_mode(). + +Signed-off-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 4c6df4b4ca1b26f4532d403b544f649a1c801fd1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_drv.h | 2 +- + drivers/gpu/drm/i915/intel_lvds.c | 8 ++++---- + drivers/gpu/drm/i915/intel_panel.c | 14 ++------------ + 3 files changed, 7 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 176080822a74..dbfe5f7bb3de 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -551,7 +551,7 @@ extern int intel_panel_init(struct intel_panel *panel, + struct drm_display_mode *fixed_mode); + extern void intel_panel_fini(struct intel_panel *panel); + +-extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, ++extern void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, + struct drm_display_mode *adjusted_mode); + extern void intel_pch_panel_fitting(struct intel_crtc *crtc, + struct intel_crtc_config *pipe_config, +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index acaaafc75502..b8af94a5be39 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -128,8 +128,8 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder) + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); +- struct drm_display_mode *fixed_mode = +- lvds_encoder->attached_connector->base.panel.fixed_mode; ++ const struct drm_display_mode *adjusted_mode = ++ &crtc->config.adjusted_mode; + int pipe = crtc->pipe; + u32 temp; + +@@ -183,9 +183,9 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder) + temp &= ~LVDS_ENABLE_DITHER; + } + temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); +- if (fixed_mode->flags & DRM_MODE_FLAG_NHSYNC) ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) + temp |= LVDS_HSYNC_POLARITY; +- if (fixed_mode->flags & DRM_MODE_FLAG_NVSYNC) ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) + temp |= LVDS_VSYNC_POLARITY; + + I915_WRITE(lvds_encoder->reg, temp); +diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c +index 913cb9d7fd32..42114ecbae0e 100644 +--- a/drivers/gpu/drm/i915/intel_panel.c ++++ b/drivers/gpu/drm/i915/intel_panel.c +@@ -36,20 +36,10 @@ + #define PCI_LBPC 0xf4 /* legacy/combination backlight modes */ + + void +-intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, ++intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, + struct drm_display_mode *adjusted_mode) + { +- adjusted_mode->hdisplay = fixed_mode->hdisplay; +- adjusted_mode->hsync_start = fixed_mode->hsync_start; +- adjusted_mode->hsync_end = fixed_mode->hsync_end; +- adjusted_mode->htotal = fixed_mode->htotal; +- +- adjusted_mode->vdisplay = fixed_mode->vdisplay; +- adjusted_mode->vsync_start = fixed_mode->vsync_start; +- adjusted_mode->vsync_end = fixed_mode->vsync_end; +- adjusted_mode->vtotal = fixed_mode->vtotal; +- +- adjusted_mode->clock = fixed_mode->clock; ++ drm_mode_copy(adjusted_mode, fixed_mode); + + drm_mode_set_crtcinfo(adjusted_mode, 0); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0758-drm-i915-fix-up-the-relocate_entry-refactoring.patch b/patches.baytrail/0758-drm-i915-fix-up-the-relocate_entry-refactoring.patch new file mode 100644 index 000000000000..999c138456c0 --- /dev/null +++ b/patches.baytrail/0758-drm-i915-fix-up-the-relocate_entry-refactoring.patch @@ -0,0 +1,42 @@ +From ecb19c85701f90c3830e6a09905b667b7b7f0a4f Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 2 Sep 2013 20:56:23 +0200 +Subject: drm/i915: fix up the relocate_entry refactoring + +Somehow we've lost the error handling in the patch split-up between +the internal and external patch. This regression has been introduced +in + +commit 5032d871f7d300aee10c309ea004eb4f851553fe +Author: Rafael Barbalho +Date: Wed Aug 21 17:10:51 2013 +0100 + + drm/i915: Cleaning up the relocate entry function + +This bug is exercised by igt/gem_reloc_vs_gpu/interruptible. + +Cc: Rafael Barbalho +Signed-off-by: Daniel Vetter +(cherry picked from commit d4d36014ca37e6fa8271b0690e678b76456faa01) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 792c52a235ee..bf345777ae9f 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -310,6 +310,9 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, + else + ret = relocate_entry_gtt(obj, reloc); + ++ if (ret) ++ return ret; ++ + /* and update the user's relocation entry */ + reloc->presumed_offset = target_offset; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0759-drm-i915-fix-hpd-work-vs.-flush_work-in-the-pageflip.patch b/patches.baytrail/0759-drm-i915-fix-hpd-work-vs.-flush_work-in-the-pageflip.patch new file mode 100644 index 000000000000..8acb9bafc026 --- /dev/null +++ b/patches.baytrail/0759-drm-i915-fix-hpd-work-vs.-flush_work-in-the-pageflip.patch @@ -0,0 +1,92 @@ +From b9e38537f8f9e07abdf9e5f1a266e1d6c1d83b9c Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 2 Sep 2013 16:22:25 +0200 +Subject: drm/i915: fix hpd work vs. flush_work in the pageflip code deadlock + +Historically we've run our own driver hotplug handling in our own +work-queue, which then launched the drm core hotplug handling in the +system workqueue. This is important since we flush our own driver +workqueue in the pageflip code while hodling modeset locks, and only +the drm hotplug code grabbed these locks. But with + +commit 69787f7da6b2adc4054357a661aaa1701a9ca76f +Author: Daniel Vetter +Date: Tue Oct 23 18:23:34 2012 +0000 + + drm: run the hpd irq event code directly + +this was changed and now we could deadlock in our flip handler if +there's a hotplug work blocking the progress of the crucial unpin +works. So this broke the careful deadlock avoidance implemented in + +commit b4a98e57fc27854b5938fc8b08b68e5e68b91e1f +Author: Chris Wilson +Date: Thu Nov 1 09:26:26 2012 +0000 + + drm/i915: Flush outstanding unpin tasks before pageflipping + +Since the rule thus far has been that work items on our own workqueue +may never grab modeset locks simply restore that rule again. + +v2: Add a comment to the declaration of dev_priv->wq to warn readers +about the tricky implications of using it. Suggested by Chris Wilson. + +Cc: Chris Wilson +Cc: Stuart Abercrombie +Reported-by: Stuart Abercrombie +References: http://permalink.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/26239 +Cc: stable@vger.kernel.org +Reviewed-by: Chris Wilson +[danvet: Squash in a comment at the place where we schedule the work. +Requested after-the-fact by Chris on irc since the hpd work isn't the +only place we botch this.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 645416f5adc87c8fae44289cdba7562f3ade8f5c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 7 +++++++ + drivers/gpu/drm/i915/i915_irq.c | 9 +++++++-- + 2 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 52a3785a3fdf..35874b3a86dc 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1236,6 +1236,13 @@ typedef struct drm_i915_private { + + unsigned int fsb_freq, mem_freq, is_ddr3; + ++ /** ++ * wq - Driver workqueue for GEM. ++ * ++ * NOTE: Work items scheduled here are not allowed to grab any modeset ++ * locks, for otherwise the flushing done in the pageflip code will ++ * result in deadlocks. ++ */ + struct workqueue_struct *wq; + + /* Display functions */ +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 4c137d6ea761..4b91228fd9bd 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1027,8 +1027,13 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, + dev_priv->display.hpd_irq_setup(dev); + spin_unlock(&dev_priv->irq_lock); + +- queue_work(dev_priv->wq, +- &dev_priv->hotplug_work); ++ /* ++ * Our hotplug handler can grab modeset locks (by calling down into the ++ * fb helpers). Hence it must not be run on our own dev-priv->wq work ++ * queue for otherwise the flush_work in the pageflip code will ++ * deadlock. ++ */ ++ schedule_work(&dev_priv->hotplug_work); + } + + static void gmbus_irq_handler(struct drm_device *dev) +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0760-drm-i915-handle-sdvo-input-pixel-multiplier-correctl.patch b/patches.baytrail/0760-drm-i915-handle-sdvo-input-pixel-multiplier-correctl.patch new file mode 100644 index 000000000000..7e1a35d3b06a --- /dev/null +++ b/patches.baytrail/0760-drm-i915-handle-sdvo-input-pixel-multiplier-correctl.patch @@ -0,0 +1,92 @@ +From 7742ef3f3c05272aa9016765c8ddb36429ff4a88 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 3 Sep 2013 20:40:36 +0200 +Subject: drm/i915: handle sdvo input pixel multiplier correctly again +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The sdvo input timing needs to be the actual mode, the sdvo +encoder automatically adjusts for the need of pixel doubling or +quadrupling. This was lost in pipe config conversion of the +pixel multiplier in + +commit 6cc5f341b5830541a1b6945435ca90c69b1b8b21 +Author: Daniel Vetter +Date: Wed Mar 27 00:44:53 2013 +0100 + + drm/i915: add pipe_config->pixel_multiplier + +While at it ditch the intel_ prefix from the crtc in +intel_sdvo_mode_set. + +Cc: Jesse Barnes +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit eeb4793779060e0ae27fc8a85b8dac2ab3620934) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_sdvo.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c +index 317e058fb3cf..85037b9d4934 100644 +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1151,11 +1151,10 @@ static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder) + { + struct drm_device *dev = intel_encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- struct drm_crtc *crtc = intel_encoder->base.crtc; +- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ struct intel_crtc *crtc = to_intel_crtc(intel_encoder->base.crtc); + struct drm_display_mode *adjusted_mode = +- &intel_crtc->config.adjusted_mode; +- struct drm_display_mode *mode = &intel_crtc->config.requested_mode; ++ &crtc->config.adjusted_mode; ++ struct drm_display_mode *mode = &crtc->config.requested_mode; + struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder); + u32 sdvox; + struct intel_sdvo_in_out_map in_out; +@@ -1213,13 +1212,15 @@ static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder) + * adjusted_mode. + */ + intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); ++ input_dtd.part1.clock /= crtc->config.pixel_multiplier; ++ + if (intel_sdvo->is_tv || intel_sdvo->is_lvds) + input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags; + if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) + DRM_INFO("Setting input timings on %s failed\n", + SDVO_NAME(intel_sdvo)); + +- switch (intel_crtc->config.pixel_multiplier) { ++ switch (crtc->config.pixel_multiplier) { + default: + WARN(1, "unknown pixel mutlipler specified\n"); + case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; +@@ -1252,9 +1253,9 @@ static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder) + } + + if (INTEL_PCH_TYPE(dev) >= PCH_CPT) +- sdvox |= SDVO_PIPE_SEL_CPT(intel_crtc->pipe); ++ sdvox |= SDVO_PIPE_SEL_CPT(crtc->pipe); + else +- sdvox |= SDVO_PIPE_SEL(intel_crtc->pipe); ++ sdvox |= SDVO_PIPE_SEL(crtc->pipe); + + if (intel_sdvo->has_hdmi_audio) + sdvox |= SDVO_AUDIO_ENABLE; +@@ -1264,7 +1265,7 @@ static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder) + } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { + /* done in crtc_mode_set as it lives inside the dpll register */ + } else { +- sdvox |= (intel_crtc->config.pixel_multiplier - 1) ++ sdvox |= (crtc->config.pixel_multiplier - 1) + << SDVO_PORT_MULTIPLY_SHIFT; + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0761-drm-i915-fix-i9xx_crtc_clock_get-for-multiplied-pixe.patch b/patches.baytrail/0761-drm-i915-fix-i9xx_crtc_clock_get-for-multiplied-pixe.patch new file mode 100644 index 000000000000..5970f949984d --- /dev/null +++ b/patches.baytrail/0761-drm-i915-fix-i9xx_crtc_clock_get-for-multiplied-pixe.patch @@ -0,0 +1,50 @@ +From f0e96ae2b5b6c9cec49a6e0e4de85d286e90cf9a Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 3 Sep 2013 20:40:37 +0200 +Subject: drm/i915: fix i9xx_crtc_clock_get for multiplied pixels +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The dpll actually runs at the port clock so we don't need +to multiply it again with the pixel multiplier to get the +adjusted_mode.clock. This is in contrast to the ironlake +pixel clock readout code which uses the fdi dotclock: That +one does _not_ run with multiplied pixels. + +This issue goes back to the original clock readout code added +in + +commit f1f644dc66cbaf5a4c7dcde683361536b41885b9 +Author: Jesse Barnes +Date: Thu Jun 27 00:39:25 2013 +0300 + + drm/i915: get mode clock when reading the pipe config v9 + +Cc: Jesse Barnes +Cc: Ville Syrjälä +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit a2dc53e7dc4d22f20aecdfa10f85004de442e4d0) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_display.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 369fdb452125..403580f53764 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -7317,8 +7317,7 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, + } + } + +- pipe_config->adjusted_mode.clock = clock.dot * +- pipe_config->pixel_multiplier; ++ pipe_config->adjusted_mode.clock = clock.dot; + } + + static void ironlake_crtc_clock_get(struct intel_crtc *crtc, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0762-drm-i915-Convert-execbuf-code-to-use-vmas.patch b/patches.baytrail/0762-drm-i915-Convert-execbuf-code-to-use-vmas.patch new file mode 100644 index 000000000000..55e50eae5a80 --- /dev/null +++ b/patches.baytrail/0762-drm-i915-Convert-execbuf-code-to-use-vmas.patch @@ -0,0 +1,790 @@ +From 5d48ef03d16356e15cae49456706339d40e973d4 Mon Sep 17 00:00:00 2001 +From: Ben Widawsky +Date: Wed, 14 Aug 2013 11:38:36 +0200 +Subject: drm/i915: Convert execbuf code to use vmas + +In order to transition more of our code over to using a VMA instead of +an pair - we must have the vma accessible at execbuf time. Up +until now, we've only had a VMA when actually binding an object. + +The previous patch helped handle the distinction on bound vs. unbound. +This patch will help us catch leaks, and other issues before we actually +shuffle a bunch of stuff around. + +This attempts to convert all the execbuf code to speak in vmas. Since +the execbuf code is very self contained it was a nice isolated +conversion. + +The meat of the code is about turning eb_objects into eb_vma, and then +wiring up the rest of the code to use vmas instead of obj, vm pairs. + +Unfortunately, to do this, we must move the exec_list link from the obj +structure. This list is reused in the eviction code, so we must also +modify the eviction code to make this work. + +WARNING: This patch makes an already hotly profiled path slower. The cost is +unavoidable. In reply to this mail, I will attach the extra data. + +v2: Release table lock early, and two a 2 phase vma lookup to avoid +having to use a GFP_ATOMIC. (Chris) + +v3: s/obj_exec_list/obj_exec_link/ +Updates to address +commit 6d2b888569d366beb4be72cacfde41adee2c25e1 +Author: Chris Wilson +Date: Wed Aug 7 18:30:54 2013 +0100 + + drm/i915: List objects allocated from stolen memory in debugfs + +v4: Use obj = vma->obj for neatness in some places (Chris) +need_reloc_mappable() should return false if ppgtt (Chris) + +Signed-off-by: Ben Widawsky +[danvet: Split out prep patches. Also remove a FIXME comment which is +now taken care of.] +Signed-off-by: Daniel Vetter + +(cherry picked from commit 27173f1f95db5e74ceb35fe9a2f2f348ea11bac9) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 16 +- + drivers/gpu/drm/i915/i915_gem.c | 1 - + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 320 ++++++++++++++++------------- + 3 files changed, 183 insertions(+), 154 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 35874b3a86dc..b6494b24098d 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -568,6 +568,13 @@ struct i915_vma { + /** This vma's place in the batchbuffer or on the eviction list */ + struct list_head exec_list; + ++ /** ++ * Used for performing relocations during execbuffer insertion. ++ */ ++ struct hlist_node exec_node; ++ unsigned long exec_handle; ++ struct drm_i915_gem_exec_object2 *exec_entry; ++ + }; + + struct i915_ctx_hang_stats { +@@ -1398,8 +1405,6 @@ struct drm_i915_gem_object { + struct list_head ring_list; + /** Used in execbuf to temporarily hold a ref */ + struct list_head obj_exec_link; +- /** This object's place in the batchbuffer or on the eviction list */ +- struct list_head exec_list; + + /** + * This is set if the object is on the active lists (has pending +@@ -1485,13 +1490,6 @@ struct drm_i915_gem_object { + void *dma_buf_vmapping; + int vmapping_count; + +- /** +- * Used for performing relocations during execbuffer insertion. +- */ +- struct hlist_node exec_node; +- unsigned long exec_handle; +- struct drm_i915_gem_exec_object2 *exec_entry; +- + struct intel_ring_buffer *ring; + + /** Breadcrumb of last rendering to the buffer. */ +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index f21a0c36a40b..c4c56f98d6e6 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -3978,7 +3978,6 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, + { + INIT_LIST_HEAD(&obj->global_list); + INIT_LIST_HEAD(&obj->ring_list); +- INIT_LIST_HEAD(&obj->exec_list); + INIT_LIST_HEAD(&obj->obj_exec_link); + INIT_LIST_HEAD(&obj->vma_list); + +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index bf345777ae9f..5dcfd4f59f87 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -33,24 +33,24 @@ + #include "intel_drv.h" + #include + +-struct eb_objects { +- struct list_head objects; ++struct eb_vmas { ++ struct list_head vmas; + int and; + union { +- struct drm_i915_gem_object *lut[0]; ++ struct i915_vma *lut[0]; + struct hlist_head buckets[0]; + }; + }; + +-static struct eb_objects * +-eb_create(struct drm_i915_gem_execbuffer2 *args) ++static struct eb_vmas * ++eb_create(struct drm_i915_gem_execbuffer2 *args, struct i915_address_space *vm) + { +- struct eb_objects *eb = NULL; ++ struct eb_vmas *eb = NULL; + + if (args->flags & I915_EXEC_HANDLE_LUT) { + int size = args->buffer_count; +- size *= sizeof(struct drm_i915_gem_object *); +- size += sizeof(struct eb_objects); ++ size *= sizeof(struct i915_vma *); ++ size += sizeof(struct eb_vmas); + eb = kmalloc(size, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY); + } + +@@ -61,7 +61,7 @@ eb_create(struct drm_i915_gem_execbuffer2 *args) + while (count > 2*size) + count >>= 1; + eb = kzalloc(count*sizeof(struct hlist_head) + +- sizeof(struct eb_objects), ++ sizeof(struct eb_vmas), + GFP_TEMPORARY); + if (eb == NULL) + return eb; +@@ -70,64 +70,97 @@ eb_create(struct drm_i915_gem_execbuffer2 *args) + } else + eb->and = -args->buffer_count; + +- INIT_LIST_HEAD(&eb->objects); ++ INIT_LIST_HEAD(&eb->vmas); + return eb; + } + + static void +-eb_reset(struct eb_objects *eb) ++eb_reset(struct eb_vmas *eb) + { + if (eb->and >= 0) + memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head)); + } + + static int +-eb_lookup_objects(struct eb_objects *eb, +- struct drm_i915_gem_exec_object2 *exec, +- const struct drm_i915_gem_execbuffer2 *args, +- struct drm_file *file) ++eb_lookup_vmas(struct eb_vmas *eb, ++ struct drm_i915_gem_exec_object2 *exec, ++ const struct drm_i915_gem_execbuffer2 *args, ++ struct i915_address_space *vm, ++ struct drm_file *file) + { +- int i; ++ struct drm_i915_gem_object *obj; ++ struct list_head objects; ++ int i, ret = 0; + ++ INIT_LIST_HEAD(&objects); + spin_lock(&file->table_lock); ++ /* Grab a reference to the object and release the lock so we can lookup ++ * or create the VMA without using GFP_ATOMIC */ + for (i = 0; i < args->buffer_count; i++) { +- struct drm_i915_gem_object *obj; +- + obj = to_intel_bo(idr_find(&file->object_idr, exec[i].handle)); + if (obj == NULL) { + spin_unlock(&file->table_lock); + DRM_DEBUG("Invalid object handle %d at index %d\n", + exec[i].handle, i); +- return -ENOENT; ++ ret = -ENOENT; ++ goto out; + } + +- if (!list_empty(&obj->exec_list)) { ++ if (!list_empty(&obj->obj_exec_link)) { + spin_unlock(&file->table_lock); + DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", + obj, exec[i].handle, i); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out; + } + + drm_gem_object_reference(&obj->base); +- list_add_tail(&obj->exec_list, &eb->objects); ++ list_add_tail(&obj->obj_exec_link, &objects); ++ } ++ spin_unlock(&file->table_lock); + +- obj->exec_entry = &exec[i]; ++ i = 0; ++ list_for_each_entry(obj, &objects, obj_exec_link) { ++ struct i915_vma *vma; ++ ++ vma = i915_gem_obj_lookup_or_create_vma(obj, vm); ++ if (IS_ERR(vma)) { ++ /* XXX: We don't need an error path fro vma because if ++ * the vma was created just for this execbuf, object ++ * unreference should kill it off.*/ ++ DRM_DEBUG("Failed to lookup VMA\n"); ++ ret = PTR_ERR(vma); ++ goto out; ++ } ++ ++ list_add_tail(&vma->exec_list, &eb->vmas); ++ ++ vma->exec_entry = &exec[i]; + if (eb->and < 0) { +- eb->lut[i] = obj; ++ eb->lut[i] = vma; + } else { + uint32_t handle = args->flags & I915_EXEC_HANDLE_LUT ? i : exec[i].handle; +- obj->exec_handle = handle; +- hlist_add_head(&obj->exec_node, ++ vma->exec_handle = handle; ++ hlist_add_head(&vma->exec_node, + &eb->buckets[handle & eb->and]); + } ++ ++i; + } +- spin_unlock(&file->table_lock); + +- return 0; ++ ++out: ++ while (!list_empty(&objects)) { ++ obj = list_first_entry(&objects, ++ struct drm_i915_gem_object, ++ obj_exec_link); ++ list_del_init(&obj->obj_exec_link); ++ if (ret) ++ drm_gem_object_unreference(&obj->base); ++ } ++ return ret; + } + +-static struct drm_i915_gem_object * +-eb_get_object(struct eb_objects *eb, unsigned long handle) ++static struct i915_vma *eb_get_vma(struct eb_vmas *eb, unsigned long handle) + { + if (eb->and < 0) { + if (handle >= -eb->and) +@@ -139,27 +172,25 @@ eb_get_object(struct eb_objects *eb, unsigned long handle) + + head = &eb->buckets[handle & eb->and]; + hlist_for_each(node, head) { +- struct drm_i915_gem_object *obj; ++ struct i915_vma *vma; + +- obj = hlist_entry(node, struct drm_i915_gem_object, exec_node); +- if (obj->exec_handle == handle) +- return obj; ++ vma = hlist_entry(node, struct i915_vma, exec_node); ++ if (vma->exec_handle == handle) ++ return vma; + } + return NULL; + } + } + +-static void +-eb_destroy(struct eb_objects *eb) +-{ +- while (!list_empty(&eb->objects)) { +- struct drm_i915_gem_object *obj; ++static void eb_destroy(struct eb_vmas *eb) { ++ while (!list_empty(&eb->vmas)) { ++ struct i915_vma *vma; + +- obj = list_first_entry(&eb->objects, +- struct drm_i915_gem_object, ++ vma = list_first_entry(&eb->vmas, ++ struct i915_vma, + exec_list); +- list_del_init(&obj->exec_list); +- drm_gem_object_unreference(&obj->base); ++ list_del_init(&vma->exec_list); ++ drm_gem_object_unreference(&vma->obj->base); + } + kfree(eb); + } +@@ -223,22 +254,24 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, + + static int + i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, +- struct eb_objects *eb, ++ struct eb_vmas *eb, + struct drm_i915_gem_relocation_entry *reloc, + struct i915_address_space *vm) + { + struct drm_device *dev = obj->base.dev; + struct drm_gem_object *target_obj; + struct drm_i915_gem_object *target_i915_obj; ++ struct i915_vma *target_vma; + uint32_t target_offset; + int ret = -EINVAL; + + /* we've already hold a reference to all valid objects */ +- target_obj = &eb_get_object(eb, reloc->target_handle)->base; +- if (unlikely(target_obj == NULL)) ++ target_vma = eb_get_vma(eb, reloc->target_handle); ++ if (unlikely(target_vma == NULL)) + return -ENOENT; ++ target_i915_obj = target_vma->obj; ++ target_obj = &target_vma->obj->base; + +- target_i915_obj = to_intel_bo(target_obj); + target_offset = i915_gem_obj_ggtt_offset(target_i915_obj); + + /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and +@@ -320,14 +353,13 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, + } + + static int +-i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, +- struct eb_objects *eb, +- struct i915_address_space *vm) ++i915_gem_execbuffer_relocate_vma(struct i915_vma *vma, ++ struct eb_vmas *eb) + { + #define N_RELOC(x) ((x) / sizeof(struct drm_i915_gem_relocation_entry)) + struct drm_i915_gem_relocation_entry stack_reloc[N_RELOC(512)]; + struct drm_i915_gem_relocation_entry __user *user_relocs; +- struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; ++ struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; + int remain, ret; + + user_relocs = to_user_ptr(entry->relocs_ptr); +@@ -346,8 +378,8 @@ i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, + do { + u64 offset = r->presumed_offset; + +- ret = i915_gem_execbuffer_relocate_entry(obj, eb, r, +- vm); ++ ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, r, ++ vma->vm); + if (ret) + return ret; + +@@ -368,17 +400,16 @@ i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, + } + + static int +-i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, +- struct eb_objects *eb, +- struct drm_i915_gem_relocation_entry *relocs, +- struct i915_address_space *vm) ++i915_gem_execbuffer_relocate_vma_slow(struct i915_vma *vma, ++ struct eb_vmas *eb, ++ struct drm_i915_gem_relocation_entry *relocs) + { +- const struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; ++ const struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; + int i, ret; + + for (i = 0; i < entry->relocation_count; i++) { +- ret = i915_gem_execbuffer_relocate_entry(obj, eb, &relocs[i], +- vm); ++ ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, &relocs[i], ++ vma->vm); + if (ret) + return ret; + } +@@ -387,10 +418,10 @@ i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, + } + + static int +-i915_gem_execbuffer_relocate(struct eb_objects *eb, ++i915_gem_execbuffer_relocate(struct eb_vmas *eb, + struct i915_address_space *vm) + { +- struct drm_i915_gem_object *obj; ++ struct i915_vma *vma; + int ret = 0; + + /* This is the fast path and we cannot handle a pagefault whilst +@@ -401,8 +432,8 @@ i915_gem_execbuffer_relocate(struct eb_objects *eb, + * lockdep complains vehemently. + */ + pagefault_disable(); +- list_for_each_entry(obj, &eb->objects, exec_list) { +- ret = i915_gem_execbuffer_relocate_object(obj, eb, vm); ++ list_for_each_entry(vma, &eb->vmas, exec_list) { ++ ret = i915_gem_execbuffer_relocate_vma(vma, eb); + if (ret) + break; + } +@@ -415,31 +446,32 @@ i915_gem_execbuffer_relocate(struct eb_objects *eb, + #define __EXEC_OBJECT_HAS_FENCE (1<<30) + + static int +-need_reloc_mappable(struct drm_i915_gem_object *obj) ++need_reloc_mappable(struct i915_vma *vma) + { +- struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; +- return entry->relocation_count && !use_cpu_reloc(obj); ++ struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; ++ return entry->relocation_count && !use_cpu_reloc(vma->obj) && ++ i915_is_ggtt(vma->vm); + } + + static int +-i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj, +- struct intel_ring_buffer *ring, +- struct i915_address_space *vm, +- bool *need_reloc) ++i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, ++ struct intel_ring_buffer *ring, ++ bool *need_reloc) + { +- struct drm_i915_private *dev_priv = obj->base.dev->dev_private; +- struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; ++ struct drm_i915_private *dev_priv = ring->dev->dev_private; ++ struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; + bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; + bool need_fence, need_mappable; ++ struct drm_i915_gem_object *obj = vma->obj; + int ret; + + need_fence = + has_fenced_gpu_access && + entry->flags & EXEC_OBJECT_NEEDS_FENCE && + obj->tiling_mode != I915_TILING_NONE; +- need_mappable = need_fence || need_reloc_mappable(obj); ++ need_mappable = need_fence || need_reloc_mappable(vma); + +- ret = i915_gem_object_pin(obj, vm, entry->alignment, need_mappable, ++ ret = i915_gem_object_pin(obj, vma->vm, entry->alignment, need_mappable, + false); + if (ret) + return ret; +@@ -467,8 +499,8 @@ i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj, + obj->has_aliasing_ppgtt_mapping = 1; + } + +- if (entry->offset != i915_gem_obj_offset(obj, vm)) { +- entry->offset = i915_gem_obj_offset(obj, vm); ++ if (entry->offset != vma->node.start) { ++ entry->offset = vma->node.start; + *need_reloc = true; + } + +@@ -485,14 +517,15 @@ i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj, + } + + static void +-i915_gem_execbuffer_unreserve_object(struct drm_i915_gem_object *obj) ++i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma) + { + struct drm_i915_gem_exec_object2 *entry; ++ struct drm_i915_gem_object *obj = vma->obj; + +- if (!i915_gem_obj_bound_any(obj)) ++ if (!drm_mm_node_allocated(&vma->node)) + return; + +- entry = obj->exec_entry; ++ entry = vma->exec_entry; + + if (entry->flags & __EXEC_OBJECT_HAS_FENCE) + i915_gem_object_unpin_fence(obj); +@@ -505,41 +538,40 @@ i915_gem_execbuffer_unreserve_object(struct drm_i915_gem_object *obj) + + static int + i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, +- struct list_head *objects, +- struct i915_address_space *vm, ++ struct list_head *vmas, + bool *need_relocs) + { + struct drm_i915_gem_object *obj; +- struct list_head ordered_objects; ++ struct i915_vma *vma; ++ struct list_head ordered_vmas; + bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; + int retry; + +- INIT_LIST_HEAD(&ordered_objects); +- while (!list_empty(objects)) { ++ INIT_LIST_HEAD(&ordered_vmas); ++ while (!list_empty(vmas)) { + struct drm_i915_gem_exec_object2 *entry; + bool need_fence, need_mappable; + +- obj = list_first_entry(objects, +- struct drm_i915_gem_object, +- exec_list); +- entry = obj->exec_entry; ++ vma = list_first_entry(vmas, struct i915_vma, exec_list); ++ obj = vma->obj; ++ entry = vma->exec_entry; + + need_fence = + has_fenced_gpu_access && + entry->flags & EXEC_OBJECT_NEEDS_FENCE && + obj->tiling_mode != I915_TILING_NONE; +- need_mappable = need_fence || need_reloc_mappable(obj); ++ need_mappable = need_fence || need_reloc_mappable(vma); + + if (need_mappable) +- list_move(&obj->exec_list, &ordered_objects); ++ list_move(&vma->exec_list, &ordered_vmas); + else +- list_move_tail(&obj->exec_list, &ordered_objects); ++ list_move_tail(&vma->exec_list, &ordered_vmas); + + obj->base.pending_read_domains = I915_GEM_GPU_DOMAINS & ~I915_GEM_DOMAIN_COMMAND; + obj->base.pending_write_domain = 0; + obj->pending_fenced_gpu_access = false; + } +- list_splice(&ordered_objects, objects); ++ list_splice(&ordered_vmas, vmas); + + /* Attempt to pin all of the buffers into the GTT. + * This is done in 3 phases: +@@ -558,47 +590,47 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, + int ret = 0; + + /* Unbind any ill-fitting objects or pin. */ +- list_for_each_entry(obj, objects, exec_list) { +- struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; ++ list_for_each_entry(vma, vmas, exec_list) { ++ struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; + bool need_fence, need_mappable; +- u32 obj_offset; + +- if (!i915_gem_obj_bound(obj, vm)) ++ obj = vma->obj; ++ ++ if (!drm_mm_node_allocated(&vma->node)) + continue; + +- obj_offset = i915_gem_obj_offset(obj, vm); + need_fence = + has_fenced_gpu_access && + entry->flags & EXEC_OBJECT_NEEDS_FENCE && + obj->tiling_mode != I915_TILING_NONE; +- need_mappable = need_fence || need_reloc_mappable(obj); ++ need_mappable = need_fence || need_reloc_mappable(vma); + + WARN_ON((need_mappable || need_fence) && +- !i915_is_ggtt(vm)); ++ !i915_is_ggtt(vma->vm)); + + if ((entry->alignment && +- obj_offset & (entry->alignment - 1)) || ++ vma->node.start & (entry->alignment - 1)) || + (need_mappable && !obj->map_and_fenceable)) +- ret = i915_vma_unbind(i915_gem_obj_to_vma(obj, vm)); ++ ret = i915_vma_unbind(vma); + else +- ret = i915_gem_execbuffer_reserve_object(obj, ring, vm, need_relocs); ++ ret = i915_gem_execbuffer_reserve_vma(vma, ring, need_relocs); + if (ret) + goto err; + } + + /* Bind fresh objects */ +- list_for_each_entry(obj, objects, exec_list) { +- if (i915_gem_obj_bound(obj, vm)) ++ list_for_each_entry(vma, vmas, exec_list) { ++ if (drm_mm_node_allocated(&vma->node)) + continue; + +- ret = i915_gem_execbuffer_reserve_object(obj, ring, vm, need_relocs); ++ ret = i915_gem_execbuffer_reserve_vma(vma, ring, need_relocs); + if (ret) + goto err; + } + + err: /* Decrement pin count for bound objects */ +- list_for_each_entry(obj, objects, exec_list) +- i915_gem_execbuffer_unreserve_object(obj); ++ list_for_each_entry(vma, vmas, exec_list) ++ i915_gem_execbuffer_unreserve_vma(vma); + + if (ret != -ENOSPC || retry++) + return ret; +@@ -614,24 +646,27 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, + struct drm_i915_gem_execbuffer2 *args, + struct drm_file *file, + struct intel_ring_buffer *ring, +- struct eb_objects *eb, +- struct drm_i915_gem_exec_object2 *exec, +- struct i915_address_space *vm) ++ struct eb_vmas *eb, ++ struct drm_i915_gem_exec_object2 *exec) + { + struct drm_i915_gem_relocation_entry *reloc; +- struct drm_i915_gem_object *obj; ++ struct i915_address_space *vm; ++ struct i915_vma *vma; + bool need_relocs; + int *reloc_offset; + int i, total, ret; + int count = args->buffer_count; + ++ if (WARN_ON(list_empty(&eb->vmas))) ++ return 0; ++ ++ vm = list_first_entry(&eb->vmas, struct i915_vma, exec_list)->vm; ++ + /* We may process another execbuffer during the unlock... */ +- while (!list_empty(&eb->objects)) { +- obj = list_first_entry(&eb->objects, +- struct drm_i915_gem_object, +- exec_list); +- list_del_init(&obj->exec_list); +- drm_gem_object_unreference(&obj->base); ++ while (!list_empty(&eb->vmas)) { ++ vma = list_first_entry(&eb->vmas, struct i915_vma, exec_list); ++ list_del_init(&vma->exec_list); ++ drm_gem_object_unreference(&vma->obj->base); + } + + mutex_unlock(&dev->struct_mutex); +@@ -695,20 +730,19 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, + + /* reacquire the objects */ + eb_reset(eb); +- ret = eb_lookup_objects(eb, exec, args, file); ++ ret = eb_lookup_vmas(eb, exec, args, vm, file); + if (ret) + goto err; + + need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; +- ret = i915_gem_execbuffer_reserve(ring, &eb->objects, vm, &need_relocs); ++ ret = i915_gem_execbuffer_reserve(ring, &eb->vmas, &need_relocs); + if (ret) + goto err; + +- list_for_each_entry(obj, &eb->objects, exec_list) { +- int offset = obj->exec_entry - exec; +- ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, +- reloc + reloc_offset[offset], +- vm); ++ list_for_each_entry(vma, &eb->vmas, exec_list) { ++ int offset = vma->exec_entry - exec; ++ ret = i915_gem_execbuffer_relocate_vma_slow(vma, eb, ++ reloc + reloc_offset[offset]); + if (ret) + goto err; + } +@@ -727,14 +761,15 @@ err: + + static int + i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, +- struct list_head *objects) ++ struct list_head *vmas) + { +- struct drm_i915_gem_object *obj; ++ struct i915_vma *vma; + uint32_t flush_domains = 0; + bool flush_chipset = false; + int ret; + +- list_for_each_entry(obj, objects, exec_list) { ++ list_for_each_entry(vma, vmas, exec_list) { ++ struct drm_i915_gem_object *obj = vma->obj; + ret = i915_gem_object_sync(obj, ring); + if (ret) + return ret; +@@ -809,13 +844,13 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, + } + + static void +-i915_gem_execbuffer_move_to_active(struct list_head *objects, +- struct i915_address_space *vm, ++i915_gem_execbuffer_move_to_active(struct list_head *vmas, + struct intel_ring_buffer *ring) + { +- struct drm_i915_gem_object *obj; ++ struct i915_vma *vma; + +- list_for_each_entry(obj, objects, exec_list) { ++ list_for_each_entry(vma, vmas, exec_list) { ++ struct drm_i915_gem_object *obj = vma->obj; + u32 old_read = obj->base.read_domains; + u32 old_write = obj->base.write_domain; + +@@ -825,8 +860,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects, + obj->base.read_domains = obj->base.pending_read_domains; + obj->fenced_gpu_access = obj->pending_fenced_gpu_access; + +- /* FIXME: This lookup gets fixed later <-- danvet */ +- list_move_tail(&i915_gem_obj_to_vma(obj, vm)->mm_list, &vm->active_list); ++ list_move_tail(&vma->mm_list, &vma->vm->active_list); + i915_gem_object_move_to_active(obj, ring); + if (obj->base.write_domain) { + obj->dirty = 1; +@@ -885,7 +919,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + struct i915_address_space *vm) + { + drm_i915_private_t *dev_priv = dev->dev_private; +- struct eb_objects *eb; ++ struct eb_vmas *eb; + struct drm_i915_gem_object *batch_obj; + struct drm_clip_rect *cliprects = NULL; + struct intel_ring_buffer *ring; +@@ -1025,7 +1059,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + goto pre_mutex_err; + } + +- eb = eb_create(args); ++ eb = eb_create(args, vm); + if (eb == NULL) { + mutex_unlock(&dev->struct_mutex); + ret = -ENOMEM; +@@ -1033,18 +1067,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + } + + /* Look up object handles */ +- ret = eb_lookup_objects(eb, exec, args, file); ++ ret = eb_lookup_vmas(eb, exec, args, vm, file); + if (ret) + goto err; + + /* take note of the batch buffer before we might reorder the lists */ +- batch_obj = list_entry(eb->objects.prev, +- struct drm_i915_gem_object, +- exec_list); ++ batch_obj = list_entry(eb->vmas.prev, struct i915_vma, exec_list)->obj; + + /* Move the objects en-masse into the GTT, evicting if necessary. */ + need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; +- ret = i915_gem_execbuffer_reserve(ring, &eb->objects, vm, &need_relocs); ++ ret = i915_gem_execbuffer_reserve(ring, &eb->vmas, &need_relocs); + if (ret) + goto err; + +@@ -1054,7 +1086,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + if (ret) { + if (ret == -EFAULT) { + ret = i915_gem_execbuffer_relocate_slow(dev, args, file, ring, +- eb, exec, vm); ++ eb, exec); + BUG_ON(!mutex_is_locked(&dev->struct_mutex)); + } + if (ret) +@@ -1076,7 +1108,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping) + i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level); + +- ret = i915_gem_execbuffer_move_to_gpu(ring, &eb->objects); ++ ret = i915_gem_execbuffer_move_to_gpu(ring, &eb->vmas); + if (ret) + goto err; + +@@ -1131,7 +1163,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, + + trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags); + +- i915_gem_execbuffer_move_to_active(&eb->objects, vm, ring); ++ i915_gem_execbuffer_move_to_active(&eb->vmas, ring); + i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj); + + err: +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0763-drm-i915-inline-vma_create-into-lookup_or_create_vma.patch b/patches.baytrail/0763-drm-i915-inline-vma_create-into-lookup_or_create_vma.patch new file mode 100644 index 000000000000..e8ac1eca9345 --- /dev/null +++ b/patches.baytrail/0763-drm-i915-inline-vma_create-into-lookup_or_create_vma.patch @@ -0,0 +1,159 @@ +From 4f1234ad50faafbb7897a1bb5a7926a74cb1f453 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 14 Aug 2013 14:14:04 +0200 +Subject: drm/i915: inline vma_create into lookup_or_create_vma + +In the execbuf code we don't clean up any vmas which ended up not +getting bound for code simplicity. To make sure that we don't end up +creating multiple vma for the same vm kill the somewhat dangerous +vma_create function and inline it into lookup_or_create. + +This is just a safety measure to prevent surprises in the future. + +Also update the somewhat confused comment in the execbuf code and +clarify what kind of magic is going on with a new one. + +v2: Keep the function separate as requested by Chris. But give it a __ +prefix for paranoia and move it tighter together with the other vma +stuff. + +Cc: Chris Wilson +Cc: Ben Widawsky +Acked-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit e656a6cba0febf12a9838882b891e1c5917c7a8b) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 2 -- + drivers/gpu/drm/i915/i915_gem.c | 50 +++++++++++++++--------------- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 11 +++++-- + drivers/gpu/drm/i915/i915_gem_stolen.c | 2 +- + 4 files changed, 34 insertions(+), 31 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index b6494b24098d..d5cff9718103 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1826,8 +1826,6 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, + struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, + size_t size); + void i915_gem_free_object(struct drm_gem_object *obj); +-struct i915_vma *i915_gem_vma_create(struct drm_i915_gem_object *obj, +- struct i915_address_space *vm); + void i915_gem_vma_destroy(struct i915_vma *vma); + + int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index c4c56f98d6e6..6820d0a1231f 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -4109,9 +4109,20 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) + i915_gem_object_free(obj); + } + +-struct i915_vma *i915_gem_vma_create(struct drm_i915_gem_object *obj, ++struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, + struct i915_address_space *vm) + { ++ struct i915_vma *vma; ++ list_for_each_entry(vma, &obj->vma_list, vma_link) ++ if (vma->vm == vm) ++ return vma; ++ ++ return NULL; ++} ++ ++static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj, ++ struct i915_address_space *vm) ++{ + struct i915_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL); + if (vma == NULL) + return ERR_PTR(-ENOMEM); +@@ -4131,6 +4142,19 @@ struct i915_vma *i915_gem_vma_create(struct drm_i915_gem_object *obj, + return vma; + } + ++struct i915_vma * ++i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, ++ struct i915_address_space *vm) ++{ ++ struct i915_vma *vma; ++ ++ vma = i915_gem_obj_to_vma(obj, vm); ++ if (!vma) ++ vma = __i915_gem_vma_create(obj, vm); ++ ++ return vma; ++} ++ + void i915_gem_vma_destroy(struct i915_vma *vma) + { + WARN_ON(vma->node.allocated); +@@ -4857,27 +4881,3 @@ unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o, + + return 0; + } +- +-struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, +- struct i915_address_space *vm) +-{ +- struct i915_vma *vma; +- list_for_each_entry(vma, &obj->vma_list, vma_link) +- if (vma->vm == vm) +- return vma; +- +- return NULL; +-} +- +-struct i915_vma * +-i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, +- struct i915_address_space *vm) +-{ +- struct i915_vma *vma; +- +- vma = i915_gem_obj_to_vma(obj, vm); +- if (!vma) +- vma = i915_gem_vma_create(obj, vm); +- +- return vma; +-} +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 5dcfd4f59f87..93c8b28ff2e1 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -123,11 +123,16 @@ eb_lookup_vmas(struct eb_vmas *eb, + list_for_each_entry(obj, &objects, obj_exec_link) { + struct i915_vma *vma; + ++ /* ++ * NOTE: We can leak any vmas created here when something fails ++ * later on. But that's no issue since vma_unbind can deal with ++ * vmas which are not actually bound. And since only ++ * lookup_or_create exists as an interface to get at the vma ++ * from the (obj, vm) we don't run the risk of creating ++ * duplicated vmas for the same vm. ++ */ + vma = i915_gem_obj_lookup_or_create_vma(obj, vm); + if (IS_ERR(vma)) { +- /* XXX: We don't need an error path fro vma because if +- * the vma was created just for this execbuf, object +- * unreference should kill it off.*/ + DRM_DEBUG("Failed to lookup VMA\n"); + ret = PTR_ERR(vma); + goto out; +diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c +index 9969d10b80f5..b902f2afc8e2 100644 +--- a/drivers/gpu/drm/i915/i915_gem_stolen.c ++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c +@@ -392,7 +392,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, + if (gtt_offset == I915_GTT_OFFSET_NONE) + return obj; + +- vma = i915_gem_vma_create(obj, ggtt); ++ vma = i915_gem_obj_lookup_or_create_vma(obj, ggtt); + if (IS_ERR(vma)) { + ret = PTR_ERR(vma); + goto err_out; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0764-drm-i915-Don-t-destroy-the-vma-placeholder-during-ex.patch b/patches.baytrail/0764-drm-i915-Don-t-destroy-the-vma-placeholder-during-ex.patch new file mode 100644 index 000000000000..948332e2c836 --- /dev/null +++ b/patches.baytrail/0764-drm-i915-Don-t-destroy-the-vma-placeholder-during-ex.patch @@ -0,0 +1,55 @@ +From a35424bc1cd91732fb3dae696f5a65fab604ca5e Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Tue, 20 Aug 2013 12:56:40 +0100 +Subject: drm/i915: Don't destroy the vma placeholder during execbuffer + reservation + +The execbuffer handle and exec_link were moved from the object into the +vma. As the vma may be unbound and destroyed whilst attempting to +reserve the execbuffer objects (either through a forced unbind to fix up +a misalignment or through an evict-everything call) we need to prevent +the free of the i915_vma itself. Otherwise not only is the list of +objects to reserve corrupt, but we continue to reference stale vma +entries. + +Fixes kernel crash with i-g-t/gem_evict_everything + +This regression has been introduced in + +commit 04038a515d6eda6dd0857c0ade0b3950d372f4c0 +Author: Ben Widawsky +AuthorDate: Wed Aug 14 11:38:36 2013 +0200 + + drm/i915: Convert execbuf code to use vmas + +Reported-by: Dan Carpenter +References: http://www.spinics.net/lists/intel-gfx/msg32038.html +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68298 +Signed-off-by: Chris Wilson +Cc: Ben Widawsky +Signed-off-by: Daniel Vetter +(cherry picked from commit aaa0566792dc7ae68deb1959663581ea8c75d311) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 6820d0a1231f..29b7e1c32b84 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -4159,6 +4159,11 @@ void i915_gem_vma_destroy(struct i915_vma *vma) + { + WARN_ON(vma->node.allocated); + list_del(&vma->vma_link); ++ ++ /* Keep the vma as a placeholder in the execbuffer reservation lists */ ++ if (!list_empty(&vma->exec_list)) ++ return; ++ + kfree(vma); + } + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0765-drm-i915-More-vma-fixups-around-unbind-destroy.patch b/patches.baytrail/0765-drm-i915-More-vma-fixups-around-unbind-destroy.patch new file mode 100644 index 000000000000..0925406eefac --- /dev/null +++ b/patches.baytrail/0765-drm-i915-More-vma-fixups-around-unbind-destroy.patch @@ -0,0 +1,162 @@ +From 8c7430e0360652b1a96ce2ce29799091ef05e7c3 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 26 Aug 2013 11:23:47 +0200 +Subject: drm/i915: More vma fixups around unbind/destroy + +The important bugfix here is that we must not unlink the vma when +we keep it around as a placeholder for the execbuf code. Since then we +won't find it again when execbuf gets interrupt and restarted and +create a 2nd vma. And since the code as-is isn't fit yet to deal with +more than one vma, hilarity ensues. + +Specifically the dma map/unmap of the sg table isn't adjusted for +multiple vmas yet and will blow up like this: + +BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 +IP: [] i915_gem_gtt_finish_object+0x73/0xc8 [i915] +PGD 56bb5067 PUD ad3dd067 PMD 0 +Oops: 0000 [#1] SMP +Modules linked in: tcp_lp ppdev parport_pc lp parport ipv6 dm_mod dcdbas snd_hda_codec_hdmi pcspkr snd_hda_codec_realtek serio_raw i2c_i801 iTCO_wdt iTCO_vendor_support snd_hda_intel snd_hda_codec lpc_ich snd_hwdep mfd_core snd_pcm snd_page_alloc snd_timer snd soundcore acpi_cpufreq i915 video button drm_kms_helper drm mperf freq_table +CPU: 1 PID: 16650 Comm: fbo-maxsize Not tainted 3.11.0-rc4_nightlytop_d93f59_debug_20130814_+ #6957 +Hardware name: Dell Inc. OptiPlex 9010/03JR84, BIOS A01 05/04/2012 +task: ffff8800563b3f00 ti: ffff88004bdf4000 task.ti: ffff88004bdf4000 +RIP: 0010:[] [] i915_gem_gtt_finish_object+0x73/0xc8 [i915] +RSP: 0018:ffff88004bdf5958 EFLAGS: 00010246 +RAX: 0000000000000000 RBX: ffff8801135e0000 RCX: ffff8800ad3bf8e0 +RDX: ffff8800ad3bf8e0 RSI: 0000000000000000 RDI: ffff8801007ee780 +RBP: ffff88004bdf5978 R08: ffff8800ad3bf8e0 R09: 0000000000000000 +R10: ffffffff86ca1810 R11: ffff880036a17101 R12: ffff8801007ee780 +R13: 0000000000018001 R14: ffff880118c4e000 R15: ffff8801007ee780 +FS: 00007f401a0ce740(0000) GS:ffff88011e280000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000000008 CR3: 000000005635c000 CR4: 00000000001407e0 +Stack: + ffff8801007ee780 ffff88005c253180 0000000000018000 ffff8801135e0000 + ffff88004bdf59a8 ffffffffa0088e55 0000000000000011 ffff8801007eec00 + 0000000000018000 ffff880036a17101 ffff88004bdf5a08 ffffffffa0089026 +Call Trace: + [] i915_vma_unbind+0xdf/0x1ab [i915] + [] __i915_gem_shrink+0x105/0x177 [i915] + [] i915_gem_object_get_pages_gtt+0x108/0x309 [i915] + [] i915_gem_object_get_pages+0x61/0x90 [i915] + [] ? gen6_ppgtt_insert_entries+0x103/0x125 [i915] + [] i915_gem_object_pin+0x1fa/0x5df [i915] + [] i915_gem_execbuffer_reserve_object.isra.6+0x8d/0x1bc [i915] + [] i915_gem_execbuffer_reserve+0x229/0x367 [i915] + [] i915_gem_do_execbuffer.isra.12+0x4dc/0xf3a [i915] + [] ? might_fault+0x40/0x90 + [] i915_gem_execbuffer2+0x187/0x222 [i915] + [] drm_ioctl+0x308/0x442 [drm] + [] ? i915_gem_execbuffer+0x3ae/0x3ae [i915] + [] ? __do_page_fault+0x3dd/0x481 + [] vfs_ioctl+0x26/0x39 + [] do_vfs_ioctl+0x40e/0x451 + [] ? sysret_check+0x1b/0x56 + [] SyS_ioctl+0x57/0x87 + [] ? trace_hardirqs_on_thunk+0x3a/0x3f + [] system_call_fastpath+0x16/0x1b +Code: 48 c7 c6 84 30 0e a0 31 c0 e8 d0 e9 f7 ff bf c6 a7 00 00 e8 07 af 2c e1 41 f6 84 24 03 01 00 00 10 75 44 49 8b 84 24 08 01 00 00 <8b> 50 08 48 8b 30 49 8b 86 b0 04 00 00 48 89 c7 48 81 c7 98 00 +RIP [] i915_gem_gtt_finish_object+0x73/0xc8 [i915] + RSP +CR2: 0000000000000008 + +As a consequence we need to change the "only one vma for now" check in +vma_unbind - since vma_destroy isn't always called the obj->vma_list +might not be empty. Instead check that the vma list is singular at the +beginning of vma_unbind. This is also more symmetric with bind_to_vm. + +This fixes the igt/gem_evict_everything|alignment testcases. + +v2: +- Add a paranoid WARN to mark_free in the eviction code to make sure + we never try to evict a vma used by the execbuf code right now. +- Move the check for a temporary execbuf vma into vma_destroy - + otherwise the failure path cleanup in bind_to_vm will blow up. + +Our first attempting at fixing this was + +commit 1be81a2f2cfd8789a627401d470423358fba2d76 +Author: Chris Wilson +Date: Tue Aug 20 12:56:40 2013 +0100 + + drm/i915: Don't destroy the vma placeholder during execbuffer reservation + +Squash with this when merging! + +v3: Improvements suggested in Chris' review: +- Move the WARN_ON in vma_destroy that checks for vmas with an drm_mm + allocation before the early return. +- Bail out if we hit the WARN in mark_free to hopefully make the + kernel survive for long enough to capture it. + +Cc: Chris Wilson +Cc: Ben Widawsky +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68298 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68171 +Tested-by: lu hua (v2) +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +(cherry picked from commit b93dab6e9d286ec2cd95b28078afdfa6dd515205) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem.c | 10 ++++++---- + drivers/gpu/drm/i915/i915_gem_evict.c | 3 +++ + 2 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 29b7e1c32b84..d57368d5fc1d 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2604,6 +2604,9 @@ int i915_vma_unbind(struct i915_vma *vma) + drm_i915_private_t *dev_priv = obj->base.dev->dev_private; + int ret; + ++ /* For now we only ever use 1 vma per object */ ++ WARN_ON(!list_is_singular(&obj->vma_list)); ++ + if (list_empty(&vma->vma_link)) + return 0; + +@@ -2652,9 +2655,7 @@ destroy: + i915_gem_vma_destroy(vma); + + /* Since the unbound list is global, only move to that list if +- * no more VMAs exist. +- * NB: Until we have real VMAs there will only ever be one */ +- WARN_ON(!list_empty(&obj->vma_list)); ++ * no more VMAs exist. */ + if (list_empty(&obj->vma_list)) + list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list); + +@@ -4158,12 +4159,13 @@ i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, + void i915_gem_vma_destroy(struct i915_vma *vma) + { + WARN_ON(vma->node.allocated); +- list_del(&vma->vma_link); + + /* Keep the vma as a placeholder in the execbuffer reservation lists */ + if (!list_empty(&vma->exec_list)) + return; + ++ list_del(&vma->vma_link); ++ + kfree(vma); + } + +diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c +index 91b700155850..cc8974fbcf31 100644 +--- a/drivers/gpu/drm/i915/i915_gem_evict.c ++++ b/drivers/gpu/drm/i915/i915_gem_evict.c +@@ -37,6 +37,9 @@ mark_free(struct i915_vma *vma, struct list_head *unwind) + if (vma->obj->pin_count) + return false; + ++ if (WARN_ON(!list_empty(&vma->exec_list))) ++ return false; ++ + list_add(&vma->exec_list, unwind); + return drm_mm_scan_add_block(&vma->node); + } +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0766-drm-i915-Always-prefer-CPU-relocations-with-LLC.patch b/patches.baytrail/0766-drm-i915-Always-prefer-CPU-relocations-with-LLC.patch new file mode 100644 index 000000000000..29e47e9a0d07 --- /dev/null +++ b/patches.baytrail/0766-drm-i915-Always-prefer-CPU-relocations-with-LLC.patch @@ -0,0 +1,49 @@ +From 3e771b4b332fef7727f88398f5f14de6e280dee7 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 26 Aug 2013 19:51:00 -0300 +Subject: drm/i915: Always prefer CPU relocations with LLC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A follow-on to the update of the LLC coherency logic is that we can rely +on the LLC being coherent with the CS for rewriting batchbuffers +irrespective of their cache domain. (This should have no effect +currently as all the batch buffers are expected to be I915_CACHE_LLC and +so using the cpu relocation path anyway.) + +Signed-off-by: Chris Wilson +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 2cc86b826070cf312d7b0571e383c56d31a1fe5c) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index 93c8b28ff2e1..e519f9f6e5cd 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -202,7 +202,8 @@ static void eb_destroy(struct eb_vmas *eb) { + + static inline int use_cpu_reloc(struct drm_i915_gem_object *obj) + { +- return (obj->base.write_domain == I915_GEM_DOMAIN_CPU || ++ return (HAS_LLC(obj->base.dev) || ++ obj->base.write_domain == I915_GEM_DOMAIN_CPU || + !obj->map_and_fenceable || + obj->cache_level != I915_CACHE_NONE); + } +@@ -215,7 +216,7 @@ relocate_entry_cpu(struct drm_i915_gem_object *obj, + char *vaddr; + int ret = -EINVAL; + +- ret = i915_gem_object_set_to_cpu_domain(obj, 1); ++ ret = i915_gem_object_set_to_cpu_domain(obj, true); + if (ret) + return ret; + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0767-drm-i915-add-more-VLV-IOSF-sideband-ports-accessors.patch b/patches.baytrail/0767-drm-i915-add-more-VLV-IOSF-sideband-ports-accessors.patch new file mode 100644 index 000000000000..351d8fd44ead --- /dev/null +++ b/patches.baytrail/0767-drm-i915-add-more-VLV-IOSF-sideband-ports-accessors.patch @@ -0,0 +1,126 @@ +From db7934bf88644a03618d2fea1c1d36b995cc3c26 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 27 Aug 2013 15:12:14 +0300 +Subject: drm/i915: add more VLV IOSF sideband ports accessors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For GPIO NC, CCK, CCU, and GPS CORE. + +Signed-off-by: Jani Nikula +Signed-off-by: Shobhit Kumar +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit e9f882a3f1e4ffabe0730af16d5f6d51737515a5) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_drv.h | 8 +++++ + drivers/gpu/drm/i915/i915_reg.h | 4 +++ + drivers/gpu/drm/i915/intel_sideband.c | 56 +++++++++++++++++++++++++++++++++++ + 3 files changed, 68 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index d5cff9718103..e2628579dcbe 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -2248,6 +2248,14 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val) + u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr); + void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val); + u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr); ++u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg); ++void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val); ++u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg); ++void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val); ++u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg); ++void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val); ++u32 vlv_gps_core_read(struct drm_i915_private *dev_priv, u32 reg); ++void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val); + u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg); + void vlv_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val); + u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg, +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index c159e1a6810f..8f4c8b69ebc1 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -346,6 +346,10 @@ + #define IOSF_PORT_PUNIT 0x4 + #define IOSF_PORT_NC 0x11 + #define IOSF_PORT_DPIO 0x12 ++#define IOSF_PORT_GPIO_NC 0x13 ++#define IOSF_PORT_CCK 0x14 ++#define IOSF_PORT_CCU 0xA9 ++#define IOSF_PORT_GPS_CORE 0x48 + #define VLV_IOSF_DATA (VLV_DISPLAY_BASE + 0x2104) + #define VLV_IOSF_ADDR (VLV_DISPLAY_BASE + 0x2108) + +diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c +index 9a0e6c5ea540..0a4167019769 100644 +--- a/drivers/gpu/drm/i915/intel_sideband.c ++++ b/drivers/gpu/drm/i915/intel_sideband.c +@@ -101,6 +101,62 @@ u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr) + return val; + } + ++u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg) ++{ ++ u32 val = 0; ++ vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPIO_NC, ++ PUNIT_OPCODE_REG_READ, reg, &val); ++ return val; ++} ++ ++void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val) ++{ ++ vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPIO_NC, ++ PUNIT_OPCODE_REG_WRITE, reg, &val); ++} ++ ++u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg) ++{ ++ u32 val = 0; ++ vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCK, ++ PUNIT_OPCODE_REG_READ, reg, &val); ++ return val; ++} ++ ++void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val) ++{ ++ vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCK, ++ PUNIT_OPCODE_REG_WRITE, reg, &val); ++} ++ ++u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg) ++{ ++ u32 val = 0; ++ vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCU, ++ PUNIT_OPCODE_REG_READ, reg, &val); ++ return val; ++} ++ ++void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val) ++{ ++ vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCU, ++ PUNIT_OPCODE_REG_WRITE, reg, &val); ++} ++ ++u32 vlv_gps_core_read(struct drm_i915_private *dev_priv, u32 reg) ++{ ++ u32 val = 0; ++ vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPS_CORE, ++ PUNIT_OPCODE_REG_READ, reg, &val); ++ return val; ++} ++ ++void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val) ++{ ++ vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPS_CORE, ++ PUNIT_OPCODE_REG_WRITE, reg, &val); ++} ++ + u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg) + { + u32 val = 0; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0768-drm-i915-add-VLV-pipeconf-bit-definition-for-DSI-PLL.patch b/patches.baytrail/0768-drm-i915-add-VLV-pipeconf-bit-definition-for-DSI-PLL.patch new file mode 100644 index 000000000000..2ff25d1e1002 --- /dev/null +++ b/patches.baytrail/0768-drm-i915-add-VLV-pipeconf-bit-definition-for-DSI-PLL.patch @@ -0,0 +1,34 @@ +From 06e3de15d4903284316cf6ccf24e4afe2a84c66f Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 27 Aug 2013 15:12:15 +0300 +Subject: drm/i915: add VLV pipeconf bit definition for DSI PLL lock +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +v2: Add comment this is pipe A only (Ville) + +Signed-off-by: Jani Nikula +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit b6ec10b36566c3eb330f4c03c1b00a02c974fd21) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 8f4c8b69ebc1..7a7b9c2f84cb 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -2986,6 +2986,7 @@ + #define PIPECONF_DISABLE 0 + #define PIPECONF_DOUBLE_WIDE (1<<30) + #define I965_PIPECONF_ACTIVE (1<<30) ++#define PIPECONF_DSI_PLL_LOCKED (1<<29) /* vlv & pipe A only */ + #define PIPECONF_FRAME_START_DELAY_MASK (3<<27) + #define PIPECONF_SINGLE_WIDE 0 + #define PIPECONF_PIPE_UNLOCKED 0 +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0769-drm-Constify-the-pretty-print-functions.patch b/patches.baytrail/0769-drm-Constify-the-pretty-print-functions.patch new file mode 100644 index 000000000000..c11a749d4f90 --- /dev/null +++ b/patches.baytrail/0769-drm-Constify-the-pretty-print-functions.patch @@ -0,0 +1,221 @@ +From 4ae68d3144eb021a6475549fb069944eb5806a47 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Fri, 7 Jun 2013 15:43:07 +0000 +Subject: drm: Constify the pretty-print functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The structures and strings involved with various pretty-print functions +aren't meant to be modified, so make them all const. The exception is +drm_connector_enum_list which does get modified in drm_connector_init(). + +While at it move the drm_get_connector_status_name() prototype from +drmP.h to drm_crtc.h where it belongs. + +Signed-off-by: Ville Syrjälä +Reviewed-by: Daniel Vetter +Signed-off-by: Dave Airlie +(cherry picked from commit d20d3174806ef6589cb912a488657d21fcd7ece2) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_crtc.c | 30 +++++++++++++++--------------- + include/drm/drmP.h | 1 - + include/drm/drm_crtc.h | 17 +++++++++-------- + 3 files changed, 24 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c +index a014cb1ebcaf..23be1ee46f76 100644 +--- a/drivers/gpu/drm/drm_crtc.c ++++ b/drivers/gpu/drm/drm_crtc.c +@@ -92,7 +92,7 @@ EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked); + + /* Avoid boilerplate. I'm tired of typing. */ + #define DRM_ENUM_NAME_FN(fnname, list) \ +- char *fnname(int val) \ ++ const char *fnname(int val) \ + { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(list); i++) { \ +@@ -105,7 +105,7 @@ EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked); + /* + * Global properties + */ +-static struct drm_prop_enum_list drm_dpms_enum_list[] = ++static const struct drm_prop_enum_list drm_dpms_enum_list[] = + { { DRM_MODE_DPMS_ON, "On" }, + { DRM_MODE_DPMS_STANDBY, "Standby" }, + { DRM_MODE_DPMS_SUSPEND, "Suspend" }, +@@ -117,7 +117,7 @@ DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list) + /* + * Optional properties + */ +-static struct drm_prop_enum_list drm_scaling_mode_enum_list[] = ++static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] = + { + { DRM_MODE_SCALE_NONE, "None" }, + { DRM_MODE_SCALE_FULLSCREEN, "Full" }, +@@ -125,7 +125,7 @@ static struct drm_prop_enum_list drm_scaling_mode_enum_list[] = + { DRM_MODE_SCALE_ASPECT, "Full aspect" }, + }; + +-static struct drm_prop_enum_list drm_dithering_mode_enum_list[] = ++static const struct drm_prop_enum_list drm_dithering_mode_enum_list[] = + { + { DRM_MODE_DITHERING_OFF, "Off" }, + { DRM_MODE_DITHERING_ON, "On" }, +@@ -135,7 +135,7 @@ static struct drm_prop_enum_list drm_dithering_mode_enum_list[] = + /* + * Non-global properties, but "required" for certain connectors. + */ +-static struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = ++static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = + { + { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ + { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ +@@ -144,7 +144,7 @@ static struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = + + DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list) + +-static struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = ++static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = + { + { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ + { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ +@@ -154,7 +154,7 @@ static struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = + DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name, + drm_dvi_i_subconnector_enum_list) + +-static struct drm_prop_enum_list drm_tv_select_enum_list[] = ++static const struct drm_prop_enum_list drm_tv_select_enum_list[] = + { + { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ + { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ +@@ -165,7 +165,7 @@ static struct drm_prop_enum_list drm_tv_select_enum_list[] = + + DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list) + +-static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = ++static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = + { + { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ + { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ +@@ -177,7 +177,7 @@ static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = + DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name, + drm_tv_subconnector_enum_list) + +-static struct drm_prop_enum_list drm_dirty_info_enum_list[] = { ++static const struct drm_prop_enum_list drm_dirty_info_enum_list[] = { + { DRM_MODE_DIRTY_OFF, "Off" }, + { DRM_MODE_DIRTY_ON, "On" }, + { DRM_MODE_DIRTY_ANNOTATE, "Annotate" }, +@@ -185,7 +185,7 @@ static struct drm_prop_enum_list drm_dirty_info_enum_list[] = { + + struct drm_conn_prop_enum_list { + int type; +- char *name; ++ const char *name; + int count; + }; + +@@ -211,7 +211,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = + { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0}, + }; + +-static struct drm_prop_enum_list drm_encoder_enum_list[] = ++static const struct drm_prop_enum_list drm_encoder_enum_list[] = + { { DRM_MODE_ENCODER_NONE, "None" }, + { DRM_MODE_ENCODER_DAC, "DAC" }, + { DRM_MODE_ENCODER_TMDS, "TMDS" }, +@@ -220,7 +220,7 @@ static struct drm_prop_enum_list drm_encoder_enum_list[] = + { DRM_MODE_ENCODER_VIRTUAL, "Virtual" }, + }; + +-char *drm_get_encoder_name(struct drm_encoder *encoder) ++const char *drm_get_encoder_name(const struct drm_encoder *encoder) + { + static char buf[32]; + +@@ -231,7 +231,7 @@ char *drm_get_encoder_name(struct drm_encoder *encoder) + } + EXPORT_SYMBOL(drm_get_encoder_name); + +-char *drm_get_connector_name(struct drm_connector *connector) ++const char *drm_get_connector_name(const struct drm_connector *connector) + { + static char buf[32]; + +@@ -242,7 +242,7 @@ char *drm_get_connector_name(struct drm_connector *connector) + } + EXPORT_SYMBOL(drm_get_connector_name); + +-char *drm_get_connector_status_name(enum drm_connector_status status) ++const char *drm_get_connector_status_name(enum drm_connector_status status) + { + if (status == connector_status_connected) + return "connected"; +@@ -258,7 +258,7 @@ static char printable_char(int c) + return isascii(c) && isprint(c) ? c : '?'; + } + +-char *drm_get_format_name(uint32_t format) ++const char *drm_get_format_name(uint32_t format) + { + static char buf[32]; + +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index adb4c330b086..ea284972a33c 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1545,7 +1545,6 @@ extern void drm_sysfs_destroy(void); + extern int drm_sysfs_device_add(struct drm_minor *minor); + extern void drm_sysfs_hotplug_event(struct drm_device *dev); + extern void drm_sysfs_device_remove(struct drm_minor *minor); +-extern char *drm_get_connector_status_name(enum drm_connector_status status); + extern int drm_sysfs_connector_add(struct drm_connector *connector); + extern void drm_sysfs_connector_remove(struct drm_connector *connector); + +diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h +index 7a2d68f946c6..994b910ed9ce 100644 +--- a/include/drm/drm_crtc.h ++++ b/include/drm/drm_crtc.h +@@ -903,12 +903,13 @@ extern void drm_plane_cleanup(struct drm_plane *plane); + + extern void drm_encoder_cleanup(struct drm_encoder *encoder); + +-extern char *drm_get_connector_name(struct drm_connector *connector); +-extern char *drm_get_dpms_name(int val); +-extern char *drm_get_dvi_i_subconnector_name(int val); +-extern char *drm_get_dvi_i_select_name(int val); +-extern char *drm_get_tv_subconnector_name(int val); +-extern char *drm_get_tv_select_name(int val); ++extern const char *drm_get_connector_name(const struct drm_connector *connector); ++extern const char *drm_get_connector_status_name(enum drm_connector_status status); ++extern const char *drm_get_dpms_name(int val); ++extern const char *drm_get_dvi_i_subconnector_name(int val); ++extern const char *drm_get_dvi_i_select_name(int val); ++extern const char *drm_get_tv_subconnector_name(int val); ++extern const char *drm_get_tv_select_name(int val); + extern void drm_fb_release(struct drm_file *file_priv); + extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group); + extern bool drm_probe_ddc(struct i2c_adapter *adapter); +@@ -1000,7 +1001,7 @@ extern int drm_mode_create_tv_properties(struct drm_device *dev, int num_formats + extern int drm_mode_create_scaling_mode_property(struct drm_device *dev); + extern int drm_mode_create_dithering_property(struct drm_device *dev); + extern int drm_mode_create_dirty_info_property(struct drm_device *dev); +-extern char *drm_get_encoder_name(struct drm_encoder *encoder); ++extern const char *drm_get_encoder_name(const struct drm_encoder *encoder); + + extern int drm_mode_connector_attach_encoder(struct drm_connector *connector, + struct drm_encoder *encoder); +@@ -1100,6 +1101,6 @@ extern int drm_format_num_planes(uint32_t format); + extern int drm_format_plane_cpp(uint32_t format, int plane); + extern int drm_format_horz_chroma_subsampling(uint32_t format); + extern int drm_format_vert_chroma_subsampling(uint32_t format); +-extern char *drm_get_format_name(uint32_t format); ++extern const char *drm_get_format_name(uint32_t format); + + #endif /* __DRM_CRTC_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0770-drm-use-ida-to-allocate-connector-ids.patch b/patches.baytrail/0770-drm-use-ida-to-allocate-connector-ids.patch new file mode 100644 index 000000000000..50ca8a85a12a --- /dev/null +++ b/patches.baytrail/0770-drm-use-ida-to-allocate-connector-ids.patch @@ -0,0 +1,166 @@ +From fe27353196ffd321891fcbce6b578e03a89016ca Mon Sep 17 00:00:00 2001 +From: Ilia Mirkin +Date: Wed, 7 Aug 2013 22:34:48 -0400 +Subject: drm: use ida to allocate connector ids +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This makes it so that reloading a module does not cause all the +connector ids to change, which are user-visible and sometimes used +for configuration. + +Signed-off-by: Ilia Mirkin +Reviewed-by: Ville Syrjälä +Signed-off-by: Dave Airlie +(cherry picked from commit b21e3afe2357c0f49348a5fb61247012bf8262ec) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_crtc.c | 62 ++++++++++++++++++++++++++++++++-------------- + drivers/gpu/drm/drm_drv.c | 2 ++ + include/drm/drm_crtc.h | 2 ++ + 3 files changed, 48 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c +index 23be1ee46f76..57ad5cbf995d 100644 +--- a/drivers/gpu/drm/drm_crtc.c ++++ b/drivers/gpu/drm/drm_crtc.c +@@ -186,29 +186,29 @@ static const struct drm_prop_enum_list drm_dirty_info_enum_list[] = { + struct drm_conn_prop_enum_list { + int type; + const char *name; +- int count; ++ struct ida ida; + }; + + /* + * Connector and encoder types. + */ + static struct drm_conn_prop_enum_list drm_connector_enum_list[] = +-{ { DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 }, +- { DRM_MODE_CONNECTOR_VGA, "VGA", 0 }, +- { DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 }, +- { DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 }, +- { DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 }, +- { DRM_MODE_CONNECTOR_Composite, "Composite", 0 }, +- { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 }, +- { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 }, +- { DRM_MODE_CONNECTOR_Component, "Component", 0 }, +- { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 }, +- { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 }, +- { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 }, +- { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 }, +- { DRM_MODE_CONNECTOR_TV, "TV", 0 }, +- { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, +- { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0}, ++{ { DRM_MODE_CONNECTOR_Unknown, "Unknown" }, ++ { DRM_MODE_CONNECTOR_VGA, "VGA" }, ++ { DRM_MODE_CONNECTOR_DVII, "DVI-I" }, ++ { DRM_MODE_CONNECTOR_DVID, "DVI-D" }, ++ { DRM_MODE_CONNECTOR_DVIA, "DVI-A" }, ++ { DRM_MODE_CONNECTOR_Composite, "Composite" }, ++ { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" }, ++ { DRM_MODE_CONNECTOR_LVDS, "LVDS" }, ++ { DRM_MODE_CONNECTOR_Component, "Component" }, ++ { DRM_MODE_CONNECTOR_9PinDIN, "DIN" }, ++ { DRM_MODE_CONNECTOR_DisplayPort, "DP" }, ++ { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" }, ++ { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" }, ++ { DRM_MODE_CONNECTOR_TV, "TV" }, ++ { DRM_MODE_CONNECTOR_eDP, "eDP" }, ++ { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" }, + }; + + static const struct drm_prop_enum_list drm_encoder_enum_list[] = +@@ -220,6 +220,22 @@ static const struct drm_prop_enum_list drm_encoder_enum_list[] = + { DRM_MODE_ENCODER_VIRTUAL, "Virtual" }, + }; + ++void drm_connector_ida_init(void) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++) ++ ida_init(&drm_connector_enum_list[i].ida); ++} ++ ++void drm_connector_ida_destroy(void) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++) ++ ida_destroy(&drm_connector_enum_list[i].ida); ++} ++ + const char *drm_get_encoder_name(const struct drm_encoder *encoder) + { + static char buf[32]; +@@ -718,6 +734,8 @@ int drm_connector_init(struct drm_device *dev, + int connector_type) + { + int ret; ++ struct ida *connector_ida = ++ &drm_connector_enum_list[connector_type].ida; + + drm_modeset_lock_all(dev); + +@@ -730,7 +748,12 @@ int drm_connector_init(struct drm_device *dev, + connector->funcs = funcs; + connector->connector_type = connector_type; + connector->connector_type_id = +- ++drm_connector_enum_list[connector_type].count; /* TODO */ ++ ida_simple_get(connector_ida, 1, 0, GFP_KERNEL); ++ if (connector->connector_type_id < 0) { ++ ret = connector->connector_type_id; ++ drm_mode_object_put(dev, &connector->base); ++ goto out; ++ } + INIT_LIST_HEAD(&connector->probed_modes); + INIT_LIST_HEAD(&connector->modes); + connector->edid_blob_ptr = NULL; +@@ -771,6 +794,9 @@ void drm_connector_cleanup(struct drm_connector *connector) + list_for_each_entry_safe(mode, t, &connector->modes, head) + drm_mode_remove(connector, mode); + ++ ida_remove(&drm_connector_enum_list[connector->connector_type].ida, ++ connector->connector_type_id); ++ + drm_mode_object_put(dev, &connector->base); + list_del(&connector->head); + dev->mode_config.num_connector--; +diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c +index b1f0a0bf77cb..98b158e58538 100644 +--- a/drivers/gpu/drm/drm_drv.c ++++ b/drivers/gpu/drm/drm_drv.c +@@ -231,6 +231,7 @@ static int __init drm_core_init(void) + int ret = -ENOMEM; + + drm_global_init(); ++ drm_connector_ida_init(); + idr_init(&drm_minors_idr); + + if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) +@@ -278,6 +279,7 @@ static void __exit drm_core_exit(void) + + unregister_chrdev(DRM_MAJOR, "drm"); + ++ drm_connector_ida_destroy(); + idr_destroy(&drm_minors_idr); + } + +diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h +index 994b910ed9ce..1dd883ed93c9 100644 +--- a/include/drm/drm_crtc.h ++++ b/include/drm/drm_crtc.h +@@ -879,6 +879,8 @@ extern int drm_crtc_init(struct drm_device *dev, + const struct drm_crtc_funcs *funcs); + extern void drm_crtc_cleanup(struct drm_crtc *crtc); + ++extern void drm_connector_ida_init(void); ++extern void drm_connector_ida_destroy(void); + extern int drm_connector_init(struct drm_device *dev, + struct drm_connector *connector, + const struct drm_connector_funcs *funcs, +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0771-drm-add-MIPI-DSI-encoder-and-connector-types.patch b/patches.baytrail/0771-drm-add-MIPI-DSI-encoder-and-connector-types.patch new file mode 100644 index 000000000000..964fc4e6ac0f --- /dev/null +++ b/patches.baytrail/0771-drm-add-MIPI-DSI-encoder-and-connector-types.patch @@ -0,0 +1,63 @@ +From 09c226650fe770a7c0f2e14db823e20353b108e1 Mon Sep 17 00:00:00 2001 +From: Shobhit Kumar +Date: Tue, 27 Aug 2013 15:12:13 +0300 +Subject: drm: add MIPI DSI encoder and connector types +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Shobhit Kumar +Signed-off-by: Jani Nikula +Acked-by: Dave Airlie +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit b89232732f642bfa24f9e252dd241ddfb40d3817) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/drm_crtc.c | 2 ++ + include/uapi/drm/drm_mode.h | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c +index 57ad5cbf995d..589dd6088bb1 100644 +--- a/drivers/gpu/drm/drm_crtc.c ++++ b/drivers/gpu/drm/drm_crtc.c +@@ -209,6 +209,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = + { DRM_MODE_CONNECTOR_TV, "TV" }, + { DRM_MODE_CONNECTOR_eDP, "eDP" }, + { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" }, ++ { DRM_MODE_CONNECTOR_DSI, "DSI" }, + }; + + static const struct drm_prop_enum_list drm_encoder_enum_list[] = +@@ -218,6 +219,7 @@ static const struct drm_prop_enum_list drm_encoder_enum_list[] = + { DRM_MODE_ENCODER_LVDS, "LVDS" }, + { DRM_MODE_ENCODER_TVDAC, "TV" }, + { DRM_MODE_ENCODER_VIRTUAL, "Virtual" }, ++ { DRM_MODE_ENCODER_DSI, "DSI" }, + }; + + void drm_connector_ida_init(void) +diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h +index 82adefbabfa4..10b6db73d8a4 100644 +--- a/include/uapi/drm/drm_mode.h ++++ b/include/uapi/drm/drm_mode.h +@@ -176,6 +176,7 @@ struct drm_mode_get_plane_res { + #define DRM_MODE_ENCODER_LVDS 3 + #define DRM_MODE_ENCODER_TVDAC 4 + #define DRM_MODE_ENCODER_VIRTUAL 5 ++#define DRM_MODE_ENCODER_DSI 6 + + struct drm_mode_get_encoder { + __u32 encoder_id; +@@ -214,6 +215,7 @@ struct drm_mode_get_encoder { + #define DRM_MODE_CONNECTOR_TV 13 + #define DRM_MODE_CONNECTOR_eDP 14 + #define DRM_MODE_CONNECTOR_VIRTUAL 15 ++#define DRM_MODE_CONNECTOR_DSI 16 + + struct drm_mode_get_connector { + +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0772-drm-i915-add-MIPI-DSI-register-definitions.patch b/patches.baytrail/0772-drm-i915-add-MIPI-DSI-register-definitions.patch new file mode 100644 index 000000000000..6b0e8090a5ad --- /dev/null +++ b/patches.baytrail/0772-drm-i915-add-MIPI-DSI-register-definitions.patch @@ -0,0 +1,443 @@ +From 4cde04db3bc33f57d4eafe446b74652479aa92c1 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 27 Aug 2013 15:12:16 +0300 +Subject: drm/i915: add MIPI DSI register definitions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add definitions for VLV MIPI DSI registers. + +v2: Small fixes per Ville's review comments. + +Signed-off-by: Jani Nikula +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 3230bf14c14e04d49525d172db53a55e153447a7) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/i915_reg.h | 410 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 410 insertions(+) + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 7a7b9c2f84cb..b26cf9b5b1e4 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -5121,4 +5121,414 @@ + #define PIPE_CSC_POSTOFF_ME(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_ME, _PIPE_B_CSC_POSTOFF_ME) + #define PIPE_CSC_POSTOFF_LO(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_LO, _PIPE_B_CSC_POSTOFF_LO) + ++/* VLV MIPI registers */ ++ ++#define _MIPIA_PORT_CTRL (VLV_DISPLAY_BASE + 0x61190) ++#define _MIPIB_PORT_CTRL (VLV_DISPLAY_BASE + 0x61700) ++#define MIPI_PORT_CTRL(pipe) _PIPE(pipe, _MIPIA_PORT_CTRL, _MIPIB_PORT_CTRL) ++#define DPI_ENABLE (1 << 31) /* A + B */ ++#define MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT 27 ++#define MIPIA_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 27) ++#define DUAL_LINK_MODE_MASK (1 << 26) ++#define DUAL_LINK_MODE_FRONT_BACK (0 << 26) ++#define DUAL_LINK_MODE_PIXEL_ALTERNATIVE (1 << 26) ++#define DITHERING_ENABLE (1 << 25) /* A + B */ ++#define FLOPPED_HSTX (1 << 23) ++#define DE_INVERT (1 << 19) /* XXX */ ++#define MIPIA_FLISDSI_DELAY_COUNT_SHIFT 18 ++#define MIPIA_FLISDSI_DELAY_COUNT_MASK (0xf << 18) ++#define AFE_LATCHOUT (1 << 17) ++#define LP_OUTPUT_HOLD (1 << 16) ++#define MIPIB_FLISDSI_DELAY_COUNT_HIGH_SHIFT 15 ++#define MIPIB_FLISDSI_DELAY_COUNT_HIGH_MASK (1 << 15) ++#define MIPIB_MIPI4DPHY_DELAY_COUNT_SHIFT 11 ++#define MIPIB_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 11) ++#define CSB_SHIFT 9 ++#define CSB_MASK (3 << 9) ++#define CSB_20MHZ (0 << 9) ++#define CSB_10MHZ (1 << 9) ++#define CSB_40MHZ (2 << 9) ++#define BANDGAP_MASK (1 << 8) ++#define BANDGAP_PNW_CIRCUIT (0 << 8) ++#define BANDGAP_LNC_CIRCUIT (1 << 8) ++#define MIPIB_FLISDSI_DELAY_COUNT_LOW_SHIFT 5 ++#define MIPIB_FLISDSI_DELAY_COUNT_LOW_MASK (7 << 5) ++#define TEARING_EFFECT_DELAY (1 << 4) /* A + B */ ++#define TEARING_EFFECT_SHIFT 2 /* A + B */ ++#define TEARING_EFFECT_MASK (3 << 2) ++#define TEARING_EFFECT_OFF (0 << 2) ++#define TEARING_EFFECT_DSI (1 << 2) ++#define TEARING_EFFECT_GPIO (2 << 2) ++#define LANE_CONFIGURATION_SHIFT 0 ++#define LANE_CONFIGURATION_MASK (3 << 0) ++#define LANE_CONFIGURATION_4LANE (0 << 0) ++#define LANE_CONFIGURATION_DUAL_LINK_A (1 << 0) ++#define LANE_CONFIGURATION_DUAL_LINK_B (2 << 0) ++ ++#define _MIPIA_TEARING_CTRL (VLV_DISPLAY_BASE + 0x61194) ++#define _MIPIB_TEARING_CTRL (VLV_DISPLAY_BASE + 0x61704) ++#define MIPI_TEARING_CTRL(pipe) _PIPE(pipe, _MIPIA_TEARING_CTRL, _MIPIB_TEARING_CTRL) ++#define TEARING_EFFECT_DELAY_SHIFT 0 ++#define TEARING_EFFECT_DELAY_MASK (0xffff << 0) ++ ++/* XXX: all bits reserved */ ++#define _MIPIA_AUTOPWG (VLV_DISPLAY_BASE + 0x611a0) ++ ++/* MIPI DSI Controller and D-PHY registers */ ++ ++#define _MIPIA_DEVICE_READY (VLV_DISPLAY_BASE + 0xb000) ++#define _MIPIB_DEVICE_READY (VLV_DISPLAY_BASE + 0xb800) ++#define MIPI_DEVICE_READY(pipe) _PIPE(pipe, _MIPIA_DEVICE_READY, _MIPIB_DEVICE_READY) ++#define BUS_POSSESSION (1 << 3) /* set to give bus to receiver */ ++#define ULPS_STATE_MASK (3 << 1) ++#define ULPS_STATE_ENTER (2 << 1) ++#define ULPS_STATE_EXIT (1 << 1) ++#define ULPS_STATE_NORMAL_OPERATION (0 << 1) ++#define DEVICE_READY (1 << 0) ++ ++#define _MIPIA_INTR_STAT (VLV_DISPLAY_BASE + 0xb004) ++#define _MIPIB_INTR_STAT (VLV_DISPLAY_BASE + 0xb804) ++#define MIPI_INTR_STAT(pipe) _PIPE(pipe, _MIPIA_INTR_STAT, _MIPIB_INTR_STAT) ++#define _MIPIA_INTR_EN (VLV_DISPLAY_BASE + 0xb008) ++#define _MIPIB_INTR_EN (VLV_DISPLAY_BASE + 0xb808) ++#define MIPI_INTR_EN(pipe) _PIPE(pipe, _MIPIA_INTR_EN, _MIPIB_INTR_EN) ++#define TEARING_EFFECT (1 << 31) ++#define SPL_PKT_SENT_INTERRUPT (1 << 30) ++#define GEN_READ_DATA_AVAIL (1 << 29) ++#define LP_GENERIC_WR_FIFO_FULL (1 << 28) ++#define HS_GENERIC_WR_FIFO_FULL (1 << 27) ++#define RX_PROT_VIOLATION (1 << 26) ++#define RX_INVALID_TX_LENGTH (1 << 25) ++#define ACK_WITH_NO_ERROR (1 << 24) ++#define TURN_AROUND_ACK_TIMEOUT (1 << 23) ++#define LP_RX_TIMEOUT (1 << 22) ++#define HS_TX_TIMEOUT (1 << 21) ++#define DPI_FIFO_UNDERRUN (1 << 20) ++#define LOW_CONTENTION (1 << 19) ++#define HIGH_CONTENTION (1 << 18) ++#define TXDSI_VC_ID_INVALID (1 << 17) ++#define TXDSI_DATA_TYPE_NOT_RECOGNISED (1 << 16) ++#define TXCHECKSUM_ERROR (1 << 15) ++#define TXECC_MULTIBIT_ERROR (1 << 14) ++#define TXECC_SINGLE_BIT_ERROR (1 << 13) ++#define TXFALSE_CONTROL_ERROR (1 << 12) ++#define RXDSI_VC_ID_INVALID (1 << 11) ++#define RXDSI_DATA_TYPE_NOT_REGOGNISED (1 << 10) ++#define RXCHECKSUM_ERROR (1 << 9) ++#define RXECC_MULTIBIT_ERROR (1 << 8) ++#define RXECC_SINGLE_BIT_ERROR (1 << 7) ++#define RXFALSE_CONTROL_ERROR (1 << 6) ++#define RXHS_RECEIVE_TIMEOUT_ERROR (1 << 5) ++#define RX_LP_TX_SYNC_ERROR (1 << 4) ++#define RXEXCAPE_MODE_ENTRY_ERROR (1 << 3) ++#define RXEOT_SYNC_ERROR (1 << 2) ++#define RXSOT_SYNC_ERROR (1 << 1) ++#define RXSOT_ERROR (1 << 0) ++ ++#define _MIPIA_DSI_FUNC_PRG (VLV_DISPLAY_BASE + 0xb00c) ++#define _MIPIB_DSI_FUNC_PRG (VLV_DISPLAY_BASE + 0xb80c) ++#define MIPI_DSI_FUNC_PRG(pipe) _PIPE(pipe, _MIPIA_DSI_FUNC_PRG, _MIPIB_DSI_FUNC_PRG) ++#define CMD_MODE_DATA_WIDTH_MASK (7 << 13) ++#define CMD_MODE_NOT_SUPPORTED (0 << 13) ++#define CMD_MODE_DATA_WIDTH_16_BIT (1 << 13) ++#define CMD_MODE_DATA_WIDTH_9_BIT (2 << 13) ++#define CMD_MODE_DATA_WIDTH_8_BIT (3 << 13) ++#define CMD_MODE_DATA_WIDTH_OPTION1 (4 << 13) ++#define CMD_MODE_DATA_WIDTH_OPTION2 (5 << 13) ++#define VID_MODE_FORMAT_MASK (0xf << 7) ++#define VID_MODE_NOT_SUPPORTED (0 << 7) ++#define VID_MODE_FORMAT_RGB565 (1 << 7) ++#define VID_MODE_FORMAT_RGB666 (2 << 7) ++#define VID_MODE_FORMAT_RGB666_LOOSE (3 << 7) ++#define VID_MODE_FORMAT_RGB888 (4 << 7) ++#define CMD_MODE_CHANNEL_NUMBER_SHIFT 5 ++#define CMD_MODE_CHANNEL_NUMBER_MASK (3 << 5) ++#define VID_MODE_CHANNEL_NUMBER_SHIFT 3 ++#define VID_MODE_CHANNEL_NUMBER_MASK (3 << 3) ++#define DATA_LANES_PRG_REG_SHIFT 0 ++#define DATA_LANES_PRG_REG_MASK (7 << 0) ++ ++#define _MIPIA_HS_TX_TIMEOUT (VLV_DISPLAY_BASE + 0xb010) ++#define _MIPIB_HS_TX_TIMEOUT (VLV_DISPLAY_BASE + 0xb810) ++#define MIPI_HS_TX_TIMEOUT(pipe) _PIPE(pipe, _MIPIA_HS_TX_TIMEOUT, _MIPIB_HS_TX_TIMEOUT) ++#define HIGH_SPEED_TX_TIMEOUT_COUNTER_MASK 0xffffff ++ ++#define _MIPIA_LP_RX_TIMEOUT (VLV_DISPLAY_BASE + 0xb014) ++#define _MIPIB_LP_RX_TIMEOUT (VLV_DISPLAY_BASE + 0xb814) ++#define MIPI_LP_RX_TIMEOUT(pipe) _PIPE(pipe, _MIPIA_LP_RX_TIMEOUT, _MIPIB_LP_RX_TIMEOUT) ++#define LOW_POWER_RX_TIMEOUT_COUNTER_MASK 0xffffff ++ ++#define _MIPIA_TURN_AROUND_TIMEOUT (VLV_DISPLAY_BASE + 0xb018) ++#define _MIPIB_TURN_AROUND_TIMEOUT (VLV_DISPLAY_BASE + 0xb818) ++#define MIPI_TURN_AROUND_TIMEOUT(pipe) _PIPE(pipe, _MIPIA_TURN_AROUND_TIMEOUT, _MIPIB_TURN_AROUND_TIMEOUT) ++#define TURN_AROUND_TIMEOUT_MASK 0x3f ++ ++#define _MIPIA_DEVICE_RESET_TIMER (VLV_DISPLAY_BASE + 0xb01c) ++#define _MIPIB_DEVICE_RESET_TIMER (VLV_DISPLAY_BASE + 0xb81c) ++#define MIPI_DEVICE_RESET_TIMER(pipe) _PIPE(pipe, _MIPIA_DEVICE_RESET_TIMER, _MIPIB_DEVICE_RESET_TIMER) ++#define DEVICE_RESET_TIMER_MASK 0xffff ++ ++#define _MIPIA_DPI_RESOLUTION (VLV_DISPLAY_BASE + 0xb020) ++#define _MIPIB_DPI_RESOLUTION (VLV_DISPLAY_BASE + 0xb820) ++#define MIPI_DPI_RESOLUTION(pipe) _PIPE(pipe, _MIPIA_DPI_RESOLUTION, _MIPIB_DPI_RESOLUTION) ++#define VERTICAL_ADDRESS_SHIFT 16 ++#define VERTICAL_ADDRESS_MASK (0xffff << 16) ++#define HORIZONTAL_ADDRESS_SHIFT 0 ++#define HORIZONTAL_ADDRESS_MASK 0xffff ++ ++#define _MIPIA_DBI_FIFO_THROTTLE (VLV_DISPLAY_BASE + 0xb024) ++#define _MIPIB_DBI_FIFO_THROTTLE (VLV_DISPLAY_BASE + 0xb824) ++#define MIPI_DBI_FIFO_THROTTLE(pipe) _PIPE(pipe, _MIPIA_DBI_FIFO_THROTTLE, _MIPIB_DBI_FIFO_THROTTLE) ++#define DBI_FIFO_EMPTY_HALF (0 << 0) ++#define DBI_FIFO_EMPTY_QUARTER (1 << 0) ++#define DBI_FIFO_EMPTY_7_LOCATIONS (2 << 0) ++ ++/* regs below are bits 15:0 */ ++#define _MIPIA_HSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb028) ++#define _MIPIB_HSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb828) ++#define MIPI_HSYNC_PADDING_COUNT(pipe) _PIPE(pipe, _MIPIA_HSYNC_PADDING_COUNT, _MIPIB_HSYNC_PADDING_COUNT) ++ ++#define _MIPIA_HBP_COUNT (VLV_DISPLAY_BASE + 0xb02c) ++#define _MIPIB_HBP_COUNT (VLV_DISPLAY_BASE + 0xb82c) ++#define MIPI_HBP_COUNT(pipe) _PIPE(pipe, _MIPIA_HBP_COUNT, _MIPIB_HBP_COUNT) ++ ++#define _MIPIA_HFP_COUNT (VLV_DISPLAY_BASE + 0xb030) ++#define _MIPIB_HFP_COUNT (VLV_DISPLAY_BASE + 0xb830) ++#define MIPI_HFP_COUNT(pipe) _PIPE(pipe, _MIPIA_HFP_COUNT, _MIPIB_HFP_COUNT) ++ ++#define _MIPIA_HACTIVE_AREA_COUNT (VLV_DISPLAY_BASE + 0xb034) ++#define _MIPIB_HACTIVE_AREA_COUNT (VLV_DISPLAY_BASE + 0xb834) ++#define MIPI_HACTIVE_AREA_COUNT(pipe) _PIPE(pipe, _MIPIA_HACTIVE_AREA_COUNT, _MIPIB_HACTIVE_AREA_COUNT) ++ ++#define _MIPIA_VSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb038) ++#define _MIPIB_VSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb838) ++#define MIPI_VSYNC_PADDING_COUNT(pipe) _PIPE(pipe, _MIPIA_VSYNC_PADDING_COUNT, _MIPIB_VSYNC_PADDING_COUNT) ++ ++#define _MIPIA_VBP_COUNT (VLV_DISPLAY_BASE + 0xb03c) ++#define _MIPIB_VBP_COUNT (VLV_DISPLAY_BASE + 0xb83c) ++#define MIPI_VBP_COUNT(pipe) _PIPE(pipe, _MIPIA_VBP_COUNT, _MIPIB_VBP_COUNT) ++ ++#define _MIPIA_VFP_COUNT (VLV_DISPLAY_BASE + 0xb040) ++#define _MIPIB_VFP_COUNT (VLV_DISPLAY_BASE + 0xb840) ++#define MIPI_VFP_COUNT(pipe) _PIPE(pipe, _MIPIA_VFP_COUNT, _MIPIB_VFP_COUNT) ++ ++#define _MIPIA_HIGH_LOW_SWITCH_COUNT (VLV_DISPLAY_BASE + 0xb044) ++#define _MIPIB_HIGH_LOW_SWITCH_COUNT (VLV_DISPLAY_BASE + 0xb844) ++#define MIPI_HIGH_LOW_SWITCH_COUNT(pipe) _PIPE(pipe, _MIPIA_HIGH_LOW_SWITCH_COUNT, _MIPIB_HIGH_LOW_SWITCH_COUNT) ++/* regs above are bits 15:0 */ ++ ++#define _MIPIA_DPI_CONTROL (VLV_DISPLAY_BASE + 0xb048) ++#define _MIPIB_DPI_CONTROL (VLV_DISPLAY_BASE + 0xb848) ++#define MIPI_DPI_CONTROL(pipe) _PIPE(pipe, _MIPIA_DPI_CONTROL, _MIPIB_DPI_CONTROL) ++#define DPI_LP_MODE (1 << 6) ++#define BACKLIGHT_OFF (1 << 5) ++#define BACKLIGHT_ON (1 << 4) ++#define COLOR_MODE_OFF (1 << 3) ++#define COLOR_MODE_ON (1 << 2) ++#define TURN_ON (1 << 1) ++#define SHUTDOWN (1 << 0) ++ ++#define _MIPIA_DPI_DATA (VLV_DISPLAY_BASE + 0xb04c) ++#define _MIPIB_DPI_DATA (VLV_DISPLAY_BASE + 0xb84c) ++#define MIPI_DPI_DATA(pipe) _PIPE(pipe, _MIPIA_DPI_DATA, _MIPIB_DPI_DATA) ++#define COMMAND_BYTE_SHIFT 0 ++#define COMMAND_BYTE_MASK (0x3f << 0) ++ ++#define _MIPIA_INIT_COUNT (VLV_DISPLAY_BASE + 0xb050) ++#define _MIPIB_INIT_COUNT (VLV_DISPLAY_BASE + 0xb850) ++#define MIPI_INIT_COUNT(pipe) _PIPE(pipe, _MIPIA_INIT_COUNT, _MIPIB_INIT_COUNT) ++#define MASTER_INIT_TIMER_SHIFT 0 ++#define MASTER_INIT_TIMER_MASK (0xffff << 0) ++ ++#define _MIPIA_MAX_RETURN_PKT_SIZE (VLV_DISPLAY_BASE + 0xb054) ++#define _MIPIB_MAX_RETURN_PKT_SIZE (VLV_DISPLAY_BASE + 0xb854) ++#define MIPI_MAX_RETURN_PKT_SIZE(pipe) _PIPE(pipe, _MIPIA_MAX_RETURN_PKT_SIZE, _MIPIB_MAX_RETURN_PKT_SIZE) ++#define MAX_RETURN_PKT_SIZE_SHIFT 0 ++#define MAX_RETURN_PKT_SIZE_MASK (0x3ff << 0) ++ ++#define _MIPIA_VIDEO_MODE_FORMAT (VLV_DISPLAY_BASE + 0xb058) ++#define _MIPIB_VIDEO_MODE_FORMAT (VLV_DISPLAY_BASE + 0xb858) ++#define MIPI_VIDEO_MODE_FORMAT(pipe) _PIPE(pipe, _MIPIA_VIDEO_MODE_FORMAT, _MIPIB_VIDEO_MODE_FORMAT) ++#define RANDOM_DPI_DISPLAY_RESOLUTION (1 << 4) ++#define DISABLE_VIDEO_BTA (1 << 3) ++#define IP_TG_CONFIG (1 << 2) ++#define VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE (1 << 0) ++#define VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS (2 << 0) ++#define VIDEO_MODE_BURST (3 << 0) ++ ++#define _MIPIA_EOT_DISABLE (VLV_DISPLAY_BASE + 0xb05c) ++#define _MIPIB_EOT_DISABLE (VLV_DISPLAY_BASE + 0xb85c) ++#define MIPI_EOT_DISABLE(pipe) _PIPE(pipe, _MIPIA_EOT_DISABLE, _MIPIB_EOT_DISABLE) ++#define LP_RX_TIMEOUT_ERROR_RECOVERY_DISABLE (1 << 7) ++#define HS_RX_TIMEOUT_ERROR_RECOVERY_DISABLE (1 << 6) ++#define LOW_CONTENTION_RECOVERY_DISABLE (1 << 5) ++#define HIGH_CONTENTION_RECOVERY_DISABLE (1 << 4) ++#define TXDSI_TYPE_NOT_RECOGNISED_ERROR_RECOVERY_DISABLE (1 << 3) ++#define TXECC_MULTIBIT_ERROR_RECOVERY_DISABLE (1 << 2) ++#define CLOCKSTOP (1 << 1) ++#define EOT_DISABLE (1 << 0) ++ ++#define _MIPIA_LP_BYTECLK (VLV_DISPLAY_BASE + 0xb060) ++#define _MIPIB_LP_BYTECLK (VLV_DISPLAY_BASE + 0xb860) ++#define MIPI_LP_BYTECLK(pipe) _PIPE(pipe, _MIPIA_LP_BYTECLK, _MIPIB_LP_BYTECLK) ++#define LP_BYTECLK_SHIFT 0 ++#define LP_BYTECLK_MASK (0xffff << 0) ++ ++/* bits 31:0 */ ++#define _MIPIA_LP_GEN_DATA (VLV_DISPLAY_BASE + 0xb064) ++#define _MIPIB_LP_GEN_DATA (VLV_DISPLAY_BASE + 0xb864) ++#define MIPI_LP_GEN_DATA(pipe) _PIPE(pipe, _MIPIA_LP_GEN_DATA, _MIPIB_LP_GEN_DATA) ++ ++/* bits 31:0 */ ++#define _MIPIA_HS_GEN_DATA (VLV_DISPLAY_BASE + 0xb068) ++#define _MIPIB_HS_GEN_DATA (VLV_DISPLAY_BASE + 0xb868) ++#define MIPI_HS_GEN_DATA(pipe) _PIPE(pipe, _MIPIA_HS_GEN_DATA, _MIPIB_HS_GEN_DATA) ++ ++#define _MIPIA_LP_GEN_CTRL (VLV_DISPLAY_BASE + 0xb06c) ++#define _MIPIB_LP_GEN_CTRL (VLV_DISPLAY_BASE + 0xb86c) ++#define MIPI_LP_GEN_CTRL(pipe) _PIPE(pipe, _MIPIA_LP_GEN_CTRL, _MIPIB_LP_GEN_CTRL) ++#define _MIPIA_HS_GEN_CTRL (VLV_DISPLAY_BASE + 0xb070) ++#define _MIPIB_HS_GEN_CTRL (VLV_DISPLAY_BASE + 0xb870) ++#define MIPI_HS_GEN_CTRL(pipe) _PIPE(pipe, _MIPIA_HS_GEN_CTRL, _MIPIB_HS_GEN_CTRL) ++#define LONG_PACKET_WORD_COUNT_SHIFT 8 ++#define LONG_PACKET_WORD_COUNT_MASK (0xffff << 8) ++#define SHORT_PACKET_PARAM_SHIFT 8 ++#define SHORT_PACKET_PARAM_MASK (0xffff << 8) ++#define VIRTUAL_CHANNEL_SHIFT 6 ++#define VIRTUAL_CHANNEL_MASK (3 << 6) ++#define DATA_TYPE_SHIFT 0 ++#define DATA_TYPE_MASK (3f << 0) ++/* data type values, see include/video/mipi_display.h */ ++ ++#define _MIPIA_GEN_FIFO_STAT (VLV_DISPLAY_BASE + 0xb074) ++#define _MIPIB_GEN_FIFO_STAT (VLV_DISPLAY_BASE + 0xb874) ++#define MIPI_GEN_FIFO_STAT(pipe) _PIPE(pipe, _MIPIA_GEN_FIFO_STAT, _MIPIB_GEN_FIFO_STAT) ++#define DPI_FIFO_EMPTY (1 << 28) ++#define DBI_FIFO_EMPTY (1 << 27) ++#define LP_CTRL_FIFO_EMPTY (1 << 26) ++#define LP_CTRL_FIFO_HALF_EMPTY (1 << 25) ++#define LP_CTRL_FIFO_FULL (1 << 24) ++#define HS_CTRL_FIFO_EMPTY (1 << 18) ++#define HS_CTRL_FIFO_HALF_EMPTY (1 << 17) ++#define HS_CTRL_FIFO_FULL (1 << 16) ++#define LP_DATA_FIFO_EMPTY (1 << 10) ++#define LP_DATA_FIFO_HALF_EMPTY (1 << 9) ++#define LP_DATA_FIFO_FULL (1 << 8) ++#define HS_DATA_FIFO_EMPTY (1 << 2) ++#define HS_DATA_FIFO_HALF_EMPTY (1 << 1) ++#define HS_DATA_FIFO_FULL (1 << 0) ++ ++#define _MIPIA_HS_LS_DBI_ENABLE (VLV_DISPLAY_BASE + 0xb078) ++#define _MIPIB_HS_LS_DBI_ENABLE (VLV_DISPLAY_BASE + 0xb878) ++#define MIPI_HS_LP_DBI_ENABLE(pipe) _PIPE(pipe, _MIPIA_HS_LS_DBI_ENABLE, _MIPIB_HS_LS_DBI_ENABLE) ++#define DBI_HS_LP_MODE_MASK (1 << 0) ++#define DBI_LP_MODE (1 << 0) ++#define DBI_HS_MODE (0 << 0) ++ ++#define _MIPIA_DPHY_PARAM (VLV_DISPLAY_BASE + 0xb080) ++#define _MIPIB_DPHY_PARAM (VLV_DISPLAY_BASE + 0xb880) ++#define MIPI_DPHY_PARAM(pipe) _PIPE(pipe, _MIPIA_DPHY_PARAM, _MIPIB_DPHY_PARAM) ++#define EXIT_ZERO_COUNT_SHIFT 24 ++#define EXIT_ZERO_COUNT_MASK (0x3f << 24) ++#define TRAIL_COUNT_SHIFT 16 ++#define TRAIL_COUNT_MASK (0x1f << 16) ++#define CLK_ZERO_COUNT_SHIFT 8 ++#define CLK_ZERO_COUNT_MASK (0xff << 8) ++#define PREPARE_COUNT_SHIFT 0 ++#define PREPARE_COUNT_MASK (0x3f << 0) ++ ++/* bits 31:0 */ ++#define _MIPIA_DBI_BW_CTRL (VLV_DISPLAY_BASE + 0xb084) ++#define _MIPIB_DBI_BW_CTRL (VLV_DISPLAY_BASE + 0xb884) ++#define MIPI_DBI_BW_CTRL(pipe) _PIPE(pipe, _MIPIA_DBI_BW_CTRL, _MIPIB_DBI_BW_CTRL) ++ ++#define _MIPIA_CLK_LANE_SWITCH_TIME_CNT (VLV_DISPLAY_BASE + 0xb088) ++#define _MIPIB_CLK_LANE_SWITCH_TIME_CNT (VLV_DISPLAY_BASE + 0xb888) ++#define MIPI_CLK_LANE_SWITCH_TIME_CNT(pipe) _PIPE(pipe, _MIPIA_CLK_LANE_SWITCH_TIME_CNT, _MIPIB_CLK_LANE_SWITCH_TIME_CNT) ++#define LP_HS_SSW_CNT_SHIFT 16 ++#define LP_HS_SSW_CNT_MASK (0xffff << 16) ++#define HS_LP_PWR_SW_CNT_SHIFT 0 ++#define HS_LP_PWR_SW_CNT_MASK (0xffff << 0) ++ ++#define _MIPIA_STOP_STATE_STALL (VLV_DISPLAY_BASE + 0xb08c) ++#define _MIPIB_STOP_STATE_STALL (VLV_DISPLAY_BASE + 0xb88c) ++#define MIPI_STOP_STATE_STALL(pipe) _PIPE(pipe, _MIPIA_STOP_STATE_STALL, _MIPIB_STOP_STATE_STALL) ++#define STOP_STATE_STALL_COUNTER_SHIFT 0 ++#define STOP_STATE_STALL_COUNTER_MASK (0xff << 0) ++ ++#define _MIPIA_INTR_STAT_REG_1 (VLV_DISPLAY_BASE + 0xb090) ++#define _MIPIB_INTR_STAT_REG_1 (VLV_DISPLAY_BASE + 0xb890) ++#define MIPI_INTR_STAT_REG_1(pipe) _PIPE(pipe, _MIPIA_INTR_STAT_REG_1, _MIPIB_INTR_STAT_REG_1) ++#define _MIPIA_INTR_EN_REG_1 (VLV_DISPLAY_BASE + 0xb094) ++#define _MIPIB_INTR_EN_REG_1 (VLV_DISPLAY_BASE + 0xb894) ++#define MIPI_INTR_EN_REG_1(pipe) _PIPE(pipe, _MIPIA_INTR_EN_REG_1, _MIPIB_INTR_EN_REG_1) ++#define RX_CONTENTION_DETECTED (1 << 0) ++ ++/* XXX: only pipe A ?!? */ ++#define MIPIA_DBI_TYPEC_CTRL (VLV_DISPLAY_BASE + 0xb100) ++#define DBI_TYPEC_ENABLE (1 << 31) ++#define DBI_TYPEC_WIP (1 << 30) ++#define DBI_TYPEC_OPTION_SHIFT 28 ++#define DBI_TYPEC_OPTION_MASK (3 << 28) ++#define DBI_TYPEC_FREQ_SHIFT 24 ++#define DBI_TYPEC_FREQ_MASK (0xf << 24) ++#define DBI_TYPEC_OVERRIDE (1 << 8) ++#define DBI_TYPEC_OVERRIDE_COUNTER_SHIFT 0 ++#define DBI_TYPEC_OVERRIDE_COUNTER_MASK (0xff << 0) ++ ++ ++/* MIPI adapter registers */ ++ ++#define _MIPIA_CTRL (VLV_DISPLAY_BASE + 0xb104) ++#define _MIPIB_CTRL (VLV_DISPLAY_BASE + 0xb904) ++#define MIPI_CTRL(pipe) _PIPE(pipe, _MIPIA_CTRL, _MIPIB_CTRL) ++#define ESCAPE_CLOCK_DIVIDER_SHIFT 5 /* A only */ ++#define ESCAPE_CLOCK_DIVIDER_MASK (3 << 5) ++#define ESCAPE_CLOCK_DIVIDER_1 (0 << 5) ++#define ESCAPE_CLOCK_DIVIDER_2 (1 << 5) ++#define ESCAPE_CLOCK_DIVIDER_4 (2 << 5) ++#define READ_REQUEST_PRIORITY_SHIFT 3 ++#define READ_REQUEST_PRIORITY_MASK (3 << 3) ++#define READ_REQUEST_PRIORITY_LOW (0 << 3) ++#define READ_REQUEST_PRIORITY_HIGH (3 << 3) ++#define RGB_FLIP_TO_BGR (1 << 2) ++ ++#define _MIPIA_DATA_ADDRESS (VLV_DISPLAY_BASE + 0xb108) ++#define _MIPIB_DATA_ADDRESS (VLV_DISPLAY_BASE + 0xb908) ++#define MIPI_DATA_ADDRESS(pipe) _PIPE(pipe, _MIPIA_DATA_ADDRESS, _MIPIB_DATA_ADDRESS) ++#define DATA_MEM_ADDRESS_SHIFT 5 ++#define DATA_MEM_ADDRESS_MASK (0x7ffffff << 5) ++#define DATA_VALID (1 << 0) ++ ++#define _MIPIA_DATA_LENGTH (VLV_DISPLAY_BASE + 0xb10c) ++#define _MIPIB_DATA_LENGTH (VLV_DISPLAY_BASE + 0xb90c) ++#define MIPI_DATA_LENGTH(pipe) _PIPE(pipe, _MIPIA_DATA_LENGTH, _MIPIB_DATA_LENGTH) ++#define DATA_LENGTH_SHIFT 0 ++#define DATA_LENGTH_MASK (0xfffff << 0) ++ ++#define _MIPIA_COMMAND_ADDRESS (VLV_DISPLAY_BASE + 0xb110) ++#define _MIPIB_COMMAND_ADDRESS (VLV_DISPLAY_BASE + 0xb910) ++#define MIPI_COMMAND_ADDRESS(pipe) _PIPE(pipe, _MIPIA_COMMAND_ADDRESS, _MIPIB_COMMAND_ADDRESS) ++#define COMMAND_MEM_ADDRESS_SHIFT 5 ++#define COMMAND_MEM_ADDRESS_MASK (0x7ffffff << 5) ++#define AUTO_PWG_ENABLE (1 << 2) ++#define MEMORY_WRITE_DATA_FROM_PIPE_RENDERING (1 << 1) ++#define COMMAND_VALID (1 << 0) ++ ++#define _MIPIA_COMMAND_LENGTH (VLV_DISPLAY_BASE + 0xb114) ++#define _MIPIB_COMMAND_LENGTH (VLV_DISPLAY_BASE + 0xb914) ++#define MIPI_COMMAND_LENGTH(pipe) _PIPE(pipe, _MIPIA_COMMAND_LENGTH, _MIPIB_COMMAND_LENGTH) ++#define COMMAND_LENGTH_SHIFT(n) (8 * (n)) /* n: 0...3 */ ++#define COMMAND_LENGTH_MASK(n) (0xff << (8 * (n))) ++ ++#define _MIPIA_READ_DATA_RETURN0 (VLV_DISPLAY_BASE + 0xb118) ++#define _MIPIB_READ_DATA_RETURN0 (VLV_DISPLAY_BASE + 0xb918) ++#define MIPI_READ_DATA_RETURN(pipe, n) \ ++ (_PIPE(pipe, _MIPIA_READ_DATA_RETURN0, _MIPIB_READ_DATA_RETURN0) + 4 * (n)) /* n: 0...7 */ ++ ++#define _MIPIA_READ_DATA_VALID (VLV_DISPLAY_BASE + 0xb138) ++#define _MIPIB_READ_DATA_VALID (VLV_DISPLAY_BASE + 0xb938) ++#define MIPI_READ_DATA_VALID(pipe) _PIPE(pipe, _MIPIA_READ_DATA_VALID, _MIPIB_READ_DATA_VALID) ++#define READ_DATA_VALID(n) (1 << (n)) ++ + #endif /* _I915_REG_H_ */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0773-drm-i915-add-MIPI-DSI-output-type-and-subtypes.patch b/patches.baytrail/0773-drm-i915-add-MIPI-DSI-output-type-and-subtypes.patch new file mode 100644 index 000000000000..26cbbd6200bc --- /dev/null +++ b/patches.baytrail/0773-drm-i915-add-MIPI-DSI-output-type-and-subtypes.patch @@ -0,0 +1,44 @@ +From 9db1dea327d92cc10800298439a4fef007e587ec Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 27 Aug 2013 15:12:17 +0300 +Subject: drm/i915: add MIPI DSI output type and subtypes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jani Nikula +Signed-off-by: Shobhit Kumar +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 72ffa333418426b46648ac84ad4f015963b025e1) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_drv.h | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index dbfe5f7bb3de..8e0d54d895be 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -93,13 +93,17 @@ + #define INTEL_OUTPUT_HDMI 6 + #define INTEL_OUTPUT_DISPLAYPORT 7 + #define INTEL_OUTPUT_EDP 8 +-#define INTEL_OUTPUT_UNKNOWN 9 ++#define INTEL_OUTPUT_DSI 9 ++#define INTEL_OUTPUT_UNKNOWN 10 + + #define INTEL_DVO_CHIP_NONE 0 + #define INTEL_DVO_CHIP_LVDS 1 + #define INTEL_DVO_CHIP_TMDS 2 + #define INTEL_DVO_CHIP_TVOUT 4 + ++#define INTEL_DSI_COMMAND_MODE 0 ++#define INTEL_DSI_VIDEO_MODE 1 ++ + struct intel_framebuffer { + struct drm_framebuffer base; + struct drm_i915_gem_object *obj; +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0774-drm-i915-add-structs-for-MIPI-DSI-output.patch b/patches.baytrail/0774-drm-i915-add-structs-for-MIPI-DSI-output.patch new file mode 100644 index 000000000000..a6bbc6c699a1 --- /dev/null +++ b/patches.baytrail/0774-drm-i915-add-structs-for-MIPI-DSI-output.patch @@ -0,0 +1,130 @@ +From 99efbb3e01856ef6d1cd2e1b072958e9d7d1fd76 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 27 Aug 2013 15:12:18 +0300 +Subject: drm/i915: add structs for MIPI DSI output +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The sub-encoder model is copied from DVO. + +v2: Add attached_connector to struct intel_dsi. + +Signed-off-by: Jani Nikula +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit f5e11b06eb8a5aa6d4918aca85f88268e131a88e) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/intel_dsi.h | 99 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 99 insertions(+) + create mode 100644 drivers/gpu/drm/i915/intel_dsi.h + +diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h +new file mode 100644 +index 000000000000..f308269cd87c +--- /dev/null ++++ b/drivers/gpu/drm/i915/intel_dsi.h +@@ -0,0 +1,99 @@ ++/* ++ * Copyright © 2013 Intel Corporation ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++ ++#ifndef _INTEL_DSI_H ++#define _INTEL_DSI_H ++ ++#include ++#include ++#include "intel_drv.h" ++ ++struct intel_dsi_device { ++ unsigned int panel_id; ++ const char *name; ++ int type; ++ const struct intel_dsi_dev_ops *dev_ops; ++ void *dev_priv; ++}; ++ ++struct intel_dsi_dev_ops { ++ bool (*init)(struct intel_dsi_device *dsi); ++ ++ /* This callback must be able to assume DSI commands can be sent */ ++ void (*enable)(struct intel_dsi_device *dsi); ++ ++ /* This callback must be able to assume DSI commands can be sent */ ++ void (*disable)(struct intel_dsi_device *dsi); ++ ++ int (*mode_valid)(struct intel_dsi_device *dsi, ++ struct drm_display_mode *mode); ++ ++ bool (*mode_fixup)(struct intel_dsi_device *dsi, ++ const struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode); ++ ++ void (*mode_set)(struct intel_dsi_device *dsi, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode); ++ ++ enum drm_connector_status (*detect)(struct intel_dsi_device *dsi); ++ ++ bool (*get_hw_state)(struct intel_dsi_device *dev); ++ ++ struct drm_display_mode *(*get_modes)(struct intel_dsi_device *dsi); ++ ++ void (*destroy) (struct intel_dsi_device *dsi); ++}; ++ ++struct intel_dsi { ++ struct intel_encoder base; ++ ++ struct intel_dsi_device dev; ++ ++ struct intel_connector *attached_connector; ++ ++ /* if true, use HS mode, otherwise LP */ ++ bool hs; ++ ++ /* virtual channel */ ++ int channel; ++ ++ /* number of DSI lanes */ ++ unsigned int lane_count; ++ ++ /* video mode pixel format for MIPI_DSI_FUNC_PRG register */ ++ u32 pixel_format; ++ ++ /* video mode format for MIPI_VIDEO_MODE_FORMAT register */ ++ u32 video_mode_format; ++ ++ /* eot for MIPI_EOT_DISABLE register */ ++ u32 eot_disable; ++}; ++ ++static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) ++{ ++ return container_of(encoder, struct intel_dsi, base.base); ++} ++ ++#endif /* _INTEL_DSI_H */ +-- +1.8.5.rc3 + diff --git a/patches.baytrail/0775-drm-i915-add-MIPI-DSI-command-sending-routines.patch b/patches.baytrail/0775-drm-i915-add-MIPI-DSI-command-sending-routines.patch new file mode 100644 index 000000000000..9af25c9e9b66 --- /dev/null +++ b/patches.baytrail/0775-drm-i915-add-MIPI-DSI-command-sending-routines.patch @@ -0,0 +1,593 @@ +From a576567dfb63cb6803f96deee10310e56423a9a8 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 27 Aug 2013 15:12:19 +0300 +Subject: drm/i915: add MIPI DSI command sending routines +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +v2: Rebase due to register bit definition change. + +v3: Mostly based on Ville's review comments. + - Use size_t for length all around. + - Reuse dsi_vc_send_short in dsi_vc_send_long. + - Remove stale/incorrect comments. + - Reverse special packet sent interrupt check. + - Use DSI controller regs for reading, not adapter. + +Signed-off-by: Jani Nikula +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +(cherry picked from commit 69c05eb2d8421cbe96c2c66ea6e3223d25928d92) +Signed-off-by: Darren Hart +--- + drivers/gpu/drm/i915/Makefile | 1 + + drivers/gpu/drm/i915/intel_dsi_cmd.c | 427 +++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/i915/intel_dsi_cmd.h | 109 +++++++++ + 3 files changed, 537 insertions(+) + create mode 100644 drivers/gpu/drm/i915/intel_dsi_cmd.c + create mode 100644 drivers/gpu/drm/i915/intel_dsi_cmd.h + +diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile +index b8449a84a0dc..8bffd292d1dc 100644 +--- a/drivers/gpu/drm/i915/Makefile ++++ b/drivers/gpu/drm/i915/Makefile +@@ -21,6 +21,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \ + intel_display.o \ + intel_crt.o \ + intel_lvds.o \ ++ intel_dsi_cmd.o \ + intel_bios.o \ + intel_ddi.o \ + intel_dp.o \ +diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.c b/drivers/gpu/drm/i915/intel_dsi_cmd.c +new file mode 100644 +index 000000000000..86577a0fc620 +--- /dev/null ++++ b/drivers/gpu/drm/i915/intel_dsi_cmd.c +@@ -0,0 +1,427 @@ ++/* ++ * Copyright © 2013 Intel Corporation ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Author: Jani Nikula ++ */ ++ ++#include ++#include ++#include ++#include